4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file tree_gui.cpp GUIs for building trees. */
13 #include "window_gui.h"
15 #include "tilehighlight_func.h"
16 #include "company_func.h"
17 #include "company_base.h"
18 #include "command_func.h"
19 #include "sound_func.h"
22 #include "widgets/tree_widget.h"
24 #include "table/sprites.h"
25 #include "table/strings.h"
26 #include "table/tree_land.h"
28 #include "safeguards.h"
30 void PlaceTreesRandomly();
33 * The build trees window.
35 class BuildTreesWindow
: public Window
37 uint16 base
; ///< Base tree number used for drawing the window.
38 uint16 count
; ///< Number of different trees available.
39 TreeType tree_to_plant
; ///< Tree number to plant, \c TREE_INVALID for a random tree.
42 BuildTreesWindow(WindowDesc
*desc
, WindowNumber window_number
) : Window(desc
)
44 this->InitNested(window_number
);
49 * Calculate the maximum size of all tree sprites
50 * @return Dimension of the largest tree sprite
52 Dimension
GetMaxTreeSpriteSize()
54 Dimension size
, this_size
;
56 /* Avoid to use it uninitialized */
57 size
.width
= 32; // default width - 2
58 size
.height
= 39; // default height - 7
62 for (int i
= this->base
; i
< this->base
+ this->count
; i
++) {
63 if (i
>= (int)lengthof(_tree_sprites
)) return size
;
64 this_size
= GetSpriteSize(_tree_sprites
[i
].sprite
, &offset
);
65 size
.width
= max
<int>(size
.width
, 2 * max
<int>(this_size
.width
, -offset
.x
));
66 size
.height
= max
<int>(size
.height
, max
<int>(this_size
.height
, -offset
.y
));
72 virtual void UpdateWidgetSize(int widget
, Dimension
*size
, const Dimension
&padding
, Dimension
*fill
, Dimension
*resize
)
74 if (widget
>= WID_BT_TYPE_11
&& widget
<= WID_BT_TYPE_34
) {
75 Dimension d
= GetMaxTreeSpriteSize();
76 /* Allow some pixels extra width and height */
77 size
->width
= d
.width
+ WD_FRAMERECT_LEFT
+ WD_FRAMERECT_RIGHT
;
78 size
->height
= d
.height
+ WD_FRAMERECT_RIGHT
+ WD_FRAMERECT_BOTTOM
+ 7; // we need some more space
82 if (widget
!= WID_BT_MANY_RANDOM
) return;
84 if (_game_mode
!= GM_EDITOR
) {
90 virtual void DrawWidget(const Rect
&r
, int widget
) const
92 if (widget
< WID_BT_TYPE_11
|| widget
> WID_BT_TYPE_34
|| widget
- WID_BT_TYPE_11
>= this->count
) return;
94 int i
= this->base
+ widget
- WID_BT_TYPE_11
;
95 /* Trees "grow" in the centre on the bottom line of the buttons */
96 DrawSprite(_tree_sprites
[i
].sprite
, _tree_sprites
[i
].pal
, (r
.left
+ r
.right
) / 2 + WD_FRAMERECT_LEFT
, r
.bottom
- 7);
99 virtual void OnClick(Point pt
, int widget
, int click_count
)
102 case WID_BT_TYPE_11
: case WID_BT_TYPE_12
: case WID_BT_TYPE_13
: case WID_BT_TYPE_14
:
103 case WID_BT_TYPE_21
: case WID_BT_TYPE_22
: case WID_BT_TYPE_23
: case WID_BT_TYPE_24
:
104 case WID_BT_TYPE_31
: case WID_BT_TYPE_32
: case WID_BT_TYPE_33
: case WID_BT_TYPE_34
:
105 if (widget
- WID_BT_TYPE_11
>= this->count
) break;
107 if (HandlePlacePushButton(this, widget
, SPR_CURSOR_TREE
, HT_RECT
)) {
108 this->tree_to_plant
= (TreeType
)(this->base
+ widget
- WID_BT_TYPE_11
);
112 case WID_BT_TYPE_RANDOM
: // tree of random type.
113 if (HandlePlacePushButton(this, WID_BT_TYPE_RANDOM
, SPR_CURSOR_TREE
, HT_RECT
)) {
114 this->tree_to_plant
= TREE_INVALID
;
118 case WID_BT_MANY_RANDOM
: // place trees randomly over the landscape
119 if (_settings_client
.sound
.confirm
) SndPlayFx(SND_15_BEEP
);
120 PlaceTreesRandomly();
121 MarkWholeScreenDirty();
126 virtual void OnPlaceObject(Point pt
, TileIndex tile
)
128 VpStartPlaceSizing(tile
, VPM_X_AND_Y
, DDSP_PLANT_TREES
);
131 virtual void OnPlaceDrag(ViewportPlaceMethod select_method
, ViewportDragDropSelectionProcess select_proc
, Point pt
)
133 VpSelectTilesWithMethod(pt
.x
, pt
.y
, select_method
);
136 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method
, ViewportDragDropSelectionProcess select_proc
, Point pt
, TileIndex start_tile
, TileIndex end_tile
)
138 if (pt
.x
!= -1 && select_proc
== DDSP_PLANT_TREES
) {
139 DoCommandP(end_tile
, this->tree_to_plant
, start_tile
,
140 CMD_PLANT_TREE
| CMD_MSG(STR_ERROR_CAN_T_PLANT_TREE_HERE
));
145 * Initialize the window data
147 virtual void OnInit()
149 this->base
= _tree_base_by_landscape
[_settings_game
.game_creation
.landscape
];
150 this->count
= _tree_count_by_landscape
[_settings_game
.game_creation
.landscape
];
153 virtual void OnPlaceObjectAbort()
155 this->RaiseButtons();
159 static const NWidgetPart _nested_build_trees_widgets
[] = {
160 NWidget(NWID_HORIZONTAL
),
161 NWidget(WWT_CLOSEBOX
, COLOUR_DARK_GREEN
),
162 NWidget(WWT_CAPTION
, COLOUR_DARK_GREEN
), SetDataTip(STR_PLANT_TREE_CAPTION
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
163 NWidget(WWT_SHADEBOX
, COLOUR_DARK_GREEN
),
164 NWidget(WWT_STICKYBOX
, COLOUR_DARK_GREEN
),
166 NWidget(WWT_PANEL
, COLOUR_DARK_GREEN
),
167 NWidget(NWID_SPACER
), SetMinimalSize(0, 2),
168 NWidget(NWID_HORIZONTAL
),
169 NWidget(NWID_SPACER
), SetMinimalSize(2, 0),
170 NWidget(NWID_VERTICAL
),
171 NWidget(NWID_HORIZONTAL
),
172 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_11
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
174 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
175 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_12
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
177 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
178 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_13
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
180 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
181 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_14
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
184 NWidget(NWID_SPACER
), SetMinimalSize(0, 1),
185 NWidget(NWID_HORIZONTAL
),
186 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_21
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
188 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
189 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_22
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
191 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
192 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_23
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
194 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
195 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_24
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
198 NWidget(NWID_SPACER
), SetMinimalSize(0, 1),
199 NWidget(NWID_HORIZONTAL
),
200 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_31
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
202 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
203 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_32
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
205 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
206 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_33
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
208 NWidget(NWID_SPACER
), SetMinimalSize(1, 0),
209 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BT_TYPE_34
), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP
),
212 NWidget(NWID_SPACER
), SetMinimalSize(0, 1),
213 NWidget(WWT_TEXTBTN
, COLOUR_GREY
, WID_BT_TYPE_RANDOM
), SetMinimalSize(139, 12), SetDataTip(STR_TREES_RANDOM_TYPE
, STR_TREES_RANDOM_TYPE_TOOLTIP
),
214 NWidget(NWID_SPACER
), SetMinimalSize(0, 1),
215 NWidget(WWT_PUSHTXTBTN
, COLOUR_GREY
, WID_BT_MANY_RANDOM
), SetMinimalSize(139, 12), SetDataTip(STR_TREES_RANDOM_TREES_BUTTON
, STR_TREES_RANDOM_TREES_TOOLTIP
),
216 NWidget(NWID_SPACER
), SetMinimalSize(0, 2),
218 NWidget(NWID_SPACER
), SetMinimalSize(2, 0),
223 static WindowDesc
_build_trees_desc(
224 WDP_AUTO
, "build_tree", 0, 0,
225 WC_BUILD_TREES
, WC_NONE
,
227 _nested_build_trees_widgets
, lengthof(_nested_build_trees_widgets
)
230 void ShowBuildTreesToolbar()
232 if (_game_mode
!= GM_EDITOR
&& !Company::IsValidID(_local_company
)) return;
233 AllocateWindowDescFront
<BuildTreesWindow
>(&_build_trees_desc
, 0);