news_gui.c
changeset 1688 787400219027
parent 1648 747061dca705
child 1891 92a3b0aa0946
equal deleted inserted replaced
1687:2265b1f3de0b 1688:787400219027
     1 #include "stdafx.h"
     1 #include "stdafx.h"
     2 #include "ttd.h"
     2 #include "ttd.h"
     3 #include "strings.h"
     3 #include "strings.h"
       
     4 #include "table/sprites.h"
     4 #include "table/strings.h"
     5 #include "table/strings.h"
     5 #include "window.h"
     6 #include "window.h"
     6 #include "gui.h"
     7 #include "gui.h"
     7 #include "viewport.h"
     8 #include "viewport.h"
     8 #include "gfx.h"
     9 #include "gfx.h"
   338 	0,
   339 	0,
   339 	0,
   340 	0,
   340 	0
   341 	0
   341 };
   342 };
   342 
   343 
       
   344 /** Get the value of an item of the news-display settings. This is
       
   345  * a little tricky since on/off/summary must use 2 bits to store the value
       
   346  * @param item the item whose value is requested
       
   347  * @return return the found value which is between 0-2
       
   348  */
       
   349 static inline byte GetNewsDisplayValue(byte item)
       
   350 {
       
   351 	assert(item < 10 && ((_news_display_opt >> (item * 2)) & 0x3) <= 2);
       
   352 	return (_news_display_opt >> (item * 2)) & 0x3;
       
   353 }
       
   354 
       
   355 /** Set the value of an item in the news-display settings. This is
       
   356  * a little tricky since on/off/summary must use 2 bits to store the value
       
   357  * @param item the item whose value is being set
       
   358  * @param val new value
       
   359  */
       
   360 static inline void SetNewsDisplayValue(byte item, byte val)
       
   361 {
       
   362 	assert(item < 10 && val <= 2);
       
   363 	item *= 2;
       
   364 	CLRBIT(_news_display_opt, item);
       
   365 	CLRBIT(_news_display_opt, item + 1);
       
   366 	_news_display_opt |= val << item;
       
   367 }
       
   368 
   343 // open up an own newspaper window for the news item
   369 // open up an own newspaper window for the news item
   344 static void ShowNewspaper(NewsItem *ni)
   370 static void ShowNewspaper(NewsItem *ni)
   345 {
   371 {
   346 	Window *w;
   372 	Window *w;
   347 	int sound;
   373 	int sound;
   390 // show news item in the ticker
   416 // show news item in the ticker
   391 static void ShowTicker(const NewsItem *ni)
   417 static void ShowTicker(const NewsItem *ni)
   392 {
   418 {
   393 	Window *w;
   419 	Window *w;
   394 
   420 
   395 	SndPlayFx(SND_16_MORSE);
   421 	if (_news_ticker_sound) SndPlayFx(SND_16_MORSE);
       
   422 
   396 	_statusbar_news_item = *ni;
   423 	_statusbar_news_item = *ni;
   397 	w = FindWindowById(WC_STATUS_BAR, 0);
   424 	w = FindWindowById(WC_STATUS_BAR, 0);
   398 	if (w != NULL)
   425 	if (w != NULL)
   399 		WP(w, def_d).data_1 = 360;
   426 		WP(w, def_d).data_1 = 360;
   400 }
   427 }
   446 
   473 
   447 		// execute the validation function to see if this item is still valid
   474 		// execute the validation function to see if this item is still valid
   448 		if ( ni->isValid != NULL && !ni->isValid(ni->data_a, ni->data_b) )
   475 		if ( ni->isValid != NULL && !ni->isValid(ni->data_a, ni->data_b) )
   449 			return;
   476 			return;
   450 
   477 
   451 		// show newspaper or send to ticker?
   478   	switch (GetNewsDisplayValue(ni->type)) {
   452 		if (!HASBIT(_news_display_opt, ni->type) && !(ni->flags & NF_FORCE_BIG))
   479   	case 0: { /* Off - show nothing only a small reminder in the status bar */
   453 			ShowTicker(ni);
   480   		Window *w = FindWindowById(WC_STATUS_BAR, 0);
   454 		else
   481 			if (w != NULL) {
   455 			ShowNewspaper(ni);
   482 				WP(w, def_d).data_2 = 91;
       
   483 				SetWindowDirty(w);
       
   484 			}
       
   485   	} break;
       
   486   	case 1: /* Summary - show ticker, but if forced big, cascade to full */
       
   487   		if (!(ni->flags & NF_FORCE_BIG)) {
       
   488   			ShowTicker(ni);
       
   489   			break;
       
   490   		}
       
   491   		/* Fallthrough */
       
   492   	case 2: /* Full - show newspaper*/
       
   493   		ShowNewspaper(ni);
       
   494   		break;
       
   495   	}
   456 	}
   496 	}
   457 }
   497 }
   458 
   498 
   459 void NewsLoop(void)
   499 void NewsLoop(void)
   460 {
   500 {
   662 		w->resize.width = 200; // can't make window any smaller than 200 pixel
   702 		w->resize.width = 200; // can't make window any smaller than 200 pixel
   663 		SetWindowDirty(w);
   703 		SetWindowDirty(w);
   664 	}
   704 	}
   665 }
   705 }
   666 
   706 
       
   707 /** Setup the disabled/enabled buttons in the message window
       
   708  * If the value is 'off' disable the [<] widget, and enable the [>] one
       
   709  * Same-wise for all the others. Starting value of 3 is the first widget
       
   710  * group. These are grouped as [<][>] .. [<][>], etc.
       
   711  */
       
   712 static void SetMessageButtonStates(Window *w, byte value, int element)
       
   713 {
       
   714 	element *= 2;
       
   715 	switch (value) {
       
   716 	case 0: /* Off */
       
   717 		SETBIT(w->disabled_state, element + 3);
       
   718 		CLRBIT(w->disabled_state, element + 3 + 1);
       
   719 		break;
       
   720 	case 1: /* Summary */
       
   721 		CLRBIT(w->disabled_state, element + 3);
       
   722 		CLRBIT(w->disabled_state, element + 3 + 1);
       
   723 		break;
       
   724 	case 2: /* Full */
       
   725 		SETBIT(w->disabled_state, element + 3 + 1);
       
   726 		CLRBIT(w->disabled_state, element + 3);
       
   727 		break;
       
   728 	default: NOT_REACHED();
       
   729 	}
       
   730 }
   667 
   731 
   668 static void MessageOptionsWndProc(Window *w, WindowEvent *e)
   732 static void MessageOptionsWndProc(Window *w, WindowEvent *e)
   669 {
   733 {
       
   734 	static const StringID message_opt[] = {STR_OFF, STR_SUMMARY, STR_FULL, INVALID_STRING_ID};
       
   735 	static const uint32 message_val[] = {0x0, 0x55555555, 0xAAAAAAAA}; // 0x555.. = 01010101010101010101 (all summary), 286.. 1010... (full)
       
   736 	static const uint32 message_dis[] = {
       
   737 		(1 << 3) | (1 << 5) | (1 << 7) | (1 << 9)  | (1 << 11) | (1 << 13) | (1 << 15) | (1 << 17) | (1 << 19) | (1 << 21),
       
   738 		0,
       
   739 		(1 << 4) | (1 << 6) | (1 << 8) | (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16) | (1 << 18) | (1 << 20) | (1 << 22),
       
   740 	};
       
   741 
       
   742 	/* WP(w, def_d).data_1 are stores the clicked state of the fake widgets
       
   743 	 * WP(w, def_d).data_2 stores state of the ALL on/off/summary button */
   670 	switch (e->event) {
   744 	switch (e->event) {
       
   745 	case WE_CREATE: {
       
   746 		uint32 val = _news_display_opt;
       
   747 		int i;
       
   748 		WP(w, def_d).data_1 = WP(w, def_d).data_2 = 0;
       
   749 
       
   750 		// Set up the initial disabled buttons in the case of 'off' or 'full'
       
   751 		for (i = 0; i != 10; i++, val >>= 2) SetMessageButtonStates(w, val & 0x3, i);
       
   752 	} break;
       
   753 
   671 	case WE_PAINT: {
   754 	case WE_PAINT: {
   672 		uint16 x = _news_display_opt;
   755 		uint32 val = _news_display_opt;
   673 		uint32 cs = 0;
   756 		int click_state = WP(w, def_d).data_1;
   674 		int i, y;
   757 		int i, y;
   675 
   758 
   676 		for (i = 3; i != 23; i += 2) {
   759 		if (_news_ticker_sound) SETBIT(w->click_state, 25);
   677 			cs |= 1 << (i + (x & 1));
       
   678 			x >>= 1;
       
   679 		}
       
   680 		cs |= (w->click_state >> 23) << 23;
       
   681 
       
   682 		w->click_state = cs;
       
   683 		DrawWindowWidgets(w);
   760 		DrawWindowWidgets(w);
   684 
       
   685 		DrawStringCentered(185, 15, STR_0205_MESSAGE_TYPES, 0);
   761 		DrawStringCentered(185, 15, STR_0205_MESSAGE_TYPES, 0);
   686 
   762 
   687 		y = 27;
   763 		/* XXX - Draw the fake widgets-buttons. Can't add these to the widget-desc since
   688 		for (i = STR_0206_ARRIVAL_OF_FIRST_VEHICLE; i <= STR_020F_GENERAL_INFORMATION; i++) {
   764 		 * openttd currently can only handle 32 widgets. So hack it *g* */
   689 			DrawString(124, y, i, 0);
   765 		for (i = 0, y = 26; i != 10; i++, y += 12, click_state >>= 1, val >>= 2) {
   690 			y += 12;
   766 			bool clicked = !!(click_state & 1);
   691 		}
   767 
   692 
   768 			DrawFrameRect(13, y, 89, 11 + y, 3, (clicked) ? 0x20 : 0);
   693 		break;
   769 			DrawStringCentered(((13 + 89 + 1) >> 1) + clicked, ((y + 11 + y + 1) >> 1) - 5 + clicked, message_opt[val & 0x3], 0x10);
   694 	}
   770 			DrawString(103, y + 1, i + STR_0206_ARRIVAL_OF_FIRST_VEHICLE, 0);
   695 
   771 		}
   696 	case WE_CLICK: {
   772 
   697 		int wid;
   773 		DrawString(  8, y + 9, message_opt[WP(w, def_d).data_2], 0x10);
   698 		if ((uint)(wid = e->click.widget - 3) < 20) {
   774 		DrawString(103, y + 9, STR_MESSAGES_ALL, 0);
   699 			if (!(wid & 1))
   775 		DrawString(103, y + 9 + 12, STR_MESSAGE_SOUND, 0);
   700 				_news_display_opt &= ~(1 << (wid / 2));
   776 
   701 			else
       
   702 				_news_display_opt |= (1 << (wid / 2));
       
   703 			SetWindowDirty(w);
       
   704 			// XXX: write settings
       
   705 		}
       
   706 		if (e->click.widget == 23) {
       
   707 			_news_display_opt = 0;
       
   708 			HandleButtonClick(w, 23);
       
   709 			SetWindowDirty(w);
       
   710 		}
       
   711 		if (e->click.widget == 24) {
       
   712 			_news_display_opt = ~0;
       
   713 			HandleButtonClick(w, 24);
       
   714 			SetWindowDirty(w);
       
   715 		}
       
   716 	} break;
   777 	} break;
       
   778 
       
   779 	case WE_CLICK:
       
   780 		switch (e->click.widget) {
       
   781 		case 2: /* Clicked on any of the fake widgets */
       
   782 			if (e->click.pt.x > 13 && e->click.pt.x < 89 && e->click.pt.y > 26 && e->click.pt.y < 146) {
       
   783 				int element = (e->click.pt.y - 26) / 12;
       
   784 				byte val = (GetNewsDisplayValue(element) + 1) % 3;
       
   785 
       
   786 				SetMessageButtonStates(w, val, element);
       
   787 				SetNewsDisplayValue(element, val);
       
   788 
       
   789 				WP(w, def_d).data_1 |= (1 << element);
       
   790 				w->flags4 |= 5 << WF_TIMEOUT_SHL; // XXX - setup unclick (fake widget)
       
   791 				SetWindowDirty(w);
       
   792 			}
       
   793 			break;
       
   794 		case 23: case 24: /* Dropdown menu for all settings */
       
   795 			ShowDropDownMenu(w, message_opt, WP(w, def_d).data_2, 24, 0, 0);
       
   796 			break;
       
   797 		case 25: /* Change ticker sound on/off */
       
   798 			_news_ticker_sound ^= 1;
       
   799 			TOGGLEBIT(w->click_state, e->click.widget);
       
   800 			InvalidateWidget(w, e->click.widget);
       
   801 			break;
       
   802 		default: { /* Clicked on the [<] .. [>] widgets */
       
   803 			int wid = e->click.widget;
       
   804 			if (wid > 2 && wid < 23) {
       
   805 				int element = (wid - 3) / 2;
       
   806 				byte val = (GetNewsDisplayValue(element) + ((wid & 1) ? -1 : 1)) % 3;
       
   807 
       
   808 				SetMessageButtonStates(w, val, element);
       
   809 				SetNewsDisplayValue(element, val);
       
   810 				SetWindowDirty(w);
       
   811 			}
       
   812 		} break;
       
   813 		} break;
       
   814 
       
   815 	case WE_DROPDOWN_SELECT: /* Select all settings for newsmessages */
       
   816 		WP(w, def_d).data_2 = e->dropdown.index;
       
   817 		_news_display_opt = message_val[WP(w, def_d).data_2];
       
   818 		w->disabled_state = message_dis[WP(w, def_d).data_2];
       
   819 		SetWindowDirty(w);
       
   820 		break;
       
   821 
       
   822 	case WE_TIMEOUT: /* XXX - Hack to animate 'fake' buttons */
       
   823 		WP(w, def_d).data_1 = 0;
       
   824 		SetWindowDirty(w);
       
   825 		break;
       
   826 
   717 	}
   827 	}
   718 }
   828 }
   719 
   829 
   720 static const Widget _message_options_widgets[] = {
   830 static const Widget _message_options_widgets[] = {
   721 {   WWT_CLOSEBOX,   RESIZE_NONE,    13,     0,    10,     0,    13, STR_00C5,								STR_018B_CLOSE_WINDOW},
   831 {   WWT_CLOSEBOX,   RESIZE_NONE,    13,     0,   10,     0,    13, STR_00C5,             STR_018B_CLOSE_WINDOW},
   722 {    WWT_CAPTION,   RESIZE_NONE,    13,    11,   369,     0,    13, STR_0204_MESSAGE_OPTIONS,STR_018C_WINDOW_TITLE_DRAG_THIS},
   832 {    WWT_CAPTION,   RESIZE_NONE,    13,    11,  409,     0,    13, STR_0204_MESSAGE_OPTIONS, STR_018C_WINDOW_TITLE_DRAG_THIS},
   723 {      WWT_PANEL,   RESIZE_NONE,    13,     0,   369,    14,   172, 0x0,											STR_NULL},
   833 {      WWT_PANEL,   RESIZE_NONE,    13,     0,  409,    14,   184, STR_NULL,             STR_NULL},
   724 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,    26,    37, STR_02B8_SUMMARY,				STR_NULL},
   834 
   725 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,    26,    37, STR_02B9_FULL,						STR_NULL},
   835 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,    26,    37, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
   726 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,    38,    49, STR_02B8_SUMMARY,				STR_NULL},
   836 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,    26,    37, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
   727 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,    38,    49, STR_02B9_FULL,						STR_NULL},
   837 
   728 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,    50,    61, STR_02B8_SUMMARY,				STR_NULL},
   838 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,    38,    49, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
   729 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,    50,    61, STR_02B9_FULL,						STR_NULL},
   839 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,    38,    49, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
   730 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,    62,    73, STR_02B8_SUMMARY,				STR_NULL},
   840 
   731 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,    62,    73, STR_02B9_FULL,						STR_NULL},
   841 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,    50,    61, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
   732 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,    74,    85, STR_02B8_SUMMARY,				STR_NULL},
   842 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,    50,    61, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
   733 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,    74,    85, STR_02B9_FULL,						STR_NULL},
   843 
   734 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,    86,    97, STR_02B8_SUMMARY,				STR_NULL},
   844 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,    62,    73, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
   735 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,    86,    97, STR_02B9_FULL,						STR_NULL},
   845 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,    62,    73, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
   736 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,    98,   109, STR_02B8_SUMMARY,				STR_NULL},
   846 
   737 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,    98,   109, STR_02B9_FULL,						STR_NULL},
   847 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,    74,    85, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
   738 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,   110,   121, STR_02B8_SUMMARY,				STR_NULL},
   848 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,    74,    85, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
   739 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,   110,   121, STR_02B9_FULL,						STR_NULL},
   849 
   740 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,   122,   133, STR_02B8_SUMMARY,				STR_NULL},
   850 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,    86,    97, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
   741 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,   122,   133, STR_02B9_FULL,						STR_NULL},
   851 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,    86,    97, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
   742 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,     2,    61,   134,   145, STR_02B8_SUMMARY,				STR_NULL},
   852 
   743 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    62,   121,   134,   145, STR_02B9_FULL,						STR_NULL},
   853 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,    98,   109, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
   744 
   854 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,    98,   109, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
   745 { WWT_PUSHTXTBTN,   RESIZE_NONE,     3,    15,   170,   154,   165, STR_MESSAGES_DISABLE_ALL,STR_NULL },
   855 
   746 { WWT_PUSHTXTBTN,   RESIZE_NONE,     3,   200,   355,   154,   165, STR_MESSAGES_ENABLE_ALL,	STR_NULL },
   856 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,   110,   121, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
       
   857 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,   110,   121, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
       
   858 
       
   859 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,   122,   133, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
       
   860 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,   122,   133, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
       
   861 
       
   862 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,     4,   12,   134,   145, SPR_ARROW_LEFT,       STR_HSCROLL_BAR_SCROLLS_LIST},
       
   863 { WWT_PUSHIMGBTN,   RESIZE_NONE,     3,    90,   98,   134,   145, SPR_ARROW_RIGHT,      STR_HSCROLL_BAR_SCROLLS_LIST},
       
   864 
       
   865 {      WWT_PANEL,   RESIZE_NONE,     3,     4,   86,   154,   165, STR_NULL,             STR_NULL},
       
   866 {   WWT_CLOSEBOX,   RESIZE_NONE,     3,    87,   98,   154,   165, STR_0225,             STR_NULL},
       
   867 {          WWT_4,   RESIZE_NONE,     3,     4,   98,   166,   177, STR_02DB_OFF,         STR_NULL},
   747 
   868 
   748 {   WIDGETS_END},
   869 {   WIDGETS_END},
   749 };
   870 };
   750 
   871 
   751 static const WindowDesc _message_options_desc = {
   872 static const WindowDesc _message_options_desc = {
   752 	270, 22, 370, 173,
   873 	270, 22, 410, 185,
   753 	WC_GAME_OPTIONS, 0,
   874 	WC_GAME_OPTIONS, 0,
   754 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
   875 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
   755 	_message_options_widgets,
   876 	_message_options_widgets,
   756 	MessageOptionsWndProc
   877 	MessageOptionsWndProc
   757 };
   878 };