(svn r16519) -Add: Prevent hiding of a window titlebar behind the status bar.
This commit is contained in:
		@@ -1468,6 +1468,56 @@ void ResizeWindow(Window *w, int delta_x, int delta_y)
 | 
				
			|||||||
	w->SetDirty();
 | 
						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 _dragging_window; ///< A window is being dragged or resized.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool HandleWindowDragging()
 | 
					static bool HandleWindowDragging()
 | 
				
			||||||
@@ -1587,37 +1637,13 @@ static bool HandleWindowDragging()
 | 
				
			|||||||
				caption_rect.bottom = caption->pos_y + caption->current_y;
 | 
									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 */
 | 
								/* 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);
 | 
								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);
 | 
								ny = Clamp(ny, 0, _screen.height - MIN_VISIBLE_TITLE_BAR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Make sure the title bar isn't hidden by behind the main tool bar */
 | 
								/* Make sure the title bar isn't hidden behind the main tool bar or the status bar. */
 | 
				
			||||||
			Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0);
 | 
								PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_MAIN_TOOLBAR, 0), w->left, PHD_DOWN);
 | 
				
			||||||
			if (v != NULL) {
 | 
								PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_STATUS_BAR,   0), w->left, PHD_UP);
 | 
				
			||||||
				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;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (w->viewport != NULL) {
 | 
								if (w->viewport != NULL) {
 | 
				
			||||||
				w->viewport->left += nx - w->left;
 | 
									w->viewport->left += nx - w->left;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user