Skip to content

Mobile Platform Support (iOS & Android) #38

Description

@jdolan

Overview

ObjectivelyMVC is built on SDL3, which ships first-class iOS and Android support. SDL3 already emulates SDL_EVENT_MOUSE_* from single-finger touch by default, and WindowController already handles SDL_EVENT_WINDOW_SAFE_AREA_CHANGED — so basic tap interaction likely works today without any changes. The gaps are multi-touch gestures, virtual keyboard, responsive layout, and touch-sized hit targets.

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


What Works Today (via SDL3 mouse emulation)

  • Single-finger tap → SDL_EVENT_MOUSE_BUTTON_DOWN/UPButton, Checkbox, Select all fire correctly
  • Single-finger drag → SDL_EVENT_MOUSE_MOTIONPanel drag, Slider works
  • Safe area inset handling already present in WindowController
  • SDL_EVENT_WINDOW_RESIZED / orientation change already triggers layout

Work Items

1. Multi-Touch Gesture Support

SDL3 delivers raw touch as SDL_EVENT_FINGER_DOWN/UP/MOTION. Two-finger gestures are not currently routed through the event system.

  • Add SDL_EVENT_FINGER_* to WindowController::respondToEvent and View::didReceiveEvent
  • Implement a gesture recognizer abstraction (tap, long-press, two-finger scroll/swipe, pinch-to-zoom) so consumers can override per-view
  • Wire two-finger scroll to ScrollView and CollectionView in place of SDL_EVENT_MOUSE_WHEEL
  • Wire pinch-to-zoom where applicable (e.g. ImageView)

2. Virtual Keyboard Integration

TextView currently relies on SDL_EVENT_TEXT_INPUT which requires SDL_StartTextInput() to be called first. On mobile this also raises the software keyboard.

  • Call SDL_StartTextInput(window) when a TextView gains focus
  • Call SDL_StopTextInput(window) when it loses focus
  • Handle SDL_EVENT_WINDOW_RESIZED triggered by the keyboard appearing/disappearing (layout must reflow)
  • Optionally suppress the software keyboard when a physical keyboard is detected

3. Touch Target Sizing

Apple HIG and Android Material both specify 44pt / 48dp minimum tap targets. ObjectivelyMVC's default control sizes are desktop-tuned and often smaller.

  • Add a minimumTouchTarget concept to Control that pads the hit-test rect without affecting visual layout
  • Default to 44pt on mobile (could be driven by a theme / stylesheet variable)
  • Audit Button, Checkbox, Slider, Select for compliance

4. Responsive Layout & Orientation

Portrait/landscape orientation changes require layout to adapt. Safe area insets (notch, home indicator, rounded corners) must be respected.

  • Ensure all pixel constants in built-in themes are DPI-independent (points, not pixels)
  • Verify pixelDensity / SDL_GetWindowPixelDensity path is used consistently (partially done)
  • Add orientation-aware layout hooks to ViewController so subclasses can rearrange on rotation
  • Test against multiple screen aspect ratios (16:9, 19.5:9, 4:3 tablets)

5. Keyboard-Free Navigation

Several components assume keyboard availability:

  • Select / dropdown: relies on keyboard to confirm selection — needs tap-to-select fallback
  • TextView: relies on keyboard shortcuts (select-all, copy, paste) — needs long-press context menu
  • Tab-stop focus traversal is irrelevant on touch — hide/skip gracefully
  • Remove assumption of cursor (hover states) in Control highlight logic

6. Build System

ObjectivelyMVC currently uses autotools. Mobile targets need CMake (iOS) or Gradle/CMake (Android).

  • Add CMakeLists.txt alongside existing autotools build
  • iOS: CMake toolchain for xcrun/iphoneos SDK
  • Android: CMakeLists.txt compatible with Android NDK's CMake integration

7. OpenGL ES Rendering Path

The Renderer currently uses OpenGL 4.1 Core Profile. Mobile requires OpenGL ES 3.0 or Metal.

  • Abstract GL calls behind a thin compatibility layer or use SDL3's SDL_gpu API for rendering primitives (2D ortho, texture blits)
  • GLSL 4.10 shaders → GLSL ES 3.0 (version header + precision qualifiers + minor syntax changes)
  • This is a shared prerequisite with the Quetoo iOS/Android renderer port

Notes

  • Objectively (the base OOP framework) is pure portable C and requires no mobile-specific changes
  • SDL3 handles the platform event loop, window lifecycle, and audio on both iOS and Android
  • The SDL_EVENT_TERMINATING, SDL_EVENT_LOW_MEMORY, SDL_EVENT_WILL_ENTER_BACKGROUND, and SDL_EVENT_DID_ENTER_FOREGROUND lifecycle events should be forwarded through WindowController for apps to respond to

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions