# HG changeset patch # User tron # Date 1100121256 0 # Node ID 67a59a1226b5c1842d58008080e7a496cea79c2d # Parent 47cdc8ab9cf71c3d1098547d16e19bc9ce16d96d (svn r538) -Feature: Windows snap at each other This is inspired by [1063636]. diff -r 47cdc8ab9cf7 -r 67a59a1226b5 lang/english.txt --- a/lang/english.txt Mon Nov 08 22:21:14 2004 +0000 +++ b/lang/english.txt Wed Nov 10 21:14:16 2004 +0000 @@ -1040,6 +1040,8 @@ STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Left STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Right +STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Window snap radius: {ORANGE}{STRING} px +STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Window snap radius: {ORANGE}disabled STR_CONFIG_PATCHES_GUI :{BLACK}Interface STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construction diff -r 47cdc8ab9cf7 -r 67a59a1226b5 lang/german.txt --- a/lang/german.txt Mon Nov 08 22:21:14 2004 +0000 +++ b/lang/german.txt Wed Nov 10 21:14:16 2004 +0000 @@ -1040,6 +1040,8 @@ STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Links STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Mitte STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Rechts +STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Fenster schnappen aneinander, wenn näher als: {ORANGE}{STRING} px +STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Fenster schnappen aneinander, wenn näher als: {ORANGE}ausgeschaltet STR_CONFIG_PATCHES_GUI :{BLACK}Oberfläche STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruktion diff -r 47cdc8ab9cf7 -r 67a59a1226b5 settings.c --- a/settings.c Mon Nov 08 22:21:14 2004 +0000 +++ b/settings.c Wed Nov 10 21:14:16 2004 +0000 @@ -829,6 +829,7 @@ {"realistic_acceleration",SDT_BOOL, (void*)false, (void*)offsetof(Patches, realistic_acceleration), NULL}, {"toolbar_pos", SDT_UINT8, (void*)0, (void*)offsetof(Patches, toolbar_pos), NULL}, + {"window_snap_radius", SDT_UINT8, (void*)10, (void*)offsetof(Patches, window_snap_radius), NULL}, {"max_trains", SDT_UINT8, (void*)80, (void*)offsetof(Patches, max_trains), NULL}, {"max_roadveh", SDT_UINT8, (void*)80, (void*)offsetof(Patches, max_roadveh), NULL}, diff -r 47cdc8ab9cf7 -r 67a59a1226b5 settings_gui.c --- a/settings_gui.c Mon Nov 08 22:21:14 2004 +0000 +++ b/settings_gui.c Wed Nov 10 21:14:16 2004 +0000 @@ -572,6 +572,7 @@ {PE_UINT8, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION, &_patches.errmsg_duration, 0, 20, 1, NULL}, {PE_UINT8, PF_MULTISTRING, STR_CONFIG_PATCHES_TOOLBAR_POS, &_patches.toolbar_pos, 0, 2, 1, &v_PositionMainToolbar}, + {PE_UINT8, PF_0ISDIS, STR_CONFIG_PATCHES_SNAP_RADIUS, &_patches.window_snap_radius, 1, 32, 1, NULL}, {PE_BOOL, 0, STR_CONFIG_PATCHES_INVISIBLE_TREES, &_patches.invisible_trees, 0, 1, 1, &InvisibleTreesActive}, }; diff -r 47cdc8ab9cf7 -r 67a59a1226b5 variables.h --- a/variables.h Mon Nov 08 22:21:14 2004 +0000 +++ b/variables.h Wed Nov 10 21:14:16 2004 +0000 @@ -114,6 +114,7 @@ bool invisible_trees; // don't show trees when buildings are transparent uint8 toolbar_pos; // position of toolbars, 0=left, 1=center, 2=right + uint8 window_snap_radius; // Windows snap at each other if closer than this byte max_trains; //max trains in game per player (these are 8bit because the unitnumber field can't hold more) byte max_roadveh; //max trucks in game per player diff -r 47cdc8ab9cf7 -r 67a59a1226b5 window.c --- a/window.c Mon Nov 08 22:21:14 2004 +0000 +++ b/window.c Wed Nov 10 21:14:16 2004 +0000 @@ -5,6 +5,9 @@ #include "viewport.h" #include "console.h" +// delta between mouse cursor and upper left corner of dragged window +static Point _drag_delta; + void HandleButtonClick(Window *w, byte widget) { w->click_state |= (1 << widget); @@ -691,50 +694,116 @@ bool HandleWindowDragging() { Window *w; - int x, y, t; - // Get out immediately if no window is being dragged at all. if (!_dragging_window) return true; // Otherwise find the window... - for(w=_windows; w != _last_window; w++) { - if (w->flags4&(WF_DRAGGING|WF_SIZING)) { + for (w = _windows; w != _last_window; w++) { + if (w->flags4 & WF_DRAGGING) { + const Window *v; + int x; + int y; + int nx; + int ny; // Stop the dragging if the left mouse button was released if (!_left_button_down) { - w->flags4 &= ~(WF_DRAGGING | WF_SIZING); + w->flags4 &= ~WF_DRAGGING; break; } - // Otherwise calculate the delta position. - x = _cursor.pos.x; - y = clamp2(_cursor.pos.y, 23, _screen.height-12); - t = _cursorpos_drag_start.x; _cursorpos_drag_start.x = x; x-=t; - t = _cursorpos_drag_start.y; _cursorpos_drag_start.y = y; y-=t; - - // No movement? - if (x == 0 && y == 0) - return false; - - // Mark the old position dirty SetWindowDirty(w); - if (w->flags4 & WF_SIZING) { - // Size the window - w->width += x; - w->height += y; - } else { - // Move the window and viewport - w->left += x; - w->top += y; - if (w->viewport) { - w->viewport->left += x; - w->viewport->top += y; + x = _cursor.pos.x + _drag_delta.x; + y = _cursor.pos.y + _drag_delta.y; + nx = x; + ny = y; + + if (_patches.window_snap_radius != 0) { + uint hsnap = _patches.window_snap_radius; + uint vsnap = _patches.window_snap_radius; + uint delta; + + // Snap at screen borders + // Left screen border + delta = abs(x); + if (delta <= hsnap) { + nx = 0; + hsnap = delta; + } + + // Right screen border + delta = abs(_screen.width - x - w->width); + if (delta <= hsnap) { + nx = _screen.width - w->width; + hsnap = delta; + } + + // Top of screen + delta = abs(y); + if (delta <= vsnap) { + ny = 0; + vsnap = delta; + } + + // Bottom of screen + delta = abs(_screen.height - y - w->height); + if (delta <= vsnap) { + ny = _screen.height - w->height; + vsnap = delta; + } + + // Snap at other windows + for (v = _windows; v != _last_window; ++v) { + if (v == w) continue; // Don't snap at yourself + + if (y + w->height > v->top && y < v->top + v->height) { + // Your left border <-> other right border + delta = abs(v->left + v->width - x); + if (delta <= hsnap) { + nx = v->left + v->width; + hsnap = delta; + } + + // Your right border <-> other left border + delta = abs(v->left - x - w->width); + if (delta <= hsnap) { + nx = v->left - w->width; + hsnap = delta; + } + } + + if (x + w->width > v->left && x < v->left + v->width) { + // Your top border <-> other bottom border + delta = abs(v->top + v->height - y); + if (delta <= vsnap) { + ny = v->top + v->height; + vsnap = delta; + } + + // Your bottom border <-> other top border + delta = abs(v->top - y - w->height); + if (delta <= vsnap) { + ny = v->top - w->height; + vsnap = delta; + } + } } } - // And also mark the new position dirty. + // Make sure the window doesn't leave the screen + // 13 is the height of the title bar + nx = clamp(nx, 13 - w->width, _screen.width - 13); + ny = clamp(ny, 0, _screen.height - 13); + + if (w->viewport != NULL) { + w->viewport->left += nx - w->left; + w->viewport->top += ny - w->top; + } + w->left = nx; + w->top = ny; + SetWindowDirty(w); return false; } @@ -748,7 +817,8 @@ { w->flags4 |= WF_DRAGGING; _dragging_window = true; - _cursorpos_drag_start = _cursor.pos; + _drag_delta.x = w->left - _cursor.pos.x; + _drag_delta.y = w->top - _cursor.pos.y; w = BringWindowToFront(w); DeleteWindowById(WC_DROPDOWN_MENU, 0); return w;