File diff r21352:172f883033dd → r21353:433db3a92931
src/group_gui.cpp
Show inline comments
 
@@ -30,6 +30,8 @@
 

	
 
#include "table/sprites.h"
 

	
 
static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels
 

	
 
typedef GUIList<const Group*> GUIGroupList;
 

	
 
static const NWidgetPart _nested_group_widgets[] = {
 
@@ -105,34 +107,26 @@ private:
 
	};
 

	
 
	VehicleID vehicle_sel; ///< Selected vehicle
 
	GroupID group_sel;     ///< Selected group (for drag/drop)
 
	GroupID group_rename;  ///< Group being renamed, INVALID_GROUP if none
 
	GroupID group_over;    ///< Group over which a vehicle is dragged, INVALID_GROUP if none
 
	GUIGroupList groups;   ///< List of groups
 
	uint tiny_step_height; ///< Step height for the group list
 
	Scrollbar *group_sb;
 

	
 
	SmallVector<int, 16> indents; ///< Indentation levels
 

	
 
	Dimension column_size[VGC_END]; ///< Size of the columns in the group list.
 

	
 
	/**
 
	 * (Re)Build the group list.
 
	 *
 
	 * @param owner The owner of the window
 
	 */
 
	void BuildGroupList(Owner owner)
 
	void AddParents(GUIGroupList *source, GroupID parent, int indent)
 
	{
 
		if (!this->groups.NeedRebuild()) return;
 

	
 
		this->groups.Clear();
 

	
 
		const Group *g;
 
		FOR_ALL_GROUPS(g) {
 
			if (g->owner == owner && g->vehicle_type == this->vli.vtype) {
 
				*this->groups.Append() = g;
 
		for (const Group **g = source->Begin(); g != source->End(); g++) {
 
			if ((*g)->parent == parent) {
 
				*this->groups.Append() = *g;
 
				*this->indents.Append() = indent;
 
				AddParents(source, (*g)->index, indent + 1);
 
			}
 
		}
 

	
 
		this->groups.Compact();
 
		this->groups.RebuildDone();
 
	}
 

	
 
	/** Sort the groups by their name */
 
@@ -159,6 +153,36 @@ private:
 
	}
 

	
 
	/**
 
	 * (Re)Build the group list.
 
	 *
 
	 * @param owner The owner of the window
 
	 */
 
	void BuildGroupList(Owner owner)
 
	{
 
		if (!this->groups.NeedRebuild()) return;
 

	
 
		this->groups.Clear();
 
		this->indents.Clear();
 

	
 
		GUIGroupList list;
 

	
 
		const Group *g;
 
		FOR_ALL_GROUPS(g) {
 
			if (g->owner == owner && g->vehicle_type == this->vli.vtype) {
 
				*list.Append() = g;
 
			}
 
		}
 

	
 
		list.ForceResort();
 
		list.Sort(&GroupNameSorter);
 

	
 
		AddParents(&list, INVALID_GROUP, 0);
 

	
 
		this->groups.Compact();
 
		this->groups.RebuildDone();
 
	}
 

	
 
	/**
 
	 * Compute tiny_step_height and column_size
 
	 * @return Total width required for the group list.
 
	 */
 
@@ -204,9 +228,10 @@ private:
 
	 * @param left Left of the row.
 
	 * @param right Right of the row.
 
	 * @param g_id Group to list.
 
	 * @param indent Indentation level.
 
	 * @param protection Whether autoreplace protection is set.
 
	 */
 
	void DrawGroupInfo(int y, int left, int right, GroupID g_id, bool protection = false) const
 
	void DrawGroupInfo(int y, int left, int right, GroupID g_id, int indent = 0, bool protection = false) const
 
	{
 
		/* Highlight the group if a vehicle is dragged over it */
 
		if (g_id == this->group_over) {
 
@@ -231,7 +256,7 @@ private:
 
			str = STR_GROUP_NAME;
 
		}
 
		int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8;
 
		DrawString(x, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
 
		DrawString(x + indent * LEVEL_WIDTH, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
 

	
 
		/* draw autoreplace protection */
 
		x = rtl ? x - 8 - this->column_size[VGC_PROTECT].width : x + 8 + this->column_size[VGC_NAME].width;
 
@@ -295,6 +320,7 @@ public:
 

	
 
		this->vli.index = ALL_GROUP;
 
		this->vehicle_sel = INVALID_VEHICLE;
 
		this->group_sel = INVALID_GROUP;
 
		this->group_rename = INVALID_GROUP;
 
		this->group_over = INVALID_GROUP;
 

	
 
@@ -308,7 +334,6 @@ public:
 
		this->groups.ForceRebuild();
 
		this->groups.NeedResort();
 
		this->BuildGroupList(vli.company);
 
		this->groups.Sort(&GroupNameSorter);
 

	
 
		this->GetWidget<NWidgetCore>(WID_GL_CAPTION)->widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this->vli.vtype;
 
		this->GetWidget<NWidgetCore>(WID_GL_LIST_VEHICLE)->tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this->vli.vtype;
 
@@ -442,7 +467,6 @@ public:
 
		this->SortVehicleList();
 

	
 
		this->BuildGroupList(this->owner);
 
		this->groups.Sort(&GroupNameSorter);
 

	
 
		this->group_sb->SetCount(this->groups.Length());
 
		this->vscroll->SetCount(this->vehicles.Length());
 
@@ -508,7 +532,7 @@ public:
 

	
 
					assert(g->owner == this->owner);
 

	
 
					DrawGroupInfo(y1, r.left, r.right, g->index, g->replace_protection);
 
					DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i], g->replace_protection);
 

	
 
					y1 += this->tiny_step_height;
 
				}
 
@@ -523,6 +547,19 @@ public:
 
				break;
 

	
 
			case WID_GL_LIST_VEHICLE:
 
				if (this->vli.index != ALL_GROUP) {
 
					/* Mark vehicles which are in sub-groups */
 
					int y = r.top;
 
					uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehicles.Length());
 
					for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
 
						const Vehicle *v = this->vehicles[i];
 
						if (v->group_id != this->vli.index) {
 
							GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 2, _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER);
 
						}
 
						y += this->resize.step_height;
 
					}
 
				}
 

	
 
				this->DrawVehicleListItems(this->vehicle_sel, this->resize.step_height, r);
 
				break;
 
		}
 
