src/bridge_gui.cpp
changeset 9367 a643c88b2791
parent 9365 95e9cbc0257e
child 9370 7e64238f2dbd
equal deleted inserted replaced
9366:2d029154291f 9367:a643c88b2791
    20 #include "sortlist_type.h"
    20 #include "sortlist_type.h"
    21 #include "widgets/dropdown_func.h"
    21 #include "widgets/dropdown_func.h"
    22 
    22 
    23 #include "table/strings.h"
    23 #include "table/strings.h"
    24 
    24 
    25 /* Save the sorting during runtime */
       
    26 static Listing _bridge_sorting = {false, 0};
       
    27 
       
    28 /**
    25 /**
    29  * Carriage for the data we need if we want to build a bridge
    26  * Carriage for the data we need if we want to build a bridge
    30  */
    27  */
    31 struct BuildBridgeData {
    28 struct BuildBridgeData {
    32 	BridgeType index;
    29 	BridgeType index;
    33 	const BridgeSpec *spec;
    30 	const BridgeSpec *spec;
    34 	Money cost;
    31 	Money cost;
    35 };
    32 };
    36 
    33 
    37 typedef GUIList<BuildBridgeData> GUIBridgeList;
    34 typedef GUIList<BuildBridgeData> GUIBridgeList;
    38 
       
    39 /** Sort the bridges by their index */
       
    40 static int CDECL BridgeIndexSorter(const void *a, const void *b)
       
    41 {
       
    42 	const BuildBridgeData* ba = (BuildBridgeData*)a;
       
    43 	const BuildBridgeData* bb = (BuildBridgeData*)b;
       
    44 	int r = ba->index - bb->index;
       
    45 
       
    46 	return (_bridge_sorting.order) ? -r : r;
       
    47 }
       
    48 
       
    49 /** Sort the bridges by their price */
       
    50 static int CDECL BridgePriceSorter(const void *a, const void *b)
       
    51 {
       
    52 	const BuildBridgeData* ba = (BuildBridgeData*)a;
       
    53 	const BuildBridgeData* bb = (BuildBridgeData*)b;
       
    54 	int r = ba->cost - bb->cost;
       
    55 
       
    56 	return (_bridge_sorting.order) ? -r : r;
       
    57 }
       
    58 
       
    59 /** Sort the bridges by their maximum speed */
       
    60 static int CDECL BridgeSpeedSorter(const void *a, const void *b)
       
    61 {
       
    62 	const BuildBridgeData* ba = (BuildBridgeData*)a;
       
    63 	const BuildBridgeData* bb = (BuildBridgeData*)b;
       
    64 	int r = ba->spec->speed - bb->spec->speed;
       
    65 
       
    66 	return (_bridge_sorting.order) ? -r : r;
       
    67 }
       
    68 
       
    69 typedef int CDECL BridgeSortListingTypeFunction(const void*, const void*);
       
    70 
       
    71 /* Availible bridge sorting functions */
       
    72 static BridgeSortListingTypeFunction* const _bridge_sorter[] = {
       
    73 	&BridgeIndexSorter,
       
    74 	&BridgePriceSorter,
       
    75 	&BridgeSpeedSorter
       
    76 };
       
    77 
       
    78 /* Names of the sorting functions */
       
    79 static const StringID _bridge_sort_listing[] = {
       
    80 	STR_SORT_BY_NUMBER,
       
    81 	STR_ENGINE_SORT_COST,
       
    82 	STR_SORT_BY_MAX_SPEED,
       
    83 	INVALID_STRING_ID
       
    84 };
       
    85 
    35 
    86 /**
    36 /**
    87  * Callback executed after a build Bridge CMD has been called
    37  * Callback executed after a build Bridge CMD has been called
    88  *
    38  *
    89  * @param scucess True if the build succeded
    39  * @param scucess True if the build succeded
   107 	BBSW_RESIZEBOX
    57 	BBSW_RESIZEBOX
   108 };
    58 };
   109 
    59 
   110 class BuildBridgeWindow : public Window {
    60 class BuildBridgeWindow : public Window {
   111 private:
    61 private:
   112 	/* The last size of the build bridge window
    62 	/* Runtime saved values */
   113 	 * is saved during runtime */
       
   114 	static uint last_size;
    63 	static uint last_size;
   115 
    64 	static Listing last_sorting;
       
    65 
       
    66 	/* Constants for sorting the bridges */
       
    67 	static const StringID sorter_names[];
       
    68 	static const GUIBridgeList::SortFunction *const sorter_funcs[];
       
    69 
       
    70 	/* Internal variables */
   116 	TileIndex start_tile;
    71 	TileIndex start_tile;
   117 	TileIndex end_tile;
    72 	TileIndex end_tile;
   118 	uint32 type;
    73 	uint32 type;
   119 	GUIBridgeList *bridges;
    74 	GUIBridgeList *bridges;
   120 
    75 
       
    76 	/** Sort the bridges by their index */
       
    77 	static int BridgeIndexSorter(const BuildBridgeData *a, const BuildBridgeData *b)
       
    78 	{
       
    79 		return a->index - b->index;
       
    80 	}
       
    81 
       
    82 	/** Sort the bridges by their price */
       
    83 	static int BridgePriceSorter(const BuildBridgeData *a, const BuildBridgeData *b)
       
    84 	{
       
    85 		return a->cost - b->cost;
       
    86 	}
       
    87 
       
    88 	/** Sort the bridges by their maximum speed */
       
    89 	static int BridgeSpeedSorter(const BuildBridgeData *a, const BuildBridgeData *b)
       
    90 	{
       
    91 		return a->spec->speed - b->spec->speed;
       
    92 	}
       
    93 
   121 	void BuildBridge(uint8 i)
    94 	void BuildBridge(uint8 i)
   122 	{
    95 	{
   123 		DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index,
    96 		DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index,
   124 				CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE));
    97 				CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE));
   125 	}
    98 	}
   126 
    99 
   127 	/** Sort the builable bridges */
   100 	/** Sort the builable bridges */
   128 	void SortBridgeList()
   101 	void SortBridgeList()
   129 	{
   102 	{
   130 		/* Skip sorting if resort bit is not set */
   103 		this->bridges->Sort();
   131 		if (!(bridges->flags & VL_RESORT)) return;
       
   132 
       
   133 		qsort(this->bridges->Begin(), this->bridges->Length(), sizeof(this->bridges->Begin()), _bridge_sorter[_bridge_sorting.criteria]);
       
   134 
   104 
   135 		/* Display the current sort variant */
   105 		/* Display the current sort variant */
   136 		this->widget[BBSW_DROPDOWN_CRITERIA].data = _bridge_sort_listing[this->bridges->sort_type];
   106 		this->widget[BBSW_DROPDOWN_CRITERIA].data = this->sorter_names[this->bridges->SortType()];
   137 
       
   138 		bridges->flags &= ~VL_RESORT;
       
   139 
   107 
   140 		/* Set the modified widgets dirty */
   108 		/* Set the modified widgets dirty */
   141 		this->InvalidateWidget(BBSW_DROPDOWN_CRITERIA);
   109 		this->InvalidateWidget(BBSW_DROPDOWN_CRITERIA);
   142 		this->InvalidateWidget(BBSW_BRIDGE_LIST);
   110 		this->InvalidateWidget(BBSW_BRIDGE_LIST);
   143 	}
   111 	}
   147 		start_tile(start),
   115 		start_tile(start),
   148 		end_tile(end),
   116 		end_tile(end),
   149 		type(br_type),
   117 		type(br_type),
   150 		bridges(bl)
   118 		bridges(bl)
   151 	{
   119 	{
       
   120 		this->bridges->SetListing(this->last_sorting);
       
   121 		this->bridges->SetSortFuncs(this->sorter_funcs);
   152 		this->SortBridgeList();
   122 		this->SortBridgeList();
   153 
   123 
   154 		/* Change the data, or the caption of the gui. Set it to road or rail, accordingly */
   124 		/* Change the data, or the caption of the gui. Set it to road or rail, accordingly */
   155 		this->widget[BBSW_CAPTION].data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE;
   125 		this->widget[BBSW_CAPTION].data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE;
   156 
   126 
   169 		this->FindWindowPlacementAndResize(desc);
   139 		this->FindWindowPlacementAndResize(desc);
   170 	}
   140 	}
   171 
   141 
   172 	~BuildBridgeWindow()
   142 	~BuildBridgeWindow()
   173 	{
   143 	{
       
   144 		this->last_sorting = this->bridges->GetListing();
       
   145 
   174 		delete bridges;
   146 		delete bridges;
   175 	}
   147 	}
   176 
   148 
   177 	virtual void OnPaint()
   149 	virtual void OnPaint()
   178 	{
   150 	{
   222 					}
   194 					}
   223 				}
   195 				}
   224 			} break;
   196 			} break;
   225 
   197 
   226 			case BBSW_DROPDOWN_ORDER:
   198 			case BBSW_DROPDOWN_ORDER:
   227 				/* Revers the sort order */
   199 				this->bridges->ToggleSortOrder();
   228 				this->bridges->flags ^= VL_DESC;
   200 				this->SetDirty();
   229 				_bridge_sorting.order = !_bridge_sorting.order;
       
   230 
       
   231 				this->bridges->flags |= VL_RESORT;
       
   232 				this->SortBridgeList();
       
   233 				break;
   201 				break;
   234 
   202 
   235 			case BBSW_DROPDOWN_CRITERIA:
   203 			case BBSW_DROPDOWN_CRITERIA:
   236 				ShowDropDownMenu(this, _bridge_sort_listing, bridges->sort_type, BBSW_DROPDOWN_CRITERIA, 0, 0);
   204 				ShowDropDownMenu(this, this->sorter_names, this->bridges->SortType(), BBSW_DROPDOWN_CRITERIA, 0, 0);
   237 				break;
   205 				break;
   238 		}
   206 		}
   239 	}
   207 	}
   240 
   208 
   241 	virtual void OnDropdownSelect(int widget, int index)
   209 	virtual void OnDropdownSelect(int widget, int index)
   242 	{
   210 	{
   243 		if (widget == BBSW_DROPDOWN_CRITERIA && this->bridges->sort_type != index) {
   211 		if (widget == BBSW_DROPDOWN_CRITERIA && this->bridges->SortType() != index) {
   244 			this->bridges->sort_type = index;
   212 			this->bridges->SetSortType(index);
   245 			_bridge_sorting.criteria = index;
   213 
   246 
       
   247 			this->bridges->flags |= VL_RESORT;
       
   248 			this->SortBridgeList();
   214 			this->SortBridgeList();
   249 		}
   215 		}
   250 	}
   216 	}
   251 
   217 
   252 	virtual void OnResize(Point new_size, Point delta)
   218 	virtual void OnResize(Point new_size, Point delta)
   259 	}
   225 	}
   260 };
   226 };
   261 
   227 
   262 /* Set the default size of the Build Bridge Window */
   228 /* Set the default size of the Build Bridge Window */
   263 uint BuildBridgeWindow::last_size = 4;
   229 uint BuildBridgeWindow::last_size = 4;
       
   230 /* Set the default sorting for the bridges */
       
   231 Listing BuildBridgeWindow::last_sorting = {false, 0};
       
   232 
       
   233 /* Availible bridge sorting functions */
       
   234 GUIBridgeList::SortFunction* const BuildBridgeWindow::sorter_funcs[] = {
       
   235 	&BridgeIndexSorter,
       
   236 	&BridgePriceSorter,
       
   237 	&BridgeSpeedSorter
       
   238 };
       
   239 
       
   240 /* Names of the sorting functions */
       
   241 const StringID BuildBridgeWindow::sorter_names[] = {
       
   242 	STR_SORT_BY_NUMBER,
       
   243 	STR_ENGINE_SORT_COST,
       
   244 	STR_SORT_BY_MAX_SPEED,
       
   245 	INVALID_STRING_ID
       
   246 };
   264 
   247 
   265 /* Widget definition for the rail bridge selection window */
   248 /* Widget definition for the rail bridge selection window */
   266 static const Widget _build_bridge_widgets[] = {
   249 static const Widget _build_bridge_widgets[] = {
   267 {   WWT_CLOSEBOX,   RESIZE_NONE,  7,   0,  10,   0,  13, STR_00C5,                    STR_018B_CLOSE_WINDOW},            // BBSW_CLOSEBOX
   250 {   WWT_CLOSEBOX,   RESIZE_NONE,  7,   0,  10,   0,  13, STR_00C5,                    STR_018B_CLOSE_WINDOW},            // BBSW_CLOSEBOX
   268 {    WWT_CAPTION,   RESIZE_NONE,  7,  11, 199,   0,  13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},  // BBSW_CAPTION
   251 {    WWT_CAPTION,   RESIZE_NONE,  7,  11, 199,   0,  13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},  // BBSW_CAPTION