window.c
changeset 867 dffd33233237
parent 857 cd1fdb44121d
child 959 e6a3bbda610f
equal deleted inserted replaced
866:d242235e6485 867:dffd33233237
    49 		}
    49 		}
    50 
    50 
    51 		w->wndproc(w, &e);
    51 		w->wndproc(w, &e);
    52 
    52 
    53 		if (w->desc_flags & WDF_STD_BTN) {
    53 		if (w->desc_flags & WDF_STD_BTN) {
    54 			if (e.click.widget == 0) DeleteWindow(w);
    54 			if (e.click.widget == 0) {
    55 			else {
    55 				DeleteWindow(w);
       
    56 			} else {
    56 				if (e.click.widget == 1) {
    57 				if (e.click.widget == 1) {
    57 					if (_ctrl_pressed)
    58 					StartWindowDrag(w);
    58 						StartWindowSizing(w);
       
    59 					else
       
    60 						StartWindowDrag(w);
       
    61 				}
    59 				}
    62 			}
    60 			}
    63 		}
    61 		}
    64 		
    62 
    65 		if (w->desc_flags & WDF_STICKY_BUTTON) {
    63 		if (w->desc_flags & WDF_RESIZABLE && wi->type == WWT_RESIZEBOX) {
    66 			if (e.click.widget == 2) {
    64 			StartWindowSizing(w);
    67 				w->click_state ^= (1 << e.click.widget);
    65 		}
    68 				w->flags4 ^= WF_STICKY;
    66 
    69 				InvalidateWidget(w, e.click.widget);
    67 		if (w->desc_flags & WDF_STICKY_BUTTON && wi->type == WWT_STICKYBOX) {
    70 			}
    68 			w->click_state ^= (1 << e.click.widget);
       
    69 			w->flags4 ^= WF_STICKY;
       
    70 			InvalidateWidget(w, e.click.widget);
    71 		}
    71 		}
    72 	} else {
    72 	} else {
    73 		w->wndproc(w, &e);
    73 		w->wndproc(w, &e);
    74 	}
    74 	}
    75 }
    75 }
   221 		vp->width = 0;
   221 		vp->width = 0;
   222 	}
   222 	}
   223 
   223 
   224 	SetWindowDirty(w);
   224 	SetWindowDirty(w);
   225 
   225 
       
   226 	free(w->widget);
       
   227 
   226 	v = --_last_window;
   228 	v = --_last_window;
   227 	count = (byte*)v - (byte*)w;
   229 	count = (byte*)v - (byte*)w;
   228 	memcpy(w, w + 1, count);
   230 	memcpy(w, w + 1, count);
   229 }
   231 }
   230 
   232 
   308 		assert(w < _last_window);
   310 		assert(w < _last_window);
   309 
   311 
   310 		if (w->window_class != WC_MAIN_WINDOW && w->window_class != WC_MAIN_TOOLBAR &&
   312 		if (w->window_class != WC_MAIN_WINDOW && w->window_class != WC_MAIN_TOOLBAR &&
   311 			  w->window_class != WC_STATUS_BAR && w->window_class != WC_NEWS_WINDOW)
   313 			  w->window_class != WC_STATUS_BAR && w->window_class != WC_NEWS_WINDOW)
   312 				return w;
   314 				return w;
       
   315 	}
       
   316 }
       
   317 
       
   318 bool IsWindowOfPrototype(Window *w, const Widget *widget)
       
   319 {
       
   320 	return (w->original_widget == widget);
       
   321 }
       
   322 
       
   323 /* Copies 'widget' to 'w->widget' */
       
   324 void AssignWidgetToWindow(Window *w, const Widget *widget)
       
   325 {
       
   326 	w->original_widget = widget;
       
   327 
       
   328 	if (widget != NULL) {
       
   329 		const Widget *wi = widget;
       
   330 		uint index = 1;
       
   331 		while (wi->type != WWT_LAST) {
       
   332 			wi++;
       
   333 			index++;
       
   334 		}
       
   335 
       
   336 		w->widget = malloc(sizeof(Widget) * index);
       
   337 		memcpy(w->widget, widget, sizeof(Widget) * index);
       
   338 	} else {
       
   339 		w->widget = NULL;
   313 	}
   340 	}
   314 }
   341 }
   315 
   342 
   316 Window *AllocateWindow(
   343 Window *AllocateWindow(
   317 							int x,
   344 							int x,
   371 //	w->unk22 = 0xFFFF;
   398 //	w->unk22 = 0xFFFF;
   372 	w->vscroll.pos = 0;
   399 	w->vscroll.pos = 0;
   373 	w->vscroll.count = 0;
   400 	w->vscroll.count = 0;
   374 	w->hscroll.pos = 0;
   401 	w->hscroll.pos = 0;
   375 	w->hscroll.count = 0;
   402 	w->hscroll.count = 0;
   376 	w->widget = widget;
   403 	AssignWidgetToWindow(w, widget);
       
   404 	w->resize.width = width;
       
   405 	w->resize.height = height;
       
   406 	w->resize.step_width = 1;
       
   407 	w->resize.step_height = 1;
   377 
   408 
   378 	{
   409 	{
   379 		int i;
   410 		int i;
   380 		for (i=0;i<lengthof(w->custom);i++)
   411 		for (i=0;i<lengthof(w->custom);i++)
   381 			w->custom[i] = 0;
   412 			w->custom[i] = 0;
   898 			w->left = nx;
   929 			w->left = nx;
   899 			w->top  = ny;
   930 			w->top  = ny;
   900 
   931 
   901 			SetWindowDirty(w);
   932 			SetWindowDirty(w);
   902 			return false;
   933 			return false;
       
   934 		} else if (w->flags4 & WF_SIZING) {
       
   935 			WindowEvent e;
       
   936 			int x, y;
       
   937 
       
   938 			/* Stop the sizing if the left mouse button was released */
       
   939 			if (!_left_button_down) {
       
   940 				w->flags4 &= ~WF_SIZING;
       
   941 				break;
       
   942 			}
       
   943 
       
   944 			x = _cursor.pos.x - _drag_delta.x;
       
   945 			y = _cursor.pos.y - _drag_delta.y;
       
   946 
       
   947 			/* X and Y has to go by step.. calculate it */
       
   948 			if (w->resize.step_width > 1)
       
   949 				x = x - (x % (int)w->resize.step_width);
       
   950 
       
   951 			if (w->resize.step_height > 1)
       
   952 				y = y - (y % (int)w->resize.step_height);
       
   953 
       
   954 			/* Check if we don't go below the minimum set size */
       
   955 			if ((int)w->width + x < (int)w->resize.width)
       
   956 				x = w->resize.width - w->width;
       
   957 			if ((int)w->height + y < (int)w->resize.height)
       
   958 				y = w->resize.height - w->height;
       
   959 
       
   960 			/* Window already on size */
       
   961 			if (x == 0 && y == 0)
       
   962 				return false;
       
   963 
       
   964 			/* Now find the new cursor pos.. this is NOT _cursor, because
       
   965 			    we move in steps. */
       
   966 			_drag_delta.x += x;
       
   967 			_drag_delta.y += y;
       
   968 
       
   969 			SetWindowDirty(w);
       
   970 
       
   971 			/* Scroll through all the windows and update the widgets if needed */
       
   972 			{
       
   973 				Widget *wi = w->widget;
       
   974 				bool resize_height = false;
       
   975 				bool resize_width = false;
       
   976 
       
   977 				while (wi->type != WWT_LAST) {
       
   978 					if (wi->resize_flag != RESIZE_NONE) {
       
   979 						/* Resize this widget */
       
   980 						if (wi->resize_flag & RESIZE_LEFT) {
       
   981 							wi->left += x;
       
   982 							resize_width = true;
       
   983 						}
       
   984 						if (wi->resize_flag & RESIZE_RIGHT) {
       
   985 							wi->right += x;
       
   986 							resize_width = true;
       
   987 						}
       
   988 
       
   989 						if (wi->resize_flag & RESIZE_TOP) {
       
   990 							wi->top += y;
       
   991 							resize_height = true;
       
   992 						}
       
   993 						if (wi->resize_flag & RESIZE_BOTTOM) {
       
   994 							wi->bottom += y;
       
   995 							resize_height = true;
       
   996 						}
       
   997 					}
       
   998 					wi++;
       
   999 				}
       
  1000 
       
  1001 				/* We resized at least 1 widget, so let's rezise the window totally */
       
  1002 				if (resize_width)
       
  1003 					w->width  = x + w->width;
       
  1004 				if (resize_height)
       
  1005 					w->height = y + w->height;
       
  1006 			}
       
  1007 
       
  1008 			e.event = WE_RESIZE;
       
  1009 			e.sizing.size.x = x + w->width;
       
  1010 			e.sizing.size.y = y + w->height;
       
  1011 			e.sizing.diff.x = x;
       
  1012 			e.sizing.diff.y = y;
       
  1013 			w->wndproc(w, &e);
       
  1014 
       
  1015 			SetWindowDirty(w);
       
  1016 			return false;
   903 		}
  1017 		}
   904 	}
  1018 	}
   905 
  1019 
   906 	_dragging_window = false;
  1020 	_dragging_window = false;
   907 	return false;
  1021 	return false;
   909 
  1023 
   910 Window *StartWindowDrag(Window *w)
  1024 Window *StartWindowDrag(Window *w)
   911 {
  1025 {
   912 	w->flags4 |= WF_DRAGGING;
  1026 	w->flags4 |= WF_DRAGGING;
   913 	_dragging_window = true;
  1027 	_dragging_window = true;
       
  1028 
   914 	_drag_delta.x = w->left - _cursor.pos.x;
  1029 	_drag_delta.x = w->left - _cursor.pos.x;
   915 	_drag_delta.y = w->top  - _cursor.pos.y;
  1030 	_drag_delta.y = w->top  - _cursor.pos.y;
       
  1031 
   916 	w = BringWindowToFront(w);
  1032 	w = BringWindowToFront(w);
   917 	DeleteWindowById(WC_DROPDOWN_MENU, 0);
  1033 	DeleteWindowById(WC_DROPDOWN_MENU, 0);
   918 	return w;
  1034 	return w;
   919 }
  1035 }
   920 
  1036 
   921 Window *StartWindowSizing(Window *w)
  1037 Window *StartWindowSizing(Window *w)
   922 {
  1038 {
   923 	w->flags4 |= WF_SIZING;
  1039 	w->flags4 |= WF_SIZING;
   924 	_dragging_window = true;
  1040 	_dragging_window = true;
   925 	_cursorpos_drag_start = _cursor.pos;
  1041 
       
  1042 	_drag_delta.x = _cursor.pos.x;
       
  1043 	_drag_delta.y = _cursor.pos.y;
       
  1044 
   926 	w = BringWindowToFront(w);
  1045 	w = BringWindowToFront(w);
   927 	DeleteWindowById(WC_DROPDOWN_MENU, 0);
  1046 	DeleteWindowById(WC_DROPDOWN_MENU, 0);
   928 	return w;
  1047 	return w;
   929 }
  1048 }
   930 
  1049 
  1088 
  1207 
  1089 static void HandleKeypress(uint32 key)
  1208 static void HandleKeypress(uint32 key)
  1090 {
  1209 {
  1091 	Window *w;
  1210 	Window *w;
  1092 	WindowEvent we;
  1211 	WindowEvent we;
  1093  /* Stores if a window with a textfield for typing is open 	
  1212  /* Stores if a window with a textfield for typing is open
  1094   * If this is the case, keypress events are only passed to windows with text fields and 
  1213   * If this is the case, keypress events are only passed to windows with text fields and
  1095 	* to thein this main toolbar. */
  1214 	* to thein this main toolbar. */
  1096 	bool query_open = false;
  1215 	bool query_open = false;
  1097 
  1216 
  1098 	// Setup event
  1217 	// Setup event
  1099 	we.keypress.event = WE_KEYPRESS;
  1218 	we.keypress.event = WE_KEYPRESS;
  1367 			w++;
  1486 			w++;
  1368 		}
  1487 		}
  1369 	}
  1488 	}
  1370 }
  1489 }
  1371 
  1490 
  1372 /* It is possible that a stickied window gets to a position where the 
  1491 /* It is possible that a stickied window gets to a position where the
  1373  * 'close' button is outside the gaming area. You cannot close it then; except
  1492  * 'close' button is outside the gaming area. You cannot close it then; except
  1374  * with this function. It closes all windows calling the standard function,
  1493  * with this function. It closes all windows calling the standard function,
  1375  * then, does a little hacked loop of closing all stickied windows. Note
  1494  * then, does a little hacked loop of closing all stickied windows. Note
  1376  * that standard windows (status bar, etc.) are not stickied, so these aren't affected */
  1495  * that standard windows (status bar, etc.) are not stickied, so these aren't affected */
  1377 void DeleteAllNonVitalWindows(void)
  1496 void DeleteAllNonVitalWindows(void)