Changeset - r25206:136702761466
[Not reviewed]
master
0 5 0
Rubidium - 4 years ago 2021-04-18 18:29:46
rubidium@openttd.org
Codechange: merge duplicated logic to scroll in lists by key into a single function
5 files changed with 87 insertions and 115 deletions:
0 comments (0 inline, 0 general)
src/network/network_content_gui.cpp
Show inline comments
 
@@ -860,61 +860,37 @@ public:
 
				break;
 
		}
 
	}
 

	
 
	EventState OnKeyPress(WChar key, uint16 keycode) override
 
	{
 
		switch (keycode) {
 
			case WKC_UP:
 
				/* scroll up by one */
 
				if (this->list_pos > 0) this->list_pos--;
 
				break;
 
			case WKC_DOWN:
 
				/* scroll down by one */
 
				if (this->list_pos < (int)this->content.size() - 1) this->list_pos++;
 
				break;
 
			case WKC_PAGEUP:
 
				/* scroll up a page */
 
				this->list_pos = (this->list_pos < this->vscroll->GetCapacity()) ? 0 : this->list_pos - this->vscroll->GetCapacity();
 
				break;
 
			case WKC_PAGEDOWN:
 
				/* scroll down a page */
 
				this->list_pos = std::min(this->list_pos + this->vscroll->GetCapacity(), (int)this->content.size() - 1);
 
				break;
 
			case WKC_HOME:
 
				/* jump to beginning */
 
				this->list_pos = 0;
 
				break;
 
			case WKC_END:
 
				/* jump to end */
 
				this->list_pos = (int)this->content.size() - 1;
 
				break;
 
		if (this->vscroll->UpdateListPositionOnKeyPress(this->list_pos, keycode) == ES_NOT_HANDLED) {
 
			switch (keycode) {
 
				case WKC_SPACE:
 
				case WKC_RETURN:
 
					if (keycode == WKC_RETURN || !IsWidgetFocused(WID_NCL_FILTER)) {
 
						if (this->selected != nullptr) {
 
							_network_content_client.ToggleSelectedState(this->selected);
 
							this->content.ForceResort();
 
							this->InvalidateData();
 
						}
 
						if (this->filter_data.types.any()) {
 
							this->content.ForceRebuild();
 
							this->InvalidateData();
 
						}
 
						return ES_HANDLED;
 
					}
 
					/* space is pressed and filter is focused. */
 
					FALLTHROUGH;
 

	
 
			case WKC_SPACE:
 
			case WKC_RETURN:
 
				if (keycode == WKC_RETURN || !IsWidgetFocused(WID_NCL_FILTER)) {
 
					if (this->selected != nullptr) {
 
						_network_content_client.ToggleSelectedState(this->selected);
 
						this->content.ForceResort();
 
						this->InvalidateData();
 
					}
 
					if (this->filter_data.types.any()) {
 
						this->content.ForceRebuild();
 
						this->InvalidateData();
 
					}
 
					return ES_HANDLED;
 
				}
 
				/* space is pressed and filter is focused. */
 
				FALLTHROUGH;
 

	
 
			default:
 
				return ES_NOT_HANDLED;
 
				default:
 
					return ES_NOT_HANDLED;
 
			}
 
		}
 

	
 
		if (this->content.size() == 0) {
 
			this->list_pos = 0; // above stuff may result in "-1".
 
			if (this->UpdateFilterState()) {
 
				this->content.ForceRebuild();
 
				this->InvalidateData();
 
			}
 
			return ES_HANDLED;
 
		}
src/network/network_gui.cpp
Show inline comments
 
@@ -63,14 +63,14 @@ static const StringID _connection_types_
 
void UpdateNetworkGameWindow()
 
{
 
	InvalidateWindowData(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME, 0);
 
}
 

	
 
typedef GUIList<NetworkGameList*, StringFilter&> GUIGameServerList;
 
typedef uint16 ServerListPosition;
 
static const ServerListPosition SLP_INVALID = 0xFFFF;
 
typedef int ServerListPosition;
 
static const ServerListPosition SLP_INVALID = -1;
 

	
 
/** Full blown container to make it behave exactly as we want :) */
 
class NWidgetServerListHeader : public NWidgetContainer {
 
	static const uint MINIMUM_NAME_WIDTH_BEFORE_NEW_HEADER = 150; ///< Minimum width before adding a new header
 
	bool visible[6]; ///< The visible headers
 
public:
 
@@ -768,45 +768,14 @@ public:
 

	
 
	EventState OnKeyPress(WChar key, uint16 keycode) override
 
	{
 
		EventState state = ES_NOT_HANDLED;
 

	
 
		/* handle up, down, pageup, pagedown, home and end */
 
		if (keycode == WKC_UP || keycode == WKC_DOWN || keycode == WKC_PAGEUP || keycode == WKC_PAGEDOWN || keycode == WKC_HOME || keycode == WKC_END) {
 
			if (this->servers.size() == 0) return ES_HANDLED;
 
			switch (keycode) {
 
				case WKC_UP:
 
					/* scroll up by one */
 
					if (this->list_pos == SLP_INVALID) return ES_HANDLED;
 
					if (this->list_pos > 0) this->list_pos--;
 
					break;
 
				case WKC_DOWN:
 
					/* scroll down by one */
 
					if (this->list_pos == SLP_INVALID) return ES_HANDLED;
 
					if (this->list_pos < this->servers.size() - 1) this->list_pos++;
 
					break;
 
				case WKC_PAGEUP:
 
					/* scroll up a page */
 
					if (this->list_pos == SLP_INVALID) return ES_HANDLED;
 
					this->list_pos = (this->list_pos < this->vscroll->GetCapacity()) ? 0 : this->list_pos - this->vscroll->GetCapacity();
 
					break;
 
				case WKC_PAGEDOWN:
 
					/* scroll down a page */
 
					if (this->list_pos == SLP_INVALID) return ES_HANDLED;
 
					this->list_pos = std::min(this->list_pos + this->vscroll->GetCapacity(), (int)this->servers.size() - 1);
 
					break;
 
				case WKC_HOME:
 
					/* jump to beginning */
 
					this->list_pos = 0;
 
					break;
 
				case WKC_END:
 
					/* jump to end */
 
					this->list_pos = (ServerListPosition)this->servers.size() - 1;
 
					break;
 
				default: NOT_REACHED();
 
			}
 
		if (this->vscroll->UpdateListPositionOnKeyPress(this->list_pos, keycode) == ES_HANDLED) {
 
			if (this->list_pos == SLP_INVALID) return ES_HANDLED;
 

	
 
			this->server = this->servers[this->list_pos];
 

	
 
			/* Scroll to the new server if it is outside the current range. */
 
			this->ScrollToSelectedServer();
 

	
src/newgrf_gui.cpp
Show inline comments
 
@@ -1315,48 +1315,14 @@ struct NewGRFWindow : public Window, New
 
	}
 

	
 
	EventState OnKeyPress(WChar key, uint16 keycode) override
 
	{
 
		if (!this->editable) return ES_NOT_HANDLED;
 

	
 
		switch (keycode) {
 
			case WKC_UP:
 
				/* scroll up by one */
 
				if (this->avail_pos > 0) this->avail_pos--;
 
				break;
 

	
 
			case WKC_DOWN:
 
				/* scroll down by one */
 
				if (this->avail_pos < (int)this->avails.size() - 1) this->avail_pos++;
 
				break;
 

	
 
			case WKC_PAGEUP:
 
				/* scroll up a page */
 
				this->avail_pos = (this->avail_pos < this->vscroll2->GetCapacity()) ? 0 : this->avail_pos - this->vscroll2->GetCapacity();
 
				break;
 
		if (this->vscroll2->UpdateListPositionOnKeyPress(this->avail_pos, keycode) == ES_NOT_HANDLED) return ES_NOT_HANDLED;
 

	
 
			case WKC_PAGEDOWN:
 
				/* scroll down a page */
 
				this->avail_pos = std::min(this->avail_pos + this->vscroll2->GetCapacity(), (int)this->avails.size() - 1);
 
				break;
 

	
 
			case WKC_HOME:
 
				/* jump to beginning */
 
				this->avail_pos = 0;
 
				break;
 

	
 
			case WKC_END:
 
				/* jump to end */
 
				this->avail_pos = (uint)this->avails.size() - 1;
 
				break;
 

	
 
			default:
 
				return ES_NOT_HANDLED;
 
		}
 

	
 
		if (this->avails.size() == 0) this->avail_pos = -1;
 
		if (this->avail_pos >= 0) {
 
			this->active_sel = nullptr;
 
			DeleteWindowByClass(WC_GRF_PARAMETERS);
 
			if (this->avail_sel != this->avails[this->avail_pos]) DeleteWindowByClass(WC_TEXTFILE);
 
			this->avail_sel = this->avails[this->avail_pos];
 
			this->vscroll2->ScrollTowards(this->avail_pos);
src/widget.cpp
Show inline comments
 
@@ -1972,12 +1972,72 @@ int Scrollbar::GetScrolledRowFromWidget(
 
	uint pos = w->GetRowFromWidget(clickpos, widget, padding, line_height);
 
	if (pos != INT_MAX) pos += this->GetPosition();
 
	return (pos >= this->GetCount()) ? INT_MAX : pos;
 
}
 

	
 
/**
 
 * Update the given list position as if it were on this scroll bar when the given keycode was pressed.
 
 * This does not update the actual position of this scroll bar, that is left to the caller. It does,
 
 * however use the capacity and count of the scroll bar for the bounds and amount to scroll.
 
 *
 
 * When the count is 0 or the return is ES_NOT_HANDLED, then the position is not updated.
 
 * With WKC_UP and WKC_DOWN the position goes one up or down respectively.
 
 * With WKC_PAGEUP and WKC_PAGEDOWN the position goes one capacity up or down respectively.
 
 * With WKC_HOME the first position is selected and with WKC_END the last position is selected.
 
 * This function ensures that pos is in the range [0..count).
 
 * @param list_position The current position in the list.
 
 * @param key_code      The pressed key code.
 
 * @return ES_NOT_HANDLED when another key than the 6 specific keys was pressed, otherwise ES_HANDLED.
 
 */
 
EventState Scrollbar::UpdateListPositionOnKeyPress(int &list_position, uint16 keycode) const
 
{
 
	int new_pos = list_position;
 
	switch (keycode) {
 
		case WKC_UP:
 
			/* scroll up by one */
 
			new_pos--;
 
			break;
 

	
 
		case WKC_DOWN:
 
			/* scroll down by one */
 
			new_pos++;
 
			break;
 

	
 
		case WKC_PAGEUP:
 
			/* scroll up a page */
 
			new_pos -= this->GetCapacity();
 
			break;
 

	
 
		case WKC_PAGEDOWN:
 
			/* scroll down a page */
 
			new_pos += this->GetCapacity();
 
			break;
 

	
 
		case WKC_HOME:
 
			/* jump to beginning */
 
			new_pos = 0;
 
			break;
 

	
 
		case WKC_END:
 
			/* jump to end */
 
			new_pos = this->GetCount() - 1;
 
			break;
 

	
 
		default:
 
			return ES_NOT_HANDLED;
 
	}
 

	
 
	/* If there are no elements, there is nothing to scroll/update. */
 
	if (this->GetCount() != 0) {
 
		list_position = Clamp(new_pos, 0, this->GetCount() - 1);
 
	}
 
	return ES_HANDLED;
 
}
 

	
 

	
 
/**
 
 * Set capacity of visible elements from the size and resize properties of a widget.
 
 * @param w       Window.
 
 * @param widget  Widget with size and resize properties.
 
 * @param padding Padding to subtract from the size.
 
 * @note Updates the position if needed.
 
 */
src/widget_type.h
Show inline comments
 
@@ -746,12 +746,13 @@ public:
 
			/* scroll down so that the item is at the bottom */
 
			this->SetPosition(position - this->GetCapacity() + 1);
 
		}
 
	}
 

	
 
	int GetScrolledRowFromWidget(int clickpos, const Window * const w, int widget, int padding = 0, int line_height = -1) const;
 
	EventState UpdateListPositionOnKeyPress(int &list_position, uint16 keycode) const;
 
};
 

	
 
/**
 
 * Nested widget to display and control a scrollbar in a window.
 
 * Also assign the scrollbar to other widgets using #SetScrollbar() to make the mousewheel work.
 
 * @ingroup NestedWidgets
0 comments (0 inline, 0 general)