Touch interface for phones and tablets; category toolbar for mouse and touch
- touch.rs: gesture recognition (tap, double tap, long press, drag, two-finger pan/pinch/rotate) - Touch mode: Auto (touch device or first touch) / On / Off in Settings -> Game - Larger interface factor on touch screens, top bar wraps, smaller minimap, fewer messages - Toolbar grouped into categories with pop-up rows and a menu button, also on the desktop - Long press shows information or drops held units; double tap with the hand slaps - Savegame name via the browser's text dialog when the name field is tapped - Touch help texts (EN/DE) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6f037294c0
commit
af6be62805
10 files changed
+744
-152
No files matched your search
+13
-1
@@ -40,6 +40,7 @@ pub enum Item {
|
||||
RenderScale,
|
||||
GameSpeed,
|
||||
Hints,
|
||||
TouchUi,
|
||||
}
|
||||
|
||||
fn tab_items(tab: usize) -> &'static [Item] {
|
||||
@@ -48,7 +49,7 @@ fn tab_items(tab: usize) -> &'static [Item] {
|
||||
0 => &[Language, Volume, MusicVolume, Mute],
|
||||
1 => &[RotateSpeed, ZoomSpeed, EdgeScroll, InvertMouse],
|
||||
2 => &[Outlines, WallDetail, Lights, UiScale, RenderScale],
|
||||
3 => &[GameSpeed, Hints],
|
||||
3 => &[GameSpeed, Hints, TouchUi],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
@@ -70,6 +71,7 @@ fn item_label(it: Item) -> String {
|
||||
Item::RenderScale => "set.render_scale",
|
||||
Item::GameSpeed => "set.game_speed",
|
||||
Item::Hints => "set.hints",
|
||||
Item::TouchUi => "set.touch_ui",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -108,6 +110,11 @@ fn item_value(it: Item, s: &Settings) -> String {
|
||||
Item::RenderScale => format!("1/{}", s.render_scale.max(1)),
|
||||
Item::GameSpeed => format!("{}x", s.game_speed as i32),
|
||||
Item::Hints => onoff(s.hints),
|
||||
Item::TouchUi => match s.touch_ui {
|
||||
1 => tr("val.on"),
|
||||
2 => tr("val.off"),
|
||||
_ => trf("val.auto_state", &[tr(if crate::ui::touch_ui() { "val.on" } else { "val.off" })]),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +149,7 @@ fn item_change(it: Item, s: &mut Settings, d: i32) {
|
||||
Item::RenderScale => s.render_scale = cycle(&(1u8..=16).collect::<Vec<u8>>(), s.render_scale.clamp(1, 16), d),
|
||||
Item::GameSpeed => s.game_speed = cycle(&[1.0f32, 2.0], s.game_speed, d),
|
||||
Item::Hints => s.hints = !s.hints,
|
||||
Item::TouchUi => s.touch_ui = cycle(&[0u8, 1, 2], s.touch_ui, d),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +184,7 @@ enum Btn {
|
||||
Scroll(i32),
|
||||
FileSave,
|
||||
FileLoad,
|
||||
NameField,
|
||||
}
|
||||
|
||||
pub enum MenuAction {
|
||||
@@ -194,6 +203,7 @@ pub enum MenuAction {
|
||||
CloudSave(Option<String>, String), // (id to overwrite, name)
|
||||
CloudLoad(String),
|
||||
CloudDelete(String),
|
||||
EditName, // the name field was tapped (touch: ask with a browser dialog)
|
||||
}
|
||||
|
||||
pub struct Menu {
|
||||
@@ -364,6 +374,7 @@ impl Menu {
|
||||
self.scroll_by(d * self.rows_visible.max(1) as i32, cloud.list.len());
|
||||
MenuAction::Consumed
|
||||
}
|
||||
Some(Btn::NameField) => MenuAction::EditName,
|
||||
Some(Btn::FileSave) => MenuAction::FileSave,
|
||||
Some(Btn::FileLoad) => MenuAction::FileLoad,
|
||||
}
|
||||
@@ -599,6 +610,7 @@ impl Menu {
|
||||
let fw = (inner_w - (fx - inner_x) - bw - CW()).max(CW() * 8.0);
|
||||
draw_rectangle(fx, top, fw, CH() * 2.0, Color::new(0.02, 0.01, 0.02, 1.0));
|
||||
draw_rectangle_lines(fx, top, fw, CH() * 2.0, 2.0, FRAME_HI);
|
||||
self.buttons.push((Rect::new(fx, top, fw, CH() * 2.0), Btn::NameField));
|
||||
let blink = if (get_time() * 2.0) as i64 % 2 == 0 { "_" } else { " " };
|
||||
let maxc = ((fw - CW() * 2.0) / CW()).max(1.0) as usize;
|
||||
let shown: String = {
|
||||
|
||||
Reference in new issue
Block a user