src/window.cpp
branchNewGRF_ports
changeset 6872 1c4a4a609f85
parent 6871 5a9dc001e1ad
child 6878 7d1ff2f621c7
equal deleted inserted replaced
6871:5a9dc001e1ad 6872:1c4a4a609f85
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include <stdarg.h>
     6 #include <stdarg.h>
     7 #include "openttd.h"
     7 #include "openttd.h"
     8 #include "debug.h"
     8 #include "debug.h"
     9 #include "functions.h"
     9 #include "player_func.h"
    10 #include "map.h"
    10 #include "gfx_func.h"
    11 #include "player.h"
       
    12 #include "window.h"
       
    13 #include "gfx.h"
       
    14 #include "viewport.h"
       
    15 #include "console.h"
    11 #include "console.h"
       
    12 #include "viewport_func.h"
    16 #include "variables.h"
    13 #include "variables.h"
       
    14 #include "genworld.h"
       
    15 #include "blitter/factory.hpp"
       
    16 #include "window_gui.h"
       
    17 #include "zoom_func.h"
       
    18 #include "core/alloc_func.hpp"
       
    19 #include "map_func.h"
       
    20 #include "vehicle_base.h"
       
    21 #include "settings_type.h"
       
    22 
    17 #include "table/sprites.h"
    23 #include "table/sprites.h"
    18 #include "genworld.h"
       
    19 #include "helpers.hpp"
       
    20 #include "blitter/factory.hpp"
       
    21 
    24 
    22 /* delta between mouse cursor and upper left corner of dragged window */
    25 /* delta between mouse cursor and upper left corner of dragged window */
    23 static Point _drag_delta;
    26 static Point _drag_delta;
    24 
    27 
    25 static Window _windows[25];
    28 static Window _windows[MAX_NUMBER_OF_WINDOWS];
    26 Window *_z_windows[lengthof(_windows)];
    29 Window *_z_windows[lengthof(_windows)];
    27 Window **_last_z_window; ///< always points to the next free space in the z-array
    30 Window **_last_z_window; ///< always points to the next free space in the z-array
    28 
    31 
    29 void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...)
    32 Point _cursorpos_drag_start;
    30 {
    33 
    31 	va_list wdg_list;
    34 int _scrollbar_start_pos;
    32 
    35 int _scrollbar_size;
    33 	va_start(wdg_list, widgets);
    36 byte _scroller_click_timeout;
    34 
    37 
    35 	while (widgets != WIDGET_LIST_END) {
    38 bool _scrolling_scrollbar;
    36 		w->SetWidgetDisabledState(widgets, disab_stat);
    39 bool _scrolling_viewport;
    37 		widgets = va_arg(wdg_list, int);
    40 bool _popup_menu_active;
    38 	}
    41 
    39 
    42 byte _special_mouse_mode;
    40 	va_end(wdg_list);
    43 
    41 }
       
    42 
       
    43 void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...)
       
    44 {
       
    45 	va_list wdg_list;
       
    46 
       
    47 	va_start(wdg_list, widgets);
       
    48 
       
    49 	while (widgets != WIDGET_LIST_END) {
       
    50 		w->SetWidgetHiddenState(widgets, hidden_stat);
       
    51 		widgets = va_arg(wdg_list, int);
       
    52 	}
       
    53 
       
    54 	va_end(wdg_list);
       
    55 }
       
    56 
       
    57 void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...)
       
    58 {
       
    59 	va_list wdg_list;
       
    60 
       
    61 	va_start(wdg_list, widgets);
       
    62 
       
    63 	while (widgets != WIDGET_LIST_END) {
       
    64 		w->SetWidgetLoweredState(widgets, lowered_stat);
       
    65 		widgets = va_arg(wdg_list, int);
       
    66 	}
       
    67 
       
    68 	va_end(wdg_list);
       
    69 }
       
    70 
       
    71 void RaiseWindowButtons(Window *w)
       
    72 {
       
    73 	uint i;
       
    74 
       
    75 	for (i = 0; i < w->widget_count; i++) {
       
    76 		if (w->IsWidgetLowered(i)) {
       
    77 			w->RaiseWidget(i);
       
    78 			InvalidateWidget(w, i);
       
    79 		}
       
    80 	}
       
    81 }
       
    82 
    44 
    83 void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...)
    45 void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...)
    84 {
    46 {
    85 	va_list wdg_list;
    47 	va_list wdg_list;
    86 
    48 
   125 void Window::RaiseButtons()
    87 void Window::RaiseButtons()
   126 {
    88 {
   127 	uint i;
    89 	uint i;
   128 
    90 
   129 	for (i = 0; i < this->widget_count; i++) {
    91 	for (i = 0; i < this->widget_count; i++) {
   130 		if (IsWidgetLowered(i)) {
    92 		if (this->IsWidgetLowered(i)) {
   131 			RaiseWidget(i);
    93 			this->RaiseWidget(i);
   132 			InvalidateWidget(i);
    94 			this->InvalidateWidget(i);
   133 		}
    95 		}
   134 	}
    96 	}
   135 }
    97 }
   136 
    98 
   137 void Window::InvalidateWidget(byte widget_index)
    99 void Window::InvalidateWidget(byte widget_index) const
   138 {
   100 {
   139 	const Widget *wi = &this->widget[widget_index];
   101 	const Widget *wi = &this->widget[widget_index];
   140 
   102 
   141 	/* Don't redraw the window if the widget is invisible or of no-type */
   103 	/* Don't redraw the window if the widget is invisible or of no-type */
   142 	if (wi->type == WWT_EMPTY || IsWidgetHidden(widget_index)) return;
   104 	if (wi->type == WWT_EMPTY || IsWidgetHidden(widget_index)) return;
   143 
   105 
   144 	SetDirtyBlocks(this->left + wi->left, this->top + wi->top, this->left + wi->right + 1, this->top + wi->bottom + 1);
   106 	SetDirtyBlocks(this->left + wi->left, this->top + wi->top, this->left + wi->right + 1, this->top + wi->bottom + 1);
   145 }
   107 }
   146 
   108 
   147 void HandleButtonClick(Window *w, byte widget)
   109 void Window::HandleButtonClick(byte widget)
   148 {
   110 {
   149 	w->LowerWidget(widget);
   111 	this->LowerWidget(widget);
   150 	w->flags4 |= 5 << WF_TIMEOUT_SHL;
   112 	this->flags4 |= 5 << WF_TIMEOUT_SHL;
   151 	InvalidateWidget(w, widget);
   113 	this->InvalidateWidget(widget);
   152 }
   114 }
   153 
       
   154 
   115 
   155 static void StartWindowDrag(Window *w);
   116 static void StartWindowDrag(Window *w);
   156 static void StartWindowSizing(Window *w);
   117 static void StartWindowSizing(Window *w);
   157 
   118 
   158 static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click)
   119 static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click)
   177 			/* special widget handling for buttons*/
   138 			/* special widget handling for buttons*/
   178 			switch (wi->type) {
   139 			switch (wi->type) {
   179 				case WWT_PANEL   | WWB_PUSHBUTTON: /* WWT_PUSHBTN */
   140 				case WWT_PANEL   | WWB_PUSHBUTTON: /* WWT_PUSHBTN */
   180 				case WWT_IMGBTN  | WWB_PUSHBUTTON: /* WWT_PUSHIMGBTN */
   141 				case WWT_IMGBTN  | WWB_PUSHBUTTON: /* WWT_PUSHIMGBTN */
   181 				case WWT_TEXTBTN | WWB_PUSHBUTTON: /* WWT_PUSHTXTBTN */
   142 				case WWT_TEXTBTN | WWB_PUSHBUTTON: /* WWT_PUSHTXTBTN */
   182 					HandleButtonClick(w, e.we.click.widget);
   143 					w->HandleButtonClick(e.we.click.widget);
   183 					break;
   144 					break;
   184 			}
   145 			}
   185 		} else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) {
   146 		} else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) {
   186 			ScrollbarClickHandler(w, wi, e.we.click.pt.x, e.we.click.pt.y);
   147 			ScrollbarClickHandler(w, wi, e.we.click.pt.x, e.we.click.pt.y);
   187 		}
   148 		}
   198 			}
   159 			}
   199 		}
   160 		}
   200 
   161 
   201 		if (w->desc_flags & WDF_RESIZABLE && wi->type == WWT_RESIZEBOX) {
   162 		if (w->desc_flags & WDF_RESIZABLE && wi->type == WWT_RESIZEBOX) {
   202 			StartWindowSizing(w);
   163 			StartWindowSizing(w);
   203 			InvalidateWidget(w, e.we.click.widget);
   164 			w->InvalidateWidget(e.we.click.widget);
   204 			return;
   165 			return;
   205 		}
   166 		}
   206 
   167 
   207 		if (w->desc_flags & WDF_STICKY_BUTTON && wi->type == WWT_STICKYBOX) {
   168 		if (w->desc_flags & WDF_STICKY_BUTTON && wi->type == WWT_STICKYBOX) {
   208 			w->flags4 ^= WF_STICKY;
   169 			w->flags4 ^= WF_STICKY;
   209 			InvalidateWidget(w, e.we.click.widget);
   170 			w->InvalidateWidget(e.we.click.widget);
   210 			return;
   171 			return;
   211 		}
   172 		}
   212 	}
   173 	}
   213 
   174 
   214 	w->wndproc(w, &e);
   175 	w->wndproc(w, &e);
  1081 	for (wz = _last_z_window; wz != _z_windows;) {
  1042 	for (wz = _last_z_window; wz != _z_windows;) {
  1082 		w = *--wz;
  1043 		w = *--wz;
  1083 
  1044 
  1084 		if (w->flags4&WF_TIMEOUT_MASK && !(--w->flags4&WF_TIMEOUT_MASK)) {
  1045 		if (w->flags4&WF_TIMEOUT_MASK && !(--w->flags4&WF_TIMEOUT_MASK)) {
  1085 			CallWindowEventNP(w, WE_TIMEOUT);
  1046 			CallWindowEventNP(w, WE_TIMEOUT);
  1086 			if (w->desc_flags & WDF_UNCLICK_BUTTONS) RaiseWindowButtons(w);
  1047 			if (w->desc_flags & WDF_UNCLICK_BUTTONS) w->RaiseButtons();
  1087 		}
  1048 		}
  1088 	}
  1049 	}
  1089 }
  1050 }
  1090 
  1051 
  1091 Window *GetCallbackWnd()
  1052 Window *GetCallbackWnd()
  1696 	e.event = WE_KEYPRESS;
  1657 	e.event = WE_KEYPRESS;
  1697 	e.we.keypress.key     = GB(key,  0, 16);
  1658 	e.we.keypress.key     = GB(key,  0, 16);
  1698 	e.we.keypress.keycode = GB(key, 16, 16);
  1659 	e.we.keypress.keycode = GB(key, 16, 16);
  1699 	e.we.keypress.cont = true;
  1660 	e.we.keypress.cont = true;
  1700 
  1661 
       
  1662 	/*
       
  1663 	 * The Unicode standard defines an area called the private use area. Code points in this
       
  1664 	 * area are reserved for private use and thus not portable between systems. For instance,
       
  1665 	 * Apple defines code points for the arrow keys in this area, but these are only printable
       
  1666 	 * on a system running OS X. We don't want these keys to show up in text fields and such,
       
  1667 	 * and thus we have to clear the unicode character when we encounter such a key.
       
  1668 	 */
       
  1669 	if (e.we.keypress.key >= 0xE000 && e.we.keypress.key <= 0xF8FF) e.we.keypress.key = 0;
       
  1670 
       
  1671 	/*
       
  1672 	 * If both key and keycode is zero, we don't bother to process the event.
       
  1673 	 */
       
  1674 	if (e.we.keypress.key == 0 && e.we.keypress.keycode == 0) return;
       
  1675 
  1701 	/* check if we have a query string window open before allowing hotkeys */
  1676 	/* check if we have a query string window open before allowing hotkeys */
  1702 	if (FindWindowById(WC_QUERY_STRING,            0) != NULL ||
  1677 	if (FindWindowById(WC_QUERY_STRING,            0) != NULL ||
  1703 			FindWindowById(WC_SEND_NETWORK_MSG,        0) != NULL ||
  1678 			FindWindowById(WC_SEND_NETWORK_MSG,        0) != NULL ||
  1704 			FindWindowById(WC_GENERATE_LANDSCAPE,      0) != NULL ||
  1679 			FindWindowById(WC_GENERATE_LANDSCAPE,      0) != NULL ||
  1705 			FindWindowById(WC_CONSOLE,                 0) != NULL ||
  1680 			FindWindowById(WC_CONSOLE,                 0) != NULL ||
  1989 		const Window *w = *wz;
  1964 		const Window *w = *wz;
  1990 		if (w->window_class == cls && w->window_number == number) SetWindowDirty(w);
  1965 		if (w->window_class == cls && w->window_number == number) SetWindowDirty(w);
  1991 	}
  1966 	}
  1992 }
  1967 }
  1993 
  1968 
  1994 void InvalidateWidget(const Window *w, byte widget_index)
       
  1995 {
       
  1996 	const Widget *wi = &w->widget[widget_index];
       
  1997 
       
  1998 	/* Don't redraw the window if the widget is invisible or of no-type */
       
  1999 	if (wi->type == WWT_EMPTY || w->IsWidgetHidden(widget_index)) return;
       
  2000 
       
  2001 	SetDirtyBlocks(w->left + wi->left, w->top + wi->top, w->left + wi->right + 1, w->top + wi->bottom + 1);
       
  2002 }
       
  2003 
       
  2004 void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index)
  1969 void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index)
  2005 {
  1970 {
  2006 	Window* const *wz;
  1971 	Window* const *wz;
  2007 
  1972 
  2008 	FOR_ALL_WINDOWS(wz) {
  1973 	FOR_ALL_WINDOWS(wz) {
  2009 		const Window *w = *wz;
  1974 		const Window *w = *wz;
  2010 		if (w->window_class == cls && w->window_number == number) {
  1975 		if (w->window_class == cls && w->window_number == number) {
  2011 			InvalidateWidget(w, widget_index);
  1976 			w->InvalidateWidget(widget_index);
  2012 		}
  1977 		}
  2013 	}
  1978 	}
  2014 }
  1979 }
  2015 
  1980 
  2016 void InvalidateWindowClasses(WindowClass cls)
  1981 void InvalidateWindowClasses(WindowClass cls)
  2195 				continue;
  2160 				continue;
  2196 
  2161 
  2197 			default:
  2162 			default:
  2198 				left = w->left;
  2163 				left = w->left;
  2199 				if (left + (w->width >> 1) >= neww) left = neww - w->width;
  2164 				if (left + (w->width >> 1) >= neww) left = neww - w->width;
       
  2165 				if (left < 0) left = 0;
       
  2166 
  2200 				top = w->top;
  2167 				top = w->top;
  2201 				if (top + (w->height >> 1) >= newh) top = newh - w->height;
  2168 				if (top + (w->height >> 1) >= newh) top = newh - w->height;
       
  2169 				if (top < 0) top = 0;
  2202 				break;
  2170 				break;
  2203 		}
  2171 		}
  2204 
  2172 
  2205 		if (w->viewport != NULL) {
  2173 		if (w->viewport != NULL) {
  2206 			w->viewport->left += left - w->left;
  2174 			w->viewport->left += left - w->left;