src/misc_gui.cpp
changeset 9265 ead232da4056
parent 9228 defd5984cb60
child 9272 e64b518a7b54
equal deleted inserted replaced
9264:9380b4a14c92 9265:ead232da4056
   326 {
   326 {
   327 	DeleteWindowById(WC_GAME_OPTIONS, 0);
   327 	DeleteWindowById(WC_GAME_OPTIONS, 0);
   328 	new AboutWindow();
   328 	new AboutWindow();
   329 }
   329 }
   330 
   330 
   331 static uint64 _errmsg_decode_params[20];
       
   332 static StringID _errmsg_message_1, _errmsg_message_2;
       
   333 static uint _errmsg_duration;
       
   334 
       
   335 
       
   336 static const Widget _errmsg_widgets[] = {
   331 static const Widget _errmsg_widgets[] = {
   337 {   WWT_CLOSEBOX,   RESIZE_NONE,     4,     0,    10,     0,    13, STR_00C5,         STR_018B_CLOSE_WINDOW},
   332 {   WWT_CLOSEBOX,   RESIZE_NONE,     4,     0,    10,     0,    13, STR_00C5,         STR_018B_CLOSE_WINDOW},
   338 {    WWT_CAPTION,   RESIZE_NONE,     4,    11,   239,     0,    13, STR_00B2_MESSAGE, STR_NULL},
   333 {    WWT_CAPTION,   RESIZE_NONE,     4,    11,   239,     0,    13, STR_00B2_MESSAGE, STR_NULL},
   339 {      WWT_PANEL,   RESIZE_NONE,     4,     0,   239,    14,    45, 0x0,              STR_NULL},
   334 {      WWT_PANEL,   RESIZE_NONE,     4,     0,   239,    14,    45, 0x0,              STR_NULL},
   340 {    WIDGETS_END},
   335 {    WIDGETS_END},
   345 {    WWT_CAPTION,   RESIZE_NONE,     4,    11,   333,     0,    13, STR_00B3_MESSAGE_FROM, STR_NULL},
   340 {    WWT_CAPTION,   RESIZE_NONE,     4,    11,   333,     0,    13, STR_00B3_MESSAGE_FROM, STR_NULL},
   346 {      WWT_PANEL,   RESIZE_NONE,     4,     0,   333,    14,   136, 0x0,                   STR_NULL},
   341 {      WWT_PANEL,   RESIZE_NONE,     4,     0,   333,    14,   136, 0x0,                   STR_NULL},
   347 {   WIDGETS_END},
   342 {   WIDGETS_END},
   348 };
   343 };
   349 
   344 
   350 static void ErrmsgWndProc(Window *w, WindowEvent *e)
   345 struct ErrmsgWindow : public Window {
   351 {
   346 private:
   352 	switch (e->event) {
   347 	uint duration;
   353 		case WE_PAINT:
   348 	uint64 decode_params[20];
   354 			CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params));
   349 	StringID message_1;
   355 			DrawWindowWidgets(w);
   350 	StringID message_2;
   356 			CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params));
   351 
   357 
   352 public:
   358 			/* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages.
   353 	ErrmsgWindow(Point pt, int width, int height, StringID msg1, StringID msg2, const Widget *widget) : Window(pt.x, pt.y, width, height, NULL, WC_ERRMSG, widget)
   359 			* If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything
   354 	{
   360 			*/
   355 		this->duration = _patches.errmsg_duration;
   361 			SwitchToErrorRefStack();
   356 		CopyOutDParam(this->decode_params, 0, lengthof(this->decode_params));
   362 			RewindTextRefStack();
   357 		this->message_1 = msg1;
   363 
   358 		this->message_2 = msg2;
   364 			if (!IsWindowOfPrototype(w, _errmsg_face_widgets)) {
   359 		this->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET;
   365 				DrawStringMultiCenter(
   360 		this->FindWindowPlacementAndResize(width, height);
   366 					120,
   361 	}
   367 					(_errmsg_message_1 == INVALID_STRING_ID ? 25 : 15),
   362 
   368 					_errmsg_message_2,
   363 	virtual void OnPaint()
   369 					w->width - 2);
   364 	{
   370 				if (_errmsg_message_1 != INVALID_STRING_ID) {
   365 		static int y[][3] = {
   371 					DrawStringMultiCenter(
   366 			{15, 25, 30}, // _errmsg_widgets
   372 						120,
   367 			{45, 65, 90}, // _errmsg_face_widgets
   373 						30,
   368 		};
   374 						_errmsg_message_1,
   369 
   375 						w->width - 2);
   370 		CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
   376 				}
   371 		DrawWindowWidgets(this);
   377 			} else {
   372 		CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
   378 				const Player *p = GetPlayer((PlayerID)GetDParamX(_errmsg_decode_params,2));
   373 
   379 				DrawPlayerFace(p->face, p->player_color, 2, 16);
   374 		/* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages.
   380 
   375 		* If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything
   381 				DrawStringMultiCenter(
   376 		*/
   382 					214,
   377 		SwitchToErrorRefStack();
   383 					(_errmsg_message_1 == INVALID_STRING_ID ? 65 : 45),
   378 		RewindTextRefStack();
   384 					_errmsg_message_2,
   379 
   385 					w->width - 2);
   380 		byte i = 0;
   386 				if (_errmsg_message_1 != INVALID_STRING_ID) {
   381 		if (IsWindowOfPrototype(this, _errmsg_face_widgets)) {
   387 					DrawStringMultiCenter(
   382 			const Player *p = GetPlayer((PlayerID)GetDParamX(this->decode_params, 2));
   388 						214,
   383 			DrawPlayerFace(p->face, p->player_color, 2, 16);
   389 						90,
   384 			i = 1;
   390 						_errmsg_message_1,
   385 		}
   391 						w->width - 2);
   386 
   392 				}
   387 		byte j = (this->message_1 == INVALID_STRING_ID) ? 1 : 0;
   393 			}
   388 		DrawStringMultiCenter(this->width - 120, y[i][j], this->message_2, this->width - 2);
   394 
   389 		if (j == 0) {
   395 			/* Switch back to the normal text ref. stack for NewGRF texts */
   390 			DrawStringMultiCenter(this->width - 120, y[i][2], this->message_1, this->width - 2);
   396 			SwitchToNormalRefStack();
   391 		}
   397 			break;
   392 
   398 
   393 		/* Switch back to the normal text ref. stack for NewGRF texts */
   399 		case WE_MOUSELOOP:
   394 		SwitchToNormalRefStack();
   400 			if (_right_button_down) delete w;
   395 	}
   401 			break;
   396 
   402 
   397 	virtual void OnMouseLoop()
   403 		case WE_100_TICKS:
   398 	{
   404 			if (--_errmsg_duration == 0) delete w;
   399 		if (_right_button_down) delete this;
   405 			break;
   400 	}
   406 
   401 
   407 		case WE_DESTROY:
   402 	virtual void OnHundredthTick()
   408 			SetRedErrorSquare(0);
   403 	{
   409 			extern StringID _switch_mode_errorstr;
   404 		if (--this->duration == 0) delete this;
   410 			_switch_mode_errorstr = INVALID_STRING_ID;
   405 	}
   411 			break;
   406 
   412 
   407 	~ErrmsgWindow()
   413 		case WE_KEYPRESS:
   408 	{
   414 			if (e->we.keypress.keycode == WKC_SPACE) {
   409 		SetRedErrorSquare(0);
   415 				/* Don't continue. */
   410 		extern StringID _switch_mode_errorstr;
   416 				e->we.keypress.cont = false;
   411 		_switch_mode_errorstr = INVALID_STRING_ID;
   417 				delete w;
   412 	}
   418 			}
   413 
   419 			break;
   414 	virtual bool OnKeyPress(uint16 key, uint16 keycode)
   420 	}
   415 	{
   421 }
   416 		if (keycode != WKC_SPACE) return true;
       
   417 		delete this;
       
   418 		return false;
       
   419 	}
       
   420 };
   422 
   421 
   423 void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y)
   422 void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y)
   424 {
   423 {
   425 	DeleteWindowById(WC_ERRMSG, 0);
   424 	DeleteWindowById(WC_ERRMSG, 0);
   426 
   425 
       
   426 	if (!_patches.errmsg_duration) return;
       
   427 
   427 	if (msg_2 == STR_NULL) msg_2 = STR_EMPTY;
   428 	if (msg_2 == STR_NULL) msg_2 = STR_EMPTY;
   428 
       
   429 	_errmsg_message_1 = msg_1;
       
   430 	_errmsg_message_2 = msg_2;
       
   431 	CopyOutDParam(_errmsg_decode_params, 0, lengthof(_errmsg_decode_params));
       
   432 	_errmsg_duration = _patches.errmsg_duration;
       
   433 	if (!_errmsg_duration) return;
       
   434 
   429 
   435 	Point pt;
   430 	Point pt;
   436 	const ViewPort *vp;
   431 	const ViewPort *vp;
   437 	Window *w;
   432 
   438 
   433 	if (msg_1 != STR_013B_OWNED_BY || GetDParam(2) >= 8) {
   439 	if (_errmsg_message_1 != STR_013B_OWNED_BY || GetDParamX(_errmsg_decode_params,2) >= 8) {
       
   440 		if ((x | y) != 0) {
   434 		if ((x | y) != 0) {
   441 			pt = RemapCoords2(x, y);
   435 			pt = RemapCoords2(x, y);
   442 			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
   436 			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
   443 
   437 
   444 			/* move x pos to opposite corner */
   438 			/* move x pos to opposite corner */
   451 
   445 
   452 		} else {
   446 		} else {
   453 			pt.x = (_screen.width - 240) >> 1;
   447 			pt.x = (_screen.width - 240) >> 1;
   454 			pt.y = (_screen.height - 46) >> 1;
   448 			pt.y = (_screen.height - 46) >> 1;
   455 		}
   449 		}
   456 		w = new Window(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets);
   450 		new ErrmsgWindow(pt, 240, 46, msg_1, msg_2, _errmsg_widgets);
   457 	} else {
   451 	} else {
   458 		if ((x | y) != 0) {
   452 		if ((x | y) != 0) {
   459 			pt = RemapCoords2(x, y);
   453 			pt = RemapCoords2(x, y);
   460 			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
   454 			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
   461 			pt.x = Clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (334/2), 0, _screen.width - 334);
   455 			pt.x = Clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (334/2), 0, _screen.width - 334);
   462 			pt.y = Clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (137/2), 22, _screen.height - 137);
   456 			pt.y = Clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (137/2), 22, _screen.height - 137);
   463 		} else {
   457 		} else {
   464 			pt.x = (_screen.width - 334) >> 1;
   458 			pt.x = (_screen.width - 334) >> 1;
   465 			pt.y = (_screen.height - 137) >> 1;
   459 			pt.y = (_screen.height - 137) >> 1;
   466 		}
   460 		}
   467 		w = new Window(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets);
   461 		new ErrmsgWindow(pt, 334, 137, msg_1, msg_2, _errmsg_face_widgets);
   468 	}
   462 	}
   469 
   463 }
   470 	w->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET;
       
   471 }
       
   472 
       
   473 
   464 
   474 void ShowEstimatedCostOrIncome(Money cost, int x, int y)
   465 void ShowEstimatedCostOrIncome(Money cost, int x, int y)
   475 {
   466 {
   476 	StringID msg = STR_0805_ESTIMATED_COST;
   467 	StringID msg = STR_0805_ESTIMATED_COST;
   477 
   468