tree_gui.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #include "stdafx.h"
00013 #include "window_gui.h"
00014 #include "gfx_func.h"
00015 #include "tilehighlight_func.h"
00016 #include "company_func.h"
00017 #include "company_base.h"
00018 #include "command_func.h"
00019 #include "sound_func.h"
00020 #include "tree_map.h"
00021 
00022 #include "table/sprites.h"
00023 #include "table/strings.h"
00024 #include "table/tree_land.h"
00025 
00026 void PlaceTreesRandomly();
00027 
00029 enum BuildTreesWidgets {
00030   BTW_TYPE_11,
00031   BTW_TYPE_12,
00032   BTW_TYPE_13,
00033   BTW_TYPE_14,
00034   BTW_TYPE_21,
00035   BTW_TYPE_22,
00036   BTW_TYPE_23,
00037   BTW_TYPE_24,
00038   BTW_TYPE_31,
00039   BTW_TYPE_32,
00040   BTW_TYPE_33,
00041   BTW_TYPE_34,
00042   BTW_TYPE_RANDOM,
00043   BTW_MANY_RANDOM,
00044 };
00045 
00047 const PalSpriteID tree_sprites[] = {
00048   { 1621, PAL_NONE }, { 1587, PAL_NONE }, { 1656, PAL_NONE }, { 1579, PAL_NONE },
00049   { 1607, PAL_NONE }, { 1593, PAL_NONE }, { 1614, PAL_NONE }, { 1586, PAL_NONE },
00050   { 1663, PAL_NONE }, { 1677, PAL_NONE }, { 1691, PAL_NONE }, { 1705, PAL_NONE },
00051   { 1711, PAL_NONE }, { 1746, PAL_NONE }, { 1753, PAL_NONE }, { 1732, PAL_NONE },
00052   { 1739, PAL_NONE }, { 1718, PAL_NONE }, { 1725, PAL_NONE }, { 1760, PAL_NONE },
00053   { 1838, PAL_NONE }, { 1844, PAL_NONE }, { 1866, PAL_NONE }, { 1871, PAL_NONE },
00054   { 1899, PAL_NONE }, { 1935, PAL_NONE }, { 1928, PAL_NONE }, { 1915, PAL_NONE },
00055   { 1887, PAL_NONE }, { 1908, PAL_NONE }, { 1824, PAL_NONE }, { 1943, PAL_NONE },
00056   { 1950, PAL_NONE }, { 1957, PALETTE_TO_GREEN }, { 1964, PALETTE_TO_RED },        { 1971, PAL_NONE },
00057   { 1978, PAL_NONE }, { 1985, PALETTE_TO_RED, },  { 1992, PALETTE_TO_PALE_GREEN }, { 1999, PALETTE_TO_YELLOW }, { 2006, PALETTE_TO_RED }
00058 };
00059 
00060 
00064 class BuildTreesWindow : public Window
00065 {
00066   uint16 base;        
00067   uint16 count;       
00068   TreeType tree_to_plant; 
00069 
00070 public:
00071   BuildTreesWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
00072   {
00073     this->InitNested(desc, window_number);
00074     ResetObjectToPlace();
00075   }
00076 
00081   Dimension GetMaxTreeSpriteSize()
00082   {
00083     Dimension size, this_size;
00084     Point offset;
00085     /* Avoid to use it uninitialized */
00086     size.width  = 32; // default width - 2
00087     size.height = 39; // default height - 7
00088     offset.x = 0;
00089     offset.y = 0;
00090 
00091     for (int i = this->base; i < this->base + this->count; i++) {
00092       if (i >= (int)lengthof(tree_sprites)) return size;
00093       this_size = GetSpriteSize(tree_sprites[i].sprite, &offset);
00094       size.width = max<int>(size.width, 2 * max<int>(this_size.width, -offset.x));
00095       size.height = max<int>(size.height, max<int>(this_size.height, -offset.y));
00096     }
00097 
00098     return size;
00099   }
00100 
00101   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00102   {
00103     if (widget >= BTW_TYPE_11 && widget <= BTW_TYPE_34) {
00104       Dimension d = GetMaxTreeSpriteSize();
00105       /* Allow some pixels extra width and height */
00106       size->width = d.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
00107       size->height = d.height + WD_FRAMERECT_RIGHT + WD_FRAMERECT_BOTTOM + 7; // we need some more space
00108       return;
00109     }
00110 
00111     if (widget != BTW_MANY_RANDOM) return;
00112 
00113     if (_game_mode != GM_EDITOR) {
00114       size->width = 0;
00115       size->height = 0;
00116     }
00117   }
00118 
00119   virtual void OnPaint()
00120   {
00121     this->DrawWidgets();
00122   }
00123 
00124   virtual void DrawWidget(const Rect &r, int widget) const
00125   {
00126     if (widget < BTW_TYPE_11 || widget > BTW_TYPE_34 || widget - BTW_TYPE_11 >= this->count) return;
00127 
00128     int i = this->base + widget - BTW_TYPE_11;
00129     /* Trees "grow" in the centre on the bottom line of the buttons */
00130     DrawSprite(tree_sprites[i].sprite, tree_sprites[i].pal, (r.left + r.right) / 2 + WD_FRAMERECT_LEFT, r.bottom - 7);
00131   }
00132 
00133   virtual void OnClick(Point pt, int widget, int click_count)
00134   {
00135     switch (widget) {
00136       case BTW_TYPE_11: case BTW_TYPE_12: case BTW_TYPE_13: case BTW_TYPE_14:
00137       case BTW_TYPE_21: case BTW_TYPE_22: case BTW_TYPE_23: case BTW_TYPE_24:
00138       case BTW_TYPE_31: case BTW_TYPE_32: case BTW_TYPE_33: case BTW_TYPE_34:
00139         if (widget - BTW_TYPE_11 >= this->count) break;
00140 
00141         if (HandlePlacePushButton(this, widget, SPR_CURSOR_TREE, HT_RECT)) {
00142           this->tree_to_plant = (TreeType)(this->base + widget - BTW_TYPE_11);
00143         }
00144         break;
00145 
00146       case BTW_TYPE_RANDOM: // tree of random type.
00147         if (HandlePlacePushButton(this, BTW_TYPE_RANDOM, SPR_CURSOR_TREE, HT_RECT)) {
00148           this->tree_to_plant = TREE_INVALID;
00149         }
00150         break;
00151 
00152       case BTW_MANY_RANDOM: // place trees randomly over the landscape
00153         this->LowerWidget(BTW_MANY_RANDOM);
00154         this->flags4 |= WF_TIMEOUT_BEGIN;
00155         SndPlayFx(SND_15_BEEP);
00156         PlaceTreesRandomly();
00157         MarkWholeScreenDirty();
00158         break;
00159     }
00160   }
00161 
00162   virtual void OnPlaceObject(Point pt, TileIndex tile)
00163   {
00164     VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_PLANT_TREES);
00165     VpSetPlaceSizingLimit(20);
00166   }
00167 
00168   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00169   {
00170     VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00171   }
00172 
00173   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00174   {
00175     if (pt.x != -1 && select_proc == DDSP_PLANT_TREES) {
00176       DoCommandP(end_tile, this->tree_to_plant, start_tile,
00177         CMD_PLANT_TREE | CMD_MSG(STR_ERROR_CAN_T_PLANT_TREE_HERE));
00178     }
00179   }
00180 
00184   virtual void OnInit()
00185   {
00186     this->base  = _tree_base_by_landscape[_settings_game.game_creation.landscape];
00187     this->count = _tree_count_by_landscape[_settings_game.game_creation.landscape];
00188   }
00189 
00190   virtual void OnTimeout()
00191   {
00192     this->RaiseWidget(BTW_MANY_RANDOM);
00193     this->SetWidgetDirty(BTW_MANY_RANDOM);
00194   }
00195 
00196   virtual void OnPlaceObjectAbort()
00197   {
00198     this->RaiseButtons();
00199   }
00200 };
00201 
00202 static const NWidgetPart _nested_build_trees_widgets[] = {
00203   NWidget(NWID_HORIZONTAL),
00204     NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00205     NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_PLANT_TREE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00206     NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
00207     NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
00208   EndContainer(),
00209   NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
00210     NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00211     NWidget(NWID_HORIZONTAL),
00212       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
00213       NWidget(NWID_VERTICAL),
00214         NWidget(NWID_HORIZONTAL),
00215           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_11), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00216           EndContainer(),
00217           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00218           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_12), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00219           EndContainer(),
00220           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00221           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_13), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00222           EndContainer(),
00223           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00224           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_14), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00225           EndContainer(),
00226         EndContainer(),
00227         NWidget(NWID_SPACER), SetMinimalSize(0, 1),
00228         NWidget(NWID_HORIZONTAL),
00229           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_21), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00230           EndContainer(),
00231           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00232           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_22), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00233           EndContainer(),
00234           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00235           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_23), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00236           EndContainer(),
00237           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00238           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_24), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00239           EndContainer(),
00240         EndContainer(),
00241         NWidget(NWID_SPACER), SetMinimalSize(0, 1),
00242         NWidget(NWID_HORIZONTAL),
00243           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_31), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00244           EndContainer(),
00245           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00246           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_32), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00247           EndContainer(),
00248           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00249           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_33), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00250           EndContainer(),
00251           NWidget(NWID_SPACER), SetMinimalSize(1, 0),
00252           NWidget(WWT_PANEL, COLOUR_GREY, BTW_TYPE_34), SetMinimalSize(34, 46), SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP),
00253           EndContainer(),
00254         EndContainer(),
00255         NWidget(NWID_SPACER), SetMinimalSize(0, 1),
00256         NWidget(WWT_TEXTBTN, COLOUR_GREY, BTW_TYPE_RANDOM), SetMinimalSize(139, 12), SetDataTip(STR_TREES_RANDOM_TYPE, STR_TREES_RANDOM_TYPE_TOOLTIP),
00257         NWidget(NWID_SPACER), SetMinimalSize(0, 1),
00258         NWidget(WWT_TEXTBTN, COLOUR_GREY, BTW_MANY_RANDOM), SetMinimalSize(139, 12), SetDataTip(STR_TREES_RANDOM_TREES_BUTTON, STR_TREES_RANDOM_TREES_TOOLTIP),
00259         NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00260       EndContainer(),
00261       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
00262     EndContainer(),
00263   EndContainer(),
00264 };
00265 
00266 static const WindowDesc _build_trees_desc(
00267   WDP_AUTO, 0, 0,
00268   WC_BUILD_TREES, WC_NONE,
00269   WDF_CONSTRUCTION,
00270   _nested_build_trees_widgets, lengthof(_nested_build_trees_widgets)
00271 );
00272 
00273 void ShowBuildTreesToolbar()
00274 {
00275   if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
00276   AllocateWindowDescFront<BuildTreesWindow>(&_build_trees_desc, 0);
00277 }