diff options
Diffstat (limited to 'src/window.cpp')
-rw-r--r-- | src/window.cpp | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/src/window.cpp b/src/window.cpp index 2f4a5eb59..38b963bbd 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1468,6 +1468,56 @@ void ResizeWindow(Window *w, int delta_x, int delta_y) w->SetDirty(); } +/** The minimum number of pixels of the title bar must be visible in both the X or Y direction */ +static const int MIN_VISIBLE_TITLE_BAR = 13; + +/** Direction for moving the window. */ +enum PreventHideDirection { + PHD_UP, ///< Above v is a safe position. + PHD_DOWN, ///< Below v is a safe position. +}; + +/** + * Do not allow hiding of the rectangle with base coordinates \a nx and \a ny behind window \a v. + * If needed, move the window base coordinates to keep it visible. + * @param nx Base horizontal coordinate of the rectangle. + * @param ny Base vertical coordinate of the rectangle. + * @param rect Rectangle that must stay visible for #MIN_VISIBLE_TITLE_BAR pixels (horizontally, vertically, or both) + * @param v Window lying in front of the rectangle. + * @param px Previous horizontal base coordinate. + * @param dir If no room horizontally, move the rectangle to the indicated position. + */ +void PreventHiding(int *nx, int *ny, const Rect &rect, const Window *v, int px, PreventHideDirection dir) +{ + if (v == NULL) return; + + int v_bottom = v->top + v->height; + int v_right = v->left + v->width; + int safe_y = (dir == PHD_UP) ? (v->top - MIN_VISIBLE_TITLE_BAR - rect.top) : (v_bottom + MIN_VISIBLE_TITLE_BAR - rect.bottom); // Compute safe vertical position. + + if (*ny + rect.top <= v->top - MIN_VISIBLE_TITLE_BAR) return; // Above v is enough space + if (*ny + rect.bottom >= v_bottom + MIN_VISIBLE_TITLE_BAR) return; // Below v is enough space + + /* Vertically, the rectangle is hidden behind v. */ + if (*nx + rect.left + MIN_VISIBLE_TITLE_BAR < v->left) { // At left of v. + if (v->left < MIN_VISIBLE_TITLE_BAR) *ny = safe_y; // But enough room, force it to a safe position. + return; + } + if (*nx + rect.right - MIN_VISIBLE_TITLE_BAR > v_right) { // At right of v. + if (v_right > _screen.width - MIN_VISIBLE_TITLE_BAR) *ny = safe_y; // Not enough room, force it to a safe position. + return; + } + + /* Horizontally also hidden, force movement to a safe area. */ + if (px + rect.left < v->left && v->left >= MIN_VISIBLE_TITLE_BAR) { // Coming from the left, and enough room there. + *nx = v->left - MIN_VISIBLE_TITLE_BAR - rect.left; + } else if (px + rect.right > v_right && v_right <= _screen.width - MIN_VISIBLE_TITLE_BAR) { // Coming from the right, and enough room there. + *nx = v_right + MIN_VISIBLE_TITLE_BAR - rect.right; + } else { + *ny = safe_y; + } +} + static bool _dragging_window; ///< A window is being dragged or resized. static bool HandleWindowDragging() @@ -1587,37 +1637,13 @@ static bool HandleWindowDragging() caption_rect.bottom = caption->pos_y + caption->current_y; } - /* The minimum number of pixels of the title bar must be visible - * in both the X or Y direction */ - static const int MIN_VISIBLE_TITLE_BAR = 13; - /* Make sure the window doesn't leave the screen */ nx = Clamp(nx, MIN_VISIBLE_TITLE_BAR - caption_rect.right, _screen.width - MIN_VISIBLE_TITLE_BAR - caption_rect.left); ny = Clamp(ny, 0, _screen.height - MIN_VISIBLE_TITLE_BAR); - /* Make sure the title bar isn't hidden by behind the main tool bar */ - Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0); - if (v != NULL) { - int v_bottom = v->top + v->height; - int v_right = v->left + v->width; - if (ny + caption_rect.top >= v->top && ny + caption_rect.top < v_bottom) { - if ((v->left < MIN_VISIBLE_TITLE_BAR && nx + caption_rect.left < v->left) || - (v_right > _screen.width - MIN_VISIBLE_TITLE_BAR && nx + caption_rect.right > v_right)) { - ny = v_bottom; - } else { - if (nx + caption_rect.left > v->left - MIN_VISIBLE_TITLE_BAR && - nx + caption_rect.right < v_right + MIN_VISIBLE_TITLE_BAR) { - if (w->top >= v_bottom) { - ny = v_bottom; - } else if (w->left < nx) { - nx = v->left - MIN_VISIBLE_TITLE_BAR - caption_rect.left; - } else { - nx = v_right + MIN_VISIBLE_TITLE_BAR - caption_rect.right; - } - } - } - } - } + /* Make sure the title bar isn't hidden behind the main tool bar or the status bar. */ + PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_MAIN_TOOLBAR, 0), w->left, PHD_DOWN); + PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_STATUS_BAR, 0), w->left, PHD_UP); if (w->viewport != NULL) { w->viewport->left += nx - w->left; |