@@ -560,7 +597,9 @@ public:
 
				uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height);
 
				if (id_g >= this->groups.Length()) return;
 

	
 
				this->vli.index = this->groups[id_g]->index;
 
				this->group_sel = this->vli.index = this->groups[id_g]->index;
 

	
 
				SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
 

	
 
				this->vehicles.ForceRebuild();
 
				this->SetDirty();
 
@@ -620,14 +659,46 @@ public:
 
			case WID_GL_REPLACE_PROTECTION: {
 
				const Group *g = Group::GetIfValid(this->vli.index);
 
				if (g != NULL) {
 
					DoCommandP(0, this->vli.index, !g->replace_protection, CMD_SET_GROUP_REPLACE_PROTECTION);
 
					DoCommandP(0, this->vli.index, !g->replace_protection | (_ctrl_pressed << 1), CMD_SET_GROUP_REPLACE_PROTECTION);
 
				}
 
				break;
 
			}
 
		}
 
	}
 

	
 
	virtual void OnDragDrop(Point pt, int widget)
 
	void OnDragDrop_Group(Point pt, int widget)
 
	{
 
		const Group *g = Group::Get(this->group_sel);
 

	
 
		switch (widget) {
 
			case WID_GL_ALL_VEHICLES: // All vehicles
 
			case WID_GL_DEFAULT_VEHICLES: // Ungroupd vehicles
 
				if (g->parent != INVALID_GROUP) {
 
					DoCommandP(0, this->group_sel | (1 << 16), INVALID_GROUP, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT));
 
				}
 

	
 
				this->group_sel = INVALID_GROUP;
 
				this->group_over = INVALID_GROUP;
 
				this->SetDirty();
 
				break;
 

	
 
			case WID_GL_LIST_GROUP: { // Matrix group
 
				uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height);
 
				GroupID new_g = id_g >= this->groups.Length() ? INVALID_GROUP : this->groups[id_g]->index;
 

	
 
				if (this->group_sel != new_g && g->parent != new_g) {
 
					DoCommandP(0, this->group_sel | (1 << 16), new_g, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT));
 
				}
 

	
 
				this->group_sel = INVALID_GROUP;
 
				this->group_over = INVALID_GROUP;
 
				this->SetDirty();
 
				break;
 
			}
 
		}
 
	}
 

	
 
	void OnDragDrop_Vehicle(Point pt, int widget)
 
	{
 
		switch (widget) {
 
			case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles
 
@@ -668,12 +739,19 @@ public:
 
				break;
 
			}
 
		}
 
	}
 

	
 
	virtual void OnDragDrop(Point pt, int widget)
 
	{
 
		if (this->vehicle_sel != INVALID_VEHICLE) OnDragDrop_Vehicle(pt, widget);
 
		if (this->group_sel != INVALID_GROUP) OnDragDrop_Group(pt, widget);
 

	
 
		_cursor.vehchain = false;
 
	}
 

	
 
	virtual void OnQueryTextFinished(char *str)
 
	{
 
		if (str != NULL) DoCommandP(0, this->group_rename, 0, CMD_RENAME_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), NULL, str);
 
		if (str != NULL) DoCommandP(0, this->group_rename, 0, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), NULL, str);
 
		this->group_rename = INVALID_GROUP;
 
	}
 

	
 
@@ -742,7 +820,7 @@ public:
 

	
 
	virtual void OnMouseDrag(Point pt, int widget)
 
	{
 
		if (this->vehicle_sel == INVALID_VEHICLE) return;
 
		if (this->vehicle_sel == INVALID_VEHICLE && this->group_sel == INVALID_GROUP) return;
 

	
 
		/* A vehicle is dragged over... */
 
		GroupID new_group_over = INVALID_GROUP;
 
@@ -759,7 +837,11 @@ public:
 
		}
 

	
 
		/* Do not highlight when dragging over the current group */
 
		if (Vehicle::Get(vehicle_sel)->group_id == new_group_over) new_group_over = INVALID_GROUP;
 
		if (this->vehicle_sel != INVALID_VEHICLE) {
 
			if (Vehicle::Get(vehicle_sel)->group_id == new_group_over) new_group_over = INVALID_GROUP;
 
		} else if (this->group_sel != INVALID_GROUP) {
 
			if (this->group_sel == new_group_over || Group::Get(this->group_sel)->parent == new_group_over) new_group_over = INVALID_GROUP;
 
		}
 

	
 
		/* Mark widgets as dirty if the group changed. */
 
		if (new_group_over != this->group_over) {