mirror of https://github.com/OpenTTD/OpenTTD
(svn r538) -Feature: Windows snap at each other
This is inspired by [1063636].release/0.4.5
parent
603618a75b
commit
872f49ae8a
|
@ -1040,6 +1040,8 @@ STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position of main toolbar: {ORANGE}{STR
|
||||||
STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Left
|
STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Left
|
||||||
STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre
|
STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre
|
||||||
STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Right
|
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_GUI :{BLACK}Interface
|
||||||
STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construction
|
STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construction
|
||||||
|
|
|
@ -1040,6 +1040,8 @@ STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position der Haupttoolbar: {ORANGE}{
|
||||||
STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Links
|
STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Links
|
||||||
STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Mitte
|
STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Mitte
|
||||||
STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Rechts
|
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_GUI :{BLACK}Oberfläche
|
||||||
STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruktion
|
STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruktion
|
||||||
|
|
|
@ -829,6 +829,7 @@ static const SettingDesc patch_settings[] = {
|
||||||
{"realistic_acceleration",SDT_BOOL, (void*)false, (void*)offsetof(Patches, realistic_acceleration), NULL},
|
{"realistic_acceleration",SDT_BOOL, (void*)false, (void*)offsetof(Patches, realistic_acceleration), NULL},
|
||||||
|
|
||||||
{"toolbar_pos", SDT_UINT8, (void*)0, (void*)offsetof(Patches, toolbar_pos), 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_trains", SDT_UINT8, (void*)80, (void*)offsetof(Patches, max_trains), NULL},
|
||||||
{"max_roadveh", SDT_UINT8, (void*)80, (void*)offsetof(Patches, max_roadveh), NULL},
|
{"max_roadveh", SDT_UINT8, (void*)80, (void*)offsetof(Patches, max_roadveh), NULL},
|
||||||
|
|
|
@ -572,6 +572,7 @@ static const PatchEntry _patches_ui[] = {
|
||||||
{PE_UINT8, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION, &_patches.errmsg_duration, 0, 20, 1, NULL},
|
{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_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},
|
{PE_BOOL, 0, STR_CONFIG_PATCHES_INVISIBLE_TREES, &_patches.invisible_trees, 0, 1, 1, &InvisibleTreesActive},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ typedef struct Patches {
|
||||||
bool invisible_trees; // don't show trees when buildings are transparent
|
bool invisible_trees; // don't show trees when buildings are transparent
|
||||||
|
|
||||||
uint8 toolbar_pos; // position of toolbars, 0=left, 1=center, 2=right
|
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_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
|
byte max_roadveh; //max trucks in game per player
|
||||||
|
|
128
window.c
128
window.c
|
@ -5,6 +5,9 @@
|
||||||
#include "viewport.h"
|
#include "viewport.h"
|
||||||
#include "console.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)
|
void HandleButtonClick(Window *w, byte widget)
|
||||||
{
|
{
|
||||||
w->click_state |= (1 << widget);
|
w->click_state |= (1 << widget);
|
||||||
|
@ -691,50 +694,116 @@ bool HandlePopupMenu()
|
||||||
bool HandleWindowDragging()
|
bool HandleWindowDragging()
|
||||||
{
|
{
|
||||||
Window *w;
|
Window *w;
|
||||||
int x, y, t;
|
|
||||||
|
|
||||||
// Get out immediately if no window is being dragged at all.
|
// Get out immediately if no window is being dragged at all.
|
||||||
if (!_dragging_window)
|
if (!_dragging_window)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise find the window...
|
// Otherwise find the window...
|
||||||
for(w=_windows; w != _last_window; w++) {
|
for (w = _windows; w != _last_window; w++) {
|
||||||
if (w->flags4&(WF_DRAGGING|WF_SIZING)) {
|
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
|
// Stop the dragging if the left mouse button was released
|
||||||
if (!_left_button_down) {
|
if (!_left_button_down) {
|
||||||
w->flags4 &= ~(WF_DRAGGING | WF_SIZING);
|
w->flags4 &= ~WF_DRAGGING;
|
||||||
break;
|
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);
|
SetWindowDirty(w);
|
||||||
|
|
||||||
if (w->flags4 & WF_SIZING) {
|
x = _cursor.pos.x + _drag_delta.x;
|
||||||
// Size the window
|
y = _cursor.pos.y + _drag_delta.y;
|
||||||
w->width += x;
|
nx = x;
|
||||||
w->height += y;
|
ny = y;
|
||||||
} else {
|
|
||||||
// Move the window and viewport
|
if (_patches.window_snap_radius != 0) {
|
||||||
w->left += x;
|
uint hsnap = _patches.window_snap_radius;
|
||||||
w->top += y;
|
uint vsnap = _patches.window_snap_radius;
|
||||||
if (w->viewport) {
|
uint delta;
|
||||||
w->viewport->left += x;
|
|
||||||
w->viewport->top += y;
|
// 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);
|
SetWindowDirty(w);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -748,7 +817,8 @@ Window *StartWindowDrag(Window *w)
|
||||||
{
|
{
|
||||||
w->flags4 |= WF_DRAGGING;
|
w->flags4 |= WF_DRAGGING;
|
||||||
_dragging_window = true;
|
_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);
|
w = BringWindowToFront(w);
|
||||||
DeleteWindowById(WC_DROPDOWN_MENU, 0);
|
DeleteWindowById(WC_DROPDOWN_MENU, 0);
|
||||||
return w;
|
return w;
|
||||||
|
|
Loading…
Reference in New Issue