Changeset - r15241:1536e1ddc5ef
[Not reviewed]
master
0 2 0
alberth - 14 years ago 2010-05-23 14:53:39
alberth@openttd.org
(svn r19886) -Add [FS#3705]: Perform window callback during mouse dragging for the purpose of highlighting the destination (sbr).
2 files changed with 26 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/window.cpp
Show inline comments
 
@@ -1337,96 +1337,114 @@ static void DecreaseWindowCounters()
 
		if ((w->flags4 & WF_TIMEOUT_MASK) && !(--w->flags4 & WF_TIMEOUT_MASK)) {
 
			w->OnTimeout();
 
			if (w->desc_flags & WDF_UNCLICK_BUTTONS) w->RaiseButtons(true);
 
		}
 
	}
 
}
 

	
 
Window *GetCallbackWnd()
 
{
 
	return FindWindowById(_thd.window_class, _thd.window_number);
 
}
 

	
 
static void HandlePlacePresize()
 
{
 
	if (_special_mouse_mode != WSM_PRESIZE) return;
 

	
 
	Window *w = GetCallbackWnd();
 
	if (w == NULL) return;
 

	
 
	Point pt = GetTileBelowCursor();
 
	if (pt.x == -1) {
 
		_thd.selend.x = -1;
 
		return;
 
	}
 

	
 
	w->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y));
 
}
 

	
 
static bool HandleDragDrop()
 
{
 
	if (_special_mouse_mode != WSM_DRAGDROP) return true;
 
	if (_left_button_down) return false;
 

	
 
	Window *w = GetCallbackWnd();
 

	
 
	if (w != NULL) {
 
		/* send an event in client coordinates. */
 
		Point pt;
 
		pt.x = _cursor.pos.x - w->left;
 
		pt.y = _cursor.pos.y - w->top;
 
		w->OnDragDrop(pt, GetWidgetFromPos(w, pt.x, pt.y));
 
	}
 

	
 
	ResetObjectToPlace();
 

	
 
	return false;
 
}
 

	
 
static bool HandleMouseDrag()
 
{
 
	if (_special_mouse_mode != WSM_DRAGDROP) return true;
 
	if (!_left_button_down || (_cursor.delta.x == 0 && _cursor.delta.y == 0)) return true;
 

	
 
	Window *w = GetCallbackWnd();
 

	
 
	if (w != NULL) {
 
		/* Send an event in client coordinates. */
 
		Point pt;
 
		pt.x = _cursor.pos.x - w->left;
 
		pt.y = _cursor.pos.y - w->top;
 
		w->OnMouseDrag(pt, GetWidgetFromPos(w, pt.x, pt.y));
 
	}
 

	
 
	return false;
 
}
 

	
 
static bool HandleMouseOver()
 
{
 
	Window *w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
 

	
 
	/* We changed window, put a MOUSEOVER event to the last window */
 
	if (_mouseover_last_w != NULL && _mouseover_last_w != w) {
 
		/* Reset mouse-over coordinates of previous window */
 
		Point pt = { -1, -1 };
 
		_mouseover_last_w->OnMouseOver(pt, 0);
 
	}
 

	
 
	/* _mouseover_last_w will get reset when the window is deleted, see DeleteWindow() */
 
	_mouseover_last_w = w;
 

	
 
	if (w != NULL) {
 
		/* send an event in client coordinates. */
 
		Point pt = { _cursor.pos.x - w->left, _cursor.pos.y - w->top };
 
		const NWidgetCore *widget = w->nested_root->GetWidgetFromPos(pt.x, pt.y);
 
		if (widget != NULL) w->OnMouseOver(pt, widget->index);
 
	}
 

	
 
	/* Mouseover never stops execution */
 
	return true;
 
}
 

	
 
/**
 
 * Resize the window.
 
 * Update all the widgets of a window based on their resize flags
 
 * Both the areas of the old window and the new sized window are set dirty
 
 * ensuring proper redrawal.
 
 * @param w       Window to resize
 
 * @param delta_x Delta x-size of changed window (positive if larger, etc.)
 
 * @param delta_y Delta y-size of changed window
 
 */
 
void ResizeWindow(Window *w, int delta_x, int delta_y)
 
