src/bridge_gui.cpp
changeset 9365 95e9cbc0257e
parent 9320 4e17d11b92e4
child 9367 a643c88b2791
equal deleted inserted replaced
9364:5476e1a21517 9365:95e9cbc0257e
   118 	uint32 type;
   118 	uint32 type;
   119 	GUIBridgeList *bridges;
   119 	GUIBridgeList *bridges;
   120 
   120 
   121 	void BuildBridge(uint8 i)
   121 	void BuildBridge(uint8 i)
   122 	{
   122 	{
   123 		DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->sort_list[i].index,
   123 		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));
   124 				CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE));
   125 	}
   125 	}
   126 
   126 
   127 	/** Sort the builable bridges */
   127 	/** Sort the builable bridges */
   128 	void SortBridgeList()
   128 	void SortBridgeList()
   129 	{
   129 	{
   130 		/* Skip sorting if resort bit is not set */
   130 		/* Skip sorting if resort bit is not set */
   131 		if (!(bridges->flags & VL_RESORT)) return;
   131 		if (!(bridges->flags & VL_RESORT)) return;
   132 
   132 
   133 		qsort(this->bridges->sort_list, this->bridges->list_length, sizeof(this->bridges->sort_list[0]), _bridge_sorter[_bridge_sorting.criteria]);
   133 		qsort(this->bridges->Begin(), this->bridges->Length(), sizeof(this->bridges->Begin()), _bridge_sorter[_bridge_sorting.criteria]);
   134 
   134 
   135 		/* Display the current sort variant */
   135 		/* Display the current sort variant */
   136 		this->widget[BBSW_DROPDOWN_CRITERIA].data = _bridge_sort_listing[this->bridges->sort_type];
   136 		this->widget[BBSW_DROPDOWN_CRITERIA].data = _bridge_sort_listing[this->bridges->sort_type];
   137 
   137 
   138 		bridges->flags &= ~VL_RESORT;
   138 		bridges->flags &= ~VL_RESORT;
   153 
   153 
   154 		/* Change the data, or the caption of the gui. Set it to road or rail, accordingly */
   154 		/* 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;
   155 		this->widget[BBSW_CAPTION].data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE;
   156 
   156 
   157 		this->resize.step_height = 22;
   157 		this->resize.step_height = 22;
   158 		this->vscroll.count = bl->list_length;
   158 		this->vscroll.count = bl->Length();
   159 
   159 
   160 		if (this->last_size <= 4) {
   160 		if (this->last_size <= 4) {
   161 			this->vscroll.cap = 4;
   161 			this->vscroll.cap = 4;
   162 		} else {
   162 		} else {
   163 			/* Resize the bridge selection window if we used a bigger one the last time */
   163 			/* Resize the bridge selection window if we used a bigger one the last time */
   169 		this->FindWindowPlacementAndResize(desc);
   169 		this->FindWindowPlacementAndResize(desc);
   170 	}
   170 	}
   171 
   171 
   172 	~BuildBridgeWindow()
   172 	~BuildBridgeWindow()
   173 	{
   173 	{
   174 		free(this->bridges->sort_list);
       
   175 		delete bridges;
   174 		delete bridges;
   176 	}
   175 	}
   177 
   176 
   178 	virtual void OnPaint()
   177 	virtual void OnPaint()
   179 	{
   178 	{
   181 
   180 
   182 		this->DrawSortButtonState(BBSW_DROPDOWN_ORDER, (this->bridges->flags & VL_DESC) ? SBS_DOWN : SBS_UP);
   181 		this->DrawSortButtonState(BBSW_DROPDOWN_ORDER, (this->bridges->flags & VL_DESC) ? SBS_DOWN : SBS_UP);
   183 
   182 
   184 		uint y = this->widget[BBSW_BRIDGE_LIST].top + 2;
   183 		uint y = this->widget[BBSW_BRIDGE_LIST].top + 2;
   185 
   184 
   186 		for (int i = this->vscroll.pos; (i < (this->vscroll.cap + this->vscroll.pos)) && (i < this->bridges->list_length); i++) {
   185 		for (int i = this->vscroll.pos; (i < (this->vscroll.cap + this->vscroll.pos)) && (i < (int)this->bridges->Length()); i++) {
   187 			const BridgeSpec *b = this->bridges->sort_list[i].spec;
   186 			const BridgeSpec *b = this->bridges->Get(i)->spec;
   188 
   187 
   189 			SetDParam(2, this->bridges->sort_list[i].cost);
   188 			SetDParam(2, this->bridges->Get(i)->cost);
   190 			SetDParam(1, b->speed * 10 / 16);
   189 			SetDParam(1, b->speed * 10 / 16);
   191 			SetDParam(0, b->material);
   190 			SetDParam(0, b->material);
   192 
   191 
   193 			DrawSprite(b->sprite, b->pal, 3, y);
   192 			DrawSprite(b->sprite, b->pal, 3, y);
   194 			DrawString(44, y, STR_500D, TC_FROMSTRING);
   193 			DrawString(44, y, STR_500D, TC_FROMSTRING);
   198 	}
   197 	}
   199 
   198 
   200 	virtual EventState OnKeyPress(uint16 key, uint16 keycode)
   199 	virtual EventState OnKeyPress(uint16 key, uint16 keycode)
   201 	{
   200 	{
   202 		const uint8 i = keycode - '1';
   201 		const uint8 i = keycode - '1';
   203 		if (i < 9 && i < this->bridges->list_length) {
   202 		if (i < 9 && i < this->bridges->Length()) {
   204 			/* Build the requested bridge */
   203 			/* Build the requested bridge */
   205 			this->BuildBridge(i);
   204 			this->BuildBridge(i);
   206 			delete this;
   205 			delete this;
   207 			return ES_HANDLED;
   206 			return ES_HANDLED;
   208 		}
   207 		}
   215 			default: break;
   214 			default: break;
   216 			case BBSW_BRIDGE_LIST: {
   215 			case BBSW_BRIDGE_LIST: {
   217 				uint i = ((int)pt.y - this->widget[BBSW_BRIDGE_LIST].top) / this->resize.step_height;
   216 				uint i = ((int)pt.y - this->widget[BBSW_BRIDGE_LIST].top) / this->resize.step_height;
   218 				if (i < this->vscroll.cap) {
   217 				if (i < this->vscroll.cap) {
   219 					i += this->vscroll.pos;
   218 					i += this->vscroll.pos;
   220 					if (i < this->bridges->list_length) {
   219 					if (i < this->bridges->Length()) {
   221 						this->BuildBridge(i);
   220 						this->BuildBridge(i);
   222 						delete this;
   221 						delete this;
   223 					}
   222 					}
   224 				}
   223 				}
   225 			} break;
   224 			} break;
   252 
   251 
   253 	virtual void OnResize(Point new_size, Point delta)
   252 	virtual void OnResize(Point new_size, Point delta)
   254 	{
   253 	{
   255 		this->vscroll.cap += delta.y / (int)this->resize.step_height;
   254 		this->vscroll.cap += delta.y / (int)this->resize.step_height;
   256 		this->widget[BBSW_BRIDGE_LIST].data = (this->vscroll.cap << 8) + 1;
   255 		this->widget[BBSW_BRIDGE_LIST].data = (this->vscroll.cap << 8) + 1;
   257 		SetVScrollCount(this, this->bridges->list_length);
   256 		SetVScrollCount(this, this->bridges->Length());
   258 
   257 
   259 		this->last_size = this->vscroll.cap;
   258 		this->last_size = this->vscroll.cap;
   260 	}
   259 	}
   261 };
   260 };
   262 
   261 
   282 	WDP_AUTO, WDP_AUTO, 200, 114, 200, 114,
   281 	WDP_AUTO, WDP_AUTO, 200, 114, 200, 114,
   283 	WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
   282 	WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
   284 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
   283 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
   285 	_build_bridge_widgets,
   284 	_build_bridge_widgets,
   286 };
   285 };
   287 
       
   288 /**
       
   289  * Add a buildable bridge to the list.
       
   290  *  If the list is empty a new one is created.
       
   291  *
       
   292  * @param bl The list which we want to manage
       
   293  * @param item The item to add
       
   294  * @return The pointer to the list
       
   295  */
       
   296 static GUIBridgeList *PushBridgeList(GUIBridgeList *bl, BuildBridgeData item)
       
   297 {
       
   298 	if (bl == NULL) {
       
   299 		/* Create the list if needed */
       
   300 		bl = new GUIBridgeList();
       
   301 		bl->flags |= VL_RESORT;
       
   302 		if (_bridge_sorting.order) bl->flags |= VL_DESC;
       
   303 		bl->list_length = 1;
       
   304 		bl->sort_type = _bridge_sorting.criteria;
       
   305 	} else {
       
   306 		/* Resize the list */
       
   307 		bl->list_length++;
       
   308 	}
       
   309 
       
   310 	bl->sort_list = ReallocT(bl->sort_list, bl->list_length);
       
   311 
       
   312 	bl->sort_list[bl->list_length - 1] = item;
       
   313 
       
   314 	return bl;
       
   315 }
       
   316 
   286 
   317 /**
   287 /**
   318  * Prepare the data for the build a bridge window.
   288  * Prepare the data for the build a bridge window.
   319  *  If we can't build a bridge under the given conditions
   289  *  If we can't build a bridge under the given conditions
   320  *  show an error message.
   290  *  show an error message.
   348 		 * length of the middle parts of the bridge */
   318 		 * length of the middle parts of the bridge */
   349 		const uint bridge_len = GetTunnelBridgeLength(start, end);
   319 		const uint bridge_len = GetTunnelBridgeLength(start, end);
   350 		/* total length of bridge */
   320 		/* total length of bridge */
   351 		const uint tot_bridgedata_len = CalcBridgeLenCostFactor(bridge_len + 2);
   321 		const uint tot_bridgedata_len = CalcBridgeLenCostFactor(bridge_len + 2);
   352 
   322 
       
   323 		bl = new GUIBridgeList();
       
   324 
   353 		/* loop for all bridgetypes */
   325 		/* loop for all bridgetypes */
   354 		for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) {
   326 		for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) {
   355 			if (CheckBridge_Stuff(brd_type, bridge_len)) {
   327 			if (CheckBridge_Stuff(brd_type, bridge_len)) {
   356 				/* bridge is accepted, add to list */
   328 				/* bridge is accepted, add to list */
   357 				BuildBridgeData item;
   329 				BuildBridgeData *item = bl->Append();
   358 				item.index = brd_type;
   330 				item->index = brd_type;
   359 				item.spec = GetBridgeSpec(brd_type);
   331 				item->spec = GetBridgeSpec(brd_type);
   360 				/* Add to terraforming & bulldozing costs the cost of the
   332 				/* Add to terraforming & bulldozing costs the cost of the
   361 				 * bridge itself (not computed with DC_QUERY_COST) */
   333 				 * bridge itself (not computed with DC_QUERY_COST) */
   362 				item.cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * item.spec->price) >> 8);
   334 				item->cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * item->spec->price) >> 8);
   363 				bl = PushBridgeList(bl, item);
       
   364 			}
   335 			}
   365 		}
   336 		}
   366 	}
   337 	}
   367 
   338 
   368 	if (bl != NULL) {
   339 	if (bl != NULL && bl->Length() != 0) {
   369 		new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl);
   340 		new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl);
   370 	} else {
   341 	} else {
       
   342 		if (bl != NULL) delete bl;
   371 		ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
   343 		ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
   372 	}
   344 	}
   373 }
   345 }