window.c
changeset 4171 5c6e60c392c3
parent 4077 d4d440dd8925
child 4300 c7e43c47a2b9
equal deleted inserted replaced
4170:81bafc4dd1b9 4171:5c6e60c392c3
    22 	w->flags4 |= 5 << WF_TIMEOUT_SHL;
    22 	w->flags4 |= 5 << WF_TIMEOUT_SHL;
    23 	InvalidateWidget(w, widget);
    23 	InvalidateWidget(w, widget);
    24 }
    24 }
    25 
    25 
    26 
    26 
    27 static Window* StartWindowDrag(Window* w);
    27 static Window *StartWindowDrag(Window *w);
    28 static Window* StartWindowSizing(Window* w);
    28 static Window *StartWindowSizing(Window *w);
    29 
    29 
    30 static void DispatchLeftClickEvent(Window* w, int x, int y)
    30 static void DispatchLeftClickEvent(Window *w, int x, int y)
    31 {
    31 {
    32 	WindowEvent e;
    32 	WindowEvent e;
    33 	const Widget *wi;
    33 	const Widget *wi;
    34 
    34 
    35 	e.click.pt.x = x;
    35 	e.click.pt.x = x;
    84 	}
    84 	}
    85 
    85 
    86 	w->wndproc(w, &e);
    86 	w->wndproc(w, &e);
    87 }
    87 }
    88 
    88 
    89 static void DispatchRightClickEvent(Window* w, int x, int y)
    89 static void DispatchRightClickEvent(Window *w, int x, int y)
    90 {
    90 {
    91 	WindowEvent e;
    91 	WindowEvent e;
    92 
    92 
    93 	/* default tooltips handler? */
    93 	/* default tooltips handler? */
    94 	if (w->desc_flags & WDF_STD_TOOLTIPS) {
    94 	if (w->desc_flags & WDF_STD_TOOLTIPS) {
   112  * compatible scrollbars if the mouse is pointed over the bar or its contents
   112  * compatible scrollbars if the mouse is pointed over the bar or its contents
   113  * @param *w Window
   113  * @param *w Window
   114  * @param widget the widget where the scrollwheel was used
   114  * @param widget the widget where the scrollwheel was used
   115  * @param wheel scroll up or down
   115  * @param wheel scroll up or down
   116  */
   116  */
   117 static void DispatchMouseWheelEvent(Window* w, int widget, int wheel)
   117 static void DispatchMouseWheelEvent(Window *w, int widget, int wheel)
   118 {
   118 {
   119 	const Widget *wi1, *wi2;
   119 	const Widget *wi1, *wi2;
   120 	Scrollbar *sb;
   120 	Scrollbar *sb;
   121 
   121 
   122 	if (widget < 0) return;
   122 	if (widget < 0) return;
   140 		}
   140 		}
   141 	}
   141 	}
   142 }
   142 }
   143 
   143 
   144 
   144 
   145 static void DrawOverlappedWindow(Window* w, int left, int top, int right, int bottom);
   145 static void DrawOverlappedWindow(Window *w, int left, int top, int right, int bottom);
   146 
   146 
   147 void DrawOverlappedWindowForAll(int left, int top, int right, int bottom)
   147 void DrawOverlappedWindowForAll(int left, int top, int right, int bottom)
   148 {
   148 {
   149 	Window *w;
   149 	Window *w;
   150 	DrawPixelInfo bk;
   150 	DrawPixelInfo bk;
   158 			DrawOverlappedWindow(w, left, top, right, bottom);
   158 			DrawOverlappedWindow(w, left, top, right, bottom);
   159 		}
   159 		}
   160 	}
   160 	}
   161 }
   161 }
   162 
   162 
   163 static void DrawOverlappedWindow(Window* w, int left, int top, int right, int bottom)
   163 static void DrawOverlappedWindow(Window *w, int left, int top, int right, int bottom)
   164 {
   164 {
   165 	const Window* v = w;
   165 	const Window *v = w;
   166 	int x;
   166 	int x;
   167 
   167 
   168 	while (++v != _last_window) {
   168 	while (++v != _last_window) {
   169 		if (right > v->left &&
   169 		if (right > v->left &&
   170 				bottom > v->top &&
   170 				bottom > v->top &&
   217 
   217 
   218 	e.event = event;
   218 	e.event = event;
   219 	w->wndproc(w, &e);
   219 	w->wndproc(w, &e);
   220 }
   220 }
   221 
   221 
   222 void SetWindowDirty(const Window* w)
   222 void SetWindowDirty(const Window *w)
   223 {
   223 {
   224 	if (w == NULL) return;
   224 	if (w == NULL) return;
   225 	SetDirtyBlocks(w->left, w->top, w->left + w->width, w->top + w->height);
   225 	SetDirtyBlocks(w->left, w->top, w->left + w->width, w->top + w->height);
   226 }
   226 }
   227 
   227 
   291 		}
   291 		}
   292 	}
   292 	}
   293 }
   293 }
   294 
   294 
   295 
   295 
   296 static Window* BringWindowToFront(Window* w);
   296 static Window *BringWindowToFront(Window *w);
   297 
   297 
   298 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number)
   298 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number)
   299 {
   299 {
   300 	Window *w = FindWindowById(cls, number);
   300 	Window *w = FindWindowById(cls, number);
   301 
   301 
   318  * there are certain windows that always need to be on-top; these include
   318  * there are certain windows that always need to be on-top; these include
   319  * - Toolbar, Statusbar (always on)
   319  * - Toolbar, Statusbar (always on)
   320  * - New window, Chatbar (only if open)
   320  * - New window, Chatbar (only if open)
   321  * @param w window that is put into the foreground
   321  * @param w window that is put into the foreground
   322  */
   322  */
   323 static Window* BringWindowToFront(Window* w)
   323 static Window *BringWindowToFront(Window *w)
   324 {
   324 {
   325 	Window *v;
   325 	Window *v;
   326 	Window temp;
   326 	Window temp;
   327 
   327 
   328 	v = _last_window;
   328 	v = _last_window;
   376 		assert(w < _last_window);
   376 		assert(w < _last_window);
   377 		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w;
   377 		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w;
   378 	}
   378 	}
   379 }
   379 }
   380 
   380 
   381 bool IsWindowOfPrototype(const Window* w, const Widget* widget)
   381 bool IsWindowOfPrototype(const Window *w, const Widget *widget)
   382 {
   382 {
   383 	return (w->original_widget == widget);
   383 	return (w->original_widget == widget);
   384 }
   384 }
   385 
   385 
   386 /* Copies 'widget' to 'w->widget' to allow for resizable windows */
   386 /* Copies 'widget' to 'w->widget' to allow for resizable windows */
   388 {
   388 {
   389 	w->original_widget = widget;
   389 	w->original_widget = widget;
   390 
   390 
   391 	if (widget != NULL) {
   391 	if (widget != NULL) {
   392 		uint index = 1;
   392 		uint index = 1;
   393 		const Widget* wi;
   393 		const Widget *wi;
   394 
   394 
   395 		for (wi = widget; wi->type != WWT_LAST; wi++) index++;
   395 		for (wi = widget; wi->type != WWT_LAST; wi++) index++;
   396 
   396 
   397 		w->widget = realloc(w->widget, sizeof(*w->widget) * index);
   397 		w->widget = realloc(w->widget, sizeof(*w->widget) * index);
   398 		memcpy(w->widget, widget, sizeof(*w->widget) * index);
   398 		memcpy(w->widget, widget, sizeof(*w->widget) * index);
  1068 
  1068 
  1069 	_dragging_window = false;
  1069 	_dragging_window = false;
  1070 	return false;
  1070 	return false;
  1071 }
  1071 }
  1072 
  1072 
  1073 static Window* StartWindowDrag(Window* w)
  1073 static Window *StartWindowDrag(Window *w)
  1074 {
  1074 {
  1075 	w->flags4 |= WF_DRAGGING;
  1075 	w->flags4 |= WF_DRAGGING;
  1076 	_dragging_window = true;
  1076 	_dragging_window = true;
  1077 
  1077 
  1078 	_drag_delta.x = w->left - _cursor.pos.x;
  1078 	_drag_delta.x = w->left - _cursor.pos.x;
  1081 	w = BringWindowToFront(w);
  1081 	w = BringWindowToFront(w);
  1082 	DeleteWindowById(WC_DROPDOWN_MENU, 0);
  1082 	DeleteWindowById(WC_DROPDOWN_MENU, 0);
  1083 	return w;
  1083 	return w;
  1084 }
  1084 }
  1085 
  1085 
  1086 static Window* StartWindowSizing(Window* w)
  1086 static Window *StartWindowSizing(Window *w)
  1087 {
  1087 {
  1088 	w->flags4 |= WF_SIZING;
  1088 	w->flags4 |= WF_SIZING;
  1089 	_dragging_window = true;
  1089 	_dragging_window = true;
  1090 
  1090 
  1091 	_drag_delta.x = _cursor.pos.x;
  1091 	_drag_delta.x = _cursor.pos.x;
  1168 		dx = _cursor.delta.x;
  1168 		dx = _cursor.delta.x;
  1169 		dy = _cursor.delta.y;
  1169 		dy = _cursor.delta.y;
  1170 	}
  1170 	}
  1171 
  1171 
  1172 	if (w->window_class != WC_SMALLMAP) {
  1172 	if (w->window_class != WC_SMALLMAP) {
  1173 		ViewPort* vp = IsPtInWindowViewport(w, _cursor.pos.x, _cursor.pos.y);
  1173 		ViewPort *vp = IsPtInWindowViewport(w, _cursor.pos.x, _cursor.pos.y);
  1174 
  1174 
  1175 		if (vp == NULL)
  1175 		if (vp == NULL)
  1176 			goto stop_capt;
  1176 			goto stop_capt;
  1177 
  1177 
  1178 		WP(w,vp_d).scrollpos_x += dx << vp->zoom;
  1178 		WP(w,vp_d).scrollpos_x += dx << vp->zoom;
  1280  * @param w @see Window pointer pointing to the other window
  1280  * @param w @see Window pointer pointing to the other window
  1281  * @param msg Specifies the message to be sent
  1281  * @param msg Specifies the message to be sent
  1282  * @param wparam Specifies additional message-specific information
  1282  * @param wparam Specifies additional message-specific information
  1283  * @param lparam Specifies additional message-specific information
  1283  * @param lparam Specifies additional message-specific information
  1284  */
  1284  */
  1285 static void SendWindowMessageW(Window* w, uint msg, uint wparam, uint lparam)
  1285 static void SendWindowMessageW(Window *w, uint msg, uint wparam, uint lparam)
  1286 {
  1286 {
  1287 	WindowEvent e;
  1287 	WindowEvent e;
  1288 
  1288 
  1289 	e.message.event  = WE_MESSAGE;
  1289 	e.message.event  = WE_MESSAGE;
  1290 	e.message.msg    = msg;
  1290 	e.message.msg    = msg;
  1534 	return -1;
  1534 	return -1;
  1535 }
  1535 }
  1536 
  1536 
  1537 void InvalidateWindow(WindowClass cls, WindowNumber number)
  1537 void InvalidateWindow(WindowClass cls, WindowNumber number)
  1538 {
  1538 {
  1539 	const Window* w;
  1539 	const Window *w;
  1540 
  1540 
  1541 	for (w = _windows; w != _last_window; w++) {
  1541 	for (w = _windows; w != _last_window; w++) {
  1542 		if (w->window_class == cls && w->window_number == number) SetWindowDirty(w);
  1542 		if (w->window_class == cls && w->window_number == number) SetWindowDirty(w);
  1543 	}
  1543 	}
  1544 }
  1544 }
  1545 
  1545 
  1546 void InvalidateWidget(const Window* w, byte widget_index)
  1546 void InvalidateWidget(const Window *w, byte widget_index)
  1547 {
  1547 {
  1548 	const Widget *wi = &w->widget[widget_index];
  1548 	const Widget *wi = &w->widget[widget_index];
  1549 
  1549 
  1550 	/* Don't redraw the window if the widget is invisible or of no-type */
  1550 	/* Don't redraw the window if the widget is invisible or of no-type */
  1551 	if (wi->type == WWT_EMPTY || HASBIT(w->hidden_state, widget_index)) return;
  1551 	if (wi->type == WWT_EMPTY || HASBIT(w->hidden_state, widget_index)) return;
  1553 	SetDirtyBlocks(w->left + wi->left, w->top + wi->top, w->left + wi->right + 1, w->top + wi->bottom + 1);
  1553 	SetDirtyBlocks(w->left + wi->left, w->top + wi->top, w->left + wi->right + 1, w->top + wi->bottom + 1);
  1554 }
  1554 }
  1555 
  1555 
  1556 void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index)
  1556 void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index)
  1557 {
  1557 {
  1558 	const Window* w;
  1558 	const Window *w;
  1559 
  1559 
  1560 	for (w = _windows; w != _last_window; w++) {
  1560 	for (w = _windows; w != _last_window; w++) {
  1561 		if (w->window_class == cls && w->window_number == number) {
  1561 		if (w->window_class == cls && w->window_number == number) {
  1562 			InvalidateWidget(w, widget_index);
  1562 			InvalidateWidget(w, widget_index);
  1563 		}
  1563 		}
  1564 	}
  1564 	}
  1565 }
  1565 }
  1566 
  1566 
  1567 void InvalidateWindowClasses(WindowClass cls)
  1567 void InvalidateWindowClasses(WindowClass cls)
  1568 {
  1568 {
  1569 	const Window* w;
  1569 	const Window *w;
  1570 
  1570 
  1571 	for (w = _windows; w != _last_window; w++) {
  1571 	for (w = _windows; w != _last_window; w++) {
  1572 		if (w->window_class == cls) SetWindowDirty(w);
  1572 		if (w->window_class == cls) SetWindowDirty(w);
  1573 	}
  1573 	}
  1574 }
  1574 }