OpenTTD Source 20241224-master-gee860a5c8e
tree_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "window_gui.h"
12#include "gfx_func.h"
13#include "tilehighlight_func.h"
14#include "company_func.h"
15#include "company_base.h"
16#include "command_func.h"
17#include "core/random_func.hpp"
18#include "sound_func.h"
19#include "strings_func.h"
20#include "zoom_func.h"
21#include "tree_map.h"
22#include "tree_cmd.h"
23
24#include "widgets/tree_widget.h"
25
26#include "table/sprites.h"
27#include "table/strings.h"
28#include "table/tree_land.h"
29
30#include "safeguards.h"
31
33uint PlaceTreeGroupAroundTile(TileIndex tile, TreeType treetype, uint radius, uint count, bool set_zone);
34
37 { 1621, PAL_NONE }, { 1635, PAL_NONE }, { 1656, PAL_NONE }, { 1579, PAL_NONE },
38 { 1607, PAL_NONE }, { 1593, PAL_NONE }, { 1614, PAL_NONE }, { 1586, PAL_NONE },
39 { 1663, PAL_NONE }, { 1677, PAL_NONE }, { 1691, PAL_NONE }, { 1705, PAL_NONE },
40 { 1711, PAL_NONE }, { 1746, PAL_NONE }, { 1753, PAL_NONE }, { 1732, PAL_NONE },
41 { 1739, PAL_NONE }, { 1718, PAL_NONE }, { 1725, PAL_NONE }, { 1760, PAL_NONE },
42 { 1838, PAL_NONE }, { 1844, PAL_NONE }, { 1866, PAL_NONE }, { 1871, PAL_NONE },
43 { 1899, PAL_NONE }, { 1935, PAL_NONE }, { 1928, PAL_NONE }, { 1915, PAL_NONE },
44 { 1887, PAL_NONE }, { 1908, PAL_NONE }, { 1824, PAL_NONE }, { 1943, PAL_NONE },
45 { 1950, PAL_NONE }, { 1957, PALETTE_TO_GREEN }, { 1964, PALETTE_TO_RED }, { 1971, PAL_NONE },
46 { 1978, PAL_NONE }, { 1985, PALETTE_TO_RED, }, { 1992, PALETTE_TO_PALE_GREEN }, { 1999, PALETTE_TO_YELLOW }, { 2006, PALETTE_TO_RED }
47};
48
54{
55 const uint16_t base = _tree_base_by_landscape[_settings_game.game_creation.landscape];
56 const uint16_t count = _tree_count_by_landscape[_settings_game.game_creation.landscape];
57
58 Dimension size, this_size;
59 Point offset;
60 /* Avoid to use it uninitialized */
61 size.width = ScaleGUITrad(32); // default width - WD_FRAMERECT_LEFT
62 size.height = ScaleGUITrad(39); // default height - BUTTON_BOTTOM_OFFSET
63 offset.x = 0;
64 offset.y = 0;
65
66 for (int i = base; i < base + count; i++) {
67 if (i >= (int)lengthof(tree_sprites)) return size;
68 this_size = GetSpriteSize(tree_sprites[i].sprite, &offset);
69 size.width = std::max<int>(size.width, 2 * std::max<int>(this_size.width, -offset.x));
70 size.height = std::max<int>(size.height, std::max<int>(this_size.height, -offset.y));
71 }
72
73 return size;
74}
75
76
81{
83 static const int BUTTON_BOTTOM_OFFSET = 7;
84
85 enum PlantingMode {
86 PM_NORMAL,
87 PM_FOREST_SM,
88 PM_FOREST_LG,
89 };
90
92 PlantingMode mode;
93
98 {
99 this->RaiseButtons();
100
101 const int current_tree = this->tree_to_plant;
102
103 if (this->tree_to_plant >= 0) {
104 /* Activate placement */
106 SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT | HT_DIAGONAL, this->window_class, this->window_number);
107 this->tree_to_plant = current_tree; // SetObjectToPlace may call ResetObjectToPlace which may reset tree_to_plant to -1
108 } else {
109 /* Deactivate placement */
111 }
112
113 if (this->tree_to_plant == TREE_INVALID) {
115 } else if (this->tree_to_plant >= 0) {
116 this->LowerWidget(WID_BT_TYPE_BUTTON_FIRST + this->tree_to_plant);
117 }
118
119 switch (this->mode) {
120 case PM_NORMAL: this->LowerWidget(WID_BT_MODE_NORMAL); break;
121 case PM_FOREST_SM: this->LowerWidget(WID_BT_MODE_FOREST_SM); break;
122 case PM_FOREST_LG: this->LowerWidget(WID_BT_MODE_FOREST_LG); break;
123 default: NOT_REACHED();
124 }
125
126 this->SetDirty();
127 }
128
129 void DoPlantForest(TileIndex tile)
130 {
131 TreeType treetype = (TreeType)this->tree_to_plant;
132 if (this->tree_to_plant == TREE_INVALID) {
133 treetype = (TreeType)(InteractiveRandomRange(_tree_count_by_landscape[_settings_game.game_creation.landscape]) + _tree_base_by_landscape[_settings_game.game_creation.landscape]);
134 }
135 const uint radius = this->mode == PM_FOREST_LG ? 12 : 5;
136 const uint count = this->mode == PM_FOREST_LG ? 12 : 5;
137 // Create tropic zones only when the tree type is selected by the user and not picked randomly.
138 PlaceTreeGroupAroundTile(tile, treetype, radius, count, this->tree_to_plant != TREE_INVALID);
139 }
140
141public:
143 {
144 this->CreateNestedTree();
146
148 /* Show scenario editor tools in editor */
149 if (_game_mode != GM_EDITOR) {
151 }
152 this->FinishInitNested(window_number);
153 }
154
156 {
157 if (widget >= WID_BT_TYPE_BUTTON_FIRST) {
158 /* Ensure tree type buttons are sized after the largest tree type */
160 size.width = d.width + padding.width;
161 size.height = d.height + padding.height + ScaleGUITrad(BUTTON_BOTTOM_OFFSET); // we need some more space
162 }
163 }
164
165 void DrawWidget(const Rect &r, WidgetID widget) const override
166 {
167 if (widget >= WID_BT_TYPE_BUTTON_FIRST) {
168 const int index = widget - WID_BT_TYPE_BUTTON_FIRST;
169 /* Trees "grow" in the centre on the bottom line of the buttons */
170 DrawSprite(tree_sprites[index].sprite, tree_sprites[index].pal, CenterBounds(r.left, r.right, 0), r.bottom - ScaleGUITrad(BUTTON_BOTTOM_OFFSET));
171 }
172 }
173
174 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
175 {
176 switch (widget) {
177 case WID_BT_TYPE_RANDOM: // tree of random type.
178 this->tree_to_plant = this->tree_to_plant == TREE_INVALID ? -1 : TREE_INVALID;
179 this->UpdateMode();
180 break;
181
182 case WID_BT_MANY_RANDOM: // place trees randomly over the landscape
186 break;
187
189 this->mode = PM_NORMAL;
190 this->UpdateMode();
191 break;
192
194 assert(_game_mode == GM_EDITOR);
195 this->mode = PM_FOREST_SM;
196 this->UpdateMode();
197 break;
198
200 assert(_game_mode == GM_EDITOR);
201 this->mode = PM_FOREST_LG;
202 this->UpdateMode();
203 break;
204
205 default:
206 if (widget >= WID_BT_TYPE_BUTTON_FIRST) {
207 const int index = widget - WID_BT_TYPE_BUTTON_FIRST;
208 this->tree_to_plant = this->tree_to_plant == index ? -1 : index;
209 this->UpdateMode();
210 }
211 break;
212 }
213 }
214
215 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
216 {
217 if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL) {
219 } else {
221 }
222 }
223
225 {
226 if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL) {
227 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
228 } else {
229 TileIndex tile = TileVirtXY(pt.x, pt.y);
230
231 if (this->mode == PM_NORMAL) {
232 Command<CMD_PLANT_TREE>::Post(tile, tile, this->tree_to_plant, false);
233 } else {
234 this->DoPlantForest(tile);
235 }
236 }
237 }
238
239 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
240 {
241 if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL && pt.x != -1 && select_proc == DDSP_PLANT_TREES) {
242 Command<CMD_PLANT_TREE>::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, start_tile, this->tree_to_plant, _ctrl_pressed);
243 }
244 }
245
246 void OnPlaceObjectAbort() override
247 {
248 this->tree_to_plant = -1;
249 this->UpdateMode();
250 }
251};
252
259static std::unique_ptr<NWidgetBase> MakeTreeTypeButtons()
260{
261 const uint8_t type_base = _tree_base_by_landscape[_settings_game.game_creation.landscape];
262 const uint8_t type_count = _tree_count_by_landscape[_settings_game.game_creation.landscape];
263
264 /* Toyland has 9 tree types, which look better in 3x3 than 4x3 */
265 const int num_columns = type_count == 9 ? 3 : 4;
266 const int num_rows = CeilDiv(type_count, num_columns);
267 uint8_t cur_type = type_base;
268
269 auto vstack = std::make_unique<NWidgetVertical>(NC_EQUALSIZE);
270 vstack->SetPIP(0, 1, 0);
271
272 for (int row = 0; row < num_rows; row++) {
273 auto hstack = std::make_unique<NWidgetHorizontal>(NC_EQUALSIZE);
274 hstack->SetPIP(0, 1, 0);
275 for (int col = 0; col < num_columns; col++) {
276 if (cur_type > type_base + type_count) break;
277 auto button = std::make_unique<NWidgetBackground>(WWT_PANEL, COLOUR_GREY, WID_BT_TYPE_BUTTON_FIRST + cur_type);
278 button->SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP);
279 hstack->Add(std::move(button));
280 cur_type++;
281 }
282 vstack->Add(std::move(hstack));
283 }
284
285 return vstack;
286}
287
288static constexpr NWidgetPart _nested_build_trees_widgets[] = {
290 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
291 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_PLANT_TREE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
292 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
293 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
294 EndContainer(),
295 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
296 NWidget(NWID_VERTICAL), SetPIP(0, 1, 0), SetPadding(2),
298 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BT_TYPE_RANDOM), SetDataTip(STR_TREES_RANDOM_TYPE, STR_TREES_RANDOM_TYPE_TOOLTIP),
299 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BT_SE_PANE),
300 NWidget(NWID_VERTICAL), SetPIP(0, 1, 0),
302 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BT_MODE_NORMAL), SetFill(1, 0), SetDataTip(STR_TREES_MODE_NORMAL_BUTTON, STR_TREES_MODE_NORMAL_TOOLTIP),
303 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BT_MODE_FOREST_SM), SetFill(1, 0), SetDataTip(STR_TREES_MODE_FOREST_SM_BUTTON, STR_TREES_MODE_FOREST_SM_TOOLTIP),
304 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BT_MODE_FOREST_LG), SetFill(1, 0), SetDataTip(STR_TREES_MODE_FOREST_LG_BUTTON, STR_TREES_MODE_FOREST_LG_TOOLTIP),
305 EndContainer(),
306 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BT_MANY_RANDOM), SetDataTip(STR_TREES_RANDOM_TREES_BUTTON, STR_TREES_RANDOM_TREES_TOOLTIP),
307 EndContainer(),
308 EndContainer(),
309 EndContainer(),
310 EndContainer(),
311};
312
313static WindowDesc _build_trees_desc(
314 WDP_AUTO, "build_tree", 0, 0,
317 _nested_build_trees_widgets
318);
319
320void ShowBuildTreesToolbar()
321{
322 if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
323 AllocateWindowDescFront<BuildTreesWindow>(_build_trees_desc, 0);
324}
The build trees window.
Definition tree_gui.cpp:81
PlantingMode mode
Current mode for planting.
Definition tree_gui.cpp:92
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition tree_gui.cpp:165
void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override
The user is dragging over the map when the tile highlight mode has been set.
Definition tree_gui.cpp:224
void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override
The user has dragged over the map when the tile highlight mode has been set.
Definition tree_gui.cpp:239
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition tree_gui.cpp:155
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition tree_gui.cpp:174
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
Definition tree_gui.cpp:215
int tree_to_plant
Tree number to plant, TREE_INVALID for a random tree.
Definition tree_gui.cpp:91
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
Definition tree_gui.cpp:246
static const int BUTTON_BOTTOM_OFFSET
Visual Y offset of tree root from the bottom of the tree type buttons.
Definition tree_gui.cpp:83
void UpdateMode()
Update the GUI and enable/disable planting to reflect selected options.
Definition tree_gui.cpp:97
Functions related to commands.
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Functions related to companies.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:922
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:988
Functions related to the gfx engine.
int CenterBounds(int min, int max, int size)
Determine where to draw a centred object inside a widget.
Definition gfx_func.h:166
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:940
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1529
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition map_func.h:404
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Pseudo random number generator.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:57
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
Functions related to sound.
@ SND_15_BEEP
19 == 0x13 GUI button click
Definition sound_type.h:66
This file contains all sprite-related enums and defines.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:280
Functions related to OTTD's strings.
SoundSettings sound
sound effect settings
Dimensions (a width and height) of a rectangle in 2D.
uint8_t landscape
the landscape we're currently in
GameCreationSettings game_creation
settings used during the creation of a game (map)
Partial widget specification to allow NWidgets to be written nested.
Combination of a palette sprite and a 'real' sprite.
Definition gfx_type.h:23
Coordinates of a point in 2D.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Specification of a rectangle with absolute coordinates of all edges.
bool confirm
Play sound effect on successful constructions or other actions.
High level window description.
Definition window_gui.h:159
Data structure for an opened window.
Definition window_gui.h:273
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1733
ResizeInfo resize
Resize information.
Definition window_gui.h:314
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1723
WindowClass window_class
Window class.
Definition window_gui.h:301
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
Definition window.cpp:525
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:977
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:466
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
Functions related to tile highlights.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method)
Selects tiles while dragging.
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
void VpStartDragging(ViewportDragDropSelectionProcess process)
Drag over the map while holding the left mouse down.
void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDragDropSelectionProcess process)
highlighting tiles while only going over them with the mouse
@ HT_DIAGONAL
Also allow 'diagonal rectangles'. Only usable in combination with HT_RECT or HT_POINT.
@ HT_RECT
rectangle (stations, depots, ...)
Command definitions related to tree tiles.
static Dimension GetMaxTreeSpriteSize()
Calculate the maximum size of all tree sprites.
Definition tree_gui.cpp:53
uint PlaceTreeGroupAroundTile(TileIndex tile, TreeType treetype, uint radius, uint count, bool set_zone)
Place some trees in a radius around a tile.
Definition tree_cmd.cpp:307
void PlaceTreesRandomly()
Place some trees randomly.
Definition tree_cmd.cpp:247
const PalSpriteID tree_sprites[]
Tree Sprites with their palettes.
Definition tree_gui.cpp:36
static std::unique_ptr< NWidgetBase > MakeTreeTypeButtons()
Make widgets for the current available tree types.
Definition tree_gui.cpp:259
Sprites to use and how to display them for tree tiles.
Map accessors for tree tiles.
TreeType
List of tree types along all landscape types.
Definition tree_map.h:25
@ TREE_INVALID
An invalid tree.
Definition tree_map.h:32
Types related to the tree widgets.
@ WID_BT_MANY_RANDOM
Button to build many random trees.
Definition tree_widget.h:20
@ WID_BT_SE_PANE
Selection pane to show/hide scenario editor tools.
Definition tree_widget.h:16
@ WID_BT_MODE_NORMAL
Select normal/rectangle planting mode.
Definition tree_widget.h:17
@ WID_BT_MODE_FOREST_SM
Select small forest planting mode.
Definition tree_widget.h:18
@ WID_BT_TYPE_BUTTON_FIRST
First tree type selection button. (This must be last in the enum.)
Definition tree_widget.h:21
@ WID_BT_MODE_FOREST_LG
Select large forest planting mode.
Definition tree_widget.h:19
@ WID_BT_TYPE_RANDOM
Button to build random type of tree.
Definition tree_widget.h:15
ViewportDragDropSelectionProcess
Drag and drop selection process, or, what to do with an area of land when you've selected it.
@ DDSP_PLANT_TREES
Plant trees.
ViewportPlaceMethod
Viewport place method (type of highlighted area and placed objects)
@ VPM_X_AND_Y
area of land in X and Y directions
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:35
@ SZSP_HORIZONTAL
Display plane with zero size vertically, and filling and resizing horizontally.
@ NC_EQUALSIZE
Value of the NCB_EQUALSIZE flag.
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:75
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:55
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:50
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:66
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:64
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:61
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:77
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:69
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:80
Functions, definitions and such used only by the GUI.
@ WDF_CONSTRUCTION
This window is used for construction; close it whenever changing company.
Definition window_gui.h:203
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:147
int WidgetID
Widget ID.
Definition window_type.h:18
int32_t WindowNumber
Number to differentiate different windows of the same class.
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:45
@ WC_BUILD_TREES
Build trees toolbar; Window numbers:
Definition window_type.h:86
Functions related to zooming.