diff --git a/data/ui/options/misc_d.png b/data/ui/options/misc_d.png new file mode 100644 index 00000000..d1a6392e Binary files /dev/null and b/data/ui/options/misc_d.png differ diff --git a/data/ui/options/misc_h.png b/data/ui/options/misc_h.png new file mode 100644 index 00000000..7573b667 Binary files /dev/null and b/data/ui/options/misc_h.png differ diff --git a/data/ui/options/misc_i.png b/data/ui/options/misc_i.png new file mode 100644 index 00000000..4eeea84f Binary files /dev/null and b/data/ui/options/misc_i.png differ diff --git a/data/ui/options/misc_n.png b/data/ui/options/misc_n.png new file mode 100644 index 00000000..df5341ac Binary files /dev/null and b/data/ui/options/misc_n.png differ diff --git a/src/Settings.hx b/src/Settings.hx index ec5ee100..a00d5780 100644 --- a/src/Settings.hx +++ b/src/Settings.hx @@ -255,6 +255,12 @@ class Settings { } @:hlNative public static function open_web_url(url:String):Void {} + + @:hlNative public static function export_prefs():Void {} + + @:hlNative public static function start_import_prefs(prefsCb:(b:hl.Bytes) -> Void):Void {} + + @:hlNative public static function call_import_cb():Void {} #end #if (!android) diff --git a/src/gui/OptionsDlg.hx b/src/gui/OptionsDlg.hx index ecfecd85..dc1b1b04 100644 --- a/src/gui/OptionsDlg.hx +++ b/src/gui/OptionsDlg.hx @@ -1,5 +1,6 @@ package gui; +import haxe.DynamicAccess; import hxd.BitmapData; import h2d.filter.DropShadow; import h2d.Text; @@ -18,6 +19,7 @@ import src.Settings; class OptionsDlg extends GuiImage { var musicSliderFunc:(dt:Float, mouseState:MouseState) -> Void; + var importing:Bool = false; public function new(pause:Bool = false) { function chooseBg() { @@ -80,10 +82,10 @@ class OptionsDlg extends GuiImage { hotkeysBtn.extent = new Vector(134, 65); window.addChild(hotkeysBtn); - var onlineBtn = new GuiImage(ResourceLoader.getResource("data/ui/options/online_i.png", ResourceLoader.getImage, this.imageResources).toTile()); - onlineBtn.position = new Vector(548, 19); - onlineBtn.extent = new Vector(134, 65); - window.addChild(onlineBtn); + var miscBtn = new GuiButton(loadButtonImages('data/ui/options/misc')); + miscBtn.position = new Vector(548, 19); + miscBtn.extent = new Vector(134, 65); + window.addChild(miscBtn); var applyFunc:Void->Void = () -> { Settings.applySettings(); @@ -120,6 +122,10 @@ class OptionsDlg extends GuiImage { hotkeysPanel.position = new Vector(30, 88); hotkeysPanel.extent = new Vector(726, 394); + var miscPanel = new GuiControl(); + miscPanel.position = new Vector(30, 88); + miscPanel.extent = new Vector(726, 394); + var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt"); var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry); @:privateAccess markerFelt32b.loader = ResourceLoader.loader; @@ -457,6 +463,31 @@ class OptionsDlg extends GuiImage { parent.addChild(remapBtn); } + function makeButton(text:String, yPos:Int, buttonText:String, pressedAction:() -> Void, parent:GuiControl, right:Bool = false) { + var textObj = new GuiText(markerFelt32); + textObj.position = new Vector(right ? 368 : 5, yPos); + textObj.extent = new Vector(212, 14); + textObj.text.text = text; + textObj.text.textColor = 0xFFFFFF; + textObj.text.dropShadow = { + dx: 1 * Settings.uiScale, + dy: 1 * Settings.uiScale, + alpha: 0.5, + color: 0 + }; + parent.addChild(textObj); + + var btn = new GuiButtonText(loadButtonImages("data/ui/options/bind"), markerFelt24); + btn.position = new Vector(right ? 363 + 203 : 203, yPos - 3); + btn.txtCtrl.text.text = buttonText; + btn.setExtent(new Vector(152, 49)); + btn.pressedAction = (sender) -> { + pressedAction(); + } + + parent.addChild(btn); + } + if (Util.isTouchDevice()) { var textObj = new GuiText(markerFelt32); textObj.position = new Vector(5, 38); @@ -527,10 +558,44 @@ class OptionsDlg extends GuiImage { hotkeysPanel, true); } + // MISC PANEL + makeButton("Import Progress:", 38, "Import", () -> { + trace("Start prefs import"); + importing = true; + Settings.start_import_prefs((data) -> { + try { + // convert to string + var jsonStr = @:privateAccess String.fromUTF8(data); + // parse JSON + var json = haxe.Json.parse(jsonStr); + + var highScoreData:DynamicAccess> = json.highScores; + for (key => value in highScoreData) { + Settings.highScores.set(key, value); + } + var easterEggData:DynamicAccess = json.easterEggs; + if (easterEggData != null) { + for (key => value in easterEggData) { + Settings.easterEggs.set(key, value); + } + } + MarbleGame.canvas.pushDialog(new MessageBoxOkDlg("Progress data imported successfully!")); + Settings.save(); + } catch (e) { + MarbleGame.canvas.pushDialog(new MessageBoxOkDlg("Failed to import progress data: " + e.message)); + } + importing = false; // reset this flag after import is done + }); + }, miscPanel); + makeButton("Export Progress:", 38, "Export", () -> { + Settings.export_prefs(); + }, miscPanel, true); + generalBtn.pressedAction = (e) -> { if (currentTab != "general") { currentTab = "general"; - hotkeysPanel.parent.removeChild(hotkeysPanel); + hotkeysPanel.parent?.removeChild(hotkeysPanel); + miscPanel.parent?.removeChild(miscPanel); window.addChild(generalPanel); MarbleGame.canvas.render(MarbleGame.canvas.scene2d); // Force refresh } @@ -539,12 +604,23 @@ class OptionsDlg extends GuiImage { hotkeysBtn.pressedAction = (e) -> { if (currentTab != "hotkeys") { currentTab = "hotkeys"; - generalPanel.parent.removeChild(generalPanel); + generalPanel.parent?.removeChild(generalPanel); + miscPanel.parent?.removeChild(miscPanel); window.addChild(hotkeysPanel); MarbleGame.canvas.render(MarbleGame.canvas.scene2d); // Force refresh } }; + miscBtn.pressedAction = (e) -> { + if (currentTab != "misc") { + currentTab = "misc"; + generalPanel.parent?.removeChild(generalPanel); + hotkeysPanel.parent?.removeChild(hotkeysPanel); + window.addChild(miscPanel); + MarbleGame.canvas.render(MarbleGame.canvas.scene2d); // Force refresh + } + }; + // // Touch Controls buttons??? // if (Util.isTouchDevice()) { // var touchControlsTxt = new GuiText(domcasual24); @@ -600,5 +676,8 @@ class OptionsDlg extends GuiImage { super.update(dt, mouseState); if (musicSliderFunc != null) musicSliderFunc(dt, mouseState); + if (importing) { + Settings.call_import_cb(); + } } }