Changeset - r22173:0f93564a00bb
[Not reviewed]
master
0 3 0
alberth - 9 years ago 2015-07-28 18:20:54
alberth@openttd.org
(svn r27346) -Feature: Make the object placement gui an independent window.
3 files changed with 28 insertions and 40 deletions:
0 comments (0 inline, 0 general)
src/object.h
Show inline comments
 
@@ -11,16 +11,15 @@
 

	
 
#ifndef OBJECT_H
 
#define OBJECT_H
 

	
 
#include "tile_type.h"
 
#include "company_type.h"
 
#include "object_type.h"
 

	
 
void UpdateCompanyHQ(TileIndex tile, uint score);
 

	
 
void BuildObject(ObjectType type, TileIndex tile, CompanyID owner = OWNER_NONE, struct Town *town = NULL, uint8 view = 0);
 

	
 
void PlaceProc_Object(TileIndex tile);
 
void ShowBuildObjectPicker(struct Window *w);
 
void ShowBuildObjectPicker();
 

	
 
#endif /* OBJECT_H */
src/object_gui.cpp
Show inline comments
 
@@ -7,40 +7,41 @@
 
 * 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/>.
 
 */
 

	
 
/** @file object_gui.cpp The GUI for objects. */
 

	
 
#include "stdafx.h"
 
#include "command_func.h"
 
#include "newgrf.h"
 
#include "newgrf_object.h"
 
#include "newgrf_text.h"
 
#include "strings_func.h"
 
#include "viewport_func.h"
 
#include "tilehighlight_func.h"
 
#include "window_gui.h"
 
#include "window_func.h"
 
#include "zoom_func.h"
 

	
 
#include "widgets/object_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 

	
 
static ObjectClassID _selected_object_class; ///< the currently visible object class
 
static int _selected_object_index;           ///< the index of the selected object in the current class or -1
 
static uint8 _selected_object_view;          ///< the view of the selected object
 

	
 
/** The window used for building objects. */
 
class BuildObjectWindow : public PickerWindowBase {
 
class BuildObjectWindow : public Window {
 
	static const int OBJECT_MARGIN = 4; ///< The margin (in pixels) around an object.
 
	int line_height;                    ///< The height of a single line.
 
	int info_height;                    ///< The height of the info box.
 
	Scrollbar *vscroll;                 ///< The scrollbar.
 

	
 
	/** Scroll #WID_BO_CLASS_LIST so that the selected object class is visible. */
 
	void EnsureSelectedObjectClassIsVisible()
 
	{
 
		uint pos = 0;
 
		for (int i = 0; i < _selected_object_class; i++) {
 
			if (ObjectClass::Get((ObjectClassID) i)->GetUISpecCount() == 0) continue;
 
			pos++;
 
@@ -64,29 +65,31 @@ class BuildObjectWindow : public PickerW
 

	
 
	/**
 
	 * Calculate the number of columns of the #WID_BO_SELECT_MATRIX widget.
 
	 * @return Number of columns in the matrix.
 
	 */
 
	uint GetMatrixColumnCount()
 
	{
 
		const NWidgetBase *matrix = this->GetWidget<NWidgetBase>(WID_BO_SELECT_MATRIX);
 
		return 1 + (matrix->current_x - matrix->smallest_x) / matrix->resize_x;
 
	}
 

	
 
public:
 
	BuildObjectWindow(WindowDesc *desc, Window *w) : PickerWindowBase(desc, w), info_height(1)
 
	BuildObjectWindow(WindowDesc *desc, WindowNumber number) : Window(desc), info_height(1)
 
	{
 
		this->CreateNestedTree();
 
		this->vscroll = this->GetScrollbar(WID_BO_SCROLLBAR);
 
		this->FinishInitNested(0);
 
		this->FinishInitNested(number);
 

	
 
		ResetObjectToPlace();
 

	
 
		this->vscroll->SetPosition(0);
 
		this->vscroll->SetCount(ObjectClass::GetUIClassCount());
 

	
 
		NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(WID_BO_SELECT_MATRIX);
 
		matrix->SetScrollbar(this->GetScrollbar(WID_BO_SELECT_SCROLL));
 

	
 
		this->SelectOtherClass(_selected_object_class);
 
		if (this->CanRestoreSelectedObject()) {
 
			this->SelectOtherObject(_selected_object_index);
 
		} else {
 
			this->SelectFirstAvailableObject(true);
 
@@ -328,24 +331,28 @@ public:
 
	 */
 
	void SelectOtherObject(int object_index)
 
	{
 
		_selected_object_index = object_index;
 
		if (_selected_object_index != -1) {
 
			const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
			_selected_object_view = min(_selected_object_view, spec->views - 1);
 
			this->ReInit();
 
		} else {
 
			_selected_object_view = 0;
 
		}
 

	
 
		if (_selected_object_index != -1) {
 
			SetObjectToPlaceWnd(SPR_CURSOR_TRANSMITTER, PAL_NONE, HT_RECT, this);
 
		}
 

	
 
		this->UpdateButtons(_selected_object_class, _selected_object_index, _selected_object_view);
 
	}
 

	
 
	void UpdateSelectSize()
 
	{
 
		if (_selected_object_index == -1) {
 
			SetTileSelectSize(1, 1);
 
		} else {
 
			const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
			int w = GB(spec->size, HasBit(_selected_object_view, 0) ? 4 : 0, 4);
 
			int h = GB(spec->size, HasBit(_selected_object_view, 0) ? 0 : 4, 4);
 
			SetTileSelectSize(w, h);
 
@@ -393,32 +400,41 @@ public:
 
			}
 

	
 
			case WID_BO_SELECT_IMAGE: {
 
				ObjectClass *objclass = ObjectClass::Get(_selected_object_class);
 
				int num_clicked = objclass->GetIndexFromUI(GB(widget, 16, 16));
 
				if (num_clicked >= 0 && objclass->GetSpec(num_clicked)->IsAvailable()) this->SelectOtherObject(num_clicked);
 
				break;
 
			}
 

	
 
			case WID_BO_OBJECT_SPRITE:
 
				if (_selected_object_index != -1) {
 
					_selected_object_view = GB(widget, 16, 16);
 
					this->GetWidget<NWidgetMatrix>(WID_BO_OBJECT_MATRIX)->SetClicked(_selected_object_view);
 
					this->UpdateSelectSize();
 
					this->SetDirty();
 
					this->SelectOtherObject(_selected_object_index); // Re-select the object for a different view.
 
				}
 
				break;
 
		}
 
	}
 

	
 
	virtual void OnPlaceObject(Point pt, TileIndex tile)
 
	{
 
		DoCommandP(tile, ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index)->Index(),
 
				_selected_object_view, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform);
 
	}
 

	
 
	virtual void OnPlaceObjectAbort()
 
	{
 
		this->UpdateButtons(_selected_object_class, -1, _selected_object_view);
 
	}
 

	
 
	/**
 
	 * Select the first available object.
 
	 * @param change_class If true, change the class if no object in the current
 
	 *   class is available.
 
	 */
 
	void SelectFirstAvailableObject(bool change_class)
 
	{
 
		/* First try to select an object in the selected class. */
 
		ObjectClass *sel_objclass = ObjectClass::Get(_selected_object_class);
 
		for (uint i = 0; i < sel_objclass->GetSpecCount(); i++) {
 
			const ObjectSpec *spec = sel_objclass->GetSpec(i);
 
			if (spec->IsAvailable()) {
 
@@ -499,32 +515,22 @@ static const NWidgetPart _nested_build_o
 

	
 
static WindowDesc _build_object_desc(
 
	WDP_AUTO, "build_object", 0, 0,
 
	WC_BUILD_OBJECT, WC_BUILD_TOOLBAR,
 
	WDF_CONSTRUCTION,
 
	_nested_build_object_widgets, lengthof(_nested_build_object_widgets)
 
);
 

	
 
/**
 
 * Show our object picker.
 
 * @param w The toolbar window we're associated with.
 
 */
 
void ShowBuildObjectPicker(Window *w)
 
void ShowBuildObjectPicker()
 
{
 
	new BuildObjectWindow(&_build_object_desc, w);
 
	AllocateWindowDescFront<BuildObjectWindow>(&_build_object_desc, 0);
 
}
 

	
 
/** Reset all data of the object GUI. */
 
void InitializeObjectGui()
 
{
 
	_selected_object_class = (ObjectClassID)0;
 
}
 

	
 
/**
 
 * PlaceProc function, called when someone pressed the button if the
 
 *  object-tool is selected
 
 * @param tile on which to place the object
 
 */
 
void PlaceProc_Object(TileIndex tile)
 
{
 
	DoCommandP(tile, ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index)->Index(), _selected_object_view, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform);
 
}
src/terraform_gui.cpp
Show inline comments
 
@@ -201,30 +201,25 @@ struct TerraformToolbarWindow : Window {
 
				break;
 

	
 
			case WID_TT_PLANT_TREES: // Plant trees button
 
				ShowBuildTreesToolbar();
 
				break;
 

	
 
			case WID_TT_PLACE_SIGN: // Place sign button
 
				HandlePlacePushButton(this, WID_TT_PLACE_SIGN, SPR_CURSOR_SIGN, HT_RECT);
 
				this->last_user_action = widget;
 
				break;
 

	
 
			case WID_TT_PLACE_OBJECT: // Place object button
 
				/* Don't show the place object button when there are no objects to place. */
 
				if (ObjectClass::GetUIClassCount() == 0) return;
 
				if (HandlePlacePushButton(this, WID_TT_PLACE_OBJECT, SPR_CURSOR_TRANSMITTER, HT_RECT)) {
 
					ShowBuildObjectPicker(this);
 
					this->last_user_action = widget;
 
				}
 
				ShowBuildObjectPicker();
 
				break;
 

	
 
			default: NOT_REACHED();
 
		}
 
	}
 

	
 
	virtual void OnPlaceObject(Point pt, TileIndex tile)
 
	{
 
		switch (this->last_user_action) {
 
			case WID_TT_LOWER_LAND: // Lower land button
 
				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LOWER_AND_LEVEL_AREA);
 
				break;
 
@@ -240,28 +235,24 @@ struct TerraformToolbarWindow : Window {
 
			case WID_TT_DEMOLISH: // Demolish aka dynamite button
 
				PlaceProc_DemolishArea(tile);
 
				break;
 

	
 
			case WID_TT_BUY_LAND: // Buy land button
 
				DoCommandP(tile, OBJECT_OWNED_LAND, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound1E);
 
				break;
 

	
 
			case WID_TT_PLACE_SIGN: // Place sign button
 
				PlaceProc_Sign(tile);
 
				break;
 

	
 
			case WID_TT_PLACE_OBJECT: // Place object button
 
				PlaceProc_Object(tile);
 
				break;
 

	
 
			default: NOT_REACHED();
 
		}
 
	}
 

	
 
	virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
 
	{
 
		VpSelectTilesWithMethod(pt.x, pt.y, select_method);
 
	}
 

	
 
	virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
 
	{
 
		Point pt = GetToolbarAlignedWindowPosition(sm_width);
 
@@ -277,25 +268,24 @@ struct TerraformToolbarWindow : Window {
 
				case DDSP_DEMOLISH_AREA:
 
				case DDSP_RAISE_AND_LEVEL_AREA:
 
				case DDSP_LOWER_AND_LEVEL_AREA:
 
				case DDSP_LEVEL_AREA:
 
					GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
 
					break;
 
			}
 
		}
 
	}
 

	
 
	virtual void OnPlaceObjectAbort()
 
	{
 
		DeleteWindowById(WC_BUILD_OBJECT, 0);
 
		this->RaiseButtons();
 
	}
 

	
 
	static HotkeyList hotkeys;
 
};
 

	
 
/**
 
 * Handler for global hotkeys of the TerraformToolbarWindow.
 
 * @param hotkey Hotkey
 
 * @return ES_HANDLED if hotkey was accepted.
 
 */
 
static EventState TerraformToolbarGlobalHotkeys(int hotkey)
 
@@ -335,25 +325,25 @@ static const NWidgetPart _nested_terrafo
 

	
 
		NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), EndContainer(),
 

	
 
		NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_DEMOLISH), SetMinimalSize(22, 22),
 
								SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
 
		NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_BUY_LAND), SetMinimalSize(22, 22),
 
								SetFill(0, 1), SetDataTip(SPR_IMG_BUY_LAND, STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND),
 
		NWidget(WWT_PUSHIMGBTN, COLOUR_DARK_GREEN, WID_TT_PLANT_TREES), SetMinimalSize(22, 22),
 
								SetFill(0, 1), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
 
		NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_PLACE_SIGN), SetMinimalSize(22, 22),
 
								SetFill(0, 1), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
 
		NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TT_SHOW_PLACE_OBJECT),
 
			NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_PLACE_OBJECT), SetMinimalSize(22, 22),
 
			NWidget(WWT_PUSHIMGBTN, COLOUR_DARK_GREEN, WID_TT_PLACE_OBJECT), SetMinimalSize(22, 22),
 
								SetFill(0, 1), SetDataTip(SPR_IMG_TRANSMITTER, STR_SCENEDIT_TOOLBAR_PLACE_OBJECT),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
 
static WindowDesc _terraform_desc(
 
	WDP_MANUAL, "toolbar_landscape", 0, 0,
 
	WC_SCEN_LAND_GEN, WC_NONE,
 
	WDF_CONSTRUCTION,
 
	_nested_terraform_widgets, lengthof(_nested_terraform_widgets),
 
	&TerraformToolbarWindow::hotkeys
 
);
 
@@ -607,28 +597,25 @@ struct ScenarioEditorLandscapeGeneration
 

	
 
			case WID_ETT_PLACE_ROCKS: // Place rocks button
 
				HandlePlacePushButton(this, WID_ETT_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, HT_RECT);
 
				this->last_user_action = widget;
 
				break;
 

	
 
			case WID_ETT_PLACE_DESERT: // Place desert button (in tropical climate)
 
				HandlePlacePushButton(this, WID_ETT_PLACE_DESERT, SPR_CURSOR_DESERT, HT_RECT);
 
				this->last_user_action = widget;
 
				break;
 

	
 
			case WID_ETT_PLACE_OBJECT: // Place transmitter button
 
				if (HandlePlacePushButton(this, WID_ETT_PLACE_OBJECT, SPR_CURSOR_TRANSMITTER, HT_RECT)) {
 
					ShowBuildObjectPicker(this);
 
					this->last_user_action = widget;
 
				}
 
				ShowBuildObjectPicker();
 
				break;
 

	
 
			case WID_ETT_INCREASE_SIZE:
 
			case WID_ETT_DECREASE_SIZE: { // Increase/Decrease terraform size
 
				int size = (widget == WID_ETT_INCREASE_SIZE) ? 1 : -1;
 
				this->HandleButtonClick(widget);
 
				size += _terraform_size;
 

	
 
				if (!IsInsideMM(size, 1, 8 + 1)) return;
 
				_terraform_size = size;
 

	
 
				if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
 
@@ -678,28 +665,24 @@ struct ScenarioEditorLandscapeGeneration
 
			case WID_ETT_LEVEL_LAND: // Level land button
 
				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LEVEL_AREA);
 
				break;
 

	
 
			case WID_ETT_PLACE_ROCKS: // Place rocks button
 
				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_ROCKS);
 
				break;
 

	
 
			case WID_ETT_PLACE_DESERT: // Place desert button (in tropical climate)
 
				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_DESERT);
 
				break;
 

	
 
			case WID_ETT_PLACE_OBJECT: // Place transmitter button
 
				PlaceProc_Object(tile);
 
				break;
 

	
 
			default: NOT_REACHED();
 
		}
 
	}
 

	
 
	virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
 
	{
 
		VpSelectTilesWithMethod(pt.x, pt.y, select_method);
 
	}
 

	
 
	virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
 
	{
 
		if (pt.x != -1) {
0 comments (0 inline, 0 general)