Skip to content

Add touch navigation for game menus - #1014

Open
Solessfir wants to merge 8 commits into
Try:masterfrom
Solessfir:android-touch-navigation
Open

Solessfir wants to merge 8 commits into
Try:masterfrom
Solessfir:android-touch-navigation

Conversation

@Solessfir

@Solessfir Solessfir commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Adds direct touch navigation for game menus, using Tempest's Android touch events and UI scale.

  • Tap menu entries and toggle choices directly.
  • Drag sliders in 1% steps and the stock view-distance percentage choices in 10% steps.
  • Limit mobile UI scaling to fit the screen, including a configured INTERFACE.Scale multiplier.
  • Keep desktop input behavior unchanged.

Depends on Try/Tempest#127 for Android density-based implUiScale. The view-distance choices remain unhooked from rendering; this changes their interaction, not their graphics behavior.

Journal dialogs and text entry aren't covered yet.

@Try

Try commented Oct 12, 2026

Copy link
Copy Markdown
Owner

Up/down swipe moves one entry

But.. why? Any reason not to implement clickable UI?

@Solessfir

Solessfir commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor Author

On the phone UI is so small that it is near impossible to press what you want.
We'd have to increase game UI by like x3 to make it work. So without it - I found that swipes are the only good option that worked for me.
Can change to touch and increase UI if mobile detected and make it an .ini config option.

@Try

Try commented Oct 12, 2026

Copy link
Copy Markdown
Owner

On the phone UI is so small...

Too small? That is likely due to lack of AndroidAPI::implUiScale - maybe if this entry is implemented, then UI will naturally become big enough?

@Solessfir

Copy link
Copy Markdown
Contributor Author

Will investigate and post updates.

@Solessfir

Solessfir commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Implemented AndroidApi::implUiScale in Try/Tempest#127. With density scaling and a screen-fit cap, the menus are large enough for direct taps. Updated this PR to use tap selection, draggable sliders and tappable choices instead of swipe navigation.

Before:
Screenshot_20261013_030950

After:
Screenshot_20261013_003556

@Solessfir

Copy link
Copy Markdown
Contributor Author

Not very happy with this percentageRange but I think it is better that hardcode "20%|40%|60%|80%|100%|120%|140%|160%|180%|200%|220%|240%|260%|280%|300%"; values.
IDK, need your opinion on this :)

@Solessfir

Copy link
Copy Markdown
Contributor Author

Dropped percentageRange. Percentage choices now just use the script's own entries, so no parser and no hardcoded values.

@Try Try left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I think it is better that hardcode "20%|40%|60%|80%|100%|120%|140%|160%|180%|200%|220%|240%|260%|280%|300%"; values.

There are 2 variants of such control (script driven):

  1. Enum like (Range of view) - those have explicit values
  2. Slider - those have step value stored at userFloat[0]
    (OpenGothic actually doesn't have case 2 implemented - changes slider by 3% always)

Basically, it's not for engine to really decide - we just draw what UI-script wants :)

Comment thread common/gothic.cpp Outdated
if(auto window = dynamic_cast<const MainWindow*>(w)) {
const float scale = window->uiScale() * mul;
#if defined(__MOBILE_PLATFORM__)
return std::min(scale,0.85f*std::min(float(window->w())/640.f,float(window->h())/480.f));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK model resolution for gothic ui is 800x600

Comment thread common/ui/gamemenu.cpp Outdated
const int count = int(strEnumSize(touchSlider->handle->text[0]));
if(count==0)
return;
touchSlider->value = int(std::round(value*float(count-1)));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make more sense to have +1 on a tap, rather?

Comment thread common/ui/menuroot.cpp Outdated
touchStart = event.pos();
touchMoved = false;
if(current->beginTouch(touchStart-current->pos()))
touchId = event.mouseID;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be cleaner to reject mouseEvent, if mouseID!=0 ? Basically, if mouseID!=0, that means there is already some other interaction with this menu, initiated earlier by user. And if you not accepting this event (event.ignore()) - it will not cause mouseUp/mouseDrag

Comment thread common/ui/gamemenu.h Outdated
void setPlayer(const Npc& pl);

void onKeyboard(KeyCodec::Action k);
bool beginTouch(Tempest::Point pos);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: onBeginTouch for consistency

Comment thread common/ui/gamemenu.cpp Outdated
if(!choice && slider==nullptr)
return;
const auto rect = itemRect(*touchSlider);
const int knob = choice ? 0 : int(float(slider->w())*float(rect.h/2)/float(slider->h()));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please, don't use texture resolution to decide integer vs float property.

Comment thread common/ui/menuroot.cpp
}

#if defined(__MOBILE_PLATFORM__)
void MenuRoot::mouseDragEvent(MouseEvent& event) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: may you please have one definition of mouseDragEvent/mouseUpEvent, and only disable implementation code, base on platform?

@Solessfir

Copy link
Copy Markdown
Contributor Author

Thanks, addressed all of them:

  • Screen-fit cap now uses 800x600.
  • Percentage choices step +1 on tap (wrapping), only sliders drag now.
  • Slider drag maps across the item width, no texture size involved.
  • Menu ignores mouseID!=0, so the touch id bookkeeping is gone.
  • Renamed to onBeginTouch/onDragTouch/onEndTouch.
  • Single mouseDragEvent/mouseUpEvent definitions, only the bodies are platform specific.

Tested on the phone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants