Title screen: licence line and a link to the repository at the bottom
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6e257e4034
commit
f298e13d6e
6 files changed
+34
No files matched your search
@@ -528,3 +528,4 @@ unit.owl = Arkane Eule
|
|||||||
unit.wyrm = Glutwyrm
|
unit.wyrm = Glutwyrm
|
||||||
job.rest = Erholt sich im Horst
|
job.rest = Erholt sich im Horst
|
||||||
job.torment = Bearbeitet einen Gefangenen
|
job.torment = Bearbeitet einen Gefangenen
|
||||||
|
menu.license = DungeonCraft - MIT-Lizenz - (c) 2026 Richard Zink
|
||||||
@@ -529,3 +529,4 @@ unit.owl = Arcane Owl
|
|||||||
unit.wyrm = Ember Wyrm
|
unit.wyrm = Ember Wyrm
|
||||||
job.rest = Recovering in the aerie
|
job.rest = Recovering in the aerie
|
||||||
job.torment = Working on a prisoner
|
job.torment = Working on a prisoner
|
||||||
|
menu.license = DungeonCraft - MIT License - (c) 2026 Richard Zink
|
||||||
@@ -678,6 +678,7 @@ async fn main() {
|
|||||||
ui.show_help = false;
|
ui.show_help = false;
|
||||||
autosave_t = 0.0;
|
autosave_t = 0.0;
|
||||||
}
|
}
|
||||||
|
MenuAction::OpenRepo => platform::open_url(menu::REPO_URL),
|
||||||
MenuAction::EditName => {
|
MenuAction::EditName => {
|
||||||
if let Some(n) = platform::prompt(&i18n::tr("saves.name"), &menu.save_name) {
|
if let Some(n) = platform::prompt(&i18n::tr("saves.name"), &menu.save_name) {
|
||||||
menu.save_name = n.chars().filter(|c| !c.is_control()).take(40).collect();
|
menu.save_name = n.chars().filter(|c| !c.is_control()).take(40).collect();
|
||||||
|
|||||||
+21
@@ -201,8 +201,11 @@ enum Btn {
|
|||||||
Mission(usize),
|
Mission(usize),
|
||||||
StartMission,
|
StartMission,
|
||||||
Goals,
|
Goals,
|
||||||
|
Repo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const REPO_URL: &str = "https://git.familie-zink.org/zink/dungeoncraft";
|
||||||
|
|
||||||
pub enum MenuAction {
|
pub enum MenuAction {
|
||||||
None,
|
None,
|
||||||
Consumed,
|
Consumed,
|
||||||
@@ -221,6 +224,7 @@ pub enum MenuAction {
|
|||||||
CloudDelete(String),
|
CloudDelete(String),
|
||||||
EditName, // the name field was tapped (touch: ask with a browser dialog)
|
EditName, // the name field was tapped (touch: ask with a browser dialog)
|
||||||
StartMission(usize),
|
StartMission(usize),
|
||||||
|
OpenRepo,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Menu {
|
pub struct Menu {
|
||||||
@@ -403,6 +407,7 @@ impl Menu {
|
|||||||
MenuAction::Consumed
|
MenuAction::Consumed
|
||||||
}
|
}
|
||||||
Some(Btn::NameField) => MenuAction::EditName,
|
Some(Btn::NameField) => MenuAction::EditName,
|
||||||
|
Some(Btn::Repo) => MenuAction::OpenRepo,
|
||||||
Some(Btn::Campaign) => {
|
Some(Btn::Campaign) => {
|
||||||
self.page = Some(Page::Campaign);
|
self.page = Some(Page::Campaign);
|
||||||
self.scroll = 0;
|
self.scroll = 0;
|
||||||
@@ -502,6 +507,22 @@ impl Menu {
|
|||||||
gfx.text(&hint, grid_center(sw, gfx.measure(&hint, SMALL())), sh - CH() * 8.0, SMALL(), DIM);
|
gfx.text(&hint, grid_center(sw, gfx.measure(&hint, SMALL())), sh - CH() * 8.0, SMALL(), DIM);
|
||||||
let credit = tr("help.font");
|
let credit = tr("help.font");
|
||||||
gfx.text(&credit, grid_center(sw, gfx.measure(&credit, SMALL())), sh - CH() * 7.0, SMALL(), DIM);
|
gfx.text(&credit, grid_center(sw, gfx.measure(&credit, SMALL())), sh - CH() * 7.0, SMALL(), DIM);
|
||||||
|
self.draw_license(gfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// licence and repository link at the bottom of the screen (title and login)
|
||||||
|
pub fn draw_license(&mut self, gfx: &Gfx) {
|
||||||
|
let (sw, sh) = (sw(), sh());
|
||||||
|
let (mx, my) = mouse();
|
||||||
|
let lic = tr("menu.license");
|
||||||
|
gfx.text(&lic, grid_center(sw, gfx.measure(&lic, SMALL())), sh - CH() * 2.5, SMALL(), DIM);
|
||||||
|
let url = REPO_URL.trim_start_matches("https://");
|
||||||
|
let w = gfx.measure(url, SMALL());
|
||||||
|
let r = Rect::new(grid_center(sw, w), sh - CH() * 1.5, w, GH * SMALL() + 2.0);
|
||||||
|
let hot = r.contains(vec2(mx, my));
|
||||||
|
gfx.text(url, r.x, r.y, SMALL(), if hot { FRAME_HI } else { Color::new(0.5, 0.7, 1.0, 1.0) });
|
||||||
|
draw_rectangle(r.x, r.y + GH * SMALL(), r.w, (SMALL()).max(1.0), if hot { FRAME_HI } else { Color::new(0.5, 0.7, 1.0, 0.6) });
|
||||||
|
self.buttons.push((r, Btn::Repo));
|
||||||
}
|
}
|
||||||
|
|
||||||
// New game: choose the map size (width and height separately)
|
// New game: choose the map size (width and height separately)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ mod imp {
|
|||||||
fn dc_storage_get(key: *const u8, key_len: u32) -> i32;
|
fn dc_storage_get(key: *const u8, key_len: u32) -> i32;
|
||||||
fn dc_storage_take(dst: *mut u8);
|
fn dc_storage_take(dst: *mut u8);
|
||||||
fn dc_coarse_pointer() -> i32;
|
fn dc_coarse_pointer() -> i32;
|
||||||
|
fn dc_open_url(u: *const u8, ul: u32);
|
||||||
fn dc_prompt(t: *const u8, tl: u32, d: *const u8, dl: u32) -> i32;
|
fn dc_prompt(t: *const u8, tl: u32, d: *const u8, dl: u32) -> i32;
|
||||||
fn dc_storage_set(key: *const u8, key_len: u32, val: *const u8, val_len: u32);
|
fn dc_storage_set(key: *const u8, key_len: u32, val: *const u8, val_len: u32);
|
||||||
fn dc_cache_set(key: *const u8, key_len: u32, val: *const u8, val_len: u32);
|
fn dc_cache_set(key: *const u8, key_len: u32, val: *const u8, val_len: u32);
|
||||||
@@ -62,6 +63,10 @@ mod imp {
|
|||||||
unsafe { dc_coarse_pointer() != 0 }
|
unsafe { dc_coarse_pointer() != 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn open_url(url: &str) {
|
||||||
|
unsafe { dc_open_url(url.as_ptr(), url.len() as u32) }
|
||||||
|
}
|
||||||
|
|
||||||
// asks for a text with the browser's dialog; None when cancelled
|
// asks for a text with the browser's dialog; None when cancelled
|
||||||
pub fn prompt(title: &str, default: &str) -> Option<String> {
|
pub fn prompt(title: &str, default: &str) -> Option<String> {
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -122,6 +127,7 @@ mod imp {
|
|||||||
pub fn coarse_pointer() -> bool {
|
pub fn coarse_pointer() -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
pub fn open_url(_url: &str) {}
|
||||||
pub fn storage_set(key: &str, val: &str) {
|
pub fn storage_set(key: &str, val: &str) {
|
||||||
STORE.with(|s| s.borrow_mut().insert(key.to_string(), val.to_string()));
|
STORE.with(|s| s.borrow_mut().insert(key.to_string(), val.to_string()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,10 @@
|
|||||||
pending = new TextEncoder().encode(v);
|
pending = new TextEncoder().encode(v);
|
||||||
return pending.length;
|
return pending.length;
|
||||||
};
|
};
|
||||||
|
// opens a web page in a new tab (repository link)
|
||||||
|
env.dc_open_url = function (up, ul) {
|
||||||
|
try { window.open(str(up, ul), "_blank", "noopener"); } catch (e) { }
|
||||||
|
};
|
||||||
// the device's main pointer is a finger (phones, tablets)
|
// the device's main pointer is a finger (phones, tablets)
|
||||||
env.dc_coarse_pointer = function () {
|
env.dc_coarse_pointer = function () {
|
||||||
try { return window.matchMedia("(pointer: coarse)").matches ? 1 : 0; } catch (e) { return 0; }
|
try { return window.matchMedia("(pointer: coarse)").matches ? 1 : 0; } catch (e) { return 0; }
|
||||||
|
|||||||
Reference in new issue
Block a user