69 Point _cursorpos_drag_start;
 
   71 int _scrollbar_start_pos;
 
   73 byte _scroller_click_timeout = 0;
 
   95   parent_cls(parent_class),
 
   98   nwid_parts(nwid_parts),
 
   99   nwid_length(nwid_length),
 
  104   default_width_trad(def_width_trad),
 
  105   default_height_trad(def_height_trad)
 
  108   *_window_descs->
Append() = 
this;
 
  111 WindowDesc::~WindowDesc()
 
  113   _window_descs->
Erase(_window_descs->
Find(
this));
 
  144     if ((*it)->ini_key == NULL) 
continue;
 
  155   if ((*a)->ini_key != NULL && (*b)->ini_key != NULL) 
return strcmp((*a)->ini_key, (*b)->ini_key);
 
  156   return ((*b)->ini_key != NULL ? 1 : 0) - ((*a)->ini_key != NULL ? 1 : 0);
 
  170     if ((*it)->ini_key == NULL) 
continue;
 
  201   const NWidgetBase *wid = this->GetWidget<NWidgetBase>(widget);
 
  202   if (line_height < 0) line_height = wid->
resize_y;
 
  203   if (clickpos < (
int)wid->
pos_y + padding) 
return INT_MAX;
 
  204   return (clickpos - (
int)wid->
pos_y - padding) / line_height;
 
  213     NWidgetBase *nwid = this->GetWidget<NWidgetBase>(i);
 
  214     if (nwid == NULL) 
continue;
 
  216     if (nwid->IsHighlighted()) {
 
  217       nwid->SetHighlighted(TC_INVALID);
 
  234   NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget_index);
 
  235   if (nwid == NULL) 
return;
 
  237   nwid->SetHighlighted(highlighted_colour);
 
  240   if (highlighted_colour != TC_INVALID) {
 
  247       NWidgetBase *nwid = this->GetWidget<NWidgetBase>(i);
 
  248       if (nwid == NULL) 
continue;
 
  249       if (!nwid->IsHighlighted()) 
continue;
 
  267   const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget_index);
 
  268   if (nwid == NULL) 
return false;
 
  270   return nwid->IsHighlighted();
 
  282   if (widget < 0) 
return;
 
  293   NWidgetCore *nwi2 = this->GetWidget<NWidgetCore>(widget);
 
  309   return this->GetWidget<NWidgetScrollbar>(widnum);
 
  319   return this->GetWidget<NWidgetScrollbar>(widnum);
 
  410   Rect r = {0, 0, 0, 0};
 
  434   if (_focused_window == w) 
return;
 
  437   if (_focused_window != NULL) {
 
  442   Window *old_focused = _focused_window;
 
  446   if (old_focused != NULL) old_focused->
OnFocusLost();
 
  447   if (_focused_window != NULL) _focused_window->
OnFocus();
 
  457   if (_focused_window == NULL) 
return false;
 
  491     if (this->GetWidget<NWidgetCore>(widget_index) == this->
nested_focus) 
return false;
 
  497   this->
nested_focus = this->GetWidget<NWidgetCore>(widget_index);
 
  520   va_start(wdg_list, widgets);
 
  524     widgets = va_arg(wdg_list, 
int);
 
  539   va_start(wdg_list, widgets);
 
  543     widgets = va_arg(wdg_list, 
int);
 
  558     if (((type & ~WWB_PUSHBUTTON) < 
WWT_LAST || type == NWID_PUSHBUTTON_DROPDOWN) &&
 
  594   NWidgetCore *nw = this->GetWidget<NWidgetCore>(hotkey);
 
  637   bool focused_widget_changed = 
false;
 
  639   if (_focused_window != w &&                 
 
  642     focused_widget_changed = 
true;
 
  646   if (nw == NULL) 
return; 
 
  651   int widget_index = nw->
index; 
 
  677   switch (widget_type) {
 
  685       if (query != NULL) query->ClickEditBox(w, pt, widget_index, click_count, focused_widget_changed);
 
  747   if (widget_index < 0) 
return;
 
  755   w->
OnClick(pt, widget_index, click_count);
 
  767   if (wid == NULL) 
return;
 
  770   if (wid->
index >= 0) {
 
  789   if (wid == NULL) 
return;
 
  798   if (wid->
index < 0) 
return;
 
  813   if (nwid == NULL) 
return;
 
  879         left < v->left + v->
width &&
 
  880         top < v->top + v->
height) {
 
  884       if (left < (x = v->
left)) {
 
  896       if (top < (x = v->
top)) {
 
  914   dp->width = right - left;
 
  915   dp->height = bottom - top;
 
  916   dp->left = left - w->
left;
 
  917   dp->top = top - w->
top;
 
  918   dp->pitch = _screen.pitch;
 
  938   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
  942         left < w->left + w->
width &&
 
  943         top < w->top + w->
height) {
 
  970   int window_width  = this->
width;
 
  971   int window_height = this->
height;
 
  983   window_width  = 
max(window_width  + rx, this->
width);
 
  984   window_height = 
max(window_height + ry, this->
height);
 
 1031   FOR_ALL_WINDOWS_FROM_BACK(v) {
 
 1045   while (child != NULL) {
 
 1062   if (_mouseover_last_w == 
this) _mouseover_last_w = NULL;
 
 1065   if (_last_scroll_window == 
this) _last_scroll_window = NULL;
 
 1068   if (_focused_window == 
this) {
 
 1070     _focused_window = NULL;
 
 1075   if (this->
viewport != NULL) DeleteWindowViewport(
this);
 
 1103   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1119   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1135   if (force || w == NULL ||
 
 1153   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1156       goto restart_search;
 
 1175   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1176     if (w->
owner == 
id) {
 
 1178       goto restart_search;
 
 1196   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1197     if (w->
owner != old_owner) 
continue;
 
 1214         w->
owner = new_owner;
 
 1244 static inline bool IsVitalWindow(
const Window *w)
 
 1270   uint z_priority = 0;
 
 1336   if (_z_front_window == NULL) {
 
 1338     _z_front_window = _z_back_window = w;
 
 1343     uint last_z_priority = UINT_MAX;
 
 1358       _z_back_window->
z_back = w;
 
 1360     } 
else if (v == _z_front_window) {
 
 1365       _z_front_window = w;
 
 1384     assert(_z_front_window == w);
 
 1385     _z_front_window = w->
z_back;
 
 1391     assert(_z_back_window == w);
 
 1467   this->
width = sm_width;
 
 1468   this->
height = sm_height;
 
 1483   def_width  = 
max(def_width,  this->
width); 
 
 1484   def_height = 
max(def_height, this->
height);
 
 1490   if (this->
width != def_width || this->
height != def_height) {
 
 1492     int free_height = _screen.height;
 
 1494     if (wt != NULL) free_height -= wt->
height;
 
 1496     if (wt != NULL) free_height -= wt->
height;
 
 1498     int enlarge_x = 
max(
min(def_width  - this->
width,  _screen.width - this->width),  0);
 
 1514   int nx = this->
left;
 
 1517   if (nx + this->
width > _screen.width) nx -= (nx + this->
width - _screen.width);
 
 1520   ny = 
max(ny, (wt == NULL || 
this == wt || this->
top == 0) ? 0 : wt->
height);
 
 1546   int right  = width + left;
 
 1547   int bottom = height + top;
 
 1550   if (left < 0 || (main_toolbar != NULL && top < main_toolbar->height) || right > _screen.width || bottom > _screen.height) 
return false;
 
 1554   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1557     if (right > w->
left &&
 
 1586   if (left < -(width >> 2) || left > _screen.width - (width >> 1)) 
return false;
 
 1588   if (top < 22 || top > _screen.height - (height >> 2)) 
return false;
 
 1592   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1595     if (left + width > w->
left &&
 
 1597         top + height > w->
top &&
 
 1620   if (
IsGoodAutoPlace1(0, main_toolbar != NULL ? main_toolbar->
height + 2 : 2, width, height, pt)) 
return pt;
 
 1627   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1644   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1656   int left = 0, top = 24;
 
 1659   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1660     if (w->
left == left && w->
top == top) {
 
 1713       w->
left < _screen.width - 20 && w->
left > -60 && w->
top < _screen.height - 20) {
 
 1716     if (pt.x > _screen.width + 10 - default_width) {
 
 1717       pt.x = (_screen.width + 10 - default_width) - 20;
 
 1731       pt.x = (_screen.width - default_width) / 2;
 
 1732       pt.y = (_screen.height - default_height) / 2;
 
 1761   int biggest_index = -1;
 
 1812   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 1828   _z_back_window = NULL;
 
 1829   _z_front_window = NULL;
 
 1830   _focused_window = NULL;
 
 1831   _mouseover_last_w = NULL;
 
 1832   _last_scroll_window = NULL;
 
 1837   NWidgetScrollbar::InvalidateDimensionCache();
 
 1850   FOR_ALL_WINDOWS_FROM_FRONT(w) 
delete w;
 
 1852   for (w = _z_front_window; w != NULL; ) {
 
 1858   _z_front_window = NULL;
 
 1859   _z_back_window = NULL;
 
 1872 static void DecreaseWindowCounters()
 
 1875   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 1876     if (_scroller_click_timeout == 0) {
 
 1893       it->second->HandleEditBox(w, it->first);
 
 1899   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 1909 static void HandlePlacePresize()
 
 1914   if (w == NULL) 
return;
 
 1916   Point pt = GetTileBelowCursor();
 
 1939     pt.x = _cursor.
pos.x - w->
left;
 
 1940     pt.y = _cursor.
pos.y - w->
top;
 
 1958   if (_mouseover_last_w != NULL && _mouseover_last_w != w) {
 
 1960     Point pt = { -1, -1 };
 
 1965   _mouseover_last_w = w;
 
 1996   if (v == NULL) 
return;
 
 2000   int safe_y = (dir == 
PHD_UP) ? (v->
top - MIN_VISIBLE_TITLE_BAR - rect.top) : (v_bottom + MIN_VISIBLE_TITLE_BAR - rect.bottom); 
 
 2002   if (*ny + rect.top <= v->
top - MIN_VISIBLE_TITLE_BAR) 
return; 
 
 2003   if (*ny + rect.bottom >= v_bottom + MIN_VISIBLE_TITLE_BAR) 
return; 
 
 2006   if (*nx + rect.left + MIN_VISIBLE_TITLE_BAR < v->left) { 
 
 2007     if (v->
left < MIN_VISIBLE_TITLE_BAR) *ny = safe_y; 
 
 2010   if (*nx + rect.right - MIN_VISIBLE_TITLE_BAR > v_right) { 
 
 2011     if (v_right > _screen.width - MIN_VISIBLE_TITLE_BAR) *ny = safe_y; 
 
 2016   if (px + rect.left < v->
left && v->
left >= MIN_VISIBLE_TITLE_BAR) { 
 
 2017     *nx = v->
left - MIN_VISIBLE_TITLE_BAR - rect.left;
 
 2018   } 
else if (px + rect.right > v_right && v_right <= _screen.width - MIN_VISIBLE_TITLE_BAR) { 
 
 2019     *nx = v_right + MIN_VISIBLE_TITLE_BAR - rect.right;
 
 2037   if (caption != NULL) {
 
 2038     caption_rect.left   = caption->
pos_x;
 
 2040     caption_rect.top    = caption->
pos_y;
 
 2044     nx = 
Clamp(nx, MIN_VISIBLE_TITLE_BAR - caption_rect.right, _screen.width - MIN_VISIBLE_TITLE_BAR - caption_rect.left);
 
 2045     ny = 
Clamp(ny, 0, _screen.height - MIN_VISIBLE_TITLE_BAR);
 
 2073   if (delta_x != 0 || delta_y != 0) {
 
 2074     if (clamp_to_screen) {
 
 2077       int new_right  = w->
left + w->
width  + delta_x;
 
 2078       int new_bottom = w->
top  + w->
height + delta_y;
 
 2110   return (w == NULL) ? 0 : w->
top + w->
height;
 
 2121   return (w == NULL) ? _screen.height : w->
top;
 
 2140   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 2150       int x = _cursor.
pos.x + _drag_delta.x;
 
 2151       int y = _cursor.
pos.y + _drag_delta.y;
 
 2162         FOR_ALL_WINDOWS_FROM_BACK(v) {
 
 2163           if (v == w) 
continue; 
 
 2168             if (delta <= hsnap) {
 
 2175             if (delta <= hsnap) {
 
 2184             if (delta <= hsnap) {
 
 2191             if (delta <= hsnap) {
 
 2200             if (delta <= vsnap) {
 
 2207             if (delta <= vsnap) {
 
 2216             if (delta <= vsnap) {
 
 2223             if (delta <= vsnap) {
 
 2246       int x, y = _cursor.
pos.y - _drag_delta.y;
 
 2248         x = _drag_delta.x - _cursor.
pos.x;
 
 2250         x = _cursor.
pos.x - _drag_delta.x;
 
 2258       if (w->
top + w->
height + y > _screen.height) {
 
 2259         y = _screen.height - w->
height - w->
top;
 
 2296   _dragging_window = 
false;
 
 2308   _dragging_window = 
true;
 
 2310   _drag_delta.x = w->
left - _cursor.
pos.x;
 
 2311   _drag_delta.y = w->
top  - _cursor.
pos.y;
 
 2326   _dragging_window = 
true;
 
 2328   _drag_delta.x = _cursor.
pos.x;
 
 2329   _drag_delta.y = _cursor.
pos.y;
 
 2342   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 2356         i = _cursor.
pos.x - _cursorpos_drag_start.x;
 
 2359         i = _cursor.
pos.y - _cursorpos_drag_start.y;
 
 2363         if (_scroller_click_timeout == 1) {
 
 2364           _scroller_click_timeout = 3;
 
 2403     _last_scroll_window = NULL;
 
 2416     delta.x = -_cursor.
delta.x;
 
 2417     delta.y = -_cursor.
delta.y;
 
 2419     delta.x = _cursor.
delta.x;
 
 2420     delta.y = _cursor.
delta.y;
 
 2423   if (scrollwheel_scrolling) {
 
 2425     delta.x = _cursor.h_wheel;
 
 2426     delta.y = _cursor.v_wheel;
 
 2427     _cursor.v_wheel = 0;
 
 2428     _cursor.h_wheel = 0;
 
 2432   if (delta.x != 0 || delta.y != 0) _last_scroll_window->
OnScroll(delta);
 
 2434   _cursor.
delta.x = 0;
 
 2435   _cursor.
delta.y = 0;
 
 2451   bool bring_to_front = 
false;
 
 2461   int w_width  = w->
width;
 
 2462   int w_height = w->
height;
 
 2485     if (w->
left + w_width <= u->left ||
 
 2487         w->
top  + w_height <= u->top ||
 
 2492     bring_to_front = 
true;
 
 2514   switch (query->text.HandleKeyPress(key, keycode)) {
 
 2558       if (query->text.
bytes <= 1) {
 
 2593   if (key >= 0xE000 && key <= 0xF8FF) key = 0;
 
 2598   if (key == 0 && keycode == 0) 
return;
 
 2612   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 2631   HandleGlobalHotkeys(key, keycode);
 
 2641   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 2651  void Window::InsertTextString(
int wid, 
const char *str, 
bool marked, 
const char *caret, 
const char *insert_location, 
const char *replacement_end)
 
 2654   if (query == NULL) 
return;
 
 2656   if (query->text.
InsertString(str, marked, caret, insert_location, replacement_end) || marked) {
 
 2668 void HandleTextInput(
const char *str, 
bool marked, 
const char *caret, 
const char *insert_location, 
const char *replacement_end)
 
 2693   int x = _cursor.
pos.x;
 
 2694   int y = _cursor.
pos.y;
 
 2700   if (vp == NULL) 
return;
 
 2706 #define scrollspeed 3 
 2709   } 
else if (15 - (vp->
width - x) > 0) {
 
 2714   } 
else if (15 - (vp->
height - y) > 0) {
 
 2733 static void ScrollMainViewport(
int x, 
int y)
 
 2735   if (_game_mode != GM_MENU) {
 
 2772 static void HandleKeyScrolling()
 
 2780     ScrollMainViewport(scrollamt[
_dirkeys][0] * factor, scrollamt[
_dirkeys][1] * factor);
 
 2784 static void MouseLoop(
MouseClick click, 
int mousewheel)
 
 2790   HandlePlacePresize();
 
 2802   if (click == MC_NONE && mousewheel == 0 && !scrollwheel_scrolling) 
return;
 
 2804   int x = _cursor.
pos.x;
 
 2805   int y = _cursor.
pos.y;
 
 2807   if (w == NULL) 
return;
 
 2815   if (mousewheel != 0) {
 
 2824     if (scrollwheel_scrolling) click = MC_RIGHT; 
 
 2826       case MC_DOUBLE_LEFT:
 
 2828         if (!HandleViewportClicked(vp, x, y) &&
 
 2842           _cursor.h_wheel = 0;
 
 2843           _cursor.v_wheel = 0;
 
 2853       case MC_DOUBLE_LEFT:
 
 2879   static int double_click_time = 0;
 
 2880   static Point double_click_pos = {0, 0};
 
 2889       click = MC_DOUBLE_LEFT;
 
 2892     double_click_pos = _cursor.
pos;
 
 2894     _input_events_this_tick++;
 
 2898     _input_events_this_tick++;
 
 2902   if (_cursor.
wheel) {
 
 2903     mousewheel = _cursor.
wheel;
 
 2905     _input_events_this_tick++;
 
 2908   static uint32 hover_time = 0;
 
 2909   static Point hover_pos = {0, 0};
 
 2915       hover_pos = _cursor.
pos;
 
 2921         _input_events_this_tick++;
 
 2943     MouseLoop(click, mousewheel);
 
 2948   _cursor.
delta.x = 0;
 
 2949   _cursor.
delta.y = 0;
 
 2960     uint deletable_count = 0;
 
 2961     Window *w, *last_deletable = NULL;
 
 2962     FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 2972     assert(last_deletable != NULL);
 
 2973     delete last_deletable;
 
 2987   HandleKeyScrolling();
 
 2990   for (
Window *v = _z_front_window; v != NULL; ) {
 
 3000   if (_scroller_click_timeout != 0) _scroller_click_timeout--;
 
 3001   DecreaseWindowCounters();
 
 3003   if (_input_events_this_tick != 0) {
 
 3005     _input_events_this_tick = 0;
 
 3022   static int highlight_timer = 1;
 
 3023   if (--highlight_timer == 0) {
 
 3024     highlight_timer = 15;
 
 3028   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 3037   static int we4_timer = 0;
 
 3038   int t = we4_timer + 1;
 
 3041     FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 3048   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 3057   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3074   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3088   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3102   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3174   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3193   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3206   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 3225   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3234       goto restart_search;
 
 3257   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3260       goto restart_search;
 
 3277   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3280       goto restart_search;
 
 3284   FOR_ALL_WINDOWS_FROM_BACK(w) w->
SetDirty();
 
 3298   NWidgetScrollbar::InvalidateDimensionCache();
 
 3304   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3307 #ifdef ENABLE_NETWORK 
 3329   if (w == NULL) 
return 0;
 
 3331   int old_left = w->
left;
 
 3333     case 1:  w->
left = (_screen.width - w->
width) / 2; 
break;
 
 3334     case 2:  w->
left = _screen.width - w->
width; 
break;
 
 3335     default: w->
left = 0; 
break;
 
 3349   DEBUG(misc, 5, 
"Repositioning Main Toolbar...");
 
 3360   DEBUG(misc, 5, 
"Repositioning statusbar...");
 
 3371   DEBUG(misc, 5, 
"Repositioning news message...");
 
 3382   DEBUG(misc, 5, 
"Repositioning network chat window...");
 
 3395   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3413   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 3455           top = (newh - w->
height) >> 1;
 
 3456           left = (neww - w->
width) >> 1;
 
 3461         if (left + (w->
width >> 1) >= neww) left = neww - w->
width;
 
 3462         if (left < 0) left = 0;
 
 3465         if (top + (w->
height >> 1) >= newh) top = newh - w->
height;