Merge remote-tracking branch 'upstream/master'
Conflicts: src/console_gui.cpp src/genworld_gui.cpp src/group_gui.cpp src/misc_gui.cpp src/settings_gui.cpp src/widgets/settings_widget.h
This commit is contained in:
@@ -30,6 +30,10 @@
|
||||
|
||||
#include "table/sprites.h"
|
||||
|
||||
#include "safeguards.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 +109,27 @@ 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
|
||||
GroupID group_confirm; ///< Group awaiting delete confirmation
|
||||
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 */
|
||||
@@ -158,6 +155,36 @@ private:
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* (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.
|
||||
@@ -206,9 +233,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) {
|
||||
@@ -238,7 +266,7 @@ private:
|
||||
}
|
||||
}
|
||||
int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width - longer_name + 1 : left + WD_FRAMERECT_LEFT + 8;
|
||||
DrawString(x, x + this->column_size[VGC_NAME].width + longer_name - 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 + longer_name - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
|
||||
|
||||
/* draw autoreplace protection */
|
||||
x = rtl ? x - 2 - this->column_size[VGC_PROTECT].width : x + 2 + this->column_size[VGC_NAME].width;
|
||||
@@ -302,6 +330,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;
|
||||
|
||||
@@ -315,7 +344,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;
|
||||
@@ -443,7 +471,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());
|
||||
@@ -509,7 +536,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;
|
||||
}
|
||||
@@ -524,11 +551,33 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
static void DeleteGroupCallback(Window *win, bool confirmed)
|
||||
{
|
||||
if (confirmed) {
|
||||
VehicleGroupWindow *w = (VehicleGroupWindow*)win;
|
||||
w->vli.index = ALL_GROUP;
|
||||
DoCommandP(0, w->group_confirm, 0, CMD_DELETE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_DELETE));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
{
|
||||
switch (widget) {
|
||||
@@ -561,7 +610,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();
|
||||
@@ -591,10 +642,8 @@ public:
|
||||
}
|
||||
|
||||
case WID_GL_DELETE_GROUP: { // Delete the selected group
|
||||
GroupID group = this->vli.index;
|
||||
this->vli.index = ALL_GROUP;
|
||||
|
||||
DoCommandP(0, group, 0, CMD_DELETE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_DELETE));
|
||||
this->group_confirm = this->vli.index;
|
||||
ShowQuery(STR_QUERY_GROUP_DELETE_CAPTION, STR_GROUP_DELETE_QUERY_TEXT, this, DeleteGroupCallback);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -621,14 +670,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
|
||||
@@ -669,12 +750,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;
|
||||
}
|
||||
|
||||
@@ -743,7 +831,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;
|
||||
@@ -760,7 +848,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) {
|
||||
|
||||
Reference in New Issue
Block a user