{
 
	if (delta_x != 0 || delta_y != 0) {
 
		w->SetDirty();
 

	
 
		uint new_xinc = max(0, (w->nested_root->resize_x == 0) ? 0 : (int)(w->nested_root->current_x - w->nested_root->smallest_x) + delta_x);
 
		uint new_yinc = max(0, (w->nested_root->resize_y == 0) ? 0 : (int)(w->nested_root->current_y - w->nested_root->smallest_y) + delta_y);
 
		assert(w->nested_root->resize_x == 0 || new_xinc % w->nested_root->resize_x == 0);
 
		assert(w->nested_root->resize_y == 0 || new_yinc % w->nested_root->resize_y == 0);
 

	
 
		w->nested_root->AssignSizePosition(ST_RESIZE, 0, 0, w->nested_root->smallest_x + new_xinc, w->nested_root->smallest_y + new_yinc, _dynlang.text_dir == TD_RTL);
 
		w->width  = w->nested_root->current_x;
 
		w->height = w->nested_root->current_y;
 
	}
 
@@ -2012,96 +2030,97 @@ static void ScrollMainViewport(int x, in
 
}
 

	
 
/**
 
 * Describes all the different arrow key combinations the game allows
 
 * when it is in scrolling mode.
 
 * The real arrow keys are bitwise numbered as
 
 * 1 = left
 
 * 2 = up
 
 * 4 = right
 
 * 8 = down
 
 */
 
static const int8 scrollamt[16][2] = {
 
	{ 0,  0}, ///<  no key specified
 
	{-2,  0}, ///<  1 : left
 
	{ 0, -2}, ///<  2 : up
 
	{-2, -1}, ///<  3 : left  + up
 
	{ 2,  0}, ///<  4 : right
 
	{ 0,  0}, ///<  5 : left  + right = nothing
 
	{ 2, -1}, ///<  6 : right + up
 
	{ 0, -2}, ///<  7 : right + left  + up = up
 
	{ 0,  2}, ///<  8 : down
 
	{-2,  1}, ///<  9 : down  + left
 
	{ 0,  0}, ///< 10 : down  + up    = nothing
 
	{-2,  0}, ///< 11 : left  + up    +  down = left
 
	{ 2,  1}, ///< 12 : down  + right
 
	{ 0,  2}, ///< 13 : left  + right +  down = down
 
	{ 2,  0}, ///< 14 : right + up    +  down = right
 
	{ 0,  0}, ///< 15 : left  + up    +  right + down  = nothing
 
};
 

	
 
static void HandleKeyScrolling()
 
{
 
	/*
 
	 * Check that any of the dirkeys is pressed and that the focused window
 
	 * dont has an edit-box as focused widget.
 
	 */
 
	if (_dirkeys && !EditBoxInGlobalFocus()) {
 
		int factor = _shift_pressed ? 50 : 10;
 
		ScrollMainViewport(scrollamt[_dirkeys][0] * factor, scrollamt[_dirkeys][1] * factor);
 
	}
 
}
 

	
 
static void MouseLoop(MouseClick click, int mousewheel)
 
{
 
	HandlePlacePresize();
 
	UpdateTileSelection();
 

	
 
	if (!VpHandlePlaceSizingDrag())  return;
 
	if (!HandleMouseDrag())          return;
 
	if (!HandleDragDrop())           return;
 
	if (!HandleWindowDragging())     return;
 
	if (!HandleScrollbarScrolling()) return;
 
	if (!HandleViewportScroll())     return;
 
	if (!HandleMouseOver())          return;
 

	
 
	bool scrollwheel_scrolling = _settings_client.gui.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0);
 
	if (click == MC_NONE && mousewheel == 0 && !scrollwheel_scrolling) return;
 

	
 
	int x = _cursor.pos.x;
 
	int y = _cursor.pos.y;
 
	Window *w = FindWindowFromPt(x, y);
 
	if (w == NULL) return;
 

	
 
	if (!MaybeBringWindowToFront(w)) return;
 
	ViewPort *vp = IsPtInWindowViewport(w, x, y);
 

	
 
	/* Don't allow any action in a viewport if either in menu of in generating world */
 
	if (vp != NULL && (_game_mode == GM_MENU || IsGeneratingWorld())) return;
 

	
 
	if (mousewheel != 0) {
 
		if (_settings_client.gui.scrollwheel_scrolling == 0) {
 
			/* Send mousewheel event to window */
 
			w->OnMouseWheel(mousewheel);
 
		}
 

	
 
		/* Dispatch a MouseWheelEvent for widgets if it is not a viewport */
 
		if (vp == NULL) DispatchMouseWheelEvent(w, w->nested_root->GetWidgetFromPos(x - w->left, y - w->top), mousewheel);
 
	}
 

	
 
	if (vp != NULL) {
 
		if (scrollwheel_scrolling) click = MC_RIGHT; // we are using the scrollwheel in a viewport, so we emulate right mouse button
 
		switch (click) {
 
			case MC_DOUBLE_LEFT:
 
			case MC_LEFT:
 
				DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite);
 
				if (_thd.place_mode != HT_NONE &&
 
						/* query button and place sign button work in pause mode */
 
						_cursor.sprite != SPR_CURSOR_QUERY &&
 
						_cursor.sprite != SPR_CURSOR_SIGN &&
 
						_pause_mode != PM_UNPAUSED &&
 
						!_cheats.build_in_pause.value) {
 
					return;
 
				}
 

	
 
				if (_thd.place_mode == HT_NONE) {
 
					if (!HandleViewportClicked(vp, x, y) &&
 
							!(w->flags4 & WF_DISABLE_VP_SCROLL) &&
src/window_gui.h
Show inline comments
 
@@ -612,96 +612,103 @@ public:
 
	 * and while re-initializing the window. Only for widgets that render text initializing is requested.
 
	 * @param widget  Widget number.
 
	 */
 
	virtual void SetStringParameters(int widget) const {}
 

	
 
	/**
 
	 * Called when window gains focus
 
	 */
 
	virtual void OnFocus() {}
 

	
 
	/**
 
	 * Called when window looses focus
 
	 */
 
	virtual void OnFocusLost() {}
 

	
 
	/**
 
	 * A key has been pressed.
 
	 * @param key     the Unicode value of the key.
 
	 * @param keycode the untranslated key code including shift state.
 
	 * @return #ES_HANDLED if the key press has been handled and no other
 
	 *         window should receive the event.
 
	 */
 
	virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
 

	
 
	/**
 
	 * The state of the control key has changed
 
	 * @return #ES_HANDLED if the change has been handled and no other
 
	 *         window should receive the event.
 
	 */
 
	virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
 

	
 

	
 
	/**
 
	 * A click with the left mouse button has been made on the window.
 
	 * @param pt     the point inside the window that has been clicked.
 
	 * @param widget the clicked widget.
 
	 * @param click_count Number of fast consecutive clicks at same position
 
	 */
 
	virtual void OnClick(Point pt, int widget, int click_count) {}
 

	
 
	/**
 
	 * A click with the right mouse button has been made on the window.
 
	 * @param pt     the point inside the window that has been clicked.
 
	 * @param widget the clicked widget.
 
	 */
 
	virtual void OnRightClick(Point pt, int widget) {}
 

	
 
	/**
 
	 * An 'object' is being dragged at the provided position, highlight the target if possible.
 
	 * @param pt     The point inside the window that the mouse hovers over.
 
	 * @param widget The widget the mouse hovers over.
 
	 */
 
	virtual void OnMouseDrag(Point pt, int widget) {}
 

	
 
	/**
 
	 * A dragged 'object' has been released.
 
	 * @param pt     the point inside the window where the release took place.
 
	 * @param widget the widget where the release took place.
 
	 */
 
	virtual void OnDragDrop(Point pt, int widget) {}
 

	
 
	/**
 
	 * Handle the request for (viewport) scrolling.
 
	 * @param delta the amount the viewport must be scrolled.
 
	 */
 
	virtual void OnScroll(Point delta) {}
 

	
 
	/**
 
	 * The mouse is currently moving over the window or has just moved outside
 
	 * of the window. In the latter case pt is (-1, -1).
 
	 * @param pt     the point inside the window that the mouse hovers over.
 
	 * @param widget the widget the mouse hovers over.
 
	 */
 
	virtual void OnMouseOver(Point pt, int widget) {}
 

	
 
	/**
 
	 * The mouse wheel has been turned.
 
	 * @param wheel the amount of movement of the mouse wheel.
 
	 */
 
	virtual void OnMouseWheel(int wheel) {}
 

	
 

	
 
	/**
 
	 * Called for every mouse loop run, which is at least once per (game) tick.
 
	 */
 
	virtual void OnMouseLoop() {}
 

	
 
	/**
 
	 * Called once per (game) tick.
 
	 */
 
	virtual void OnTick() {}
 

	
 
	/**
 
	 * Called once every 100 (game) ticks.
 
	 */
 
	virtual void OnHundredthTick() {}
 

	
 
	/**
 
	 * Called when this window's timeout has been reached.
 
	 */
 
	virtual void OnTimeout() {}
 

	
 

	
0 comments (0 inline, 0 general)