src/window.cpp
branchNewGRF_ports
changeset 10274 b3c58f3df92b
parent 10242 52b4a9006029
child 10724 68a692eacf22
equal deleted inserted replaced
10243:e9066a148720 10274:b3c58f3df92b
   301 
   301 
   302 			return;
   302 			return;
   303 		}
   303 		}
   304 	}
   304 	}
   305 
   305 
       
   306 	/* Setup blitter, and dispatch a repaint event to window *wz */
   306 	DrawPixelInfo *dp = _cur_dpi;
   307 	DrawPixelInfo *dp = _cur_dpi;
   307 	dp->width = right - left;
   308 	dp->width = right - left;
   308 	dp->height = bottom - top;
   309 	dp->height = bottom - top;
   309 	dp->left = left - (*wz)->left;
   310 	dp->left = left - (*wz)->left;
   310 	dp->top = top - (*wz)->top;
   311 	dp->top = top - (*wz)->top;
   332 		const Window *w = *wz;
   333 		const Window *w = *wz;
   333 		if (right > w->left &&
   334 		if (right > w->left &&
   334 				bottom > w->top &&
   335 				bottom > w->top &&
   335 				left < w->left + w->width &&
   336 				left < w->left + w->width &&
   336 				top < w->top + w->height) {
   337 				top < w->top + w->height) {
       
   338 			/* Window w intersects with the rectangle => needs repaint */
   337 			DrawOverlappedWindow(wz, left, top, right, bottom);
   339 			DrawOverlappedWindow(wz, left, top, right, bottom);
   338 		}
   340 		}
   339 	}
   341 	}
   340 }
   342 }
   341 
   343 
   396 		w->window_class, w->window_number);
   398 		w->window_class, w->window_number);
   397 	return NULL;
   399 	return NULL;
   398 }
   400 }
   399 
   401 
   400 /**
   402 /**
   401  * Remove window and all its child windows from the window stack
   403  * Remove window and all its child windows from the window stack.
       
   404  * @param w Window to delete
   402  */
   405  */
   403 void DeleteWindow(Window *w)
   406 void DeleteWindow(Window *w)
   404 {
   407 {
   405 	if (w == NULL) return;
   408 	if (w == NULL) return;
   406 
   409 
   620  */
   623  */
   621 static Window *ForceFindDeletableWindow()
   624 static Window *ForceFindDeletableWindow()
   622 {
   625 {
   623 	Window* const *wz;
   626 	Window* const *wz;
   624 
   627 
   625 	for (wz = _z_windows;; wz++) {
   628 	FOR_ALL_WINDOWS(wz) {
   626 		Window *w = *wz;
   629 		Window *w = *wz;
   627 		assert(wz < _last_z_window);
       
   628 		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w;
   630 		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w;
   629 	}
   631 	}
       
   632 	NOT_REACHED();
   630 }
   633 }
   631 
   634 
   632 bool IsWindowOfPrototype(const Window *w, const Widget *widget)
   635 bool IsWindowOfPrototype(const Window *w, const Widget *widget)
   633 {
   636 {
   634 	return (w->original_widget == widget);
   637 	return (w->original_widget == widget);
  1016  * @param x position x to query
  1019  * @param x position x to query
  1017  * @param y position y to query
  1020  * @param y position y to query
  1018  * @return a pointer to the found window if any, NULL otherwise */
  1021  * @return a pointer to the found window if any, NULL otherwise */
  1019 Window *FindWindowFromPt(int x, int y)
  1022 Window *FindWindowFromPt(int x, int y)
  1020 {
  1023 {
  1021 	Window* const *wz;
  1024 	for (Window * const *wz = _last_z_window; wz != _z_windows;) {
  1022 
       
  1023 	for (wz = _last_z_window; wz != _z_windows;) {
       
  1024 		Window *w = *--wz;
  1025 		Window *w = *--wz;
  1025 		if (IsInsideBS(x, w->left, w->width) && IsInsideBS(y, w->top, w->height)) {
  1026 		if (IsInsideBS(x, w->left, w->width) && IsInsideBS(y, w->top, w->height)) {
  1026 			return w;
  1027 			return w;
  1027 		}
  1028 		}
  1028 	}
  1029 	}
  1036 void InitWindowSystem()
  1037 void InitWindowSystem()
  1037 {
  1038 {
  1038 	IConsoleClose();
  1039 	IConsoleClose();
  1039 
  1040 
  1040 	_last_z_window = _z_windows;
  1041 	_last_z_window = _z_windows;
       
  1042 	_mouseover_last_w = NULL;
  1041 	_no_scroll = 0;
  1043 	_no_scroll = 0;
  1042 }
  1044 }
  1043 
  1045 
  1044 /**
  1046 /**
  1045  * Close down the windowing system
  1047  * Close down the windowing system
  1602  * @param w Window to bring on-top
  1604  * @param w Window to bring on-top
  1603  * @return false if the window has an active modal child, true otherwise */
  1605  * @return false if the window has an active modal child, true otherwise */
  1604 static bool MaybeBringWindowToFront(const Window *w)
  1606 static bool MaybeBringWindowToFront(const Window *w)
  1605 {
  1607 {
  1606 	bool bring_to_front = false;
  1608 	bool bring_to_front = false;
  1607 	Window* const *wz;
  1609 	Window * const *wz;
  1608 	Window* const *uz;
       
  1609 
  1610 
  1610 	if (w->window_class == WC_MAIN_WINDOW ||
  1611 	if (w->window_class == WC_MAIN_WINDOW ||
  1611 			IsVitalWindow(w) ||
  1612 			IsVitalWindow(w) ||
  1612 			w->window_class == WC_TOOLTIPS ||
  1613 			w->window_class == WC_TOOLTIPS ||
  1613 			w->window_class == WC_DROPDOWN_MENU) {
  1614 			w->window_class == WC_DROPDOWN_MENU) {
  1614 		return true;
  1615 		return true;
  1615 	}
  1616 	}
  1616 
  1617 
  1617 	wz = FindWindowZPosition(w);
  1618 	wz = FindWindowZPosition(w);
  1618 	for (uz = wz; ++uz != _last_z_window;) {
  1619 	for (Window * const *uz = wz; ++uz != _last_z_window;) {
  1619 		Window *u = *uz;
  1620 		Window *u = *uz;
  1620 
  1621 
  1621 		/* A modal child will prevent the activation of the parent window */
  1622 		/* A modal child will prevent the activation of the parent window */
  1622 		if (u->parent == w && (u->desc_flags & WDF_MODAL)) {
  1623 		if (u->parent == w && (u->desc_flags & WDF_MODAL)) {
  1623 			u->flags4 |= WF_WHITE_BORDER_MASK;
  1624 			u->flags4 |= WF_WHITE_BORDER_MASK;
  1786 		Window *w = *--wz;
  1787 		Window *w = *--wz;
  1787 		w->wndproc(w, &e);
  1788 		w->wndproc(w, &e);
  1788 		if (!e.we.ctrl.cont) break;
  1789 		if (!e.we.ctrl.cont) break;
  1789 	}
  1790 	}
  1790 }
  1791 }
  1791 
       
  1792 extern void UpdateTileSelection();
       
  1793 extern bool VpHandlePlaceSizingDrag();
       
  1794 
  1792 
  1795 /**
  1793 /**
  1796  * Local counter that is incremented each time an mouse input event is detected.
  1794  * Local counter that is incremented each time an mouse input event is detected.
  1797  * The counter is used to stop auto-scrolling.
  1795  * The counter is used to stop auto-scrolling.
  1798  * @see HandleAutoscroll()
  1796  * @see HandleAutoscroll()
  1850 
  1848 
  1851 	MAX_OFFSET_DOUBLE_CLICK = 5,     ///< How much the mouse is allowed to move to call it a double click
  1849 	MAX_OFFSET_DOUBLE_CLICK = 5,     ///< How much the mouse is allowed to move to call it a double click
  1852 	TIME_BETWEEN_DOUBLE_CLICK = 500, ///< Time between 2 left clicks before it becoming a double click, in ms
  1850 	TIME_BETWEEN_DOUBLE_CLICK = 500, ///< Time between 2 left clicks before it becoming a double click, in ms
  1853 };
  1851 };
  1854 
  1852 
       
  1853 extern void UpdateTileSelection();
       
  1854 extern bool VpHandlePlaceSizingDrag();
       
  1855 
  1855 void MouseLoop(MouseClick click, int mousewheel)
  1856 void MouseLoop(MouseClick click, int mousewheel)
  1856 {
  1857 {
  1857 	int x,y;
  1858 	int x,y;
  1858 	Window *w;
  1859 	Window *w;
  1859 	ViewPort *vp;
  1860 	ViewPort *vp;
  2062 	}
  2063 	}
  2063 	return -1;
  2064 	return -1;
  2064 }
  2065 }
  2065 
  2066 
  2066 /**
  2067 /**
  2067  * Mark window data as invalid (in need of re-computing)
  2068  * Mark window as dirty (in need of repainting)
  2068  * @param w Window with invalid data
  2069  * @param cls Window class
       
  2070  * @param number Window number in that class
  2069  */
  2071  */
  2070 void InvalidateWindow(WindowClass cls, WindowNumber number)
  2072 void InvalidateWindow(WindowClass cls, WindowNumber number)
  2071 {
  2073 {
  2072 	Window* const *wz;
  2074 	Window* const *wz;
  2073 
  2075 
  2075 		const Window *w = *wz;
  2077 		const Window *w = *wz;
  2076 		if (w->window_class == cls && w->window_number == number) SetWindowDirty(w);
  2078 		if (w->window_class == cls && w->window_number == number) SetWindowDirty(w);
  2077 	}
  2079 	}
  2078 }
  2080 }
  2079 
  2081 
  2080 /*
  2082 /**
  2081  * Mark a particular widget in a particular window as dirty (in need of repainting)
  2083  * Mark a particular widget in a particular window as dirty (in need of repainting)
  2082  * @param cls Window class
  2084  * @param cls Window class
  2083  * @param number Window number in that class
  2085  * @param number Window number in that class
  2084  * @param widget_index Index number of the widget that needs repainting
  2086  * @param widget_index Index number of the widget that needs repainting
  2085  */
  2087  */
  2093 			w->InvalidateWidget(widget_index);
  2095 			w->InvalidateWidget(widget_index);
  2094 		}
  2096 		}
  2095 	}
  2097 	}
  2096 }
  2098 }
  2097 
  2099 
  2098 /*
  2100 /**
  2099  * Mark all windows of a particular class as dirty (in need of repainting)
  2101  * Mark all windows of a particular class as dirty (in need of repainting)
  2100  * @param cls Window class
  2102  * @param cls Window class
  2101  */
  2103  */
  2102 void InvalidateWindowClasses(WindowClass cls)
  2104 void InvalidateWindowClasses(WindowClass cls)
  2103 {
  2105 {
  2117 	CallWindowEventNP(w, WE_INVALIDATE_DATA);
  2119 	CallWindowEventNP(w, WE_INVALIDATE_DATA);
  2118 	SetWindowDirty(w);
  2120 	SetWindowDirty(w);
  2119 }
  2121 }
  2120 
  2122 
  2121 /**
  2123 /**
  2122  * Mark window data the window of a given class and specific window number as invalid (in need of re-computing)
  2124  * Mark window data of the window of a given class and specific window number as invalid (in need of re-computing)
  2123  * @param cls Window class
  2125  * @param cls Window class
  2124  * @param number Window number within the class
  2126  * @param number Window number within the class
  2125  */
  2127  */
  2126 void InvalidateWindowData(WindowClass cls, WindowNumber number)
  2128 void InvalidateWindowData(WindowClass cls, WindowNumber number)
  2127 {
  2129 {
  2149 /**
  2151 /**
  2150  * Dispatch WE_TICK event over all windows
  2152  * Dispatch WE_TICK event over all windows
  2151  */
  2153  */
  2152 void CallWindowTickEvent()
  2154 void CallWindowTickEvent()
  2153 {
  2155 {
  2154 	Window* const *wz;
  2156 	for (Window * const *wz = _last_z_window; wz != _z_windows;) {
  2155 
       
  2156 	for (wz = _last_z_window; wz != _z_windows;) {
       
  2157 		CallWindowEventNP(*--wz, WE_TICK);
  2157 		CallWindowEventNP(*--wz, WE_TICK);
  2158 	}
  2158 	}
  2159 }
  2159 }
  2160 
  2160 
       
  2161 /**
       
  2162  * Try to delete a non-vital window.
       
  2163  * Non-vital windows are windows other than the game selection, main toolbar,
       
  2164  * status bar, toolbar menu, and tooltip windows. Stickied windows are also
       
  2165  * considered vital.
       
  2166  */
  2161 void DeleteNonVitalWindows()
  2167 void DeleteNonVitalWindows()
  2162 {
  2168 {
  2163 	Window* const *wz;
  2169 	Window* const *wz;
  2164 
  2170 
  2165 restart_search:
  2171 restart_search: