# HG changeset patch # User KUDr # Date 1171234644 0 # Node ID 5077e6ed37889e6e8c9cd5c743ab4a87e72d9771 # Parent 42bf2d268a8644d3ec731884922077c8d09ca169 (svn r8683) [cpp_gui] -Codechange: first steps towards OO GUI (together with Bjarni) without changes in the logic -Windows are now constructed/destroyed when needed instead of reusing them from _windows[25]. This array is now replaced by std::list<> of smart pointers (eliminates the need of _z_windows) -some Window related functions turned into Window (or WindowList) methods -note that although the number of windows is now unlimited, the maximum number of viewports is still hardcoded. This causes game crash when too many industry windows are opened. -tested only on VC8/WinXP diff -r 42bf2d268a86 -r 5077e6ed3788 src/aircraft_gui.cpp --- a/src/aircraft_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/aircraft_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -349,7 +349,7 @@ if (plane_stopped != IsWindowWidgetHidden(w, 7) || plane_stopped == IsWindowWidgetHidden(w, 11)) { SetWindowWidgetHiddenState(w, 7, plane_stopped); // send to hangar SetWindowWidgetHiddenState(w, 11, !plane_stopped); // clone - SetWindowDirty(w); + w->SetDirty(); } } break; } diff -r 42bf2d268a86 -r 5077e6ed3788 src/airport_gui.cpp --- a/src/airport_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/airport_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -99,9 +99,9 @@ break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); - w = FindWindowById(WC_BUILD_STATION, 0); + w = Window::FindById(WC_BUILD_STATION, 0); if (w != 0) WP(w,def_d).close = true; break; @@ -206,21 +206,21 @@ _selected_airport_type = e->we.click.widget - 7; LowerWindowWidget(w, _selected_airport_type + 7); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; case 16: case 17: _station_show_coverage = (e->we.click.widget != 16); SetWindowWidgetLoweredState(w, 16, !_station_show_coverage); SetWindowWidgetLoweredState(w, 17, _station_show_coverage); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; } } break; case WE_MOUSELOOP: { if (WP(w,def_d).close) { - DeleteWindow(w); + w->Close(); return; } diff -r 42bf2d268a86 -r 5077e6ed3788 src/autoreplace_gui.cpp --- a/src/autoreplace_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/autoreplace_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -311,7 +311,7 @@ WP(w, replaceveh_d).wagon_btnstate = !(WP(w, replaceveh_d).wagon_btnstate); WP(w, replaceveh_d).update_left = true; WP(w, replaceveh_d).init_lists = true; - SetWindowDirty(w); + w->SetDirty(); break; case 14: @@ -351,7 +351,7 @@ WP(w, replaceveh_d).update_right = true; WP(w, replaceveh_d).init_lists = true; } - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -370,7 +370,7 @@ WP(w, replaceveh_d).update_left = true; WP(w, replaceveh_d).update_right = true; WP(w, replaceveh_d).init_lists = true; - SetWindowDirty(w); + w->SetDirty(); } break; case WE_RESIZE: @@ -384,7 +384,7 @@ case WE_INVALIDATE_DATA: if (_rebuild_left_list) WP(w, replaceveh_d).update_left = true; if (_rebuild_right_list) WP(w, replaceveh_d).update_right = true; - SetWindowDirty(w); + w->SetDirty(); break; case WE_DESTROY: diff -r 42bf2d268a86 -r 5077e6ed3788 src/bridge_gui.cpp --- a/src/bridge_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/bridge_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -32,7 +32,7 @@ static void BuildBridge(Window *w, int i) { - DeleteWindow(w); + w->Close(); DoCommandP(_bridgedata.end_tile, _bridgedata.start_tile, _bridgedata.indexes[i] | (_bridgedata.type << 8), CcBuildBridge, CMD_BUILD_BRIDGE | CMD_AUTO | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE)); diff -r 42bf2d268a86 -r 5077e6ed3788 src/build_vehicle_gui.cpp --- a/src/build_vehicle_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/build_vehicle_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -812,14 +812,14 @@ bv->descending_sort_order ^= true; _last_sort_order[bv->vehicle_type] = bv->descending_sort_order; bv->regenerate_list = true; - SetWindowDirty(w); + w->SetDirty(); break; case BUILD_VEHICLE_WIDGET_LIST: { uint i = (e->we.click.pt.y - 26) / GetVehicleListHeight(bv->vehicle_type) + w->vscroll.pos; uint num_items = EngList_Count(&bv->eng_list); bv->sel_engine = (i < num_items) ? bv->eng_list[i] : INVALID_ENGINE; - SetWindowDirty(w); + w->SetDirty(); break; } @@ -875,7 +875,7 @@ switch (e->event) { case WE_INVALIDATE_DATA: bv->regenerate_list = true; - SetWindowDirty(w); + w->SetDirty(); break; case WE_DESTROY: @@ -915,7 +915,7 @@ _last_sort_criteria[bv->vehicle_type] = bv->sort_criteria; bv->regenerate_list = true; } - SetWindowDirty(w); + w->SetDirty(); break; case WE_RESIZE: diff -r 42bf2d268a86 -r 5077e6ed3788 src/console.cpp --- a/src/console.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/console.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -51,7 +51,7 @@ _iconsole_cmdline.width = 0; _iconsole_cmdline.caretpos = 0; _iconsole_cmdline.caretxoffs = 0; - SetWindowDirty(FindWindowById(WC_CONSOLE, 0)); + Window::SetDirtyById(WC_CONSOLE, 0); } static inline void IConsoleResetHistoryPos(void) {_iconsole_historypos = ICON_HISTORY_SIZE - 1;} @@ -91,7 +91,7 @@ } case WE_MOUSELOOP: if (HandleCaret(&_iconsole_cmdline)) - SetWindowDirty(w); + w->SetDirty(); break; case WE_DESTROY: _iconsole_mode = ICONSOLE_CLOSED; @@ -101,11 +101,11 @@ switch (e->we.keypress.keycode) { case WKC_UP: IConsoleHistoryNavigate(+1); - SetWindowDirty(w); + w->SetDirty(); break; case WKC_DOWN: IConsoleHistoryNavigate(-1); - SetWindowDirty(w); + w->SetDirty(); break; case WKC_SHIFT | WKC_PAGEUP: if (iconsole_scroll - (w->height / ICON_LINE_HEIGHT) - 1 < 0) { @@ -113,7 +113,7 @@ } else { iconsole_scroll -= (w->height / ICON_LINE_HEIGHT) - 1; } - SetWindowDirty(w); + w->SetDirty(); break; case WKC_SHIFT | WKC_PAGEDOWN: if (iconsole_scroll + (w->height / ICON_LINE_HEIGHT) - 1 > ICON_BUFFER) { @@ -121,7 +121,7 @@ } else { iconsole_scroll += (w->height / ICON_LINE_HEIGHT) - 1; } - SetWindowDirty(w); + w->SetDirty(); break; case WKC_SHIFT | WKC_UP: if (iconsole_scroll <= 0) { @@ -129,7 +129,7 @@ } else { --iconsole_scroll; } - SetWindowDirty(w); + w->SetDirty(); break; case WKC_SHIFT | WKC_DOWN: if (iconsole_scroll >= ICON_BUFFER) { @@ -137,7 +137,7 @@ } else { ++iconsole_scroll; } - SetWindowDirty(w); + w->SetDirty(); break; case WKC_BACKQUOTE: IConsoleSwitch(); @@ -157,7 +157,7 @@ case (WKC_CTRL | 'V'): if (InsertTextBufferClipboard(&_iconsole_cmdline)) { IConsoleResetHistoryPos(); - SetWindowDirty(w); + w->SetDirty(); } break; case (WKC_CTRL | 'L'): @@ -165,18 +165,18 @@ break; case (WKC_CTRL | 'U'): DeleteTextBufferAll(&_iconsole_cmdline); - SetWindowDirty(w); + w->SetDirty(); break; case WKC_BACKSPACE: case WKC_DELETE: if (DeleteTextBufferChar(&_iconsole_cmdline, e->we.keypress.keycode)) { IConsoleResetHistoryPos(); - SetWindowDirty(w); + w->SetDirty(); } break; case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME: if (MoveTextBufferPos(&_iconsole_cmdline, e->we.keypress.keycode)) { IConsoleResetHistoryPos(); - SetWindowDirty(w); + w->SetDirty(); } break; default: @@ -184,7 +184,7 @@ iconsole_scroll = ICON_BUFFER; InsertTextBufferChar(&_iconsole_cmdline, e->we.keypress.key); IConsoleResetHistoryPos(); - SetWindowDirty(w); + w->SetDirty(); } else { e->we.keypress.cont = true; } @@ -403,7 +403,7 @@ IConsoleWriteToLogFile(_iconsole_buffer[ICON_BUFFER]); - SetWindowDirty(FindWindowById(WC_CONSOLE, 0)); + Window::SetDirtyById(WC_CONSOLE, 0); } /** diff -r 42bf2d268a86 -r 5077e6ed3788 src/depot_gui.cpp --- a/src/depot_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/depot_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -218,7 +218,7 @@ uint16 boxes_in_each_row = w->widget[DEPOT_WIDGET_MATRIX].data & 0xFF; /* setup disabled buttons */ - SetWindowWidgetsDisabledState(w, !IsTileOwner(tile, _local_player), + w->SetWidgetsDisabledState(!IsTileOwner(tile, _local_player), DEPOT_WIDGET_STOP_ALL, DEPOT_WIDGET_START_ALL, DEPOT_WIDGET_SELL, @@ -445,7 +445,7 @@ } WP(w, depot_d).sel = v->index; - SetWindowDirty(w); + w->SetDirty(); SetObjectToPlaceWnd(image, GetVehiclePalette(v), 4, w); } } @@ -733,7 +733,7 @@ + (type == VEH_Train ? 1 : w->hscroll.cap); // number of boxes in each row. Trains always have just one - SetWindowWidgetsHiddenState(w, type != VEH_Train, + w->SetWidgetsHiddenState(type != VEH_Train, DEPOT_WIDGET_H_SCROLL, DEPOT_WIDGET_SELL_CHAIN, WIDGET_LIST_END); @@ -892,7 +892,7 @@ VehicleID sel = WP(w, depot_d).sel; WP(w, depot_d).sel = INVALID_VEHICLE; - SetWindowDirty(w); + w->SetDirty(); if (WP(w, depot_d).type == VEH_Train) { GetDepotVehiclePtData gdvp; @@ -925,11 +925,11 @@ if (IsWindowWidgetDisabled(w, e->we.click.widget)) return; if (WP(w, depot_d).sel == INVALID_VEHICLE) return; - HandleButtonClick(w, e->we.click.widget); + w->HandleButtonClick(e->we.click.widget); v = GetVehicle(WP(w, depot_d).sel); WP(w, depot_d).sel = INVALID_VEHICLE; - SetWindowDirty(w); + w->SetDirty(); sell_cmd = (v->type == VEH_Train && (e->we.click.widget == DEPOT_WIDGET_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0; @@ -953,7 +953,7 @@ break; default: WP(w, depot_d).sel = INVALID_VEHICLE; - SetWindowDirty(w); + w->SetDirty(); } break; @@ -1003,7 +1003,7 @@ * If that is the case, we can skip looping though the windows and save time */ if (_special_mouse_mode != WSM_DRAGDROP) return; - w = FindWindowById(WC_VEHICLE_DEPOT, v->tile); + w = Window::FindById(WC_VEHICLE_DEPOT, v->tile); if (w != NULL) { WP(w, depot_d).sel = INVALID_VEHICLE; ResetObjectToPlace(); diff -r 42bf2d268a86 -r 5077e6ed3788 src/dock_gui.cpp --- a/src/dock_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/dock_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -160,12 +160,12 @@ break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); - w = FindWindowById(WC_BUILD_STATION, 0); + w = Window::FindById(WC_BUILD_STATION, 0); if (w != NULL) WP(w,def_d).close = true; - w = FindWindowById(WC_BUILD_DEPOT, 0); + w = Window::FindById(WC_BUILD_DEPOT, 0); if (w != NULL) WP(w,def_d).close = true; break; @@ -250,14 +250,14 @@ _station_show_coverage = (e->we.click.widget != 3); LowerWindowWidget(w, _station_show_coverage + 3); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; } break; case WE_MOUSELOOP: if (WP(w,def_d).close) { - DeleteWindow(w); + w->Close(); return; } @@ -325,13 +325,13 @@ LowerWindowWidget(w, _ship_depot_direction + 3); SndPlayFx(SND_15_BEEP); UpdateDocksDirection(); - SetWindowDirty(w); + w->SetDirty(); break; } } break; case WE_MOUSELOOP: - if (WP(w,def_d).close) DeleteWindow(w); + if (WP(w,def_d).close) w->Close(); break; case WE_DESTROY: diff -r 42bf2d268a86 -r 5077e6ed3788 src/engine_gui.cpp --- a/src/engine_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/engine_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -98,7 +98,7 @@ DoCommandP(0, w->window_number, 0, NULL, CMD_WANT_ENGINE_PREVIEW); /* Fallthrough */ case 3: - DeleteWindow(w); + w->Close(); break; } break; diff -r 42bf2d268a86 -r 5077e6ed3788 src/genworld.cpp --- a/src/genworld.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/genworld.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -286,7 +286,7 @@ ShowGenerateWorldProgress(); /* Centre the view on the map */ - if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) { + if (Window::FindById(WC_MAIN_WINDOW, 0) != NULL) { ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2)); } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/genworld_gui.cpp --- a/src/genworld_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/genworld_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -328,7 +328,7 @@ break; case WE_CLICK: switch (e->we.click.widget) { - case 0: DeleteWindow(w); break; + case 0: w->Close(); break; case GLAND_TEMPERATE: case GLAND_ARCTIC: case GLAND_TROPICAL: case GLAND_TOYLAND: RaiseWindowWidget(w, _opt_newgame.landscape + GLAND_TEMPERATE); SetNewLandscapeType(e->we.click.widget - GLAND_TEMPERATE); @@ -349,7 +349,7 @@ _patches_newgame.generation_seed = InteractiveRandom(); snprintf(_genseed_buffer, lengthof(_genseed_buffer), "%u", _patches_newgame.generation_seed); UpdateTextBufferSize(&_genseed_query.text); - SetWindowDirty(w); + w->SetDirty(); break; case GLAND_GENERATE_BUTTON: // Generate if (mode == GLWP_HEIGHTMAP && ( @@ -367,8 +367,8 @@ case GLAND_START_DATE_DOWN: case GLAND_START_DATE_UP: // Year buttons /* Don't allow too fast scrolling */ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { - HandleButtonClick(w, e->we.click.widget); - SetWindowDirty(w); + w->HandleButtonClick(e->we.click.widget); + w->SetDirty(); _patches_newgame.starting_year = clamp(_patches_newgame.starting_year + e->we.click.widget - GLAND_START_DATE_TEXT, MIN_YEAR, MAX_YEAR); } @@ -382,8 +382,8 @@ case GLAND_SNOW_LEVEL_DOWN: case GLAND_SNOW_LEVEL_UP: // Snow line buttons /* Don't allow too fast scrolling */ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { - HandleButtonClick(w, e->we.click.widget); - SetWindowDirty(w); + w->HandleButtonClick(e->we.click.widget); + w->SetDirty(); _patches_newgame.snow_line_height = clamp(_patches_newgame.snow_line_height + e->we.click.widget - GLAND_SNOW_LEVEL_TEXT, 2, 13); } @@ -467,7 +467,7 @@ DoCommandP(0, 13, _opt_newgame.diff.quantity_sea_lakes, NULL, CMD_CHANGE_DIFFICULTY_LEVEL); break; } - SetWindowDirty(w); + w->SetDirty(); break; case WE_ON_EDIT_TEXT: { @@ -485,7 +485,7 @@ break; } - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -628,8 +628,8 @@ case CSCEN_START_DATE_DOWN: case CSCEN_START_DATE_UP: // Year buttons /* Don't allow too fast scrolling */ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { - HandleButtonClick(w, e->we.click.widget); - SetWindowDirty(w); + w->HandleButtonClick(e->we.click.widget); + w->SetDirty(); _patches_newgame.starting_year = clamp(_patches_newgame.starting_year + e->we.click.widget - CSCEN_START_DATE_TEXT, MIN_YEAR, MAX_YEAR); } @@ -643,8 +643,8 @@ case CSCEN_FLAT_LAND_HEIGHT_DOWN: case CSCEN_FLAT_LAND_HEIGHT_UP: // Height level buttons /* Don't allow too fast scrolling */ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { - HandleButtonClick(w, e->we.click.widget); - SetWindowDirty(w); + w->HandleButtonClick(e->we.click.widget); + w->SetDirty(); _patches_newgame.se_flat_world_height = clamp(_patches_newgame.se_flat_world_height + e->we.click.widget - CSCEN_FLAT_LAND_HEIGHT_TEXT, 0, 15); } @@ -663,7 +663,7 @@ case CSCEN_MAPSIZE_X_PULLDOWN: _patches_newgame.map_x = e->we.dropdown.index + 6; break; case CSCEN_MAPSIZE_Y_PULLDOWN: _patches_newgame.map_y = e->we.dropdown.index + 6; break; } - SetWindowDirty(w); + w->SetDirty(); break; case WE_ON_EDIT_TEXT: { @@ -681,7 +681,7 @@ break; } - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -791,7 +791,7 @@ SetDParam(1, _tp.total); DrawStringCentered(90, 58, STR_GENERATION_PROGRESS, 0); - SetWindowDirty(w); + w->SetDirty(); break; } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/graph_gui.cpp --- a/src/graph_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/graph_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -281,7 +281,7 @@ if (IS_INT_INSIDE(e->we.click.widget, 3, 11)) { TOGGLEBIT(_legend_excluded_players, e->we.click.widget - 3); ToggleWidgetLoweredState(w, e->we.click.widget); - SetWindowDirty(w); + w->SetDirty(); InvalidateWindow(WC_INCOME_GRAPH, 0); InvalidateWindow(WC_OPERATING_PROFIT, 0); InvalidateWindow(WC_DELIVERED_CARGO, 0); @@ -774,7 +774,7 @@ case 11: case 12: case 13: case 14: TOGGLEBIT(_legend_excluded_cargo, e->we.click.widget - 3); ToggleWidgetLoweredState(w, e->we.click.widget); - SetWindowDirty(w); + w->SetDirty(); break; } } break; @@ -929,7 +929,7 @@ /* Raise and disable the widget for the previous selection. */ RaiseWindowWidget(w, _performance_rating_detail_player + 13); DisableWindowWidget(w, _performance_rating_detail_player + 13); - SetWindowDirty(w); + w->SetDirty(); _performance_rating_detail_player = INVALID_PLAYER; } @@ -938,7 +938,7 @@ if (GetPlayer(i)->is_active) { /* Lower the widget corresponding to this player. */ LowerWindowWidget(w, i + 13); - SetWindowDirty(w); + w->SetDirty(); _performance_rating_detail_player = i; break; @@ -958,7 +958,7 @@ DisableWindowWidget(w, i + 13); // We need a repaint - SetWindowDirty(w); + w->SetDirty(); } continue; } @@ -968,7 +968,7 @@ // New player! Yippie :p EnableWindowWidget(w, i + 13); // We need a repaint - SetWindowDirty(w); + w->SetDirty(); } x = (i == _performance_rating_detail_player) ? 1 : 0; @@ -1057,7 +1057,7 @@ RaiseWindowWidget(w, _performance_rating_detail_player + 13); _performance_rating_detail_player = (PlayerID)(e->we.click.widget - 13); LowerWindowWidget(w, _performance_rating_detail_player + 13); - SetWindowDirty(w); + w->SetDirty(); } } break; @@ -1080,7 +1080,7 @@ w->custom[1] = 5; if (_performance_rating_detail_player != INVALID_PLAYER) LowerWindowWidget(w, _performance_rating_detail_player + 13); - SetWindowDirty(w); + w->SetDirty(); break; } @@ -1097,7 +1097,7 @@ // Skip if player is not active if (p2->is_active) UpdateCompanyRatingAndValue(p2, false); } - SetWindowDirty(w); + w->SetDirty(); } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/industry_gui.cpp --- a/src/industry_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/industry_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -54,7 +54,7 @@ break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); break; } } @@ -373,7 +373,7 @@ } UpdateIndustryProduction(i); - SetWindowDirty(w); + w->SetDirty(); w->flags4 |= 5 << WF_TIMEOUT_SHL; WP(w,vp2_d).data_2 = line+1; WP(w,vp2_d).data_3 = (x < 15 ? 1 : 2); @@ -395,7 +395,7 @@ case WE_TIMEOUT: WP(w,vp2_d).data_2 = 0; WP(w,vp2_d).data_3 = 0; - SetWindowDirty(w); + w->SetDirty(); break; case WE_ON_EDIT_TEXT: @@ -405,7 +405,7 @@ i->production_rate[line] = clampu(atoi(e->we.edittext.str), 0, 255); UpdateIndustryProduction(i); - SetWindowDirty(w); + w->SetDirty(); } } } @@ -626,25 +626,25 @@ case 3: { _industry_sort_order = _industry_sort_order==0 ? 1 : 0; _industry_sort_dirty = true; - SetWindowDirty(w); + w->SetDirty(); } break; case 4: { _industry_sort_order = _industry_sort_order==2 ? 3 : 2; _industry_sort_dirty = true; - SetWindowDirty(w); + w->SetDirty(); } break; case 5: { _industry_sort_order = _industry_sort_order==4 ? 5 : 4; _industry_sort_dirty = true; - SetWindowDirty(w); + w->SetDirty(); } break; case 6: { _industry_sort_order = _industry_sort_order==6 ? 7 : 6; _industry_sort_dirty = true; - SetWindowDirty(w); + w->SetDirty(); } break; case 8: { @@ -661,7 +661,7 @@ break; case WE_4: - SetWindowDirty(w); + w->SetDirty(); break; case WE_RESIZE: @@ -689,6 +689,6 @@ w->vscroll.cap = 16; w->resize.height = w->height - 6 * 10; // minimum 10 items w->resize.step_height = 10; - SetWindowDirty(w); + w->SetDirty(); } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/main_gui.cpp --- a/src/main_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/main_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -111,7 +111,7 @@ if (IsWindowWidgetDisabled(w, widget)) return false; SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); if (IsWindowWidgetLowered(w, widget)) { ResetObjectToPlace(); @@ -456,9 +456,9 @@ } break; case WE_DESTROY: { - Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0); + Window *v = Window::FindById(WC_MAIN_TOOLBAR, 0); RaiseWindowWidget(v, WP(w,menu_d).main_button); - SetWindowDirty(v); + v->SetDirty(); return; } @@ -468,13 +468,13 @@ if (index < 0) { - Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0); + Window *w2 = Window::FindById(WC_MAIN_TOOLBAR,0); if (GetWidgetFromPos(w2, e->we.popupmenu.pt.x - w2->left, e->we.popupmenu.pt.y - w2->top) == WP(w,menu_d).main_button) index = WP(w,menu_d).sel_index; } action_id = WP(w,menu_d).action_id; - DeleteWindow(w); + w->Close(); if (index >= 0) { assert((uint)index <= lengthof(_menu_clicked_procs)); @@ -490,7 +490,7 @@ if (index == -1 || index == WP(w,menu_d).sel_index) return; WP(w,menu_d).sel_index = index; - SetWindowDirty(w); + w->SetDirty(); return; } } @@ -531,11 +531,11 @@ if (WP(w,menu_d).item_count != num) { WP(w,menu_d).item_count = num; - SetWindowDirty(w); + w->SetDirty(); num = num * 10 + 2; w->height = num; w->widget[0].bottom = w->widget[0].top + num - 1; - SetWindowDirty(w); + w->SetDirty(); } } @@ -591,9 +591,9 @@ } case WE_DESTROY: { - Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0); + Window *v = Window::FindById(WC_MAIN_TOOLBAR, 0); RaiseWindowWidget(v, WP(w,menu_d).main_button); - SetWindowDirty(v); + v->SetDirty(); return; } @@ -610,12 +610,12 @@ } if (index < 0) { - Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0); + Window *w2 = Window::FindById(WC_MAIN_TOOLBAR,0); if (GetWidgetFromPos(w2, e->we.popupmenu.pt.x - w2->left, e->we.popupmenu.pt.y - w2->top) == WP(w,menu_d).main_button) index = WP(w,menu_d).sel_index; } - DeleteWindow(w); + w->Close(); if (index >= 0) { assert(index >= 0 && index < 30); @@ -639,7 +639,7 @@ if (index == -1 || index == WP(w,menu_d).sel_index) return; WP(w,menu_d).sel_index = index; - SetWindowDirty(w); + w->SetDirty(); return; } } @@ -707,7 +707,7 @@ width = max(GetStringListMaxWidth(base_string, item_count) + 6, 140); x = w->left + clamp(x, 0, w->width - width); // or alternatively '_screen.width - width' - w = AllocateWindow(x, 22, width, item_count * 10 + 2, MenuWndProc, WC_TOOLBAR_MENU, _menu_widgets); + w = Window::Allocate(x, 22, width, item_count * 10 + 2, MenuWndProc, WC_TOOLBAR_MENU, _menu_widgets); w->widget[0].bottom = item_count * 10 + 1; w->flags4 &= ~WF_WHITE_BORDER_MASK; @@ -733,7 +733,7 @@ InvalidateWidget(w, main_button); DeleteWindowById(WC_TOOLBAR_MENU, 0); - w = AllocateWindow(x, 0x16, 0xF1, 0x52, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets); + w = Window::Allocate(x, 0x16, 0xF1, 0x52, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets); w->flags4 &= ~WF_WHITE_BORDER_MASK; WP(w,menu_d).item_count = 0; WP(w,menu_d).sel_index = (_local_player != PLAYER_SPECTATOR) ? _local_player : GetPlayerIndexFromMenu(0); @@ -883,7 +883,7 @@ vp->virtual_left = WP(w, vp_d).scrollpos_x; vp->virtual_top = WP(w, vp_d).scrollpos_y; } - SetWindowDirty(w); + w->SetDirty(); /* Update the windows that have zoom-buttons to perhaps disable their buttons */ SendWindowMessageClass(w->window_class, how, w->window_number, 0); return true; @@ -891,16 +891,16 @@ static void ToolbarZoomInClick(Window *w) { - if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) { - HandleButtonClick(w, 17); + if (DoZoomInOutWindow(ZOOM_IN, Window::FindById(WC_MAIN_WINDOW, 0))) { + w->HandleButtonClick(17); SndPlayFx(SND_15_BEEP); } } static void ToolbarZoomOutClick(Window *w) { - if (DoZoomInOutWindow(ZOOM_OUT,FindWindowById(WC_MAIN_WINDOW, 0))) { - HandleButtonClick(w, 18); + if (DoZoomInOutWindow(ZOOM_OUT,Window::FindById(WC_MAIN_WINDOW, 0))) { + w->HandleButtonClick(18); SndPlayFx(SND_15_BEEP); } } @@ -975,8 +975,8 @@ { // don't allow too fast scrolling if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { - HandleButtonClick(w, 6); - SetWindowDirty(w); + w->HandleButtonClick(6); + w->SetDirty(); _patches_newgame.starting_year = clamp(_patches_newgame.starting_year - 1, MIN_YEAR, MAX_YEAR); SetDate(ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); @@ -988,8 +988,8 @@ { // don't allow too fast scrolling if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { - HandleButtonClick(w, 7); - SetWindowDirty(w); + w->HandleButtonClick(7); + w->SetDirty(); _patches_newgame.starting_year = clamp(_patches_newgame.starting_year + 1, MIN_YEAR, MAX_YEAR); SetDate(ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); @@ -1005,16 +1005,16 @@ static void ToolbarScenZoomIn(Window *w) { - if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) { - HandleButtonClick(w, 9); + if (DoZoomInOutWindow(ZOOM_IN, Window::FindById(WC_MAIN_WINDOW, 0))) { + w->HandleButtonClick(9); SndPlayFx(SND_15_BEEP); } } static void ToolbarScenZoomOut(Window *w) { - if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) { - HandleButtonClick(w, 10); + if (DoZoomInOutWindow(ZOOM_OUT, Window::FindById(WC_MAIN_WINDOW, 0))) { + w->HandleButtonClick(10); SndPlayFx(SND_15_BEEP); } } @@ -1313,17 +1313,17 @@ break; case 12: case 13: { /* Increase/Decrease terraform size */ int size = (e->we.click.widget == 12) ? 1 : -1; - HandleButtonClick(w, e->we.click.widget); + w->HandleButtonClick(e->we.click.widget); size += _terraform_size; if (!IS_INT_INSIDE(size, 1, 8 + 1)) return; _terraform_size = size; SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); } break; case 14: /* gen random land */ - HandleButtonClick(w, 14); + w->HandleButtonClick(14); ShowCreateScenario(); break; case 15: /* Reset landscape */ @@ -1362,8 +1362,8 @@ break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); - SetWindowDirty(w); + w->RaiseButtons(); + w->SetDirty(); break; } } @@ -1383,7 +1383,7 @@ static void ToolbarScenGenLand(Window *w) { - HandleButtonClick(w, 11); + w->HandleButtonClick(11); SndPlayFx(SND_15_BEEP); ShowEditorTerraformToolBar(); @@ -1437,7 +1437,7 @@ case 5: {/* random town */ Town *t; - HandleButtonClick(w, 5); + w->HandleButtonClick(5); _generating_world = true; t = CreateRandomTown(20, _scengen_town_size); _generating_world = false; @@ -1451,7 +1451,7 @@ break; } case 6: {/* many random towns */ - HandleButtonClick(w, 6); + w->HandleButtonClick(6); _generating_world = true; if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0); @@ -1463,7 +1463,7 @@ RaiseWindowWidget(w, (_scengen_town_size - 1) + 7); _scengen_town_size = (e->we.click.widget - 7) + 1; LowerWindowWidget(w, (_scengen_town_size - 1) + 7); - SetWindowDirty(w); + w->SetDirty(); break; } break; @@ -1471,15 +1471,15 @@ case WE_TIMEOUT: RaiseWindowWidget(w, 5); RaiseWindowWidget(w, 6); - SetWindowDirty(w); + w->SetDirty(); break; case WE_PLACE_OBJ: _place_proc(e->we.place.tile); break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); LowerWindowWidget(w, (_scengen_town_size - 1) + 7); - SetWindowDirty(w); + w->SetDirty(); break; } } @@ -1494,7 +1494,7 @@ static void ToolbarScenGenTown(Window *w) { - HandleButtonClick(w, 12); + w->HandleButtonClick(12); SndPlayFx(SND_15_BEEP); AllocateWindowDescFront(&_scen_edit_town_gen_desc, 0); @@ -1645,7 +1645,7 @@ case WE_CLICK: if (e->we.click.widget == 3) { - HandleButtonClick(w, 3); + w->HandleButtonClick(3); if (!AnyTownExists()) { ShowErrorMessage(STR_0286_MUST_BUILD_TOWN_FIRST, STR_CAN_T_GENERATE_INDUSTRIES, 0, 0); @@ -1685,8 +1685,8 @@ break; } case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); - SetWindowDirty(w); + w->RaiseButtons(); + w->SetDirty(); break; case WE_TIMEOUT: RaiseWindowWidget(w, 3); @@ -1737,28 +1737,28 @@ static void ToolbarScenGenIndustry(Window *w) { - HandleButtonClick(w, 13); + w->HandleButtonClick(13); SndPlayFx(SND_15_BEEP); AllocateWindowDescFront(_scenedit_industry_descs[_opt.landscape],0); } static void ToolbarScenBuildRoad(Window *w) { - HandleButtonClick(w, 14); + w->HandleButtonClick(14); SndPlayFx(SND_15_BEEP); ShowBuildRoadScenToolbar(); } static void ToolbarScenPlantTrees(Window *w) { - HandleButtonClick(w, 15); + w->HandleButtonClick(15); SndPlayFx(SND_15_BEEP); ShowBuildTreesScenToolbar(); } static void ToolbarScenPlaceSign(Window *w) { - HandleButtonClick(w, 16); + w->HandleButtonClick(16); SndPlayFx(SND_15_BEEP); SelectSignTool(); } @@ -1811,9 +1811,9 @@ /* If spectator, disable all construction buttons * ie : Build road, rail, ships, airports and landscaping * Since enabled state is the default, just disable when needed */ - SetWindowWidgetsDisabledState(w, _current_player == PLAYER_SPECTATOR, 19, 20, 21, 22, 23, WIDGET_LIST_END); + w->SetWidgetsDisabledState(_current_player == PLAYER_SPECTATOR, 19, 20, 21, 22, 23, WIDGET_LIST_END); /* disable company list drop downs, if there are no companies */ - SetWindowWidgetsDisabledState(w, ActivePlayerCount() == 0, 7, 8, 13, 14, 15, 16, WIDGET_LIST_END); + w->SetWidgetsDisabledState(ActivePlayerCount() == 0, 7, 8, 13, 14, 15, 16, WIDGET_LIST_END); DrawWindowWidgets(w); break; @@ -1865,7 +1865,7 @@ case WE_ABORT_PLACE_OBJ: { RaiseWindowWidget(w, 25); - SetWindowDirty(w); + w->SetDirty(); } break; case WE_MOUSELOOP: @@ -1892,7 +1892,7 @@ } case WE_MESSAGE: - HandleZoomMessage(w, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 17, 18); + HandleZoomMessage(w, Window::FindById(WC_MAIN_WINDOW, 0)->viewport, 17, 18); break; } } @@ -2064,23 +2064,23 @@ case WE_ABORT_PLACE_OBJ: { RaiseWindowWidget(w, 25); - SetWindowDirty(w); + w->SetDirty(); } break; case WE_MOUSELOOP: if (IsWindowWidgetLowered(w, 0) != !!_pause) { ToggleWidgetLoweredState(w, 0); - SetWindowDirty(w); + w->SetDirty(); } if (IsWindowWidgetLowered(w, 1) != !!_fast_forward) { ToggleWidgetLoweredState(w, 1); - SetWindowDirty(w); + w->SetDirty(); } break; case WE_MESSAGE: - HandleZoomMessage(w, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 9, 10); + HandleZoomMessage(w, Window::FindById(WC_MAIN_WINDOW, 0)->viewport, 9, 10); break; } } @@ -2167,7 +2167,7 @@ DrawStringCentered(320, 1, STR_032F_AUTOSAVE, 0); } else if (_pause) { DrawStringCentered(320, 1, STR_0319_PAUSED, 0); - } else if (WP(w,def_d).data_1 > -1280 && FindWindowById(WC_NEWS_WINDOW,0) == NULL && _statusbar_news_item.string_id != 0) { + } else if (WP(w,def_d).data_1 > -1280 && Window::FindById(WC_NEWS_WINDOW,0) == NULL && _statusbar_news_item.string_id != 0) { // Draw the scrolling news text if (!DrawScrollingStatusText(&_statusbar_news_item, WP(w,def_d).data_1)) WP(w,def_d).data_1 = -1280; @@ -2185,7 +2185,7 @@ case WE_MESSAGE: w->message.msg = e->we.message.msg; - SetWindowDirty(w); + w->SetDirty(); break; case WE_CLICK: @@ -2415,7 +2415,7 @@ width = _screen.width; height = _screen.height; - w = AllocateWindow(0, 0, width, height, MainWindowWndProc, WC_MAIN_WINDOW, NULL); + w = Window::Allocate(0, 0, width, height, MainWindowWndProc, WC_MAIN_WINDOW, NULL); AssignWindowViewport(w, 0, 0, width, height, TileXY(32, 32), 0); // XXX: these are not done @@ -2474,3 +2474,4 @@ + diff -r 42bf2d268a86 -r 5077e6ed3788 src/misc/countedptr.hpp --- a/src/misc/countedptr.hpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/misc/countedptr.hpp Sun Feb 11 22:57:24 2007 +0000 @@ -3,7 +3,7 @@ #ifndef COUNTEDPTR_HPP #define COUNTEDPTR_HPP -#if 0 // reenable when needed +#if 1 // reenable when needed /** @file CCountedPtr - smart pointer implementation */ /** CCountedPtr - simple reference counting smart pointer. @@ -54,7 +54,7 @@ FORCEINLINE operator const Tcls*() const {assert(m_pT == NULL); return m_pT;} /** raw pointer casting operator - non-const way */ - FORCEINLINE operator Tcls*() {assert(m_pT == NULL); return m_pT;} + FORCEINLINE operator Tcls*() {return m_pT;} /** operator & to support output arguments */ FORCEINLINE Tcls** operator &() {assert(m_pT == NULL); return &m_pT;} @@ -72,10 +72,10 @@ FORCEINLINE bool IsNull() const {return m_pT == NULL;} /** another way how to test for NULL value */ - FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;} + //FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;} /** yet another way how to test for NULL value */ - FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;} + //FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;} /** assign pointer w/o incrementing ref count */ FORCEINLINE void Attach(Tcls* pT) {Release(); m_pT = pT;} diff -r 42bf2d268a86 -r 5077e6ed3788 src/misc_cmd.cpp --- a/src/misc_cmd.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/misc_cmd.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -329,7 +329,7 @@ /* If we are a network-client, update the difficult setting (if it is open). * Use this instead of just dirtying the window because we need to load in * the new difficulty settings */ - if (_networking && !_network_server && FindWindowById(WC_GAME_OPTIONS, 0) != NULL) + if (_networking && !_network_server && Window::FindById(WC_GAME_OPTIONS, 0) != NULL) ShowGameDifficulty(); } return 0; diff -r 42bf2d268a86 -r 5077e6ed3788 src/misc_gui.cpp --- a/src/misc_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/misc_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -277,7 +277,7 @@ case WE_MOUSELOOP: /* Timer to scroll the text and adjust the new top */ if (WP(w, scroller_d).counter++ % 3 == 0) { WP(w, scroller_d).height--; - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -398,7 +398,7 @@ break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); break; } } @@ -529,11 +529,11 @@ break; case WE_MOUSELOOP: - if (_right_button_down) DeleteWindow(w); + if (_right_button_down) w->Close(); break; case WE_4: - if (--_errmsg_duration == 0) DeleteWindow(w); + if (--_errmsg_duration == 0) w->Close(); break; case WE_DESTROY: @@ -545,7 +545,7 @@ if (e->we.keypress.keycode == WKC_SPACE) { // Don't continue. e->we.keypress.cont = false; - DeleteWindow(w); + w->Close(); } break; } @@ -572,7 +572,7 @@ if ( (x|y) != 0) { pt = RemapCoords2(x, y); - vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; + vp = Window::FindById(WC_MAIN_WINDOW, 0)->viewport; // move x pos to opposite corner pt.x = ((pt.x - vp->virtual_left) >> vp->zoom) + vp->left; @@ -586,18 +586,18 @@ pt.x = (_screen.width - 240) >> 1; pt.y = (_screen.height - 46) >> 1; } - w = AllocateWindow(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets); + w = Window::Allocate(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets); } else { if ( (x|y) != 0) { pt = RemapCoords2(x, y); - vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; + vp = Window::FindById(WC_MAIN_WINDOW, 0)->viewport; pt.x = clamp(((pt.x - vp->virtual_left) >> vp->zoom) + vp->left - (334/2), 0, _screen.width - 334); pt.y = clamp(((pt.y - vp->virtual_top) >> vp->zoom) + vp->top - (137/2), 22, _screen.height - 137); } else { pt.x = (_screen.width - 334) >> 1; pt.y = (_screen.height - 137) >> 1; } - w = AllocateWindow(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets); + w = Window::Allocate(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets); } w->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET; @@ -663,9 +663,9 @@ /* We can show tooltips while dragging tools. These are shown as long as * we are dragging the tool. Normal tooltips work with rmb */ if (WP(w, tooltips_d).paramcount == 0 ) { - if (!_right_button_down) DeleteWindow(w); + if (!_right_button_down) w->Close(); } else { - if (!_left_button_down) DeleteWindow(w); + if (!_left_button_down) w->Close(); } break; @@ -708,7 +708,7 @@ if (y + br.height > _screen.height - 12) y = _cursor.pos.y + _cursor.offs.y - br.height - 5; x = clamp(_cursor.pos.x - (br.width >> 1), 0, _screen.width - br.width); - w = AllocateWindow(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets); + w = Window::Allocate(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets); WP(w, tooltips_d).string_id = str; assert(sizeof(WP(w, tooltips_d).params[0]) == sizeof(params[0])); @@ -764,7 +764,7 @@ { if (_thd.dirty & 1) { _thd.dirty &= ~1; - SetWindowDirty(w); + w->SetDirty(); } } @@ -1092,7 +1092,7 @@ } /* Fallthrough */ case QUERY_STR_WIDGET_CANCEL: - DeleteWindow(w); + w->Close(); break; } break; @@ -1104,7 +1104,7 @@ case WE_KEYPRESS: switch (HandleEditBoxKey(w, qs, QUERY_STR_WIDGET_TEXT, e)) { case 1: goto press_ok; /* Enter pressed, confirms change */ - case 2: DeleteWindow(w); break; /* ESC pressed, closes window, abandons changes */ + case 2: w->Close(); break; /* ESC pressed, closes window, abandons changes */ } break; @@ -1218,7 +1218,7 @@ if (q->proc != NULL) q->proc(w->parent, true); /* Fallthrough */ case QUERY_WIDGET_NO: - DeleteWindow(w); + w->Close(); break; } break; @@ -1232,7 +1232,7 @@ /* Fallthrough */ case WKC_ESC: e->we.keypress.cont = false; - DeleteWindow(w); + w->Close(); break; } break; @@ -1278,7 +1278,7 @@ Window *w = AllocateWindowDesc(&_query_desc); if (w == NULL) return; - if (parent == NULL) parent = FindWindowById(WC_MAIN_WINDOW, 0); + if (parent == NULL) parent = Window::FindById(WC_MAIN_WINDOW, 0); w->parent = parent; w->left = parent->left + (parent->width / 2) - (w->width / 2); w->top = parent->top + (parent->height / 2) - (w->height / 2); @@ -1468,19 +1468,19 @@ _savegame_sort_order = (_savegame_sort_order == SORT_BY_NAME) ? SORT_BY_NAME | SORT_DESCENDING : SORT_BY_NAME; _savegame_sort_dirty = true; - SetWindowDirty(w); + w->SetDirty(); break; case 3: /* Sort save names by date */ _savegame_sort_order = (_savegame_sort_order == SORT_BY_DATE) ? SORT_BY_DATE | SORT_DESCENDING : SORT_BY_DATE; _savegame_sort_dirty = true; - SetWindowDirty(w); + w->SetDirty(); break; case 6: /* OpenTTD 'button', jumps to OpenTTD directory */ FiosBrowseTo(&o_dir); - SetWindowDirty(w); + w->SetDirty(); BuildFileList(); break; @@ -1502,13 +1502,13 @@ ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name)); ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title)); - DeleteWindow(w); + w->Close(); } else if (_saveload_mode == SLD_LOAD_HEIGHTMAP) { SetFiosType(file->type); ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name)); ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title)); - DeleteWindow(w); + w->Close(); ShowHeightmapLoad(); } else { // SLD_SAVE_GAME, SLD_SAVE_SCENARIO copy clicked name to editbox @@ -1518,7 +1518,7 @@ } } else { // Changed directory, need repaint. - SetWindowDirty(w); + w->SetDirty(); BuildFileList(); } break; @@ -1535,13 +1535,13 @@ break; case WE_KEYPRESS: if (e->we.keypress.keycode == WKC_ESC) { - DeleteWindow(w); + w->Close(); return; } if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) { if (HandleEditBoxKey(w, &WP(w, querystr_d), 10, e) == 1) /* Press Enter */ - HandleButtonClick(w, 12); + w->HandleButtonClick(12); } break; case WE_TIMEOUT: @@ -1559,7 +1559,7 @@ } UpdateTextBufferSize(&WP(w, querystr_d).text); - SetWindowDirty(w); + w->SetDirty(); } else if (IsWindowWidgetLowered(w, 12)) { /* Save button clicked */ _switch_mode = SM_SAVE; FiosMakeSavegameName(_file_to_saveload.name, WP(w,querystr_d).text.buf, sizeof(_file_to_saveload.name)); @@ -1663,7 +1663,7 @@ void RedrawAutosave(void) { - SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0)); + Window::SetDirtyById(WC_STATUS_BAR, 0); } void SetFiosType(const byte fiostype) @@ -1739,7 +1739,7 @@ SetDate(ConvertYMDToDate(_cur_year + p2, ymd.month, ymd.day)); EnginesMonthlyLoop(); - SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0)); + Window::SetDirtyById(WC_STATUS_BAR, 0); return _cur_year; } @@ -1896,17 +1896,17 @@ if (value != oldvalue) { WriteValue(ce->variable, ce->type, (int64)value); - SetWindowDirty(w); + w->SetDirty(); } w->flags4 |= 5 << WF_TIMEOUT_SHL; - SetWindowDirty(w); + w->SetDirty(); } break; case WE_TIMEOUT: WP(w,def_d).data_1 = 0; - SetWindowDirty(w); + w->SetDirty(); break; } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/music_gui.cpp --- a/src/music_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/music_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -255,7 +255,7 @@ if (p[i] == 0) { p[i] = y + 1; p[i + 1] = 0; - SetWindowDirty(w); + w->SetDirty(); SelectSongToPlay(); break; } @@ -275,13 +275,13 @@ p[i] = p[i + 1]; } - SetWindowDirty(w); + w->SetDirty(); SelectSongToPlay(); } break; case 11: // clear _playlists[msf.playlist][0] = 0; - SetWindowDirty(w); + w->SetDirty(); StopMusic(); SelectSongToPlay(); break; @@ -294,7 +294,7 @@ case 5: case 6: case 7: case 8: case 9: case 10: /* set playlist */ msf.playlist = e->we.click.widget - 5; - SetWindowDirty(w); + w->SetDirty(); InvalidateWindow(WC_MUSIC_WINDOW, 0); StopMusic(); SelectSongToPlay(); @@ -440,7 +440,7 @@ *vol = new_vol; if (vol == &msf.music_vol) MusicVolumeChanged(new_vol); - SetWindowDirty(w); + w->SetDirty(); } _left_button_clicked = false; @@ -455,7 +455,7 @@ break; case 12: case 13: case 14: case 15: case 16: case 17: // playlist msf.playlist = e->we.click.widget - 12; - SetWindowDirty(w); + w->SetDirty(); InvalidateWindow(WC_MUSIC_TRACK_SELECTION, 0); StopMusic(); SelectSongToPlay(); diff -r 42bf2d268a86 -r 5077e6ed3788 src/network/network_gui.cpp --- a/src/network/network_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/network/network_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -405,7 +405,7 @@ _ng_sorting.order = !!(ld->flags & VL_DESC); _ng_sorting.criteria = ld->sort_type; - SetWindowDirty(w); + w->SetDirty(); break; case 9: { /* Matrix to show networkgames */ NetworkGameList *cur_item; @@ -418,7 +418,7 @@ for (; id_v > 0 && cur_item != NULL; id_v--) cur_item = cur_item->next; nd->server = cur_item; - SetWindowDirty(w); + w->SetDirty(); } break; case 11: /* Find server automatically */ switch (_network_lan_internet) { @@ -461,7 +461,7 @@ break; } - SetWindowDirty(w); + w->SetDirty(); break; case WE_MOUSELOOP: @@ -471,7 +471,7 @@ case WE_MESSAGE: if (e->we.message.msg != 0) nd->server = NULL; ld->flags |= VL_REBUILD; - SetWindowDirty(w); + w->SetDirty(); break; case WE_KEYPRESS: @@ -665,7 +665,7 @@ if (y >= w->vscroll.count) return; nd->map = (y == 0) ? NULL : _fios_list + y - 1; - SetWindowDirty(w); + w->SetDirty(); } break; case 7: case 8: /* Connection type */ ShowDropDownMenu(w, _connection_types_dropdown, _network_advertise, 8, 0, 0); // do it for widget 8 @@ -694,7 +694,7 @@ ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name)); ttd_strlcpy(_file_to_saveload.title, nd->map->title, sizeof(_file_to_saveload.title)); - DeleteWindow(w); + w->Close(); SwitchMode(SM_START_SCENARIO); } } @@ -718,7 +718,7 @@ case 16: _network_game_info.server_lang = e->we.dropdown.index; break; } - SetWindowDirty(w); + w->SetDirty(); break; case WE_MOUSELOOP: @@ -737,7 +737,7 @@ case WE_ON_EDIT_TEXT: { ttd_strlcpy(_network_server_password, e->we.edittext.str, lengthof(_network_server_password)); _network_game_info.use_password = (_network_server_password[0] != '\0'); - SetWindowDirty(w); + w->SetDirty(); } break; } } @@ -928,7 +928,7 @@ id_v += w->vscroll.pos; nd->company = (id_v >= nd->server->info.companies_on) ? INVALID_PLAYER : NetworkLobbyFindCompanyIndex(id_v); - SetWindowDirty(w); + w->SetDirty(); } break; case 7: /* Join company */ if (nd->company != (byte)-1) { @@ -951,7 +951,7 @@ } break; case WE_MESSAGE: - SetWindowDirty(w); + w->SetDirty(); break; } } @@ -1141,10 +1141,10 @@ // If height is changed if (w->height != CLNWND_OFFSET + num + 1) { // XXX - magic unfortunately; (num + 2) has to be one bigger than heigh (num + 1) - SetWindowDirty(w); + w->SetDirty(); w->widget[2].bottom = w->widget[2].top + num + 2; w->height = CLNWND_OFFSET + num + 1; - SetWindowDirty(w); + w->SetDirty(); return false; } return true; @@ -1224,7 +1224,7 @@ h = ClientListPopupHeigth(); // Allocate the popup - w = AllocateWindow(x, y, 150, h + 1, ClientListPopupWndProc, WC_TOOLBAR_MENU, _client_list_popup_widgets); + w = Window::Allocate(x, y, 150, h + 1, ClientListPopupWndProc, WC_TOOLBAR_MENU, _client_list_popup_widgets); w->widget[0].bottom = w->widget[0].top + h; w->widget[0].right = w->widget[0].left + 150; @@ -1284,7 +1284,7 @@ if (index == -1 || index == WP(w,menu_d).sel_index) return; WP(w,menu_d).sel_index = index; - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -1342,7 +1342,7 @@ if (e->we.mouseover.pt.y == -1) { _selected_clientlist_y = 0; _selected_clientlist_item = 255; - SetWindowDirty(w); + w->SetDirty(); break; } // It did not change.. no update! @@ -1357,7 +1357,7 @@ } // Repaint - SetWindowDirty(w); + w->SetDirty(); break; case WE_DESTROY: case WE_CREATE: @@ -1387,7 +1387,7 @@ case NETWORK_GAME_PASSWORD: caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break; case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break; } - ShowQueryString(STR_EMPTY, caption, 20, 180, FindWindowById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL); + ShowQueryString(STR_EMPTY, caption, 20, 180, Window::FindById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL); } @@ -1426,7 +1426,7 @@ switch (e->we.click.widget) { case 2: /* Disconnect button */ NetworkDisconnect(); - DeleteWindow(w); + w->Close(); SwitchMode(SM_MENU); ShowNetworkGameWindow(); break; @@ -1466,7 +1466,7 @@ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); w = AllocateWindowDesc(&_network_join_status_window_desc); /* Parent the status window to the lobby */ - if (w != NULL) w->parent = FindWindowById(WC_NETWORK_WINDOW, 0); + if (w != NULL) w->parent = Window::FindById(WC_NETWORK_WINDOW, 0); } static void SendChat(const char *buf, DestType type, byte dest) @@ -1593,7 +1593,7 @@ /* Update the textbuffer */ UpdateTextBufferSize(&WP(w, querystr_d).text); - SetWindowDirty(w); + w->SetDirty(); free(pre_buf); return; } @@ -1607,7 +1607,7 @@ /* Update the textbuffer */ UpdateTextBufferSize(&WP(w, querystr_d).text); - SetWindowDirty(w); + w->SetDirty(); } free(pre_buf); } @@ -1647,7 +1647,7 @@ byte dest = GB(WP(w, querystr_d).caption, 8, 8); SendChat(WP(w, querystr_d).text.buf, type, dest); } /* FALLTHROUGH */ - case 0: /* Cancel */ DeleteWindow(w); break; + case 0: /* Cancel */ w->Close(); break; } break; @@ -1666,7 +1666,7 @@ byte dest = GB(WP(w, querystr_d).caption, 8, 8); SendChat(WP(w, querystr_d).text.buf, type, dest); } /* FALLTHROUGH */ - case 2: /* Escape */ DeleteWindow(w); break; + case 2: /* Escape */ w->Close(); break; } } break; diff -r 42bf2d268a86 -r 5077e6ed3788 src/newgrf_gui.cpp --- a/src/newgrf_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/newgrf_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -143,7 +143,7 @@ for (c = _all_grfs; c != NULL && i > 0; c = c->next, i--); WP(w, newgrf_add_d).sel = c; - SetWindowDirty(w); + w->SetDirty(); break; } @@ -179,7 +179,7 @@ case 7: /* Rescan list */ WP(w, newgrf_add_d).sel = NULL; ScanNewGRFFiles(); - SetWindowDirty(w); + w->SetDirty(); break; } break; @@ -244,7 +244,7 @@ bool disable_all = WP(w, newgrf_d).sel == NULL || !WP(w, newgrf_d).editable; SetWindowWidgetDisabledState(w, 3, !WP(w, newgrf_d).editable); - SetWindowWidgetsDisabledState(w, disable_all, + w->SetWidgetsDisabledState(disable_all, SNGRFS_REMOVE, SNGRFS_MOVE_UP, SNGRFS_MOVE_DOWN, @@ -291,7 +291,7 @@ for (c = *nd->list; c != NULL && i > 0; c = c->next, i--); nd->sel = c; - SetWindowDirty(w); + w->SetDirty(); } } @@ -380,7 +380,7 @@ WP(w, newgrf_d).sel = newsel; SetupNewGRFWindow(w); - SetWindowDirty(w); + w->SetDirty(); break; } @@ -396,7 +396,7 @@ break; } } - SetWindowDirty(w); + w->SetDirty(); break; } @@ -412,7 +412,7 @@ break; } } - SetWindowDirty(w); + w->SetDirty(); break; } @@ -423,7 +423,7 @@ for (c = *WP(w, newgrf_d).list; c != NULL && i > 0; c = c->next, i--); WP(w, newgrf_d).sel = c; - SetWindowDirty(w); + w->SetDirty(); break; } @@ -460,7 +460,7 @@ /* parse_intlist returns -1 on error */ if (c->num_params == (byte)-1) c->num_params = 0; } - SetWindowDirty(w); + w->SetDirty(); break; case WE_DESTROY: diff -r 42bf2d268a86 -r 5077e6ed3788 src/news_gui.cpp --- a/src/news_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/news_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -114,7 +114,7 @@ { switch (e->event) { case WE_CREATE: { /* If chatbar is open at creation time, we need to go above it */ - const Window *w1 = FindWindowById(WC_SEND_NETWORK_MSG, 0); + const Window *w1 = Window::FindById(WC_SEND_NETWORK_MSG, 0); w->message.msg = (w1 != NULL) ? w1->height : 0; } break; @@ -179,7 +179,7 @@ switch (e->we.click.widget) { case 1: { NewsItem *ni = WP(w, news_d).ni; - DeleteWindow(w); + w->Close(); ni->duration = 0; _forced_news = INVALID_NEWS; } break; @@ -200,7 +200,7 @@ if (e->we.keypress.keycode == WKC_SPACE) { // Don't continue. e->we.keypress.cont = false; - DeleteWindow(w); + w->Close(); } break; @@ -309,9 +309,9 @@ ni->date = _date; COPY_OUT_DPARAM(ni->params, 0, lengthof(ni->params)); - w = FindWindowById(WC_MESSAGE_HISTORY, 0); + w = Window::FindById(WC_MESSAGE_HISTORY, 0); if (w == NULL) return; - SetWindowDirty(w); + w->SetDirty(); w->vscroll.count = _total_news; } } @@ -457,7 +457,7 @@ if (_news_ticker_sound) SndPlayFx(SND_16_MORSE); _statusbar_news_item = *ni; - w = FindWindowById(WC_STATUS_BAR, 0); + w = Window::FindById(WC_STATUS_BAR, 0); if (w != NULL) WP(w, def_d).data_1 = 360; } @@ -475,14 +475,14 @@ // Ticker message // Check if the status bar message is still being displayed? - w = FindWindowById(WC_STATUS_BAR, 0); + w = Window::FindById(WC_STATUS_BAR, 0); if (w != NULL && WP(w, const def_d).data_1 > -1280) return false; // Newspaper message, decrement duration counter if (ni->duration != 0) ni->duration--; // neither newsticker nor newspaper are running - return (ni->duration == 0 || FindWindowById(WC_NEWS_WINDOW, 0) == NULL); + return (ni->duration == 0 || Window::FindById(WC_NEWS_WINDOW, 0) == NULL); } static void MoveToNextItem(void) @@ -502,11 +502,11 @@ switch (GetNewsDisplayValue(ni->type)) { case 0: { /* Off - show nothing only a small reminder in the status bar */ - Window *w = FindWindowById(WC_STATUS_BAR, 0); + Window *w = Window::FindById(WC_STATUS_BAR, 0); if (w != NULL) { WP(w, def_d).data_2 = 91; - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -558,7 +558,7 @@ if (_forced_news == INVALID_NEWS) { /* Not forced any news yet, show the current one, unless a news window is * open (which can only be the current one), then show the previous item */ - const Window *w = FindWindowById(WC_NEWS_WINDOW, 0); + const Window *w = Window::FindById(WC_NEWS_WINDOW, 0); ShowNewsMessage((w == NULL || (_current_news == _oldest_news)) ? _current_news : decreaseIndex(_current_news)); } else if (_forced_news == _oldest_news) { /* We have reached the oldest news, start anew with the latest */ @@ -707,7 +707,7 @@ w->resize.height = w->height - 12 * 6; // minimum of 4 items in the list, each item 12 high w->resize.step_width = 1; w->resize.width = 200; // can't make window any smaller than 200 pixel - SetWindowDirty(w); + w->SetDirty(); } } @@ -776,7 +776,7 @@ WP(w, def_d).data_1 |= (1 << element); w->flags4 |= 5 << WF_TIMEOUT_SHL; // XXX - setup unclick (fake widget) - SetWindowDirty(w); + w->SetDirty(); } break; case 23: case 24: /* Dropdown menu for all settings */ @@ -795,7 +795,7 @@ SetMessageButtonStates(w, val, element); SetNewsDisplayValue(element, val); - SetWindowDirty(w); + w->SetDirty(); } } break; } break; @@ -809,13 +809,13 @@ SB(_news_display_opt, i*2, 2, e->we.dropdown.index); SetMessageButtonStates(w, e->we.dropdown.index, i); } - SetWindowDirty(w); + w->SetDirty(); break; } case WE_TIMEOUT: /* XXX - Hack to animate 'fake' buttons */ WP(w, def_d).data_1 = 0; - SetWindowDirty(w); + w->SetDirty(); break; } } @@ -912,7 +912,7 @@ * We also need an update of the current, forced and visible (open window) * news's as this shifting could change the items they were pointing to */ if (_total_news != 0) { - w = FindWindowById(WC_NEWS_WINDOW, 0); + w = Window::FindById(WC_NEWS_WINDOW, 0); NewsID visible_news = (w != NULL) ? (NewsID)(WP(w, news_d).ni - _news_items) : INVALID_NEWS; for (NewsID i = n;; i = decreaseIndex(i)) { @@ -932,9 +932,9 @@ /*DEBUG(misc, 0, "-cur %3d, old %2d, lat %3d, for %3d, tot %2d", _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/ - w = FindWindowById(WC_MESSAGE_HISTORY, 0); + w = Window::FindById(WC_MESSAGE_HISTORY, 0); if (w != NULL) { - SetWindowDirty(w); + w->SetDirty(); w->vscroll.count = _total_news; } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/openttd.cpp --- a/src/openttd.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/openttd.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -969,7 +969,7 @@ static void ScrollMainViewport(int x, int y) { if (_game_mode != GM_MENU) { - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w = Window::FindById(WC_MAIN_WINDOW, 0); assert(w); WP(w,vp_d).scrollpos_x += x << w->viewport->zoom; @@ -1073,7 +1073,7 @@ void BeforeSaveGame(void) { - const Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + const Window *w = Window::FindById(WC_MAIN_WINDOW, 0); if (w != NULL) { _saved_scrollpos_x = WP(w, const vp_d).scrollpos_x; @@ -1261,7 +1261,7 @@ ResetWindowSystem(); SetupColorsAndInitialWindow(); - w = FindWindowById(WC_MAIN_WINDOW, 0); + w = Window::FindById(WC_MAIN_WINDOW, 0); WP(w,vp_d).scrollpos_x = _saved_scrollpos_x; WP(w,vp_d).scrollpos_y = _saved_scrollpos_y; @@ -1804,3 +1804,4 @@ HalSoundDriver *_sound_driver; HalVideoDriver *_video_driver; + diff -r 42bf2d268a86 -r 5077e6ed3788 src/order_gui.cpp --- a/src/order_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/order_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -475,7 +475,7 @@ if (sel == WP(w,order_d).sel) sel = -1; WP(w,order_d).sel = sel; - SetWindowDirty(w); + w->SetDirty(); } break; case ORDER_WIDGET_SKIP: diff -r 42bf2d268a86 -r 5077e6ed3788 src/player_gui.cpp --- a/src/player_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/player_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -172,7 +172,7 @@ byte mode = (byte)WP(w,def_d).data_1; bool stickied = !!(w->flags4 & WF_STICKY); PlayerID player = (PlayerID)w->window_number; - DeleteWindow(w); + w->Close(); DoShowPlayerFinances(player, !HASBIT(mode, 0), stickied); } break; @@ -432,7 +432,7 @@ } else { WP(w, livery_d).sel = 1 << j; } - SetWindowDirty(w); + w->SetDirty(); break; } } @@ -518,21 +518,21 @@ case WE_CLICK: switch (e->we.click.widget) { - case 3: DeleteWindow(w); break; + case 3: w->Close(); break; case 4: /* ok click */ DoCommandP(0, 0, WP(w,facesel_d).face, NULL, CMD_SET_PLAYER_FACE); - DeleteWindow(w); + w->Close(); break; case 5: /* male click */ case 6: /* female click */ RaiseWindowWidget(w, WP(w, facesel_d).gender + 5); WP(w, facesel_d).gender = e->we.click.widget - 5; LowerWindowWidget(w, WP(w, facesel_d).gender + 5); - SetWindowDirty(w); + w->SetDirty(); break; case 7: WP(w,facesel_d).face = (WP(w,facesel_d).gender << 31) + GB(InteractiveRandom(), 0, 31); - SetWindowDirty(w); + w->SetDirty(); break; } break; @@ -822,18 +822,18 @@ case WE_MOUSELOOP: /* redraw the window every now and then */ - if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w); + if ((++w->vscroll.pos & 0x1F) == 0) w->SetDirty(); break; case WE_PLACE_OBJ: if (DoCommandP(e->we.place.tile, 0, 0, NULL, CMD_BUILD_COMPANY_HQ | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS))) ResetObjectToPlace(); w->widget[PCW_WIDGET_BUILD_VIEW_HQ].type = WWT_PUSHTXTBTN; // this button can now behave as a normal push button - RaiseWindowButtons(w); + w->RaiseButtons(); break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); break; case WE_DESTROY: @@ -908,7 +908,7 @@ case WE_CLICK: switch (e->we.click.widget) { case 3: - DeleteWindow(w); + w->Close(); break; case 4: { DoCommandP(0, w->window_number, 0, NULL, CMD_BUY_COMPANY | CMD_MSG(STR_7060_CAN_T_BUY_COMPANY)); @@ -995,7 +995,7 @@ } } break; case WE_CLICK: /* Close the window (and show the highscore window) */ - DeleteWindow(w); + w->Close(); break; case WE_DESTROY: /* Show the highscore window when this one is closed */ if (!_networking) DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // unpause @@ -1035,7 +1035,7 @@ } break; case WE_CLICK: /* Onclick to close window, and in destroy event handle the rest */ - DeleteWindow(w); + w->Close(); break; case WE_DESTROY: /* Get back all the hidden windows */ diff -r 42bf2d268a86 -r 5077e6ed3788 src/rail_gui.cpp --- a/src/rail_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/rail_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -320,7 +320,7 @@ static void BuildRailClick_Remove(Window *w) { if (IsWindowWidgetDisabled(w, RTW_REMOVE)) return; - SetWindowDirty(w); + w->SetDirty(); SndPlayFx(SND_15_BEEP); ToggleWidgetLoweredState(w, RTW_REMOVE); @@ -524,13 +524,13 @@ break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); DisableWindowWidget(w, RTW_REMOVE); InvalidateWidget(w, RTW_REMOVE); - w = FindWindowById(WC_BUILD_STATION, 0); + w = Window::FindById(WC_BUILD_STATION, 0); if (w != NULL) WP(w,def_d).close = true; - w = FindWindowById(WC_BUILD_DEPOT, 0); + w = Window::FindById(WC_BUILD_DEPOT, 0); if (w != NULL) WP(w,def_d).close = true; break; @@ -612,7 +612,7 @@ if (!ValParamRailtype(railtype)) return; // don't recreate the window if we're clicking on a button and the window exists. - if (button < 0 || !(w = FindWindowById(WC_BUILD_TOOLBAR, 0)) || w->wndproc != BuildRailToolbWndProc) { + if (button < 0 || !(w = Window::FindById(WC_BUILD_TOOLBAR, 0)) || w->wndproc != BuildRailToolbWndProc) { DeleteWindowById(WC_BUILD_TOOLBAR, 0); _cur_railtype = railtype; w = AllocateWindowDesc(&_build_rail_desc); @@ -787,7 +787,7 @@ _railstation.orientation = e->we.click.widget - 3; LowerWindowWidget(w, _railstation.orientation + 3); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; case 5: @@ -804,7 +804,7 @@ LowerWindowWidget(w, _railstation.platlength + 11); LowerWindowWidget(w, _railstation.numtracks + 4); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; case 12: @@ -821,7 +821,7 @@ LowerWindowWidget(w, _railstation.platlength + 11); LowerWindowWidget(w, _railstation.numtracks + 4); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; case 19: @@ -830,7 +830,7 @@ SetWindowWidgetLoweredState(w, _railstation.numtracks + 4, !_railstation.dragdrop); SetWindowWidgetLoweredState(w, _railstation.platlength + 11, !_railstation.dragdrop); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; case 20: @@ -839,7 +839,7 @@ SetWindowWidgetLoweredState(w, 20, !_station_show_coverage); SetWindowWidgetLoweredState(w, 21, _station_show_coverage); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; case 22: @@ -866,7 +866,7 @@ CheckSelectedSize(w, statspec); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; } } @@ -885,12 +885,12 @@ } SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; case WE_MOUSELOOP: if (WP(w,def_d).close) { - DeleteWindow(w); + w->Close(); return; } CheckRedrawStationCoverage(w); @@ -1027,13 +1027,13 @@ _build_depot_direction = (DiagDirection)(e->we.click.widget - 3); LowerWindowWidget(w, _build_depot_direction + 3); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; } break; case WE_MOUSELOOP: - if (WP(w,def_d).close) DeleteWindow(w); + if (WP(w,def_d).close) w->Close(); return; case WE_DESTROY: @@ -1107,7 +1107,7 @@ _cur_waypoint_type = type; SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; } } @@ -1115,7 +1115,7 @@ } case WE_MOUSELOOP: - if (WP(w,def_d).close) DeleteWindow(w); + if (WP(w,def_d).close) w->Close(); break; case WE_DESTROY: @@ -1169,13 +1169,14 @@ if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) { Window *w; _last_built_railtype = _cur_railtype = RAILTYPE_RAIL; - w = FindWindowById(WC_BUILD_TOOLBAR, 0); + w = Window::FindById(WC_BUILD_TOOLBAR, 0); if (w != NULL && w->wndproc == BuildRailToolbWndProc) { SetupRailToolbar(_cur_railtype, w); - SetWindowDirty(w); + w->SetDirty(); } } MarkWholeScreenDirty(); } + diff -r 42bf2d268a86 -r 5077e6ed3788 src/road_gui.cpp --- a/src/road_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/road_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -170,7 +170,7 @@ static void BuildRoadClick_Remove(Window *w) { if (IsWindowWidgetDisabled(w, RTW_REMOVE)) return; - SetWindowDirty(w); + w->SetDirty(); SndPlayFx(SND_15_BEEP); ToggleWidgetLoweredState(w, RTW_REMOVE); SetSelectionRed(IsWindowWidgetLowered(w, RTW_REMOVE)); @@ -228,15 +228,15 @@ break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); DisableWindowWidget(w, RTW_REMOVE); InvalidateWidget(w, RTW_REMOVE); - w = FindWindowById(WC_BUS_STATION, 0); + w = Window::FindById(WC_BUS_STATION, 0); if (w != NULL) WP(w,def_d).close = true; - w = FindWindowById(WC_TRUCK_STATION, 0); + w = Window::FindById(WC_TRUCK_STATION, 0); if (w != NULL) WP(w,def_d).close = true; - w = FindWindowById(WC_BUILD_DEPOT, 0); + w = Window::FindById(WC_BUILD_DEPOT, 0); if (w != NULL) WP(w,def_d).close = true; break; @@ -384,13 +384,13 @@ _road_depot_orientation = (DiagDirection)(e->we.click.widget - 3); LowerWindowWidget(w, _road_depot_orientation + 3); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; } } break; case WE_MOUSELOOP: - if (WP(w,def_d).close) DeleteWindow(w); + if (WP(w,def_d).close) w->Close(); break; case WE_DESTROY: @@ -465,21 +465,21 @@ _road_station_picker_orientation = (DiagDirection)(e->we.click.widget - 3); LowerWindowWidget(w, _road_station_picker_orientation + 3); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; case 7: case 8: RaiseWindowWidget(w, _station_show_coverage + 7); _station_show_coverage = (e->we.click.widget != 7); LowerWindowWidget(w, _station_show_coverage + 7); SndPlayFx(SND_15_BEEP); - SetWindowDirty(w); + w->SetDirty(); break; } } break; case WE_MOUSELOOP: { if (WP(w,def_d).close) { - DeleteWindow(w); + w->Close(); return; } diff -r 42bf2d268a86 -r 5077e6ed3788 src/roadveh_gui.cpp --- a/src/roadveh_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/roadveh_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -300,7 +300,7 @@ SetWindowWidgetHiddenState(w, 8, rv_stopped); // force turn around SetWindowWidgetHiddenState(w, 11, !rv_stopped); // clone SetWindowWidgetHiddenState(w, 12, !rv_stopped); // refit - SetWindowDirty(w); + w->SetDirty(); } } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/settings_gui.cpp --- a/src/settings_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/settings_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -155,7 +155,7 @@ case 28: /* Click fullscreen on/off */ SetWindowWidgetLoweredState(w, 28, !_fullscreen); ToggleFullScreen(!_fullscreen); // toggle full-screen on/off - SetWindowDirty(w); + w->SetDirty(); return; case 30: case 31: /* Setup screenshot format dropdown */ ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, 31, 0, 0); @@ -197,7 +197,7 @@ break; case 17: /* Autosave options */ _opt.autosave = _opt_newgame.autosave = e->we.dropdown.index; - SetWindowDirty(w); + w->SetDirty(); break; case 24: /* Change interface language */ ReadLanguagePack(e->we.dropdown.index); @@ -205,11 +205,11 @@ break; case 27: /* Change resolution */ if (e->we.dropdown.index < _num_resolutions && ChangeResInGame(_resolutions[e->we.dropdown.index][0],_resolutions[e->we.dropdown.index][1])) - SetWindowDirty(w); + w->SetDirty(); break; case 31: /* Change screenshot format */ SetScreenshotFormat(e->we.dropdown.index); - SetWindowDirty(w); + w->SetDirty(); break; } break; @@ -481,14 +481,14 @@ // save value in temporary variable ((int*)&_opt_mod_temp.diff)[btn] = val; SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom - SetWindowDirty(w); + w->SetDirty(); } break; case 3: case 4: case 5: case 6: /* Easy / Medium / Hard / Custom */ // temporarily change difficulty level RaiseWindowWidget(w, _opt_mod_temp.diff_level + 3); SetDifficultyLevel(e->we.click.widget - 3, &_opt_mod_temp); LowerWindowWidget(w, _opt_mod_temp.diff_level + 3); - SetWindowDirty(w); + w->SetDirty(); break; case 7: /* Highscore Table */ ShowHighscoreTable(_opt_mod_temp.diff_level, -1); @@ -502,7 +502,7 @@ DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL); } DoCommandP(0, UINT_MAX, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL); - DeleteWindow(w); + w->Close(); // If we are in the editor, we should reload the economy. // This way when you load a game, the max loan and interest rate // are loaded correctly. @@ -511,7 +511,7 @@ break; } case 11: /* Cancel button - close window, abandon changes */ - DeleteWindow(w); + w->Close(); break; } break; @@ -519,7 +519,7 @@ if (_difficulty_timeout != 0 && !--_difficulty_timeout) { _difficulty_click_a = 0; _difficulty_click_b = 0; - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -838,7 +838,7 @@ if (value != oldvalue) { SetPatchValue(page->entries[btn].index, patches_ptr, value); - SetWindowDirty(w); + w->SetDirty(); } } else { /* only open editbox for types that its sensible for */ @@ -859,14 +859,14 @@ WP(w, def_d).data_1 = e->we.click.widget - 4; LowerWindowWidget(w, WP(w, def_d).data_1 + 4); DeleteWindowById(WC_QUERY_STRING, 0); - SetWindowDirty(w); + w->SetDirty(); break; } break; case WE_TIMEOUT: WP(w,def_d).data_2 = 0; - SetWindowDirty(w); + w->SetDirty(); break; case WE_ON_EDIT_TEXT: { @@ -879,7 +879,7 @@ if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate; SetPatchValue(pe->index, patches_ptr, value); - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -1069,7 +1069,7 @@ } w->flags4 |= 5 << WF_TIMEOUT_SHL; - SetWindowDirty(w); + w->SetDirty(); break; } @@ -1108,7 +1108,7 @@ case WE_TIMEOUT: WP(w,def_d).data_1 = 0; - SetWindowDirty(w); + w->SetDirty(); break; case WE_DESTROY: diff -r 42bf2d268a86 -r 5077e6ed3788 src/ship_gui.cpp --- a/src/ship_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/ship_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -302,7 +302,7 @@ if (ship_stopped != IsWindowWidgetHidden(w, 7) || ship_stopped == IsWindowWidgetHidden(w, 11)) { SetWindowWidgetHiddenState(w, 7, ship_stopped); // send to depot SetWindowWidgetHiddenState(w, 11, !ship_stopped); // clone - SetWindowDirty(w); + w->SetDirty(); } } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/smallmap_gui.cpp --- a/src/smallmap_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/smallmap_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -762,7 +762,7 @@ Point pt; // Find main viewport. - vp = FindWindowById(WC_MAIN_WINDOW,0)->viewport; + vp = Window::FindById(WC_MAIN_WINDOW,0)->viewport; pt = RemapCoords(WP(w, smallmap_d).scroll_x, WP(w, smallmap_d).scroll_y, 0); @@ -789,13 +789,13 @@ { int x, y; ViewPort *vp; - vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; + vp = Window::FindById(WC_MAIN_WINDOW, 0)->viewport; x = ((vp->virtual_width - (w->widget[4].right - w->widget[4].left) * TILE_SIZE) / 2 + vp->virtual_left) / 4; y = ((vp->virtual_height - (w->widget[4].bottom - w->widget[4].top ) * TILE_SIZE) / 2 + vp->virtual_top ) / 2 - TILE_SIZE * 2; WP(w, smallmap_d).scroll_x = (y - x) & ~0xF; WP(w, smallmap_d).scroll_y = (x + y) & ~0xF; - SetWindowDirty(w); + w->SetDirty(); } static void SmallMapWindowProc(Window *w, WindowEvent *e) @@ -840,7 +840,7 @@ case WE_CLICK: switch (e->we.click.widget) { case 4: { // Map window - Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w2 = Window::FindById(WC_MAIN_WINDOW, 0); Point pt; /* @@ -857,7 +857,7 @@ WP(w2, vp_d).scrollpos_x = pt.x + ((_cursor.pos.x - w->left + 2) << 4) - (w2->viewport->virtual_width >> 1); WP(w2, vp_d).scrollpos_y = pt.y + ((_cursor.pos.y - w->top - 16) << 4) - (w2->viewport->virtual_height >> 1); - SetWindowDirty(w); + w->SetDirty(); } break; case 5: // Show land contours @@ -870,14 +870,14 @@ _smallmap_type = e->we.click.widget - 5; LowerWindowWidget(w, _smallmap_type + 5); - SetWindowDirty(w); + w->SetDirty(); SndPlayFx(SND_15_BEEP); break; case 11: // Center the smallmap again SmallMapCenterOnCurrentPos(w); - SetWindowDirty(w); + w->SetDirty(); SndPlayFx(SND_15_BEEP); break; @@ -885,7 +885,7 @@ ToggleWidgetLoweredState(w, 12); _smallmap_show_towns = IsWindowWidgetLowered(w, 12); - SetWindowDirty(w); + w->SetDirty(); SndPlayFx(SND_15_BEEP); break; } @@ -902,7 +902,7 @@ case WE_MOUSELOOP: /* update the window every now and then */ - if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w); + if ((++w->vscroll.pos & 0x1F) == 0) w->SetDirty(); break; case WE_SCROLL: { @@ -963,7 +963,7 @@ WP(w, smallmap_d).scroll_y = y; WP(w, smallmap_d).subscroll = sub; - SetWindowDirty(w); + w->SetDirty(); } break; } } @@ -1029,7 +1029,7 @@ case 6: DoZoomInOutWindow(ZOOM_OUT, w); break; case 7: { /* location button (move main view to same spot as this view) 'Paste Location' */ - Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w2 = Window::FindById(WC_MAIN_WINDOW, 0); int x = WP(w, vp_d).scrollpos_x; // Where is the main looking at int y = WP(w, vp_d).scrollpos_y; @@ -1039,7 +1039,7 @@ } break; case 8: { /* inverse location button (move this view to same spot as main view) 'Copy Location' */ - const Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0); + const Window *w2 = Window::FindById(WC_MAIN_WINDOW, 0); int x = WP(w2, const vp_d).scrollpos_x; int y = WP(w2, const vp_d).scrollpos_y; @@ -1095,13 +1095,13 @@ int i = 0; // find next free window number for extra viewport - while (FindWindowById(WC_EXTRA_VIEW_PORT, i) != NULL) i++; + while (Window::FindById(WC_EXTRA_VIEW_PORT, i) != NULL) i++; w = AllocateWindowDescFront(&_extra_view_port_desc, i); if (w != NULL) { int x, y; // the main window with the main view - v = FindWindowById(WC_MAIN_WINDOW, 0); + v = Window::FindById(WC_MAIN_WINDOW, 0); // New viewport start ats (zero,zero) AssignWindowViewport(w, 3, 17, 294, 214, 0 , 0); diff -r 42bf2d268a86 -r 5077e6ed3788 src/sound.cpp --- a/src/sound.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/sound.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -193,12 +193,12 @@ static void SndPlayScreenCoordFx(SoundFx sound, int x, int y) { - Window* const *wz; if (msf.effect_vol == 0) return; - FOR_ALL_WINDOWS(wz) { - const ViewPort *vp = (*wz)->viewport; + Window *w; + FOR_ALL_WINDOWS(w) { + const ViewPort *vp = w->viewport; if (vp != NULL && IS_INSIDE_1D(x, vp->virtual_left, vp->virtual_width) && diff -r 42bf2d268a86 -r 5077e6ed3788 src/station_gui.cpp --- a/src/station_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/station_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -171,26 +171,24 @@ void RebuildStationLists(void) { - Window* const *wz; + Window *w; - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + FOR_ALL_WINDOWS(w) { if (w->window_class == WC_STATION_LIST) { WP(w, plstations_d).flags |= SL_REBUILD; - SetWindowDirty(w); + w->SetDirty(); } } } void ResortStationLists(void) { - Window* const *wz; + Window *w; - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + FOR_ALL_WINDOWS(w) { if (w->window_class == WC_STATION_LIST) { WP(w, plstations_d).flags |= SL_RESORT; - SetWindowDirty(w); + w->SetDirty(); } } } @@ -409,7 +407,7 @@ } SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK)); sl->flags |= SL_REBUILD; - SetWindowDirty(w); + w->SetDirty(); break; case STATIONLIST_WIDGET_FACILALL: { @@ -421,7 +419,7 @@ facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK; sl->flags |= SL_REBUILD; - SetWindowDirty(w); + w->SetDirty(); break; } case STATIONLIST_WIDGET_CARGOALL: { @@ -434,7 +432,7 @@ cargo_filter = CARGO_ALL_SELECTED; sl->flags |= SL_REBUILD; - SetWindowDirty(w); + w->SetDirty(); break; } case STATIONLIST_WIDGET_SORTBY: /*flip sorting method asc/desc*/ @@ -443,7 +441,7 @@ sl->flags |= SL_RESORT; w->flags4 |= 5 << WF_TIMEOUT_SHL; LowerWindowWidget(w, STATIONLIST_WIDGET_SORTBY); - SetWindowDirty(w); + w->SetDirty(); break; case STATIONLIST_WIDGET_SORTCRITERIA: @@ -466,7 +464,7 @@ } sl->flags |= SL_REBUILD; SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_CARGOALL, cargo_filter == CARGO_ALL_SELECTED); - SetWindowDirty(w); + w->SetDirty(); } } } break; @@ -478,7 +476,7 @@ station_sort.criteria = sl->sort_type; sl->flags |= SL_RESORT; } - SetWindowDirty(w); + w->SetDirty(); break; case WE_TICK: @@ -486,13 +484,13 @@ DEBUG(misc, 3, "Periodic rebuild station list player %d", owner); sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; sl->flags |= SL_REBUILD; - SetWindowDirty(w); + w->SetDirty(); } break; case WE_TIMEOUT: RaiseWindowWidget(w, STATIONLIST_WIDGET_SORTBY); - SetWindowDirty(w); + w->SetDirty(); break; case WE_RESIZE: @@ -741,7 +739,7 @@ break; case 8: - SetWindowDirty(w); + w->SetDirty(); /* toggle height/widget set */ if (IsWindowOfPrototype(w, _station_view_expanded_widgets)) { @@ -752,7 +750,7 @@ w->height = 210; } - SetWindowDirty(w); + w->SetDirty(); break; case 9: { diff -r 42bf2d268a86 -r 5077e6ed3788 src/terraform_gui.cpp --- a/src/terraform_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/terraform_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -248,7 +248,7 @@ break; case WE_ABORT_PLACE_OBJ: - RaiseWindowButtons(w); + w->RaiseButtons(); break; } } diff -r 42bf2d268a86 -r 5077e6ed3788 src/town_gui.cpp --- a/src/town_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/town_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -192,7 +192,7 @@ y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + w->vscroll.pos - 1); if (y >= 0) { WP(w,def_d).data_1 = y; - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -205,7 +205,7 @@ break; case WE_4: - SetWindowDirty(w); + w->SetDirty(); break; } } @@ -466,13 +466,13 @@ case 3: { /* Sort by Name ascending/descending */ _town_sort_order = (_town_sort_order == 0) ? 1 : 0; _town_sort_dirty = true; - SetWindowDirty(w); + w->SetDirty(); } break; case 4: { /* Sort by Population ascending/descending */ _town_sort_order = (_town_sort_order == 2) ? 3 : 2; _town_sort_dirty = true; - SetWindowDirty(w); + w->SetDirty(); } break; case 5: { /* Click on Town Matrix */ @@ -495,7 +495,7 @@ break; case WE_4: - SetWindowDirty(w); + w->SetDirty(); break; case WE_RESIZE: diff -r 42bf2d268a86 -r 5077e6ed3788 src/train_gui.cpp --- a/src/train_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/train_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -296,7 +296,7 @@ SetWindowWidgetHiddenState(w, 9, train_stopped); // reverse direction SetWindowWidgetHiddenState(w, 12, !train_stopped); // refit SetWindowWidgetHiddenState(w, 13, !train_stopped); // clone - SetWindowDirty(w); + w->SetDirty(); } break; } @@ -546,7 +546,7 @@ EnableWindowWidget(w, 12); EnableWindowWidget(w, e->we.click.widget); WP(w,traindetails_d).tab = e->we.click.widget - 9; - SetWindowDirty(w); + w->SetDirty(); break; } } break; diff -r 42bf2d268a86 -r 5077e6ed3788 src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/vehicle_gui.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -91,18 +91,16 @@ void RebuildVehicleLists(void) { - Window* const *wz; + Window *w; - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; - + FOR_ALL_WINDOWS(w) { switch (w->window_class) { case WC_TRAINS_LIST: case WC_ROADVEH_LIST: case WC_SHIPS_LIST: case WC_AIRCRAFT_LIST: WP(w, vehiclelist_d).l.flags |= VL_REBUILD; - SetWindowDirty(w); + w->SetDirty(); break; default: break; @@ -112,10 +110,9 @@ void ResortVehicleLists(void) { - Window* const *wz; + Window *w; - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + FOR_ALL_WINDOWS(w) { switch (w->window_class) { case WC_TRAINS_LIST: @@ -123,7 +120,7 @@ case WC_SHIPS_LIST: case WC_AIRCRAFT_LIST: WP(w, vehiclelist_d).l.flags |= VL_RESORT; - SetWindowDirty(w); + w->SetDirty(); break; default: break; @@ -370,7 +367,7 @@ int y = e->we.click.pt.y - w->widget[3].top; if (y >= 0) { WP(w,refit_d).sel = (y / (int)w->resize.step_height) + w->vscroll.pos; - SetWindowDirty(w); + w->SetDirty(); } } break; case 6: // refit button @@ -386,9 +383,9 @@ case VEH_Ship: command = CMD_REFIT_SHIP | CMD_MSG(STR_9841_CAN_T_REFIT_SHIP); break; case VEH_Aircraft: command = CMD_REFIT_AIRCRAFT | CMD_MSG(STR_A042_CAN_T_REFIT_AIRCRAFT); break; } - if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8, NULL, command)) DeleteWindow(w); + if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8, NULL, command)) w->Close(); } else { - if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8 | WP(w, refit_d).order << 16, NULL, CMD_ORDER_REFIT)) DeleteWindow(w); + if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8 | WP(w, refit_d).order << 16, NULL, CMD_ORDER_REFIT)) w->Close(); } } break; @@ -724,28 +721,28 @@ { Window *w; - w = FindWindowById(WC_VEHICLE_VIEW, from_v->index); + w = Window::FindById(WC_VEHICLE_VIEW, from_v->index); if (w != NULL) { w->window_number = to_v->index; WP(w, vp_d).follow_vehicle = to_v->index; - SetWindowDirty(w); + w->SetDirty(); - w = FindWindowById(WC_VEHICLE_ORDERS, from_v->index); + w = Window::FindById(WC_VEHICLE_ORDERS, from_v->index); if (w != NULL) { w->window_number = to_v->index; - SetWindowDirty(w); + w->SetDirty(); } - w = FindWindowById(WC_VEHICLE_REFIT, from_v->index); + w = Window::FindById(WC_VEHICLE_REFIT, from_v->index); if (w != NULL) { w->window_number = to_v->index; - SetWindowDirty(w); + w->SetDirty(); } - w = FindWindowById(WC_VEHICLE_DETAILS, from_v->index); + w = Window::FindById(WC_VEHICLE_DETAILS, from_v->index); if (w != NULL) { w->window_number = to_v->index; - SetWindowDirty(w); + w->SetDirty(); } } } @@ -821,7 +818,7 @@ HideWindowWidget(w, VLW_WIDGET_OTHER_PLAYER_FILLER); SetWindowWidgetDisabledState(w, VLW_WIDGET_AVAILABLE_VEHICLES, window_type != VLW_STANDARD); } else { - SetWindowWidgetsHiddenState(w, true, + w->SetWidgetsHiddenState(true, VLW_WIDGET_AVAILABLE_VEHICLES, VLW_WIDGET_MANAGE_VEHICLES, VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN, @@ -1006,7 +1003,7 @@ default: NOT_REACHED(); break; } - SetWindowWidgetsDisabledState(w, vl->l.list_length == 0, + w->SetWidgetsDisabledState(vl->l.list_length == 0, VLW_WIDGET_MANAGE_VEHICLES, VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN, VLW_WIDGET_STOP_ALL, @@ -1085,7 +1082,7 @@ vl->l.flags |= VL_RESORT; vl->_sorting->order = !!(vl->l.flags & VL_DESC); - SetWindowDirty(w); + w->SetDirty(); break; case VLW_WIDGET_SORT_BY_TEXT: case VLW_WIDGET_SORT_BY_PULLDOWN:/* Select sorting criteria dropdown menu */ ShowDropDownMenu(w, _vehicle_sort_listing, vl->l.sort_type, VLW_WIDGET_SORT_BY_PULLDOWN, 0, 0); @@ -1179,7 +1176,7 @@ break; default: NOT_REACHED(); } - SetWindowDirty(w); + w->SetDirty(); break; case WE_DESTROY: @@ -1194,7 +1191,7 @@ DEBUG(misc, 3, "Periodic resort %d list player %d at station %d", vl->vehicle_type, owner, station); vl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; vl->l.flags |= VL_RESORT; - SetWindowDirty(w); + w->SetDirty(); } break; diff -r 42bf2d268a86 -r 5077e6ed3788 src/viewport.cpp --- a/src/viewport.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/viewport.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -186,11 +186,12 @@ static Point _vp_move_offs; -static void DoSetViewportPosition(Window* const *wz, int left, int top, int width, int height) +static void DoSetViewportPosition(WindowList::Iterator vit, int left, int top, int width, int height) { - - for (; wz != _last_z_window; wz++) { - const Window *w = *wz; + //Window *w = (*wit).w; + + for (WindowList::Iterator wit = vit; wit != Window::s_list.m_list.end(); wit++) { + const Window *w = (*wit).w; if (left + width > w->left && w->left + w->width > left && @@ -198,26 +199,26 @@ w->top + w->height > top) { if (left < w->left) { - DoSetViewportPosition(wz, left, top, w->left - left, height); - DoSetViewportPosition(wz, left + (w->left - left), top, width - (w->left - left), height); + DoSetViewportPosition(wit, left, top, w->left - left, height); + DoSetViewportPosition(wit, left + (w->left - left), top, width - (w->left - left), height); return; } if (left + width > w->left + w->width) { - DoSetViewportPosition(wz, left, top, (w->left + w->width - left), height); - DoSetViewportPosition(wz, left + (w->left + w->width - left), top, width - (w->left + w->width - left) , height); + DoSetViewportPosition(wit, left, top, (w->left + w->width - left), height); + DoSetViewportPosition(wit, left + (w->left + w->width - left), top, width - (w->left + w->width - left) , height); return; } if (top < w->top) { - DoSetViewportPosition(wz, left, top, width, (w->top - top)); - DoSetViewportPosition(wz, left, top + (w->top - top), width, height - (w->top - top)); + DoSetViewportPosition(wit, left, top, width, (w->top - top)); + DoSetViewportPosition(wit, left, top + (w->top - top), width, height - (w->top - top)); return; } if (top + height > w->top + w->height) { - DoSetViewportPosition(wz, left, top, width, (w->top + w->height - top)); - DoSetViewportPosition(wz, left, top + (w->top + w->height - top), width , height - (w->top + w->height - top)); + DoSetViewportPosition(wit, left, top, width, (w->top + w->height - top)); + DoSetViewportPosition(wit, left, top + (w->top + w->height - top), width , height - (w->top + w->height - top)); return; } @@ -300,7 +301,8 @@ i = top + height - _screen.height; if (i >= 0) height -= i; - if (height > 0) DoSetViewportPosition(FindWindowZPosition(w) + 1, left, top, width, height); + WindowList::Iterator it = Window::s_list.Find(w); + if (height > 0) DoSetViewportPosition(++it, left, top, width, height); } } @@ -1807,7 +1809,7 @@ bool ScrollMainWindowTo(int x, int y) { Window *w; - bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0)); + bool res = ScrollWindowTo(x, y, Window::FindById(WC_MAIN_WINDOW, 0)); /* If a user scrolls to a tile (via what way what so ever) and already is on * that tile (e.g.: pressed twice), move the smallmap to that location, @@ -1815,7 +1817,7 @@ if (res) return res; - w = FindWindowById(WC_SMALLMAP, 0); + w = Window::FindById(WC_SMALLMAP, 0); if (w == NULL) return res; SmallMapCenterOnCurrentPos(w); @@ -2394,7 +2396,7 @@ e.we.place.userdata = _thd.userdata; // stop drag mode if the window has been closed - w = FindWindowById(_thd.window_class,_thd.window_number); + w = Window::FindById(_thd.window_class,_thd.window_number); if (w == NULL) { ResetObjectToPlace(); return false; @@ -2448,7 +2450,7 @@ // undo clicking on button if (_thd.place_mode != 0) { _thd.place_mode = 0; - w = FindWindowById(_thd.window_class, _thd.window_number); + w = Window::FindById(_thd.window_class, _thd.window_number); if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ); } diff -r 42bf2d268a86 -r 5077e6ed3788 src/widget.cpp --- a/src/widget.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/widget.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -121,7 +121,7 @@ } } - SetWindowDirty(w); + w->SetDirty(); } /** Returns the index for the widget located at the given position @@ -550,14 +550,14 @@ if (item >= 0) { WP(w,dropdown_d).click_delay = 4; WP(w,dropdown_d).selected_index = item; - SetWindowDirty(w); + w->SetDirty(); } } break; case WE_MOUSELOOP: { - Window *w2 = FindWindowById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num); + Window *w2 = Window::FindById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num); if (w2 == NULL) { - DeleteWindow(w); + w->Close(); return; } @@ -567,7 +567,7 @@ e.we.dropdown.button = WP(w,dropdown_d).parent_button; e.we.dropdown.index = WP(w,dropdown_d).selected_index; w2->wndproc(w2, &e); - DeleteWindow(w); + w->Close(); return; } @@ -583,12 +583,12 @@ } WP(w,dropdown_d).selected_index = item; - SetWindowDirty(w); + w->SetDirty(); } } break; case WE_DESTROY: { - Window *w2 = FindWindowById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num); + Window *w2 = Window::FindById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num); if (w2 != NULL) { RaiseWindowWidget(w2, WP(w,dropdown_d).parent_button); InvalidateWidget(w2, WP(w,dropdown_d).parent_button); @@ -633,12 +633,12 @@ top = w->top + wi->bottom + 2; height = i * 10 + 4; - w3 = FindWindowById(WC_STATUS_BAR, 0); + w3 = Window::FindById(WC_STATUS_BAR, 0); screen_bottom = w3 == NULL ? _screen.height : w3->top; /* Check if the dropdown will fully fit below the widget */ if (top + height >= screen_bottom) { - w3 = FindWindowById(WC_MAIN_TOOLBAR, 0); + w3 = Window::FindById(WC_MAIN_TOOLBAR, 0); screen_top = w3 == NULL ? 0 : w3->top + w3->height; /* If not, check if it will fit above the widget */ @@ -653,7 +653,7 @@ } } - w2 = AllocateWindow( + w2 = Window::Allocate( w->left + wi[-1].left + 1, top, wi->right - wi[-1].left + 1, diff -r 42bf2d268a86 -r 5077e6ed3788 src/window.cpp --- a/src/window.cpp Sun Feb 11 21:20:30 2007 +0000 +++ b/src/window.cpp Sun Feb 11 22:57:24 2007 +0000 @@ -19,74 +19,594 @@ // delta between mouse cursor and upper left corner of dragged window static Point _drag_delta; -static Window _windows[25]; -Window *_z_windows[lengthof(_windows)]; -Window **_last_z_window; ///< always points to the next free space in the z-array +/*static*/ WindowList Window::s_list; -void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...) +//static Window _windows[25]; +//Window *_z_windows[lengthof(_windows)]; +//Window **_last_z_window; ///< always points to the next free space in the z-array + +int32 CountedObject::AddRef() +{ + return ++m_ref_cnt; +} + +int32 CountedObject::Release() +{ + int32 res = --m_ref_cnt; + assert(res >= 0); + if (res == 0) { + FinalRelease(); + delete this; + } + return res; +} + +void WindowList::Add(Window *w) +{ + /* we will add the new window before first vital window or at the end */ + Iterator it = w->IsVital() ? m_list.end() : FindFirstVitalWindow(); + /* it should be now at the proper position where new window should be added */ + m_list.insert(it, w); +} + +void WindowList::Remove(Window *w) +{ + Iterator it = Find(w); + if (it != m_list.end()) m_list.erase(it); +} + +WindowList::Iterator WindowList::Find(Window *w) +{ + struct Match { + Window *m_w; + bool EnumProc(Iterator it) + { + return (*it).w == m_w; + } + } match = {w}; + + Iterator it = EnumT(match); + if (it == m_list.end()) { + DEBUG(misc, 3, "Window (cls %d, number %d) is not open, probably removed by recursive calls", + w->window_class, w->window_number); + } + return it; +} + +WindowList::Iterator WindowList::FindFirstVitalWindow() +{ + struct MatchNonVital { + bool EnumProc(Iterator it) + { + return !(*it).w->IsVital(); + } + } match; + + Iterator it = ReverseEnumT(match); + /* we have stopped on last non-vital window. Move one step forward to locate first vital window. */ + if (it != m_list.end()) ++it; + return it; +} + +WindowList::Iterator WindowList::FindByClass(WindowClass cls) +{ + struct MatchCls { + WindowClass m_cls; + bool EnumProc(Iterator it) + { + Window *w = (*it).w; + return w->window_class == m_cls; + } + } match = {cls}; + + Iterator it = EnumT(match); + return it; +} + +WindowList::Iterator WindowList::FindById(WindowClass cls, WindowNumber num) +{ + struct MatchClsAndId { + WindowClass m_cls; + WindowNumber m_num; + bool EnumProc(Iterator it) + { + Window *w = (*it).w; + return w->window_class == m_cls && w->window_number == m_num; + } + } match = {cls, num}; + + Iterator it = EnumT(match); + return it; +} + +/* Open a new window. +* This function is called from AllocateWindow() or AllocateWindowDesc() +* See descriptions for those functions for usage +* See AllocateWindow() for description of arguments. +* Only addition here is window_number, which is the window_number being assigned to the new window +*/ +Window::Window( + int x, int y, int w, int h, + WindowProc *proc, WindowClass cls, const Widget *widget, int wnd_number) +{ + //Window *w = FindFreeWindow(); + + ///* We have run out of windows, close one and use that as the place for our new one */ + //if (w == NULL) { + // w = FindDeletableWindow(); + // if (w == NULL) w = ForceFindDeletableWindow(); + // w->Close(); + //} + + // Set up window properties + //memset(w, 0, sizeof(*w)); + ZeroInit(); + + window_class = cls; + flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border + caption_color = 0xFF; + left = x; + top = y; + width = w; + height = h; + wndproc = proc; + AssignWidgetToWindow(this, widget); + resize.width = width; + resize.height = height; + resize.step_width = 1; + resize.step_height = 1; + window_number = wnd_number; + + //{ + // Window **wz = _last_z_window; + + // /* Hacky way of specifying always-on-top windows. These windows are + // * always above other windows because they are moved below them. + // * status-bar is above news-window because it has been created earlier. + // * Also, as the chat-window is excluded from this, it will always be + // * the last window, thus always on top. + // * XXX - Yes, ugly, probably needs something like w->always_on_top flag + // * to implement correctly, but even then you need some kind of distinction + // * between on-top of chat/news and status windows, because these conflict */ + // if (wz != _z_windows && w->window_class != WC_SEND_NETWORK_MSG) { + // if (FindWindowById(WC_MAIN_TOOLBAR, 0) != NULL) wz--; + // if (FindWindowById(WC_STATUS_BAR, 0) != NULL) wz--; + // if (FindWindowById(WC_NEWS_WINDOW, 0) != NULL) wz--; + // if (FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL) wz--; + + // assert(wz >= _z_windows); + // if (wz != _last_z_window) memmove(wz + 1, wz, (byte*)_last_z_window - (byte*)wz); + // } + + // *wz = w; + // _last_z_window++; + //} + + /* add our new window into z-order list */ + Window::s_list.Add(this); + + SetDirty(); + CallWindowEventNP(this, WE_CREATE); + + //return w; +} + +/** Find the Window whose parent pointer points to this window +* @parent w Window to find child of +* @return return a Window pointer that is the child of w, or NULL otherwise */ +Window* Window::FindChild() const +{ + Window *v; + FOR_ALL_WINDOWS(v) { + if (v->parent == this) return v; + } + + return NULL; +} + +void Window::SetDirty() const +{ + if (this == NULL) return; + SetDirtyBlocks(left, top, left + width, top + height); +} + +/*virtual*/ void Window::FinalRelease() +{ + /* Delete any children a window might have in a head-recursive manner */ + Window *v = FindChild(); + if (v != NULL) v->Close(); + + if (_thd.place_mode != VHM_NONE && + _thd.window_class == window_class && + _thd.window_number == window_number) { + ResetObjectToPlace(); + } + + CallWindowEventNP(this, WE_DESTROY); + if (viewport != NULL) DeleteWindowViewport(this); + + SetDirty(); + free(widget); + widget = NULL; + widget_count = 0; + parent = NULL; +} + +/*virtual*/ void Window::Close() +{ + s_list.Remove(this); +} + +/*virtual*/ bool Window::IsVital() +{ + WindowClass wc = window_class; + return (wc == WC_MAIN_TOOLBAR || wc == WC_STATUS_BAR || wc == WC_NEWS_WINDOW || wc == WC_SEND_NETWORK_MSG); +} + +/** +* Open a new window. If there is no space for a new window, close an open +* window. Try to avoid stickied windows, but if there is no else, close one of +* those as well. Then make sure all created windows are below some always-on-top +* ones. Finally set all variables and call the WE_CREATE event +* @param x offset in pixels from the left of the screen +* @param y offset in pixels from the top of the screen +* @param width width in pixels of the window +* @param height height in pixels of the window +* @param *proc @see WindowProc function to call when any messages/updates happen to the window +* @param cls @see WindowClass class of the window, used for identification and grouping +* @param *widget @see Widget pointer to the window layout and various elements +* @return @see Window pointer of the newly created window +*/ +/*static*/ Window* Window::Allocate( + int x, int y, int width, int height, + WindowProc *proc, WindowClass cls, const Widget *widget) +{ + return new Window(x, y, width, height, proc, cls, widget, 0); +} + +/*static*/ Window* Window::Get(WindowList::Iterator it) +{ + return (it != s_list.m_list.end()) ? (*it).w : NULL; +} + +/*static*/ Window* Window::FindById(WindowClass cls, WindowNumber num) +{ + return Get(s_list.FindById(cls, num)); +} + +/*static*/ void Window::SetDirtyById(WindowClass cls, WindowNumber num) +{ + Window *w = FindById(cls, num); + if (w != NULL) w->SetDirty(); +} + +void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...) { va_list wdg_list; va_start(wdg_list, widgets); while (widgets != WIDGET_LIST_END) { - SetWindowWidgetDisabledState(w, widgets, disab_stat); - widgets = va_arg(wdg_list, int); - } - - va_end(wdg_list); -} - -void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...) -{ - va_list wdg_list; - - va_start(wdg_list, widgets); - - while (widgets != WIDGET_LIST_END) { - SetWindowWidgetHiddenState(w, widgets, hidden_stat); + SetWindowWidgetDisabledState(this, widgets, disab_stat); widgets = va_arg(wdg_list, int); } va_end(wdg_list); } -void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...) +void CDECL Window::SetWidgetsHiddenState(bool hidden_stat, int widgets, ...) { va_list wdg_list; va_start(wdg_list, widgets); while (widgets != WIDGET_LIST_END) { - SetWindowWidgetLoweredState(w, widgets, lowered_stat); + SetWindowWidgetHiddenState(this, widgets, hidden_stat); widgets = va_arg(wdg_list, int); } va_end(wdg_list); } -void RaiseWindowButtons(Window *w) +void CDECL Window::SetWidgetsLoweredState(bool lowered_stat, int widgets, ...) +{ + va_list wdg_list; + + va_start(wdg_list, widgets); + + while (widgets != WIDGET_LIST_END) { + SetWindowWidgetLoweredState(this, widgets, lowered_stat); + widgets = va_arg(wdg_list, int); + } + + va_end(wdg_list); +} + +void Window::RaiseButtons() { uint i; - for (i = 0; i < w->widget_count; i++) { - if (IsWindowWidgetLowered(w, i)) { - RaiseWindowWidget(w, i); - InvalidateWidget(w, i); + for (i = 0; i < widget_count; i++) { + if (IsWindowWidgetLowered(this, i)) { + RaiseWindowWidget(this, i); + InvalidateWidget(this, i); } } } -void HandleButtonClick(Window *w, byte widget) +void Window::HandleButtonClick(byte widget) { - LowerWindowWidget(w, widget); - w->flags4 |= 5 << WF_TIMEOUT_SHL; - InvalidateWidget(w, widget); + LowerWindowWidget(this, widget); + this->flags4 |= 5 << WF_TIMEOUT_SHL; + InvalidateWidget(this, widget); +} + +/** On clicking on a window, make it the frontmost window of all. However +* there are certain windows that always need to be on-top; these include +* - Toolbar, Statusbar (always on) +* - New window, Chatbar (only if open) +* The window is marked dirty for a repaint if the window is actually moved +* @param w window that is put into the foreground +* @return pointer to the window, the same as the input pointer +*/ +void Window::BringToFront() +{ + WindowPtr wp = this; + WindowList::Iterator it = Window::s_list.Find(this); + Window::s_list.Remove(this); + Window::s_list.Add(this); + + SetDirty(); +} + +/** Find a window and make it the top-window on the screen. The window +* gets a white border for a brief period of time to visualize its +* "activation" +* @return a pointer to the window thus activated */ +/*static*/ Window* Window::BringToFrontById(WindowClass cls, WindowNumber num) +{ + Window *w = FindById(cls, num); + if (w != NULL) { + w->flags4 |= WF_WHITE_BORDER_MASK; + w->BringToFront(); + } + return w; +} + +static bool _dragging_window; + +void Window::StartDrag() +{ + flags4 |= WF_DRAGGING; + _dragging_window = true; + + _drag_delta.x = left - _cursor.pos.x; + _drag_delta.y = top - _cursor.pos.y; + + BringToFront(); + DeleteWindowById(WC_DROPDOWN_MENU, 0); +} + +bool Window::ContinueDrag() +{ + const Widget *t = &widget[1]; // the title bar ... ugh + const Window *v; + int x; + int y; + int nx; + int ny; + + // Stop the dragging if the left mouse button was released + if (!_left_button_down) { + flags4 &= ~WF_DRAGGING; + _dragging_window = false; + return false; + } + + SetDirty(); + + x = _cursor.pos.x + _drag_delta.x; + y = _cursor.pos.y + _drag_delta.y; + nx = x; + ny = y; + + if (_patches.window_snap_radius != 0) { + Window *v; + + int hsnap = _patches.window_snap_radius; + int vsnap = _patches.window_snap_radius; + int delta; + + FOR_ALL_WINDOWS(v) { + if (v == this) continue; // Don't snap at yourself + + if (y + height > v->top && y < v->top + v->height) { + // Your left border <-> other right border + delta = abs(v->left + v->width - x); + if (delta <= hsnap) { + nx = v->left + v->width; + hsnap = delta; + } + + // Your right border <-> other left border + delta = abs(v->left - x - width); + if (delta <= hsnap) { + nx = v->left - width; + hsnap = delta; + } + } + + if (top + height >= v->top && top <= v->top + v->height) { + // Your left border <-> other left border + delta = abs(v->left - x); + if (delta <= hsnap) { + nx = v->left; + hsnap = delta; + } + + // Your right border <-> other right border + delta = abs(v->left + v->width - x - width); + if (delta <= hsnap) { + nx = v->left + v->width - width; + hsnap = delta; + } + } + + if (x + width > v->left && x < v->left + v->width) { + // Your top border <-> other bottom border + delta = abs(v->top + v->height - y); + if (delta <= vsnap) { + ny = v->top + v->height; + vsnap = delta; + } + + // Your bottom border <-> other top border + delta = abs(v->top - y - height); + if (delta <= vsnap) { + ny = v->top - height; + vsnap = delta; + } + } + + if (left + width >= v->left && left <= v->left + v->width) { + // Your top border <-> other top border + delta = abs(v->top - y); + if (delta <= vsnap) { + ny = v->top; + vsnap = delta; + } + + // Your bottom border <-> other bottom border + delta = abs(v->top + v->height - y - height); + if (delta <= vsnap) { + ny = v->top + v->height - height; + vsnap = delta; + } + } + } + } + + // Make sure the window doesn't leave the screen + // 13 is the height of the title bar + nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left); + ny = clamp(ny, 0, _screen.height - 13); + + // Make sure the title bar isn't hidden by behind the main tool bar + v = Window::FindById(WC_MAIN_TOOLBAR, 0); + if (v != NULL) { + int v_bottom = v->top + v->height; + int v_right = v->left + v->width; + if (ny + t->top >= v->top && ny + t->top < v_bottom) { + if ((v->left < 13 && nx + t->left < v->left) || + (v_right > _screen.width - 13 && nx + t->right > v_right)) { + ny = v_bottom; + } else { + if (nx + t->left > v->left - 13 && + nx + t->right < v_right + 13) { + if (top >= v_bottom) { + ny = v_bottom; + } else if (left < nx) { + nx = v->left - 13 - t->left; + } else { + nx = v_right + 13 - t->right; + } + } + } + } + } + + if (viewport != NULL) { + viewport->left += nx - left; + viewport->top += ny - top; + } + left = nx; + top = ny; + + SetDirty(); + return false; +} + +void Window::StartSizing() +{ + flags4 |= WF_SIZING; + _dragging_window = true; + + _drag_delta.x = _cursor.pos.x; + _drag_delta.y = _cursor.pos.y; + + BringToFront(); + DeleteWindowById(WC_DROPDOWN_MENU, 0); +} + +bool Window::ContinueSizing() +{ + WindowEvent e; + int x, y; + + /* Stop the sizing if the left mouse button was released */ + if (!_left_button_down) { + flags4 &= ~WF_SIZING; + SetDirty(); + _dragging_window = false; + return false; + } + + x = _cursor.pos.x - _drag_delta.x; + y = _cursor.pos.y - _drag_delta.y; + + /* X and Y has to go by step.. calculate it. + * The cast to int is necessary else x/y are implicitly casted to + * unsigned int, which won't work. */ + if (resize.step_width > 1) x -= x % (int)resize.step_width; + + if (resize.step_height > 1) y -= y % (int)resize.step_height; + + /* Check if we don't go below the minimum set size */ + if ((int)width + x < (int)resize.width) + x = resize.width - width; + if ((int)height + y < (int)resize.height) + y = resize.height - height; + + /* Window already on size */ + if (x == 0 && y == 0) return false; + + /* Now find the new cursor pos.. this is NOT _cursor, because + we move in steps. */ + _drag_delta.x += x; + _drag_delta.y += y; + + /* ResizeWindow sets both pre- and after-size to dirty for redrawal */ + ResizeWindow(this, x, y); + + e.event = WE_RESIZE; + e.we.sizing.size.x = x + width; + e.we.sizing.size.y = y + height; + e.we.sizing.diff.x = x; + e.we.sizing.diff.y = y; + wndproc(this, &e); + return false; + +} + +/*static*/ bool Window::HandleWindowDragging(void) +{ + // Get out immediately if no window is being dragged at all. + if (!_dragging_window) return true; + + // Otherwise find the window... + Window *w; + FOR_ALL_WINDOWS(w) { + if (w->flags4 & WF_DRAGGING) { + return w->ContinueDrag(); + } else if (w->flags4 & WF_SIZING) { + return w->ContinueSizing(); + } + } + _dragging_window = false; + return false; } -static void StartWindowDrag(Window *w); -static void StartWindowSizing(Window *w); static void DispatchLeftClickEvent(Window *w, int x, int y) { @@ -112,7 +632,7 @@ case WWT_PANEL | WWB_PUSHBUTTON: /* WWT_PUSHBTN */ case WWT_IMGBTN | WWB_PUSHBUTTON: /* WWT_PUSHIMGBTN */ case WWT_TEXTBTN | WWB_PUSHBUTTON: /* WWT_PUSHTXTBTN */ - HandleButtonClick(w, e.we.click.widget); + w->HandleButtonClick(e.we.click.widget); break; } } else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) { @@ -121,18 +641,18 @@ if (w->desc_flags & WDF_STD_BTN) { if (e.we.click.widget == 0) { /* 'X' */ - DeleteWindow(w); + w->Close(); return; } if (e.we.click.widget == 1) { /* 'Title bar' */ - StartWindowDrag(w); + w->StartDrag(); return; } } if (w->desc_flags & WDF_RESIZABLE && wi->type == WWT_RESIZEBOX) { - StartWindowSizing(w); + w->StartSizing(); InvalidateWidget(w, e.we.click.widget); return; } @@ -196,64 +716,63 @@ int pos = clamp(sb->pos + wheel, 0, sb->count - sb->cap); if (pos != sb->pos) { sb->pos = pos; - SetWindowDirty(w); + w->SetDirty(); } } } } -static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right, int bottom); +static void DrawOverlappedWindow(WindowList::Iterator it, int left, int top, int right, int bottom); void DrawOverlappedWindowForAll(int left, int top, int right, int bottom) { - Window* const *wz; DrawPixelInfo bk; _cur_dpi = &bk; - FOR_ALL_WINDOWS(wz) { - const Window *w = *wz; + const Window *w; + FOR_ALL_WINDOWS(w) { if (right > w->left && bottom > w->top && left < w->left + w->width && top < w->top + w->height) { - DrawOverlappedWindow(wz, left, top, right, bottom); + DrawOverlappedWindow(it, left, top, right, bottom); } } } -static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right, int bottom) +static void DrawOverlappedWindow(WindowList::Iterator wit, int left, int top, int right, int bottom) { - Window* const *vz = wz; - int x; + Window *w = (*wit).w; - while (++vz != _last_z_window) { - const Window *v = *vz; + for (WindowList::Iterator vit = wit; ++vit != Window::s_list.m_list.end(); ) { + const Window *v = (*vit).w; + int x; if (right > v->left && bottom > v->top && left < v->left + v->width && top < v->top + v->height) { if (left < (x=v->left)) { - DrawOverlappedWindow(wz, left, top, x, bottom); - DrawOverlappedWindow(wz, x, top, right, bottom); + DrawOverlappedWindow(wit, left, top, x, bottom); + DrawOverlappedWindow(wit, x, top, right, bottom); return; } if (right > (x=v->left + v->width)) { - DrawOverlappedWindow(wz, left, top, x, bottom); - DrawOverlappedWindow(wz, x, top, right, bottom); + DrawOverlappedWindow(wit, left, top, x, bottom); + DrawOverlappedWindow(wit, x, top, right, bottom); return; } if (top < (x=v->top)) { - DrawOverlappedWindow(wz, left, top, right, x); - DrawOverlappedWindow(wz, left, x, right, bottom); + DrawOverlappedWindow(wit, left, top, right, x); + DrawOverlappedWindow(wit, left, x, right, bottom); return; } if (bottom > (x=v->top + v->height)) { - DrawOverlappedWindow(wz, left, top, right, x); - DrawOverlappedWindow(wz, left, x, right, bottom); + DrawOverlappedWindow(wit, left, top, right, x); + DrawOverlappedWindow(wit, left, x, right, bottom); return; } @@ -265,12 +784,12 @@ DrawPixelInfo *dp = _cur_dpi; dp->width = right - left; dp->height = bottom - top; - dp->left = left - (*wz)->left; - dp->top = top - (*wz)->top; + dp->left = left - w->left; + dp->top = top - w->top; dp->pitch = _screen.pitch; dp->dst_ptr = _screen.dst_ptr + top * _screen.pitch + left; dp->zoom = 0; - CallWindowEventNP(*wz, WE_PAINT); + CallWindowEventNP(w, WE_PAINT); } } @@ -282,104 +801,48 @@ w->wndproc(w, &e); } -void SetWindowDirty(const Window *w) -{ - if (w == NULL) return; - SetDirtyBlocks(w->left, w->top, w->left + w->width, w->top + w->height); -} - -/** Find the Window whose parent pointer points to this window - * @parent w Window to find child of - * @return return a Window pointer that is the child of w, or NULL otherwise */ -static Window *FindChildWindow(const Window *w) -{ - Window* const *wz; - - FOR_ALL_WINDOWS(wz) { - Window *v = *wz; - if (v->parent == w) return v; - } - - return NULL; -} - /** Find the z-value of a window. A window must already be open * or the behaviour is undefined but function should never fail */ -Window **FindWindowZPosition(const Window *w) -{ - Window **wz; - - for (wz = _z_windows; wz != _last_z_window; wz++) { - if (*wz == w) return wz; - } - - DEBUG(misc, 3, "Window (cls %d, number %d) is not open, probably removed by recursive calls", - w->window_class, w->window_number); - return NULL; -} - -void DeleteWindow(Window *w) -{ - Window *v; - Window **wz; - if (w == NULL) return; - - /* Delete any children a window might have in a head-recursive manner */ - v = FindChildWindow(w); - if (v != NULL) DeleteWindow(v); +//WindowList::Iterator FindWindowZPosition(const Window *w) +//{ +// Window *wz; +// FOR_ALL_WINDOWS(wz) { +// if (wz == w) return it; +// } +// +// DEBUG(misc, 3, "Window (cls %d, number %d) is not open, probably removed by recursive calls", +// w->window_class, w->window_number); +// return Window::s_list.m_list.end(); +//} - if (_thd.place_mode != VHM_NONE && - _thd.window_class == w->window_class && - _thd.window_number == w->window_number) { - ResetObjectToPlace(); - } - - CallWindowEventNP(w, WE_DESTROY); - if (w->viewport != NULL) DeleteWindowViewport(w); - - SetWindowDirty(w); - free(w->widget); - w->widget = NULL; - w->widget_count = 0; - w->parent = NULL; - - /* Find the window in the z-array, and effectively remove it - * by moving all windows after it one to the left */ - wz = FindWindowZPosition(w); - if (wz == NULL) return; - memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz); - _last_z_window--; -} - -Window *FindWindowById(WindowClass cls, WindowNumber number) -{ - Window* const *wz; - - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; - if (w->window_class == cls && w->window_number == number) return w; - } - - return NULL; -} +//Window *FindWindowById(WindowClass cls, WindowNumber number) +//{ +// Window *w; +// +// FOR_ALL_WINDOWS(w) { +// if (w->window_class == cls && w->window_number == number) return w; +// } +// +// return NULL; +//} void DeleteWindowById(WindowClass cls, WindowNumber number) { - DeleteWindow(FindWindowById(cls, number)); + Window *w = Window::FindById(cls, number); + if (w != NULL) w->Close(); } void DeleteWindowByClass(WindowClass cls) { - Window* const *wz; restart_search: /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { if (w->window_class == cls) { - DeleteWindow(w); + w->Close(); goto restart_search; } } @@ -391,16 +854,15 @@ * @param id PlayerID player identifier */ void DeletePlayerWindows(PlayerID id) { - Window* const *wz; restart_search: /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { if (w->caption_color == id) { - DeleteWindow(w); + w->Close(); goto restart_search; } } @@ -416,10 +878,9 @@ * @param new_player PlayerID of the new owner of the window */ void ChangeWindowOwner(PlayerID old_player, PlayerID new_player) { - Window* const *wz; + Window *w; - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + FOR_ALL_WINDOWS(w) { if (w->caption_color != old_player) continue; if (w->window_class == WC_PLAYER_COLOR) continue; @@ -436,60 +897,6 @@ } } -static void BringWindowToFront(const Window *w); - -/** Find a window and make it the top-window on the screen. The window - * gets a white border for a brief period of time to visualize its - * "activation" - * @return a pointer to the window thus activated */ -Window *BringWindowToFrontById(WindowClass cls, WindowNumber number) -{ - Window *w = FindWindowById(cls, number); - - if (w != NULL) { - w->flags4 |= WF_WHITE_BORDER_MASK; - BringWindowToFront(w); - SetWindowDirty(w); - } - - return w; -} - -static inline bool IsVitalWindow(const Window *w) -{ - WindowClass wc = w->window_class; - return (wc == WC_MAIN_TOOLBAR || wc == WC_STATUS_BAR || wc == WC_NEWS_WINDOW || wc == WC_SEND_NETWORK_MSG); -} - -/** On clicking on a window, make it the frontmost window of all. However - * there are certain windows that always need to be on-top; these include - * - Toolbar, Statusbar (always on) - * - New window, Chatbar (only if open) - * The window is marked dirty for a repaint if the window is actually moved - * @param w window that is put into the foreground - * @return pointer to the window, the same as the input pointer - */ -static void BringWindowToFront(const Window *w) -{ - Window *tempz; - Window **wz = FindWindowZPosition(w); - Window **vz = _last_z_window; - - /* Bring the window just below the vital windows */ - do { - if (--vz < _z_windows) return; - } while (IsVitalWindow(*vz)); - - if (wz == vz) return; // window is already in the right position - assert(wz < vz); - - tempz = *wz; - memmove(wz, wz + 1, (byte*)vz - (byte*)wz); - *vz = tempz; - - SetWindowDirty(w); -} - /** We have run out of windows, so find a suitable candidate for replacement. * Keep all important windows intact. These are * - Main window (gamefield), Toolbar, Statusbar (always on) @@ -497,18 +904,21 @@ * - Any sticked windows since we wanted to keep these * @return w pointer to the window that is going to be deleted */ -static Window *FindDeletableWindow(void) -{ - Window* const *wz; - - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; - if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w) && !(w->flags4 & WF_STICKY)) { - return w; - } - } - return NULL; -} +//static Window *FindDeletableWindow(void) +//{ +// Window *w; +// FOR_ALL_WINDOWS(w) { +// if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w) && !(w->flags4 & WF_STICKY)) { +// return w; +// } +// } +// FOR_ALL_WINDOWS(w) { +// if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) { +// return w; +// } +// } +// return NULL; +//} /** A window must be freed, and all are marked as important windows. Ease the * restriction a bit by allowing to delete sticky windows. Keep important/vital @@ -517,16 +927,16 @@ * @see FindDeletableWindow() * @return w Pointer to the window that is being deleted */ -static Window *ForceFindDeletableWindow(void) -{ - Window* const *wz; - - for (wz = _z_windows;; wz++) { - Window *w = *wz; - assert(wz < _last_z_window); - if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w; - } -} +//static Window *ForceFindDeletableWindow(void) +//{ +// Window* const *wz; +// +// for (wz = _z_windows;; wz++) { +// Window *w = *wz; +// assert(wz < _last_z_window); +// if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w; +// } +//} bool IsWindowOfPrototype(const Window *w, const Widget *widget) { @@ -553,115 +963,28 @@ } } -static Window *FindFreeWindow(void) -{ - Window *w; - - for (w = _windows; w < endof(_windows); w++) { - Window* const *wz; - bool window_in_use = false; - - FOR_ALL_WINDOWS(wz) { - if (*wz == w) { - window_in_use = true; - break; - } - } - - if (!window_in_use) return w; - } - - assert(_last_z_window == endof(_z_windows)); - return NULL; -} - -/* Open a new window. - * This function is called from AllocateWindow() or AllocateWindowDesc() - * See descriptions for those functions for usage - * See AllocateWindow() for description of arguments. - * Only addition here is window_number, which is the window_number being assigned to the new window - */ -static Window *LocalAllocateWindow( - int x, int y, int width, int height, - WindowProc *proc, WindowClass cls, const Widget *widget, int window_number) -{ - Window *w = FindFreeWindow(); - - /* We have run out of windows, close one and use that as the place for our new one */ - if (w == NULL) { - w = FindDeletableWindow(); - if (w == NULL) w = ForceFindDeletableWindow(); - DeleteWindow(w); - } +//static Window *FindFreeWindow(void) +//{ +// Window *w; +// +// for (w = _windows; w < endof(_windows); w++) { +// Window* const *wz; +// bool window_in_use = false; +// +// FOR_ALL_WINDOWS(wz) { +// if (*wz == w) { +// window_in_use = true; +// break; +// } +// } +// +// if (!window_in_use) return w; +// } +// +// assert(_last_z_window == endof(_z_windows)); +// return NULL; +//} - // Set up window properties - memset(w, 0, sizeof(*w)); - w->window_class = cls; - w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border - w->caption_color = 0xFF; - w->left = x; - w->top = y; - w->width = width; - w->height = height; - w->wndproc = proc; - AssignWidgetToWindow(w, widget); - w->resize.width = width; - w->resize.height = height; - w->resize.step_width = 1; - w->resize.step_height = 1; - w->window_number = window_number; - - { - Window **wz = _last_z_window; - - /* Hacky way of specifying always-on-top windows. These windows are - * always above other windows because they are moved below them. - * status-bar is above news-window because it has been created earlier. - * Also, as the chat-window is excluded from this, it will always be - * the last window, thus always on top. - * XXX - Yes, ugly, probably needs something like w->always_on_top flag - * to implement correctly, but even then you need some kind of distinction - * between on-top of chat/news and status windows, because these conflict */ - if (wz != _z_windows && w->window_class != WC_SEND_NETWORK_MSG) { - if (FindWindowById(WC_MAIN_TOOLBAR, 0) != NULL) wz--; - if (FindWindowById(WC_STATUS_BAR, 0) != NULL) wz--; - if (FindWindowById(WC_NEWS_WINDOW, 0) != NULL) wz--; - if (FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL) wz--; - - assert(wz >= _z_windows); - if (wz != _last_z_window) memmove(wz + 1, wz, (byte*)_last_z_window - (byte*)wz); - } - - *wz = w; - _last_z_window++; - } - - SetWindowDirty(w); - CallWindowEventNP(w, WE_CREATE); - - return w; -} - -/** - * Open a new window. If there is no space for a new window, close an open - * window. Try to avoid stickied windows, but if there is no else, close one of - * those as well. Then make sure all created windows are below some always-on-top - * ones. Finally set all variables and call the WE_CREATE event - * @param x offset in pixels from the left of the screen - * @param y offset in pixels from the top of the screen - * @param width width in pixels of the window - * @param height height in pixels of the window - * @param *proc @see WindowProc function to call when any messages/updates happen to the window - * @param cls @see WindowClass class of the window, used for identification and grouping - * @param *widget @see Widget pointer to the window layout and various elements - * @return @see Window pointer of the newly created window - */ -Window *AllocateWindow( - int x, int y, int width, int height, - WindowProc *proc, WindowClass cls, const Widget *widget) -{ - return LocalAllocateWindow(x, y, width, height, proc, cls, widget, 0); -} typedef struct SizeRect { int left,top,width,height; @@ -673,7 +996,6 @@ static bool IsGoodAutoPlace1(int left, int top) { int right,bottom; - Window* const *wz; _awap_r.left= left; _awap_r.top = top; @@ -684,8 +1006,8 @@ return false; // Make sure it is not obscured by any window. - FOR_ALL_WINDOWS(wz) { - const Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { if (w->window_class == WC_MAIN_WINDOW) continue; if (right > w->left && @@ -702,7 +1024,6 @@ static bool IsGoodAutoPlace2(int left, int top) { int width,height; - Window* const *wz; _awap_r.left= left; _awap_r.top = top; @@ -713,8 +1034,8 @@ if (top < 22 || top > _screen.height - (height>>2)) return false; // Make sure it is not obscured by any window. - FOR_ALL_WINDOWS(wz) { - const Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { if (w->window_class == WC_MAIN_WINDOW) continue; if (left + width > w->left && @@ -730,7 +1051,6 @@ static Point GetAutoPlacePosition(int width, int height) { - Window* const *wz; Point pt; _awap_r.width = width; @@ -738,8 +1058,8 @@ if (IsGoodAutoPlace1(0, 24)) goto ok_pos; - FOR_ALL_WINDOWS(wz) { - const Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { if (w->window_class == WC_MAIN_WINDOW) continue; if (IsGoodAutoPlace1(w->left+w->width+2,w->top)) goto ok_pos; @@ -752,8 +1072,7 @@ if (IsGoodAutoPlace1(w->left+w->width-width,w->top- height-2)) goto ok_pos; } - FOR_ALL_WINDOWS(wz) { - const Window *w = *wz; + FOR_ALL_WINDOWS(w) { if (w->window_class == WC_MAIN_WINDOW) continue; if (IsGoodAutoPlace2(w->left+w->width+2,w->top)) goto ok_pos; @@ -766,9 +1085,7 @@ int left=0,top=24; restart:; - FOR_ALL_WINDOWS(wz) { - const Window *w = *wz; - + FOR_ALL_WINDOWS(w) { if (w->left == left && w->top == top) { left += 5; top += 5; @@ -796,7 +1113,7 @@ * However if it falls too extremely outside window positions, reposition * it to an automatic place */ if (desc->parent_cls != 0 /* WC_MAIN_WINDOW */ && - (w = FindWindowById(desc->parent_cls, window_number)) != NULL && + (w = Window::FindById(desc->parent_cls, window_number)) != NULL && w->left < _screen.width - 20 && w->left > -60 && w->top < _screen.height - 20) { pt.x = w->left + 10; @@ -807,11 +1124,11 @@ } else { switch (desc->left) { case WDP_ALIGN_TBR: { /* Align the right side with the top toolbar */ - w = FindWindowById(WC_MAIN_TOOLBAR, 0); + w = Window::FindById(WC_MAIN_TOOLBAR, 0); pt.x = (w->left + w->width) - desc->width; } break; case WDP_ALIGN_TBL: /* Align the left side with the top toolbar */ - pt.x = FindWindowById(WC_MAIN_TOOLBAR, 0)->left; + pt.x = Window::FindById(WC_MAIN_TOOLBAR, 0)->left; break; case WDP_AUTO: /* Find a good automatic position for the window */ pt = GetAutoPlacePosition(desc->width, desc->height); @@ -842,7 +1159,7 @@ } allocate_window: - w = LocalAllocateWindow(pt.x, pt.y, desc->width, desc->height, desc->proc, desc->cls, desc->widgets, window_number); + w = new Window(pt.x, pt.y, desc->width, desc->height, desc->proc, desc->cls, desc->widgets, window_number); w->desc_flags = desc->flags; return w; } @@ -867,7 +1184,7 @@ { Window *w; - if (BringWindowToFrontById(desc->cls, window_number)) return NULL; + if (Window::BringToFrontById(desc->cls, window_number) != NULL) return NULL; w = LocalAllocateWindowDesc(desc, window_number); return w; } @@ -877,10 +1194,8 @@ * @return a pointer to the found window if any, NULL otherwise */ Window *FindWindowFromPt(int x, int y) { - Window* const *wz; - - for (wz = _last_z_window; wz != _z_windows;) { - Window *w = *--wz; + Window *w; + REVERSED_FOR_ALL_WINDOWS(w) { if (IS_INSIDE_1D(x, w->left, w->width) && IS_INSIDE_1D(y, w->top, w->height)) { return w; } @@ -893,28 +1208,30 @@ { IConsoleClose(); - memset(&_windows, 0, sizeof(_windows)); - _last_z_window = _z_windows; + //memset(&_windows, 0, sizeof(_windows)); + //_last_z_window = _z_windows; InitViewports(); _no_scroll = 0; } void UnInitWindowSystem(void) { - Window **wz; + Window::s_list.m_list.clear(); -restart_search: - /* Delete all windows, reset z-array. - *When we find the window to delete, we need to restart the search - * as deleting this window could cascade in deleting (many) others - * anywhere in the z-array. We call DeleteWindow() so that it can properly - * release own alloc'd memory, which otherwise could result in memleaks */ - FOR_ALL_WINDOWS(wz) { - DeleteWindow(*wz); - goto restart_search; - } - - assert(_last_z_window == _z_windows); +// Window **wz; +// +//restart_search: +// /* Delete all windows, reset z-array. +// *When we find the window to delete, we need to restart the search +// * as deleting this window could cascade in deleting (many) others +// * anywhere in the z-array. We call DeleteWindow() so that it can properly +// * release own alloc'd memory, which otherwise could result in memleaks */ +// FOR_ALL_WINDOWS(wz) { +// DeleteWindow(*wz); +// goto restart_search; +// } +// +// assert(_last_z_window == _z_windows); } void ResetWindowSystem(void) @@ -930,31 +1247,26 @@ static void DecreaseWindowCounters(void) { Window *w; - Window* const *wz; - - for (wz = _last_z_window; wz != _z_windows;) { - w = *--wz; + REVERSED_FOR_ALL_WINDOWS(w) { // Unclick scrollbar buttons if they are pressed. if (w->flags4 & (WF_SCROLL_DOWN | WF_SCROLL_UP)) { w->flags4 &= ~(WF_SCROLL_DOWN | WF_SCROLL_UP); - SetWindowDirty(w); + w->SetDirty(); } CallWindowEventNP(w, WE_MOUSELOOP); } - for (wz = _last_z_window; wz != _z_windows;) { - w = *--wz; - + REVERSED_FOR_ALL_WINDOWS(w) { if (w->flags4&WF_TIMEOUT_MASK && !(--w->flags4&WF_TIMEOUT_MASK)) { CallWindowEventNP(w, WE_TIMEOUT); - if (w->desc_flags & WDF_UNCLICK_BUTTONS) RaiseWindowButtons(w); + if (w->desc_flags & WDF_UNCLICK_BUTTONS) w->RaiseButtons(); } } } Window *GetCallbackWnd(void) { - return FindWindowById(_thd.window_class, _thd.window_number); + return Window::FindById(_thd.window_class, _thd.window_number); } static void HandlePlacePresize(void) @@ -1008,7 +1320,7 @@ if (!_popup_menu_active) return true; - w = FindWindowById(WC_TOOLBAR_MENU, 0); + w = Window::FindById(WC_TOOLBAR_MENU, 0); if (w == NULL) { _popup_menu_active = false; return false; @@ -1030,9 +1342,13 @@ static bool HandleMouseOver(void) { + static WindowClass last_cls; + static WindowNumber last_num; + Window *w; WindowEvent e; - static Window *last_w = NULL; + + Window *last_w = Window::FindById(last_cls, last_num); w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); @@ -1043,7 +1359,9 @@ e.we.mouseover.pt.y = -1; if (last_w->wndproc) last_w->wndproc(last_w, &e); } - last_w = w; + + last_cls = w->window_class; + last_num = w->window_number; if (w != NULL) { // send an event in client coordinates. @@ -1074,7 +1392,7 @@ if (x == 0 && y == 0) return; - SetWindowDirty(w); + w->SetDirty(); for (wi = w->widget; wi->type != WWT_LAST; wi++) { /* Isolate the resizing flags */ byte rsizeflag = GB(wi->display_flags, 0, 4); @@ -1107,238 +1425,11 @@ if (resize_width) w->width += x; if (resize_height) w->height += y; - SetWindowDirty(w); + w->SetDirty(); } -static bool _dragging_window; - -static bool HandleWindowDragging(void) -{ - Window* const *wz; - // Get out immediately if no window is being dragged at all. - if (!_dragging_window) return true; - - // Otherwise find the window... - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; - - if (w->flags4 & WF_DRAGGING) { - const Widget *t = &w->widget[1]; // the title bar ... ugh - const Window *v; - int x; - int y; - int nx; - int ny; - - // Stop the dragging if the left mouse button was released - if (!_left_button_down) { - w->flags4 &= ~WF_DRAGGING; - break; - } - - SetWindowDirty(w); - - x = _cursor.pos.x + _drag_delta.x; - y = _cursor.pos.y + _drag_delta.y; - nx = x; - ny = y; - - if (_patches.window_snap_radius != 0) { - Window* const *vz; - - int hsnap = _patches.window_snap_radius; - int vsnap = _patches.window_snap_radius; - int delta; - - FOR_ALL_WINDOWS(vz) { - const Window *v = *vz; - - if (v == w) continue; // Don't snap at yourself - - if (y + w->height > v->top && y < v->top + v->height) { - // Your left border <-> other right border - delta = abs(v->left + v->width - x); - if (delta <= hsnap) { - nx = v->left + v->width; - hsnap = delta; - } - - // Your right border <-> other left border - delta = abs(v->left - x - w->width); - if (delta <= hsnap) { - nx = v->left - w->width; - hsnap = delta; - } - } - - if (w->top + w->height >= v->top && w->top <= v->top + v->height) { - // Your left border <-> other left border - delta = abs(v->left - x); - if (delta <= hsnap) { - nx = v->left; - hsnap = delta; - } - - // Your right border <-> other right border - delta = abs(v->left + v->width - x - w->width); - if (delta <= hsnap) { - nx = v->left + v->width - w->width; - hsnap = delta; - } - } - - if (x + w->width > v->left && x < v->left + v->width) { - // Your top border <-> other bottom border - delta = abs(v->top + v->height - y); - if (delta <= vsnap) { - ny = v->top + v->height; - vsnap = delta; - } - - // Your bottom border <-> other top border - delta = abs(v->top - y - w->height); - if (delta <= vsnap) { - ny = v->top - w->height; - vsnap = delta; - } - } - - if (w->left + w->width >= v->left && w->left <= v->left + v->width) { - // Your top border <-> other top border - delta = abs(v->top - y); - if (delta <= vsnap) { - ny = v->top; - vsnap = delta; - } - - // Your bottom border <-> other bottom border - delta = abs(v->top + v->height - y - w->height); - if (delta <= vsnap) { - ny = v->top + v->height - w->height; - vsnap = delta; - } - } - } - } - - // Make sure the window doesn't leave the screen - // 13 is the height of the title bar - nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left); - ny = clamp(ny, 0, _screen.height - 13); - - // Make sure the title bar isn't hidden by behind the main tool bar - v = FindWindowById(WC_MAIN_TOOLBAR, 0); - if (v != NULL) { - int v_bottom = v->top + v->height; - int v_right = v->left + v->width; - if (ny + t->top >= v->top && ny + t->top < v_bottom) { - if ((v->left < 13 && nx + t->left < v->left) || - (v_right > _screen.width - 13 && nx + t->right > v_right)) { - ny = v_bottom; - } else { - if (nx + t->left > v->left - 13 && - nx + t->right < v_right + 13) { - if (w->top >= v_bottom) { - ny = v_bottom; - } else if (w->left < nx) { - nx = v->left - 13 - t->left; - } else { - nx = v_right + 13 - t->right; - } - } - } - } - } - - if (w->viewport != NULL) { - w->viewport->left += nx - w->left; - w->viewport->top += ny - w->top; - } - w->left = nx; - w->top = ny; - - SetWindowDirty(w); - return false; - } else if (w->flags4 & WF_SIZING) { - WindowEvent e; - int x, y; - - /* Stop the sizing if the left mouse button was released */ - if (!_left_button_down) { - w->flags4 &= ~WF_SIZING; - SetWindowDirty(w); - break; - } - - x = _cursor.pos.x - _drag_delta.x; - y = _cursor.pos.y - _drag_delta.y; - - /* X and Y has to go by step.. calculate it. - * The cast to int is necessary else x/y are implicitly casted to - * unsigned int, which won't work. */ - if (w->resize.step_width > 1) x -= x % (int)w->resize.step_width; - - if (w->resize.step_height > 1) y -= y % (int)w->resize.step_height; - - /* Check if we don't go below the minimum set size */ - if ((int)w->width + x < (int)w->resize.width) - x = w->resize.width - w->width; - if ((int)w->height + y < (int)w->resize.height) - y = w->resize.height - w->height; - - /* Window already on size */ - if (x == 0 && y == 0) return false; - - /* Now find the new cursor pos.. this is NOT _cursor, because - we move in steps. */ - _drag_delta.x += x; - _drag_delta.y += y; - - /* ResizeWindow sets both pre- and after-size to dirty for redrawal */ - ResizeWindow(w, x, y); - - e.event = WE_RESIZE; - e.we.sizing.size.x = x + w->width; - e.we.sizing.size.y = y + w->height; - e.we.sizing.diff.x = x; - e.we.sizing.diff.y = y; - w->wndproc(w, &e); - return false; - } - } - - _dragging_window = false; - return false; -} - -static void StartWindowDrag(Window *w) -{ - w->flags4 |= WF_DRAGGING; - _dragging_window = true; - - _drag_delta.x = w->left - _cursor.pos.x; - _drag_delta.y = w->top - _cursor.pos.y; - - BringWindowToFront(w); - DeleteWindowById(WC_DROPDOWN_MENU, 0); -} - -static void StartWindowSizing(Window *w) -{ - w->flags4 |= WF_SIZING; - _dragging_window = true; - - _drag_delta.x = _cursor.pos.x; - _drag_delta.y = _cursor.pos.y; - - BringWindowToFront(w); - DeleteWindowById(WC_DROPDOWN_MENU, 0); -} - - static bool HandleScrollbarScrolling(void) { - Window* const *wz; int i; int pos; Scrollbar *sb; @@ -1347,14 +1438,13 @@ if (!_scrolling_scrollbar) return true; // Find the scrolling window - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; - + Window *w; + FOR_ALL_WINDOWS(w) { if (w->flags4 & WF_SCROLL_MIDDLE) { // Abort if no button is clicked any more. if (!_left_button_down) { w->flags4 &= ~WF_SCROLL_MIDDLE; - SetWindowDirty(w); + w->SetDirty(); break; } @@ -1373,7 +1463,7 @@ pos = min(max(0, i + _scrollbar_start_pos) * sb->count / _scrollbar_size, max(0, sb->count - sb->cap)); if (pos != sb->pos) { sb->pos = pos; - SetWindowDirty(w); + w->SetDirty(); } return false; } @@ -1423,32 +1513,30 @@ * modal-popup; function returns a false and child window gets a white border * @param w Window to bring on-top * @return false if the window has an active modal child, true otherwise */ -static bool MaybeBringWindowToFront(const Window *w) +static bool MaybeBringWindowToFront(Window *w) { bool bring_to_front = false; - Window* const *wz; - Window* const *uz; if (w->window_class == WC_MAIN_WINDOW || - IsVitalWindow(w) || + w->IsVital() || w->window_class == WC_TOOLTIPS || w->window_class == WC_DROPDOWN_MENU) { return true; } - wz = FindWindowZPosition(w); - for (uz = wz; ++uz != _last_z_window;) { - Window *u = *uz; + WindowList::Iterator wit = Window::s_list.Find(w); + for (WindowList::Iterator it = wit; it != Window::s_list.m_list.end(); it++) { + Window *u = (*it).w; /* A modal child will prevent the activation of the parent window */ if (u->parent == w && (u->desc_flags & WDF_MODAL)) { u->flags4 |= WF_WHITE_BORDER_MASK; - SetWindowDirty(u); + u->SetDirty(); return false; } if (u->window_class == WC_MAIN_WINDOW || - IsVitalWindow(u) || + u->IsVital() || u->window_class == WC_TOOLTIPS || u->window_class == WC_DROPDOWN_MENU) { continue; @@ -1465,7 +1553,7 @@ bring_to_front = true; } - if (bring_to_front) BringWindowToFront(w); + if (bring_to_front) w->BringToFront(); return true; } @@ -1496,7 +1584,7 @@ */ void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam) { - Window *w = FindWindowById(wnd_class, wnd_num); + Window *w = Window::FindById(wnd_class, wnd_num); if (w != NULL) SendWindowMessageW(w, msg, wparam, lparam); } @@ -1509,10 +1597,10 @@ */ void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam) { - Window* const *wz; + Window *w; - FOR_ALL_WINDOWS(wz) { - if ((*wz)->window_class == wnd_class) SendWindowMessageW(*wz, msg, wparam, lparam); + FOR_ALL_WINDOWS(w) { + if (w->window_class == wnd_class) SendWindowMessageW(w, msg, wparam, lparam); } } @@ -1521,7 +1609,6 @@ * 16 bits the keycode */ void HandleKeypress(uint32 key) { - Window* const *wz; WindowEvent e; /* Stores if a window with a textfield for typing is open * If this is the case, keypress events are only passed to windows with text fields and @@ -1546,18 +1633,17 @@ e.we.keypress.cont = true; // check if we have a query string window open before allowing hotkeys - if (FindWindowById(WC_QUERY_STRING, 0) != NULL || - FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL || - FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL || - FindWindowById(WC_CONSOLE, 0) != NULL || - FindWindowById(WC_SAVELOAD, 0) != NULL) { + if (Window::FindById(WC_QUERY_STRING, 0) != NULL || + Window::FindById(WC_SEND_NETWORK_MSG, 0) != NULL || + Window::FindById(WC_GENERATE_LANDSCAPE, 0) != NULL || + Window::FindById(WC_CONSOLE, 0) != NULL || + Window::FindById(WC_SAVELOAD, 0) != NULL) { query_open = true; } // Call the event, start with the uppermost window. - for (wz = _last_z_window; wz != _z_windows;) { - Window *w = *--wz; - + Window *w; + REVERSED_FOR_ALL_WINDOWS(w) { // if a query window is open, only call the event for certain window types if (query_open && w->window_class != WC_QUERY_STRING && @@ -1572,7 +1658,7 @@ } if (e.we.keypress.cont) { - Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); + Window *w = Window::FindById(WC_MAIN_TOOLBAR, 0); // When there is no toolbar w is null, check for that if (w != NULL) w->wndproc(w, &e); } @@ -1630,13 +1716,13 @@ DecreaseWindowCounters(); HandlePlacePresize(); UpdateTileSelection(); - if (!VpHandlePlaceSizingDrag()) return; - if (!HandleDragDrop()) return; - if (!HandlePopupMenu()) return; - if (!HandleWindowDragging()) return; - if (!HandleScrollbarScrolling()) return; - if (!HandleViewportScroll()) return; - if (!HandleMouseOver()) return; + if (!VpHandlePlaceSizingDrag()) return; + if (!HandleDragDrop()) return; + if (!HandlePopupMenu()) return; + if (!Window::HandleWindowDragging()) return; + if (!HandleScrollbarScrolling()) return; + if (!HandleViewportScroll()) return; + if (!HandleMouseOver()) return; x = _cursor.pos.x; y = _cursor.pos.y; @@ -1744,31 +1830,30 @@ void UpdateWindows(void) { - Window* const *wz; static int we4_timer = 0; int t = we4_timer + 1; + Window *w; if (t >= 100) { - for (wz = _last_z_window; wz != _z_windows;) { - CallWindowEventNP(*--wz, WE_4); + REVERSED_FOR_ALL_WINDOWS(w) { + CallWindowEventNP(w, WE_4); } t = 0; } we4_timer = t; - for (wz = _last_z_window; wz != _z_windows;) { - Window *w = *--wz; + REVERSED_FOR_ALL_WINDOWS(w) { if (w->flags4 & WF_WHITE_BORDER_MASK) { w->flags4 -= WF_WHITE_BORDER_ONE; - if (!(w->flags4 & WF_WHITE_BORDER_MASK)) SetWindowDirty(w); + if (!(w->flags4 & WF_WHITE_BORDER_MASK)) w->SetDirty(); } } DrawDirtyBlocks(); - FOR_ALL_WINDOWS(wz) { - if ((*wz)->viewport != NULL) UpdateViewportPosition(*wz); + FOR_ALL_WINDOWS(w) { + if (w->viewport != NULL) UpdateViewportPosition(w); } DrawTextMessage(); // Redraw mouse cursor in case it was hidden @@ -1791,11 +1876,10 @@ void InvalidateWindow(WindowClass cls, WindowNumber number) { - Window* const *wz; + Window *w; - FOR_ALL_WINDOWS(wz) { - const Window *w = *wz; - if (w->window_class == cls && w->window_number == number) SetWindowDirty(w); + FOR_ALL_WINDOWS(w) { + if (w->window_class == cls && w->window_number == number) w->SetDirty(); } } @@ -1811,10 +1895,8 @@ void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index) { - Window* const *wz; - - FOR_ALL_WINDOWS(wz) { - const Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { if (w->window_class == cls && w->window_number == number) { InvalidateWidget(w, widget_index); } @@ -1823,57 +1905,51 @@ void InvalidateWindowClasses(WindowClass cls) { - Window* const *wz; - - FOR_ALL_WINDOWS(wz) { - if ((*wz)->window_class == cls) SetWindowDirty(*wz); + Window *w; + FOR_ALL_WINDOWS(w) { + if (w->window_class == cls) w->SetDirty(); } } void InvalidateThisWindowData(Window *w) { CallWindowEventNP(w, WE_INVALIDATE_DATA); - SetWindowDirty(w); + w->SetDirty(); } void InvalidateWindowData(WindowClass cls, WindowNumber number) { - Window* const *wz; - - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { if (w->window_class == cls && w->window_number == number) InvalidateThisWindowData(w); } } void InvalidateWindowClassesData(WindowClass cls) { - Window* const *wz; - - FOR_ALL_WINDOWS(wz) { - if ((*wz)->window_class == cls) InvalidateThisWindowData(*wz); + Window *w; + FOR_ALL_WINDOWS(w) { + if (w->window_class == cls) InvalidateThisWindowData(w); } } void CallWindowTickEvent(void) { - Window* const *wz; - - for (wz = _last_z_window; wz != _z_windows;) { - CallWindowEventNP(*--wz, WE_TICK); + Window *w; + REVERSED_FOR_ALL_WINDOWS(w) { + CallWindowEventNP(w, WE_TICK); } } void DeleteNonVitalWindows(void) { - Window* const *wz; restart_search: /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { if (w->window_class != WC_MAIN_WINDOW && w->window_class != WC_SELECT_GAME && w->window_class != WC_MAIN_TOOLBAR && @@ -1882,7 +1958,7 @@ w->window_class != WC_TOOLTIPS && (w->flags4 & WF_STICKY) == 0) { // do not delete windows which are 'pinned' - DeleteWindow(w); + w->Close(); goto restart_search; } } @@ -1895,8 +1971,6 @@ * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ void DeleteAllNonVitalWindows(void) { - Window* const *wz; - /* Delete every window except for stickied ones, then sticky ones as well */ DeleteNonVitalWindows(); @@ -1904,9 +1978,10 @@ /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS(wz) { - if ((*wz)->flags4 & WF_STICKY) { - DeleteWindow(*wz); + Window *w; + FOR_ALL_WINDOWS(w) { + if (w->flags4 & WF_STICKY) { + w->Close(); goto restart_search; } } @@ -1925,7 +2000,7 @@ DEBUG(misc, 5, "Repositioning Main Toolbar..."); if (w == NULL || w->window_class != WC_MAIN_TOOLBAR) { - w = FindWindowById(WC_MAIN_TOOLBAR, 0); + w = Window::FindById(WC_MAIN_TOOLBAR, 0); } switch (_patches.toolbar_pos) { @@ -1939,10 +2014,8 @@ void RelocateAllWindows(int neww, int newh) { - Window* const *wz; - - FOR_ALL_WINDOWS(wz) { - Window *w = *wz; + Window *w; + FOR_ALL_WINDOWS(w) { int left, top; if (w->window_class == WC_MAIN_WINDOW) { diff -r 42bf2d268a86 -r 5077e6ed3788 src/window.h --- a/src/window.h Sun Feb 11 21:20:30 2007 +0000 +++ b/src/window.h Sun Feb 11 22:57:24 2007 +0000 @@ -3,11 +3,13 @@ #ifndef WINDOW_H #define WINDOW_H +#include #include "macros.h" #include "string.h" #include "order.h" #include "rail.h" #include "airport.h" +#include "misc/countedptr.hpp" typedef struct WindowEvent WindowEvent; @@ -246,7 +248,66 @@ int lparam; } WindowMessage; -struct Window { +struct CountedObject { + int32 m_ref_cnt; + + CountedObject() + : m_ref_cnt(0) + {} + + virtual ~CountedObject() + {}; + + virtual int32 AddRef(); + virtual int32 Release(); + virtual void FinalRelease() {}; +}; + +struct Window; +typedef CCountedPtr WindowPtr; + +struct WindowList { + struct Item { + WindowPtr w; + Item(Window *v = NULL) : w(v) {} + Item(const Item &src) : w(src.w) {} + ~Item() + {} + }; + typedef std::list List; + typedef List::iterator Iterator; + typedef List::reverse_iterator ReverseIterator; + + List m_list; + + void Add(Window *w); + void Remove(Window *w); + Iterator Find(Window *w); + Iterator FindFirstVitalWindow(); + Iterator FindByClass(WindowClass cls); + Iterator FindById(WindowClass cls, WindowNumber num); + + template Iterator EnumT(Tmatch match) + { + for (Iterator it = m_list.begin(); it != m_list.end(); ++it) { + if (match.EnumProc(it)) return it; + } + return m_list.end(); + } + + template Iterator ReverseEnumT(Tmatch match) + { + for (Iterator it = m_list.end(); it != m_list.begin(); ) { + --it; + if (match.EnumProc(it)) return it; + } + return m_list.end(); + } +}; + +struct Window : public CountedObject { + static WindowList s_list; + uint16 flags4; WindowClass window_class; WindowNumber window_number; @@ -269,8 +330,100 @@ WindowMessage message; Window *parent; byte custom[WINDOW_CUSTOM_SIZE]; + + Window(int x, int y, int w, int h, WindowProc *proc, WindowClass cls, const Widget *widget, int wnd_number); + + void ZeroInit() + { + memset(&flags4, 0, sizeof(*this) - cpp_offsetof(Window, flags4)); + } + + Window* FindChild() const; + void SetDirty() const; + void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...); + void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...); + void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...); + void RaiseButtons(); + void HandleButtonClick(byte widget); + void BringToFront(); + static Window* BringToFrontById(WindowClass cls, WindowNumber number); + void StartDrag(); + bool ContinueDrag(); + void StartSizing(); + bool ContinueSizing(); + static bool HandleWindowDragging(void); + + /*virtual*/ void FinalRelease(); + virtual void Close(); + virtual bool IsVital(); + + static Window* Allocate(int x, int y, int width, int height, WindowProc *proc, WindowClass cls, const Widget *widget); + static Window* Get(WindowList::Iterator it); + static Window* FindById(WindowClass cls, WindowNumber num); + static void SetDirtyById(WindowClass cls, WindowNumber num); + + //int32 AddRef() + //{ + // const char *name = NULL; + // switch (window_class) + // { + // case WC_MAIN_WINDOW: name = "mw"; break; + // case WC_SELECT_GAME: name = "sg"; break; + // case WC_INDUSTRY_VIEW: name = "iw"; break; + // default: break; + // } + // if (name != NULL) printf("%s+\n", name); + // return CountedObject::AddRef(); + //} + + //int32 Release() + //{ + // const char *name = NULL; + // switch (window_class) + // { + // case WC_MAIN_WINDOW: name = "mw"; break; + // case WC_SELECT_GAME: name = "sg"; break; + // case WC_INDUSTRY_VIEW: name = "iw"; break; + // default: break; + // } + // if (name != NULL) printf("%s-\n", name); + // return CountedObject::Release(); + //} + + template struct EnumMatch { + Tmatch &m_match; + EnumMatch(Tmatch &m) + : m_match(m) + {} + bool EnumProc(WindowList::Iterator it) + { + return m_match->EnumProc((*it).w); + } + }; + + template Window* EnumT(Tmatch m) + { + WindowList::Iterator it = Window::s_list.EnumT(EnumMatch(m)); + return (it == Window::s_list.m_list.end()) ? NULL : (*it).w; + } + + template Window* ReverseEnumT(Tmatch m) + { + WindowList::Iterator it = Window::s_list.ReverseEnumT(EnumMatch(m)); + return (it == Window::s_list.m_list.end()) ? NULL : (*it).w; + } + }; + + +#define FOR_ALL_WINDOWS(wz) \ + for (WindowList::Iterator it = Window::s_list.m_list.begin(); it != Window::s_list.m_list.end() && (wz = (*it).w) != NULL; it++) + +#define REVERSED_FOR_ALL_WINDOWS(wz) \ + for (WindowList::ReverseIterator it = Window::s_list.m_list.rbegin(); it != Window::s_list.m_list.rend() && (wz = (*it).w) != NULL; it++) + + typedef struct querystr_d { StringID caption; Textbuf text; @@ -534,27 +687,27 @@ /* window.c */ void CallWindowEventNP(Window *w, int event); void CallWindowTickEvent(void); -void SetWindowDirty(const Window *w); +//void SetWindowDirty(const Window *w); void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam); void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam); -Window *FindWindowById(WindowClass cls, WindowNumber number); -void DeleteWindow(Window *w); +//Window *FindWindowById(WindowClass cls, WindowNumber number); +//void DeleteWindow(Window *w); void DeletePlayerWindows(PlayerID pi); void ChangeWindowOwner(PlayerID old_player, PlayerID new_player); -Window *BringWindowToFrontById(WindowClass cls, WindowNumber number); +//Window *BringWindowToFrontById(WindowClass cls, WindowNumber number); Window *FindWindowFromPt(int x, int y); bool IsWindowOfPrototype(const Window *w, const Widget *widget); void AssignWidgetToWindow(Window *w, const Widget *widget); -Window *AllocateWindow( - int x, - int y, - int width, - int height, - WindowProc *proc, - WindowClass cls, - const Widget *widget); +//Window *AllocateWindow( +// int x, +// int y, +// int width, +// int height, +// WindowProc *proc, +// WindowClass cls, +// const Widget *widget); Window *AllocateWindowDesc(const WindowDesc *desc); Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number); @@ -717,12 +870,12 @@ void InvalidateWidget(const Window *w, byte widget_index); void InvalidateThisWindowData(Window *w); void InvalidateWindowData(WindowClass cls, WindowNumber number); -void RaiseWindowButtons(Window *w); +//void RaiseWindowButtons(Window *w); void RelocateAllWindows(int neww, int newh); int PositionMainToolbar(Window *w); -void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...); -void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...); -void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...); +//void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...); +//void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...); +//void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...); /* misc_gui.c*/ void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint params[]); @@ -736,19 +889,18 @@ void DrawWindowWidgets(const Window *w); void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask); -void HandleButtonClick(Window *w, byte widget); +//void HandleButtonClick(Window *w, byte widget); Window *GetCallbackWnd(void); void DeleteNonVitalWindows(void); void DeleteAllNonVitalWindows(void); void HideVitalWindows(void); void ShowVitalWindows(void); -Window **FindWindowZPosition(const Window *w); +//WindowList::Iterator FindWindowZPosition(const Window *w); /* window.c */ -extern Window *_z_windows[]; -extern Window **_last_z_window; -#define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++) +//extern Window *_z_windows[]; +//extern Window **_last_z_window; VARDEF Point _cursorpos_drag_start;