1 /* Author: Tobi Vollebregt */
2
3 #include "mapselectdialog.h"
4
5 #include "battle.h"
6 #include "server.h"
7 #include "settings.h"
8 #include "ui.h"
9 #include "uiutils.h"
10 #include "utils/controls.h"
11 #include "utils/conversion.h"
12 #include "utils/debug.h"
13 #include "settings.h"
14 #include <lslutils/globalsmanager.h>
15 #include <wx/settings.h>
16 #include <lslutils/misc.h>
17
18 //(*InternalHeaders(MapSelectDialog)
19 #include <wx/listctrl.h>
20 #include <wx/sizer.h>
21 #include <wx/stattext.h>
22 #include <wx/textctrl.h>
23 #include <wx/radiobut.h>
24 #include "mapgridctrl.h"
25 #include <wx/choice.h>
26 #include <wx/intl.h>
27 #include <wx/button.h>
28 #include <wx/string.h>
29 //*)
30
31 //(*IdInit(MapSelectDialog)
32 const long MapSelectDialog::ID_STATICTEXT2 = wxNewId();
33 const long MapSelectDialog::ID_VERTICAL_CHOICE = wxNewId();
34 const long MapSelectDialog::ID_STATICTEXT1 = wxNewId();
35 const long MapSelectDialog::ID_HORIZONTAL_CHOICE = wxNewId();
36 const long MapSelectDialog::ID_FILTER_ALL = wxNewId();
37 const long MapSelectDialog::ID_FILTER_POPULAR = wxNewId();
38 const long MapSelectDialog::ID_FILTER_RECENT = wxNewId();
39 const long MapSelectDialog::ID_FILTER_TEXT = wxNewId();
40 const long MapSelectDialog::ID_MAP_NAME = wxNewId();
41 const long MapSelectDialog::ID_MAP_OPTS_LIST = wxNewId();
42 const long MapSelectDialog::ID_MAPGRID = wxNewId();
43 //*)
44 const long MapSelectDialog::ID_VERTICAL_DIRECTION = wxNewId();
45 const long MapSelectDialog::ID_HORIZONTAL_DIRECTION = wxNewId();
46
47 const wxString MapSelectDialog::m_dialog_name = _T("MapSelector");
48
BEGIN_EVENT_TABLE(MapSelectDialog,wxDialog)49 BEGIN_EVENT_TABLE(MapSelectDialog,wxDialog)
50 //(*EventTable(MapSelectDialog)
51 //*)
52 END_EVENT_TABLE()
53
54 MapSelectDialog::MapSelectDialog( wxWindow* parent )
55 : // WindowHintsPickle( m_dialog_name, this, wxSize( DEFSETT_MW_WIDTH, DEFSETT_MW_HEIGHT ) ),
56 m_horizontal_direction( sett().GetHorizontalSortorder() ),
57 m_vertical_direction( sett().GetVerticalSortorder() )
58 {
59 //(*Initialize(MapSelectDialog)
60 wxStaticBoxSizer* StaticBoxSizer2;
61 wxStaticText* StaticText2;
62 wxStaticText* StaticText1;
63 wxBoxSizer* BoxSizer2;
64 wxBoxSizer* boxSizerHorizontal;
65 wxBoxSizer* BoxSizer1;
66 wxStaticBoxSizer* StaticBoxSizer1;
67 wxBoxSizer* boxSizerVertical;
68 wxStdDialogButtonSizer* StdDialogButtonSizer1;
69
70 Create(parent, wxID_ANY, _("Select map (click and drag to scroll)"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX, _T("wxID_ANY"));
71 BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
72 BoxSizer2 = new wxBoxSizer(wxVERTICAL);
73 StaticText2 = new wxStaticText(this, ID_STATICTEXT2, _("Vertical sort key"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2"));
74 BoxSizer2->Add(StaticText2, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
75 boxSizerVertical = new wxBoxSizer(wxHORIZONTAL);
76 m_vertical_choice = new wxChoice(this, ID_VERTICAL_CHOICE, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_VERTICAL_CHOICE"));
77 boxSizerVertical->Add(m_vertical_choice, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
78 BoxSizer2->Add(boxSizerVertical, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
79 StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("Horizontal sort key"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
80 BoxSizer2->Add(StaticText1, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
81 boxSizerHorizontal = new wxBoxSizer(wxHORIZONTAL);
82 m_horizontal_choice = new wxChoice(this, ID_HORIZONTAL_CHOICE, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_HORIZONTAL_CHOICE"));
83 boxSizerHorizontal->Add(m_horizontal_choice, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
84 BoxSizer2->Add(boxSizerHorizontal, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
85 StaticBoxSizer1 = new wxStaticBoxSizer(wxVERTICAL, this, _("Show"));
86 m_filter_all = new wxRadioButton(this, ID_FILTER_ALL, _("All maps"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_FILTER_ALL"));
87 m_filter_all->SetToolTip(_("Shows all available maps"));
88 StaticBoxSizer1->Add(m_filter_all, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
89 m_filter_popular = new wxRadioButton(this, ID_FILTER_POPULAR, _("Popular maps"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_FILTER_POPULAR"));
90 m_filter_popular->SetToolTip(_("Shows only maps which are currently being player on the server. You must be online to use this."));
91 StaticBoxSizer1->Add(m_filter_popular, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
92 m_filter_recent = new wxRadioButton(this, ID_FILTER_RECENT, _("Recently played maps"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_FILTER_RECENT"));
93 m_filter_recent->SetValue(true);
94 m_filter_recent->SetToolTip(_("Shows only maps you played recently. (Based on your replays.)"));
95 StaticBoxSizer1->Add(m_filter_recent, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
96 BoxSizer2->Add(StaticBoxSizer1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
97 StaticBoxSizer2 = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Filter"));
98 m_filter_text = new wxTextCtrl(this, ID_FILTER_TEXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_FILTER_TEXT"));
99 m_filter_text->SetToolTip(_("Shows only maps which contain this text in their name or description."));
100 StaticBoxSizer2->Add(m_filter_text, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
101 BoxSizer2->Add(StaticBoxSizer2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
102 m_map_details = new wxStaticBoxSizer(wxVERTICAL, this, _("Map details"));
103 m_map_name = new wxStaticText(this, ID_MAP_NAME, wxEmptyString, wxDefaultPosition, wxSize(170,90), wxST_NO_AUTORESIZE, _T("ID_MAP_NAME"));
104 m_map_name->SetLabel( wxEmptyString );
105 m_map_details->Add(m_map_name, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
106 m_map_opts_list = new wxListCtrl(this, ID_MAP_OPTS_LIST, wxDefaultPosition, wxSize(170,120), wxLC_REPORT|wxLC_NO_HEADER|wxNO_BORDER, wxDefaultValidator, _T("ID_MAP_OPTS_LIST"));
107 m_map_details->Add(m_map_opts_list, 1, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
108 BoxSizer2->Add(m_map_details, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
109 StdDialogButtonSizer1 = new wxStdDialogButtonSizer();
110 StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_OK, wxEmptyString));
111 StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_CANCEL, wxEmptyString));
112 StdDialogButtonSizer1->Realize();
113 BoxSizer2->Add(StdDialogButtonSizer1, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
114 BoxSizer1->Add(BoxSizer2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
115 m_mapgrid = new MapGridCtrl(this, wxSize(600,400), ID_MAPGRID);
116 BoxSizer1->Add(m_mapgrid, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
117 SetSizer(BoxSizer1);
118 BoxSizer1->Fit(this);
119 BoxSizer1->SetSizeHints(this);
120 Center();
121
122 Connect(ID_VERTICAL_CHOICE,wxEVT_COMMAND_CHOICE_SELECTED,(wxObjectEventFunction)&MapSelectDialog::OnSortKeySelect);
123 Connect(ID_HORIZONTAL_CHOICE,wxEVT_COMMAND_CHOICE_SELECTED,(wxObjectEventFunction)&MapSelectDialog::OnSortKeySelect);
124 Connect(ID_FILTER_ALL,wxEVT_COMMAND_RADIOBUTTON_SELECTED,(wxObjectEventFunction)&MapSelectDialog::OnFilterAllSelect);
125 Connect(ID_FILTER_POPULAR,wxEVT_COMMAND_RADIOBUTTON_SELECTED,(wxObjectEventFunction)&MapSelectDialog::OnFilterPopularSelect);
126 Connect(ID_FILTER_RECENT,wxEVT_COMMAND_RADIOBUTTON_SELECTED,(wxObjectEventFunction)&MapSelectDialog::OnFilterRecentSelect);
127 Connect(ID_FILTER_TEXT,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&MapSelectDialog::OnFilterTextChanged);
128 m_mapgrid->Connect(ID_MAPGRID,wxEVT_LEFT_DCLICK,(wxObjectEventFunction)&MapSelectDialog::OnMapGridLeftDClick,0,this);
129 Connect(wxID_ANY,wxEVT_INIT_DIALOG,(wxObjectEventFunction)&MapSelectDialog::OnInit);
130 //*)
131
132 Connect(ID_MAPGRID,MapGridCtrl::MapSelectedEvt,(wxObjectEventFunction)&MapSelectDialog::OnMapSelected,0,this);
133 Connect(ID_MAPGRID,MapGridCtrl::LoadingCompletedEvt,(wxObjectEventFunction)&MapSelectDialog::OnMapLoadingCompleted,0,this);
134
135 // Ugh.. Can not have these created by generated code because wxSmith doesn't accept a symbolic size,
136 // (ie. wxSize(CONTROL_HEIGHT,CONTROL_HEIGHT)) and all Set*Size() methods don't seem to have any effect.
137 m_vertical_direction_button = new wxButton(this, ID_VERTICAL_DIRECTION, _T("ᴧ"), wxDefaultPosition, wxSize(CONTROL_HEIGHT,CONTROL_HEIGHT), 0, wxDefaultValidator, _T("ID_VERTICAL_DIRECTION"));
138 boxSizerVertical->Add(m_vertical_direction_button, 0, wxALL|wxEXPAND|wxSHAPED|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
139 m_horizontal_direction_button = new wxButton(this, ID_HORIZONTAL_DIRECTION, _T("<"), wxDefaultPosition, wxSize(CONTROL_HEIGHT,CONTROL_HEIGHT), 0, wxDefaultValidator, _T("ID_HORIZONTAL_DIRECTION"));
140 boxSizerHorizontal->Add(m_horizontal_direction_button, 0, wxALL|wxEXPAND|wxSHAPED|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
141 //<>ᴠᴧ
142
143 Connect(ID_VERTICAL_DIRECTION, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&MapSelectDialog::OnVerticalDirectionClicked);
144 Connect(ID_HORIZONTAL_DIRECTION, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&MapSelectDialog::OnHorizontalDirectionClicked);
145
146 // TODO: refactor, this is copied from battlemaptab.cpp
147 m_map_opts_list->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
148 m_map_opts_list->SetFont( wxFont( 8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT ) );
149
150 wxListItem col;
151
152 col.SetText( _("Option") );
153 m_map_opts_list->InsertColumn( 0, col );
154 col.SetText( _("Value") );
155 m_map_opts_list->InsertColumn( 1, col );
156 m_map_opts_list->SetColumnWidth( 0, 90 );
157 m_map_opts_list->SetColumnWidth( 1, 80 );
158
159 m_map_opts_list->InsertItem( 0, _("Size") );
160 m_map_opts_list->InsertItem( 1, _("Windspeed") );
161 m_map_opts_list->InsertItem( 2, _("Tidal strength") );
162 m_map_opts_list->InsertItem( 3, _("Gravity") );
163 m_map_opts_list->InsertItem( 4, _("Extractor radius") );
164 m_map_opts_list->InsertItem( 5, _("Max metal") );
165 m_map_opts_list->InsertItem( 6, _("Start positions") );
166
167 Layout();
168 ConnectGlobalEvent(this, GlobalEvent::OnUnitsyncReloaded, wxObjectEventFunction(&MapSelectDialog::OnUnitsyncReloaded));
169 }
170
~MapSelectDialog()171 MapSelectDialog::~MapSelectDialog()
172 {
173 //(*Destroy(MapSelectDialog)
174 //*)
175 sett().SetHorizontalSortkeyIndex( m_horizontal_choice->GetSelection() );
176 sett().SetVerticalSortkeyIndex( m_vertical_choice->GetSelection() );
177 sett().SetHorizontalSortorder( m_horizontal_direction );
178 sett().SetVerticalSortorder( m_vertical_direction );
179 if ( m_filter_all->GetValue() )
180 sett().SetMapSelectorFilterRadio( m_filter_all_sett );
181 else if ( m_filter_recent->GetValue() )
182 sett().SetMapSelectorFilterRadio( m_filter_recent_sett );
183 else
184 sett().SetMapSelectorFilterRadio( m_filter_popular_sett );
185 if ( IsShown() )
186 EndModal( 0 );
187 }
188
189
OnInit(wxInitDialogEvent &)190 void MapSelectDialog::OnInit( wxInitDialogEvent& /*unused*/ )
191 {
192 wxLogDebugFunc( wxEmptyString );
193
194 AppendSortKeys( m_horizontal_choice );
195 AppendSortKeys( m_vertical_choice );
196
197 m_horizontal_choice->SetSelection( sett().GetHorizontalSortkeyIndex() );
198 m_vertical_choice->SetSelection( sett().GetVerticalSortkeyIndex() );
199
200 m_horizontal_direction_button->SetLabel( m_horizontal_direction ? _T(">") : _T("<") );
201 m_vertical_direction_button->SetLabel( m_vertical_direction ? _T("ᴠ") : _T("ᴧ") );
202
203 m_maps = LSL::Util::vectorToArrayString(LSL::usync().GetMapList());
204 //true meaning replays, flase meaning savegames
205 m_replays = LSL::Util::vectorToArrayString(LSL::usync().GetPlaybackList(true));
206
207 const unsigned int lastFilter = sett().GetMapSelectorFilterRadio();
208 m_filter_popular->Enable( ui().IsConnected() );
209
210 // due to a bug / crappy design in SpringUnitSync / unitsync itself we
211 // get a replay list with one empty item when there are no replays..
212 bool no_replays = m_replays.empty() || ( m_replays.size() == 1 && m_replays[0] == wxEmptyString );
213 if ( no_replays ) {
214 m_filter_all->SetValue( true );
215 m_filter_recent->Enable( false );
216 }
217
218 if ( lastFilter == m_filter_popular_sett ) {
219 if ( ui().IsConnected() ) {
220 m_filter_popular->SetValue( true );
221 LoadPopular();
222 }
223 else {
224 m_filter_all->SetValue( true );
225 LoadAll();
226 }
227 }
228 else if ( lastFilter == m_filter_recent_sett ) {
229 if ( !no_replays ) {
230 m_filter_recent->Enable( true );
231 m_filter_recent->SetValue( true );
232 LoadRecent();
233 }
234 else {
235 m_filter_all->SetValue( true );
236 LoadAll();
237 }
238 }
239 else {
240 m_filter_all->SetValue( true );
241 LoadAll();
242 }
243
244 UpdateSortAndFilter();
245
246 m_filter_text->SetFocus();
247 }
248
249
OnSortKeySelect(wxCommandEvent &)250 void MapSelectDialog::OnSortKeySelect( wxCommandEvent& /*unused*/ )
251 {
252 wxLogDebugFunc( wxEmptyString );
253 UpdateSortAndFilter();
254 }
255
256
AppendSortKeys(wxChoice * choice)257 void MapSelectDialog::AppendSortKeys( wxChoice* choice )
258 {
259 // see MapGridCtrl for available SortKeys
260 choice->Append( _("Name"), (void*) MapGridCtrl::SortKey_Name );
261 choice->Append( _("Tidal strength"), (void*) MapGridCtrl::SortKey_TidalStrength );
262 choice->Append( _("Gravity"), (void*) MapGridCtrl::SortKey_Gravity );
263 choice->Append( _("Max metal"), (void*) MapGridCtrl::SortKey_MaxMetal );
264 choice->Append( _("Extractor radius"), (void*) MapGridCtrl::SortKey_ExtractorRadius );
265 choice->Append( _("Minimum wind"), (void*) MapGridCtrl::SortKey_MinWind );
266 choice->Append( _("Maximum wind"), (void*) MapGridCtrl::SortKey_MaxWind );
267 choice->Append( _("Average wind"), (void*) MapGridCtrl::SortKey_Wind );
268 choice->Append( _("Size (map area)"), (void*) MapGridCtrl::SortKey_Area );
269 choice->Append( _("Aspect ratio"), (void*) MapGridCtrl::SortKey_AspectRatio );
270 choice->Append( _("Number of start positions"), (void*) MapGridCtrl::SortKey_PosCount );
271 }
272
GetSelectedSortKey(wxChoice * choice)273 static MapGridCtrl::SortKey GetSelectedSortKey( wxChoice* choice )
274 {
275 const int selection = choice->GetSelection();
276 if (selection == wxNOT_FOUND) //default to first entry
277 return MapGridCtrl::SortKey_Name;
278 return (MapGridCtrl::SortKey) (int) (long) choice->GetClientData( selection );
279 }
280
281 namespace {
282 struct FilterPredicate
283 {
FilterPredicate__anonbc46f5b40111::FilterPredicate284 FilterPredicate( const wxString& _searchText ) : searchText(STD_STRING(_searchText.Lower())) {}
operator ()__anonbc46f5b40111::FilterPredicate285 bool operator () ( const LSL::UnitsyncMap& map ) const
286 {
287 return boost::to_lower_copy(map.name).find(searchText) != std::string::npos
288 || boost::to_lower_copy(map.info.description).find(searchText) != std::string::npos
289 || boost::to_lower_copy(map.info.author).find(searchText) != std::string::npos;
290 }
291 const std::string searchText;
292 };
293 }
294
UpdateSortAndFilter()295 void MapSelectDialog::UpdateSortAndFilter()
296 {
297 FilterPredicate predicate( m_filter_text->GetValue() );
298 m_mapgrid->Filter( predicate );
299 m_mapgrid->Sort( GetSelectedSortKey( m_vertical_choice ), GetSelectedSortKey( m_horizontal_choice ), m_vertical_direction, m_horizontal_direction );
300 m_mapgrid->Refresh();
301 }
302
GetSelectedMap() const303 LSL::UnitsyncMap* MapSelectDialog::GetSelectedMap() const
304 {
305 wxLogDebugFunc( wxEmptyString );
306 return m_mapgrid->GetSelectedMap();
307 }
308
OnMapSelected(wxCommandEvent & event)309 void MapSelectDialog::OnMapSelected( wxCommandEvent& event )
310 {
311 const wxString& mapname = event.GetString();
312
313 wxLogDebugFunc( mapname );
314
315 const LSL::UnitsyncMap* pMap = m_mapgrid->GetSelectedMap();
316 if ( pMap == NULL) return;
317 const LSL::UnitsyncMap& map = *pMap;
318
319 m_map_name->SetLabel(TowxString(map.name + "\n\n" + map.info.description));
320
321 // TODO: refactor, this is copied from battlemaptab.cpp
322 m_map_opts_list->SetItem( 0, 1, wxFormat( _T("%dx%d") ) % (map.info.width/512) % (map.info.height/512) );
323 m_map_opts_list->SetItem( 1, 1, wxFormat( _T("%d-%d") ) % map.info.minWind % map.info.maxWind );
324 m_map_opts_list->SetItem( 2, 1, wxFormat( _T("%d") ) % map.info.tidalStrength );
325 m_map_opts_list->SetItem( 3, 1, wxFormat( _T("%d") ) % map.info.gravity );
326 m_map_opts_list->SetItem( 4, 1, wxFormat( _T("%d") ) % map.info.extractorRadius );
327 m_map_opts_list->SetItem( 5, 1, wxFormat( _T("%.3f") ) % map.info.maxMetal );
328 m_map_opts_list->SetItem( 6, 1, wxFormat( _T("%d") ) % map.info.positions.size() );
329 }
330
OnMapLoadingCompleted(wxCommandEvent &)331 void MapSelectDialog::OnMapLoadingCompleted( wxCommandEvent& /*unused*/ )
332 {
333 wxLogDebugFunc( wxEmptyString );
334 // to apply stored sorting settings we need to re-apply sorting after loading finished
335 UpdateSortAndFilter();
336 }
337
OnVerticalDirectionClicked(wxCommandEvent &)338 void MapSelectDialog::OnVerticalDirectionClicked( wxCommandEvent& /*unused*/ )
339 {
340 wxLogDebugFunc( wxEmptyString );
341 m_vertical_direction = !m_vertical_direction;
342 m_vertical_direction_button->SetLabel( m_vertical_direction ? _T("ᴠ") : _T("ᴧ") );
343 UpdateSortAndFilter();
344 }
345
OnHorizontalDirectionClicked(wxCommandEvent &)346 void MapSelectDialog::OnHorizontalDirectionClicked( wxCommandEvent& /*unused*/ )
347 {
348 wxLogDebugFunc( wxEmptyString );
349 m_horizontal_direction = !m_horizontal_direction;
350 m_horizontal_direction_button->SetLabel( m_horizontal_direction ? _T(">") : _T("<") );
351 UpdateSortAndFilter();
352 }
353
OnMapGridLeftDClick(wxMouseEvent &)354 void MapSelectDialog::OnMapGridLeftDClick(wxMouseEvent& /*unused*/)
355 {
356 wxLogDebugFunc( wxEmptyString );
357
358 if ( m_mapgrid->GetSelectedMap() ) {
359 EndModal( wxID_OK );
360 }
361 }
362
LoadAll()363 void MapSelectDialog::LoadAll()
364 {
365 wxLogDebugFunc( wxEmptyString );
366 const int count = m_maps.size();
367
368 m_mapgrid->Clear();
369
370 for ( int i = 0; i < count; ++i ) {
371 m_mapgrid->AddMap( m_maps[i] );
372 }
373
374 m_mapgrid->Refresh();
375 }
376
LoadPopular()377 void MapSelectDialog::LoadPopular()
378 {
379 wxLogDebugFunc( wxEmptyString );
380
381 m_mapgrid->Clear();
382
383 try {
384 serverSelector().GetServer().battles_iter->IteratorBegin();
385 while ( !serverSelector().GetServer().battles_iter->EOL() ) {
386 Battle* b = serverSelector().GetServer().battles_iter->GetBattle();
387 const wxString mapname = b->GetHostMapName();
388 assert(!mapname.empty());
389 if ( b != NULL ) m_mapgrid->AddMap( mapname );
390 }
391 }
392 catch (...) {} // ui().GetServer may throw when disconnected...
393
394 m_mapgrid->Refresh();
395 }
396
LoadRecent()397 void MapSelectDialog::LoadRecent()
398 {
399 wxLogDebugFunc( wxEmptyString );
400 const int count = m_maps.size();
401
402 m_mapgrid->Clear();
403
404 // just check whether map names are contained in replay names
405 // not the most elegant solution but, hey, it works
406 for ( int i = 0; i < count; ++i ) {
407 // prefix and suffix with underscore to prevent most common partial matches
408 const wxString mapname = _T("_") + m_maps[i].BeforeLast( '.' ) + _T("_");
409 long replaycount = long(m_replays.GetCount());
410 for ( int replaynum = 0; replaynum < replaycount; replaynum++ ) {
411 if ( m_replays[replaynum].Find( mapname ) != wxNOT_FOUND )
412 m_mapgrid->AddMap( m_maps[i] );
413 }
414 }
415
416 m_mapgrid->Refresh();
417 }
418
419 // filter event handlers
420
OnFilterAllSelect(wxCommandEvent &)421 void MapSelectDialog::OnFilterAllSelect(wxCommandEvent& /*unused*/)
422 {
423 wxLogDebugFunc( wxEmptyString );
424 LoadAll();
425 }
426
OnFilterPopularSelect(wxCommandEvent &)427 void MapSelectDialog::OnFilterPopularSelect(wxCommandEvent& /*unused*/)
428 {
429 wxLogDebugFunc( wxEmptyString );
430 LoadPopular();
431 }
432
OnFilterRecentSelect(wxCommandEvent &)433 void MapSelectDialog::OnFilterRecentSelect(wxCommandEvent& /*unused*/)
434 {
435 wxLogDebugFunc( wxEmptyString );
436 LoadRecent();
437 }
438
OnFilterTextChanged(wxCommandEvent &)439 void MapSelectDialog::OnFilterTextChanged(wxCommandEvent& /*unused*/)
440 {
441 wxLogDebugFunc( wxEmptyString );
442 UpdateSortAndFilter();
443 }
444
OnUnitsyncReloaded(wxCommandEvent &)445 void MapSelectDialog::OnUnitsyncReloaded( wxCommandEvent& /*data*/ )
446 {
447 wxInitDialogEvent dummy;
448 AddPendingEvent( dummy );
449 }
450
mapSelectDialog(bool hidden,wxWindow * parent)451 wxString mapSelectDialog(bool hidden, wxWindow* parent){
452 wxString mapname = wxEmptyString;
453 assert( (hidden && parent!=NULL) || (!hidden && parent==NULL)); //at the first call, the window is created hidden
454 static MapSelectDialog* m = new MapSelectDialog(parent);
455 if ( (!hidden) && (m->ShowModal() == wxID_OK) && (m->GetSelectedMap() != NULL) ) {
456 mapname = TowxString(m->GetSelectedMap()->name);
457 }
458 return mapname;
459 }
460
461