Changeset View
Changeset View
Standalone View
Standalone View
source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp
/* Copyright (C) 2019 Wildfire Games. | /* Copyright (C) 2020 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 14 Lines | |||||
#include "ScenarioEditor/ScenarioEditor.h" | #include "ScenarioEditor/ScenarioEditor.h" | ||||
#include "ScenarioEditor/Tools/Common/ObjectSettings.h" | #include "ScenarioEditor/Tools/Common/ObjectSettings.h" | ||||
#include "ScenarioEditor/Tools/Common/MiscState.h" | #include "ScenarioEditor/Tools/Common/MiscState.h" | ||||
#include "VariationControl.h" | #include "VariationControl.h" | ||||
#include "GameInterface/Messages.h" | #include "GameInterface/Messages.h" | ||||
#include "wx/busyinfo.h" | #include "wx/busyinfo.h" | ||||
#include "wx/wxcrt.h" | |||||
namespace | |||||
{ | |||||
int CalculateSearchWeight(const wxString& filterName, const wxString& name) | |||||
{ | |||||
// At the moment we just use subsequence calculation. | |||||
int weight = 0; | |||||
// Indices for |filterName| and |name| respectively. | |||||
size_t idx_fn = 0, idx_n = 0; | |||||
while (idx_fn < filterName.Length() && idx_n < name.Length()) | |||||
{ | |||||
if (wxIsspace(filterName.GetChar(idx_fn))) | |||||
++idx_fn; | |||||
else if (wxIsspace(name.GetChar(idx_n))) | |||||
++idx_n; | |||||
else if (wxTolower(filterName.GetChar(idx_fn)) == wxTolower(name.GetChar(idx_n))) | |||||
{ | |||||
++weight; | |||||
++idx_fn; | |||||
++idx_n; | |||||
} | |||||
else | |||||
{ | |||||
++idx_n; | |||||
} | |||||
} | |||||
return weight; | |||||
} | |||||
} | |||||
enum | enum | ||||
{ | { | ||||
ID_ObjectType = 1, | ID_ObjectType = 1, | ||||
ID_ObjectFilter, | ID_ObjectFilter, | ||||
ID_ObjectAdvancedFilter, | |||||
ID_PlayerSelect, | ID_PlayerSelect, | ||||
ID_SelectObject, | ID_SelectObject, | ||||
ID_ToggleViewer, | ID_ToggleViewer, | ||||
ID_ViewerWireframe, | ID_ViewerWireframe, | ||||
ID_ViewerMove, | ID_ViewerMove, | ||||
ID_ViewerGround, | ID_ViewerGround, | ||||
ID_ViewerWater, | ID_ViewerWater, | ||||
ID_ViewerShadows, | ID_ViewerShadows, | ||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | ) | ||||
wxSizer* scrollSizer = new wxBoxSizer(wxVERTICAL); | wxSizer* scrollSizer = new wxBoxSizer(wxVERTICAL); | ||||
wxScrolledWindow* scrolledWindow = new wxScrolledWindow(this); | wxScrolledWindow* scrolledWindow = new wxScrolledWindow(this); | ||||
scrolledWindow->SetScrollRate(10, 10); | scrolledWindow->SetScrollRate(10, 10); | ||||
scrolledWindow->SetSizer(scrollSizer); | scrolledWindow->SetSizer(scrollSizer); | ||||
m_MainSizer->Add(scrolledWindow, wxSizerFlags().Proportion(1).Expand()); | m_MainSizer->Add(scrolledWindow, wxSizerFlags().Proportion(1).Expand()); | ||||
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); | wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
sizer->Add(new wxStaticText(scrolledWindow, wxID_ANY, _("Filter")), wxSizerFlags().Align(wxALIGN_CENTER)); | sizer->Add(new wxStaticText(scrolledWindow, wxID_ANY, _("Filter")), wxSizerFlags().Align(wxALIGN_CENTER)); | ||||
sizer->AddSpacer(2); | |||||
sizer->Add( | sizer->Add( | ||||
Tooltipped( | Tooltipped( | ||||
new wxTextCtrl(scrolledWindow, ID_ObjectFilter), | new wxTextCtrl(scrolledWindow, ID_ObjectFilter), | ||||
_("Enter text to filter object list") | _("Enter text to filter object list") | ||||
), | ), | ||||
wxSizerFlags().Expand().Proportion(1) | wxSizerFlags().Expand().Proportion(1) | ||||
); | ); | ||||
scrollSizer->Add(sizer, wxSizerFlags().Expand()); | scrollSizer->Add(sizer, wxSizerFlags().Expand()); | ||||
scrollSizer->AddSpacer(3); | scrollSizer->AddSpacer(3); | ||||
scrollSizer->Add(Tooltipped(new wxCheckBox( | |||||
scrolledWindow, ID_ObjectAdvancedFilter, _("Advanced Search")), | |||||
_("Provides a search without strict string equality"))); | |||||
scrollSizer->AddSpacer(3); | |||||
// ------------------------------------------------------------------------------------------ | // ------------------------------------------------------------------------------------------ | ||||
wxArrayString strings; | wxArrayString strings; | ||||
strings.Add(_("Entities")); | strings.Add(_("Entities")); | ||||
strings.Add(_("Actors (all)")); | strings.Add(_("Actors (all)")); | ||||
wxChoice* objectType = new wxChoice(scrolledWindow, ID_ObjectType, wxDefaultPosition, wxDefaultSize, strings); | wxChoice* objectType = new wxChoice(scrolledWindow, ID_ObjectType, wxDefaultPosition, wxDefaultSize, strings); | ||||
objectType->SetSelection(0); | objectType->SetSelection(0); | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
void ObjectSidebar::FilterObjects() | void ObjectSidebar::FilterObjects() | ||||
{ | { | ||||
int filterType = wxDynamicCast(FindWindow(ID_ObjectType), wxChoice)->GetSelection(); | int filterType = wxDynamicCast(FindWindow(ID_ObjectType), wxChoice)->GetSelection(); | ||||
wxString filterName = wxDynamicCast(FindWindow(ID_ObjectFilter), wxTextCtrl)->GetValue(); | wxString filterName = wxDynamicCast(FindWindow(ID_ObjectFilter), wxTextCtrl)->GetValue(); | ||||
m_Impl->m_ObjectListBox->Freeze(); | m_Impl->m_ObjectListBox->Freeze(); | ||||
m_Impl->m_ObjectListBox->Clear(); | m_Impl->m_ObjectListBox->Clear(); | ||||
if (wxDynamicCast(FindWindow(ID_ObjectAdvancedFilter), wxCheckBox)->IsChecked() && !filterName.IsEmpty()) | |||||
{ | |||||
struct Item | |||||
{ | |||||
// Weight of the pattern (higher - better). | |||||
int weight; | |||||
// We store iterator to avoid useless copying. | |||||
std::vector<AtlasMessage::sObjectsListItem>::iterator it; | |||||
bool operator<(const Item& other) const | |||||
{ | |||||
return weight > other.weight; | |||||
} | |||||
}; | |||||
std::vector<Item> searchItems; | |||||
for (std::vector<AtlasMessage::sObjectsListItem>::iterator it = m_Impl->m_Objects.begin(); it != m_Impl->m_Objects.end(); ++it) | for (std::vector<AtlasMessage::sObjectsListItem>::iterator it = m_Impl->m_Objects.begin(); it != m_Impl->m_Objects.end(); ++it) | ||||
{ | { | ||||
if (it->type == filterType) | if (it->type != filterType) | ||||
continue; | |||||
wxString name = it->name.c_str(); | |||||
int weight = CalculateSearchWeight(filterName, name); | |||||
// We don't want to show items with zero weight. | |||||
if (weight == 0) | |||||
continue; | |||||
searchItems.push_back({weight, it}); | |||||
} | |||||
std::sort(searchItems.begin(), searchItems.end()); | |||||
for (const Item& item : searchItems) | |||||
{ | { | ||||
wxString id = item.it->id.c_str(); | |||||
wxString name = item.it->name.c_str(); | |||||
m_Impl->m_ObjectListBox->Append(name, new wxStringClientData(id)); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
for (std::vector<AtlasMessage::sObjectsListItem>::iterator it = m_Impl->m_Objects.begin(); it != m_Impl->m_Objects.end(); ++it) | |||||
{ | |||||
if (it->type != filterType) | |||||
continue; | |||||
wxString id = it->id.c_str(); | wxString id = it->id.c_str(); | ||||
wxString name = it->name.c_str(); | wxString name = it->name.c_str(); | ||||
if (name.Lower().Find(filterName.Lower()) != wxNOT_FOUND) | if (name.Lower().Find(filterName.Lower()) != wxNOT_FOUND) | ||||
{ | |||||
m_Impl->m_ObjectListBox->Append(name, new wxStringClientData(id)); | m_Impl->m_ObjectListBox->Append(name, new wxStringClientData(id)); | ||||
} | } | ||||
} | } | ||||
} | |||||
m_Impl->m_ObjectListBox->Thaw(); | m_Impl->m_ObjectListBox->Thaw(); | ||||
} | } | ||||
void ObjectSidebar::OnToggleViewer(wxCommandEvent& WXUNUSED(evt)) | void ObjectSidebar::OnToggleViewer(wxCommandEvent& WXUNUSED(evt)) | ||||
{ | { | ||||
if (m_Impl->m_ActorViewerActive) | if (m_Impl->m_ActorViewerActive) | ||||
{ | { | ||||
m_ScenarioEditor.GetToolManager().SetCurrentTool(_T(""), NULL); | m_ScenarioEditor.GetToolManager().SetCurrentTool(_T(""), NULL); | ||||
} | } | ||||
else | else | ||||
Stan: negative weight possible? Else maybe size_t here and for function? | |||||
Done Inline ActionsI think I might have an idea to use negative ones. But ok, int isn't necessary here. vladislavbelov: I think I might have an idea to use negative ones. But ok, `int` isn't necessary here. | |||||
{ | { | ||||
m_ScenarioEditor.GetToolManager().SetCurrentTool(_T("ActorViewerTool"), NULL); | m_ScenarioEditor.GetToolManager().SetCurrentTool(_T("ActorViewerTool"), NULL); | ||||
Not Done Inline Actions!weight? Stan: !weight? | |||||
Done Inline ActionsProbably. vladislavbelov: Probably. | |||||
} | } | ||||
} | } | ||||
void ObjectSidebar::OnSelectType(wxCommandEvent& WXUNUSED(evt)) | void ObjectSidebar::OnSelectType(wxCommandEvent& WXUNUSED(evt)) | ||||
{ | { | ||||
FilterObjects(); | FilterObjects(); | ||||
} | } | ||||
Not Done Inline Actionsno way to avoid those conversions? Which by the way look implicit. Stan: no way to avoid those conversions? Which by the way look implicit. | |||||
Done Inline ActionsNope, it needs to have an explicit cast for different wxWidget versions. Also the function requires const wxString&, so it's not movable. vladislavbelov: Nope, it needs to have an explicit cast for different wxWidget versions. Also the function… | |||||
void ObjectSidebar::OnSelectObject(wxCommandEvent& evt) | void ObjectSidebar::OnSelectObject(wxCommandEvent& evt) | ||||
{ | { | ||||
if (evt.GetInt() < 0) | if (evt.GetInt() < 0) | ||||
return; | return; | ||||
wxString id = static_cast<wxStringClientData*>(evt.GetClientObject())->GetData(); | wxString id = static_cast<wxStringClientData*>(evt.GetClientObject())->GetData(); | ||||
// Always update the actor viewer's state even if it's inactive, | // Always update the actor viewer's state even if it's inactive, | ||||
▲ Show 20 Lines • Show All 378 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
negative weight possible? Else maybe size_t here and for function?