Skip to content

Mobile Platform Support (iOS & Android) #38

Description

@jdolan

Overview

This ticket was written before the SDL_gpu migration, and its biggest work item — an OpenGL ES
rendering path — no longer exists. ObjectivelyMVC 2.5.0 renders through ObjectivelyGPU on SDL's
GPU API, and ships its shaders precompiled for every backend SDL supports. That, plus the fact
that MVC has never depended on fontconfig, removes the two changes that would have been genuine
ports rather than additions.

What is left is smaller and more ordinary than this ticket originally described: touch gestures,
touch-sized hit targets, app lifecycle, and a build for each platform.

This remains a prerequisite for any engine using ObjectivelyMVC as its UI framework (e.g. Quetoo)
to run on mobile.


What already works

Verified by reading the tree at 2.5.0, not on a device — see Unknowns below.

Rendering No GL anywhere in Sources/. Renderer draws through ObjectivelyGPU's RenderDevice/GraphicsPipeline. Assets/ carries Renderer.{vert,frag} as .spv, .dxil and .metal, embedded as headers — Metal covers iOS, SPIR-V covers Vulkan on Android.
Fonts Font is SDL_ttf over font data the application supplies (Font::cacheFont(Data *, family)). No fontconfig, no system font enumeration, nothing to port.
Software keyboard TextView already calls SDL_StartTextInput / SDL_StopTextInput on focus and blur (TextView.c:99,191,402,409), which is what raises and dismisses the keyboard on iOS and Android.
Safe areas WindowController handles SDL_EVENT_WINDOW_SAFE_AREA_CHANGED (WindowController.c:262) — notch, home indicator, rounded corners.
Pixel density pixelDensity is threaded through Theme::font, Font and Text, and SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED / _PIXEL_SIZE_CHANGED are handled.
Orientation SDL_EVENT_WINDOW_RESIZED already drives a relayout, so rotation reflows.
Tap and drag SDL synthesises SDL_EVENT_MOUSE_* from a single finger, so Button, Checkbox, Select, Slider and Panel dragging work as they stand.
Scrolling ScrollView::captureEvent scrolls on motion with the button held (ScrollView.c:130-138), not only on the wheel — so content follows the finger, which is the mobile convention already.

Work items

1. Touch gestures

No SDL_EVENT_FINGER_* is handled anywhere; everything touch reaches MVC as emulated mouse
input. That covers one finger and nothing else.

  • Route SDL_EVENT_FINGER_DOWN/UP/MOTION through WindowController::respondToEvent and
    View::didReceiveEvent
  • A gesture abstraction a View can opt into: tap, long press, two-finger pan, pinch
  • Long press as the touch equivalent of a right click, and as TextView's selection entry point
  • Pinch where it means something (ImageView)

A drag has to be disambiguated before it is dispatched. A finger that comes down on a
Slider inside a ScrollView is a slider drag or a scroll depending on which way it moves and
how far — MVC currently gives the event to whoever hit-tests first and never reconsiders. This is
the part of this item with actual design in it; the rest is plumbing.

2. Touch target sizing

The stylesheet is desktop-tuned. Against Apple's 44pt and Material's 48dp:

Rule Now
Control min-height: 32
Checkbox > Control 20 x 20
Slider > .bar > .handle min-width: 8, min-height: 16
ScrollBar > .handle min-height: 16
TableCellView min-height: 24

Growing these visually would wreck desktop layouts, so the hit rect wants to grow without the
frame following: a Control property that pads what hitTest accepts, defaulted from the
stylesheet so a mobile theme can set it once. Note MVC's own Assets/stylesheet.css is the
place for the desktop values — the touch values belong in a sheet an app adds on top, which the
cascade already supports.

3. Application lifecycle

None of SDL_EVENT_TERMINATING, SDL_EVENT_LOW_MEMORY, SDL_EVENT_WILL_ENTER_BACKGROUND or
SDL_EVENT_DID_ENTER_FOREGROUND is forwarded. On mobile these are not optional: backgrounding
can take the GPU context with it.

  • Forward them through WindowController so an app can respond
  • Confirm Renderer::renderDeviceDidReset is enough to rebuild MVC's own GPU resources after a
    foreground, and that every View that owns a texture participates

4. Keeping the focused field visible

SDL_StartTextInput raises the keyboard, but nothing tells the OS where the text is, so the
keyboard can cover the field being edited. SDL_SetTextInputArea is never called.

  • Report the focused TextView's rect via SDL_SetTextInputArea
  • Decide whether MVC reflows around the keyboard or leaves that to the app

5. Hover has no touch equivalent

ControlStateHighlighted is set from mouse motion (Button.c:88, Slider.c:166, Panel.c:147),
and Select opens its flyout off isHighlighted (Select.c:75,92). Under touch emulation
"highlighted" only exists while a finger is down, which is not what those call sites mean.

  • Audit what each use of isHighlighted actually wants: pressed, focused, or hovered
  • Give Select a tap-to-open, tap-to-choose path that does not route through hover

6. Build

autotools and an Xcode project. Neither targets a phone.

  • iOS: an Xcode target against the iphoneos SDK, or CMake with a toolchain file
  • Android: CMake for the NDK
  • Both need the Assets/ header generation step (Assets/Makefile) to run under the new build,
    or its output checked in

7. Stale documentation

View.h:1091,1100,1340 and ViewController.h:164,173 still describe allocating and freeing
"OpenGL objects" and returning "the OpenGL viewport". Wrong since the SDL_gpu migration and
misleading to anyone reading this ticket alongside the headers.


Unknowns

  • ObjectivelyGPU has not been audited here. MVC's mobile readiness is capped by its
    dependency's; whether RenderDevice comes up on iOS Metal and Android Vulkan is the first
    thing to actually test, and it belongs in that repo's tracker if it does not.
  • None of the above has been run on a device or simulator. Everything in What already works is
    read from the source, and "the code does the right thing" is not the same as "it runs".
  • SDL_ttf and SDL_image are required (configure.ac:57); both build for mobile, but they are two
    more dependencies to stage per platform.

Not in scope

  • A mobile theme or stylesheet beyond the hit-target hook in item 2
  • Anything Quetoo-side; the engine port is its own work

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions