Skip to content

Commit

Permalink
Feature: make NewGRF active list react on key presses
Browse files Browse the repository at this point in the history
  • Loading branch information
perezdidac committed Apr 11, 2021
1 parent 2b86d42 commit a69e185
Showing 1 changed file with 80 additions and 14 deletions.
94 changes: 80 additions & 14 deletions src/newgrf_gui.cpp
Expand Up @@ -716,6 +716,21 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
}
}

/** Given a position */
void SelectActive(int position)
{
GRFConfig *c;
for (c = this->actives; c != nullptr && position > 0; c = c->next, position--) {}

if (this->active_sel != c) {
DeleteWindowByClass(WC_GRF_PARAMETERS);
DeleteWindowByClass(WC_TEXTFILE);
}
this->active_sel = c;
this->avail_sel = nullptr;
this->avail_pos = -1;
}

void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
switch (widget) {
Expand Down Expand Up @@ -997,20 +1012,11 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
case WID_NS_FILE_LIST: { // Select an active GRF.
ResetObjectToPlace();

uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST);
int pos = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST);
this->SelectActive(pos);

GRFConfig *c;
for (c = this->actives; c != nullptr && i > 0; c = c->next, i--) {}
this->InvalidateData(0);

if (this->active_sel != c) {
DeleteWindowByClass(WC_GRF_PARAMETERS);
DeleteWindowByClass(WC_TEXTFILE);
}
this->active_sel = c;
this->avail_sel = nullptr;
this->avail_pos = -1;

this->InvalidateData();
if (click_count == 1) {
if (this->editable && this->active_sel != nullptr) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
break;
Expand Down Expand Up @@ -1314,10 +1320,59 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
this->SetWidgetDisabledState(WID_NS_PRESET_SAVE, has_missing);
}

EventState OnKeyPress(WChar key, uint16 keycode) override
EventState OnKeyPressForActiveList(uint16 keycode)
{
if (!this->editable) return ES_NOT_HANDLED;
/* Get total actives and index of current selection. */
int active_pos = 0;
int active_count = 0;
for (GRFConfig *c = this->actives; c != nullptr; c = c->next, active_count++) {}
for (GRFConfig *c = this->actives; c != nullptr && c != this->active_sel; c = c->next, active_pos++) {}

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

case WKC_DOWN:
/* scroll down by one */
if (active_pos < active_count - 1) active_pos++;
break;

case WKC_PAGEUP:
/* scroll up a page */
active_pos = (active_pos < this->vscroll->GetCapacity()) ? 0 : active_pos - this->vscroll->GetCapacity();
break;

case WKC_PAGEDOWN:
/* scroll down a page */
active_pos = std::min(active_pos + this->vscroll->GetCapacity(), active_count - 1);
break;

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

case WKC_END:
/* jump to end */
active_pos = active_count - 1;
break;

default:
return ES_NOT_HANDLED;
}

if (this->actives != nullptr) {
this->SelectActive(active_pos);
this->vscroll->ScrollTowards(active_pos == active_count - 1 ? active_pos + 1 : active_pos);
this->InvalidateData(0);
}

return ES_HANDLED;
}

EventState OnKeyPressForAvailList(uint16 keycode) {
switch (keycode) {
case WKC_UP:
/* scroll up by one */
Expand Down Expand Up @@ -1366,6 +1421,17 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
return ES_HANDLED;
}

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

if (this->IsWidgetFocused(WID_NS_FILE_LIST)) {
return OnKeyPressForActiveList(keycode);
} else {
return OnKeyPressForAvailList(keycode);
}
}

void OnEditboxChanged(int wid) override
{
if (!this->editable) return;
Expand Down

0 comments on commit a69e185

Please sign in to comment.