From 89e9b9ab1d4b5238615146ea106a1bf5bf1e76fe Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Wed, 28 Feb 2018 17:04:28 +0300 Subject: [PATCH] added new method set_window_icon for macos, windows, html5 platform --- .gitignore | 1 + defos/src/defos.cpp | 8 ++ defos/src/defos_html5.cpp | 19 +++++ defos/src/defos_mac.mm | 10 +++ defos/src/defos_private.h | 4 +- defos/src/defos_win.cpp | 10 +++ example/example.gui | 160 +++++++++++++++++++++++++++++++++++++ example/example.gui_script | 11 +++ game.project | 2 + icons/js-web/html5.ico | Bin 0 -> 1150 bytes icons/x86-osx/mac.png | Bin 0 -> 2001 bytes icons/x86-win32/win.ico | Bin 0 -> 21822 bytes icons/x86_64-osx/mac.png | Bin 0 -> 2001 bytes icons/x86_64-win32/win.ico | Bin 0 -> 21822 bytes 14 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 icons/js-web/html5.ico create mode 100644 icons/x86-osx/mac.png create mode 100644 icons/x86-win32/win.ico create mode 100644 icons/x86_64-osx/mac.png create mode 100644 icons/x86_64-win32/win.ico diff --git a/.gitignore b/.gitignore index a3072b5..2f2226a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ builtins .internal .clang_complete .vscode/ +*.txt diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index a77fb7e..12749fb 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -337,6 +337,13 @@ static int on_cursor_lock_disabled(lua_State *L) return 0; } +static int set_window_icon(lua_State *L) +{ + const char *icon_path = luaL_checkstring(L, 1); + defos_set_window_icon(icon_path); + return 0; +} + void defos_emit_event(DefosEvent event) { LuaCallbackInfo *mscb = &defos_event_handlers[event]; @@ -401,6 +408,7 @@ static const luaL_reg Module_methods[] = {"get_view_size", get_view_size}, {"set_cursor", set_cursor}, {"reset_cursor", reset_cursor}, + {"set_window_icon", set_window_icon}, {0, 0}}; static void LuaInit(lua_State *L) diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index 44ef03d..2619b2b 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -144,6 +144,25 @@ void defos_set_window_title(const char* title_lua) { EM_ASM_({document.title = UTF8ToString($0)}, title_lua); } +void defos_set_window_icon(const char *icon_path) +{ + EM_ASM_({ + document.head || (document.head = document.getElementsByTagName('head')[0]); + function changeFavicon(src) { + var link = document.createElement('link'); + var oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = src; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + } + changeFavicon(UTF8ToString($0)); + }, icon_path); +} + void defos_set_window_size(float x, float y, float w, float h) { defos_set_view_size(x, y, w, h); } diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index eb5f005..e6e221f 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -110,6 +110,16 @@ void defos_set_window_size(float x, float y, float w, float h) { [window setFrame:NSMakeRect(x, win_y, w , h) display:YES]; } +void defos_set_window_icon(const char *icon_path) +{ + NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; + NSString *secondParentPath = [[bundlePath stringByDeletingLastPathComponent] stringByDeletingLastPathComponent]; + NSString *path = [secondParentPath stringByAppendingPathComponent:[NSString stringWithUTF8String:icon_path]]; + NSImage* image = [[NSImage alloc] initWithContentsOfFile: path]; + [window setRepresentedURL:[NSURL URLWithString:path]]; + [[window standardWindowButton:NSWindowDocumentIconButton] setImage:image]; +} + void defos_set_view_size(float x, float y, float w, float h) { if (isnan(x)) { NSRect frame = window.screen.frame; diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index a902274..47da7a8 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -50,6 +50,8 @@ extern bool defos_is_fullscreen(); extern bool defos_is_maximized(); extern void defos_set_window_title(const char* title_lua); +extern void defos_set_window_icon(const char *icon_path); +extern void defos_set_window_icon_mac(dmBuffer::HBuffer buffer); extern void defos_set_window_size(float x, float y, float w, float h); extern WinRect defos_get_window_size(); @@ -75,4 +77,4 @@ extern void defos_set_custom_cursor_html5(const char *url); extern void defos_set_custom_cursor_win(const char *filename); extern void defos_set_custom_cursor_mac(dmBuffer::HBuffer buffer, float hotSpotX, float hotSpotY); extern void defos_set_cursor(DefosCursor cursor); -extern void defos_reset_cursor(); +extern void defos_reset_cursor(); \ No newline at end of file diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index a7e755f..4597cb4 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -206,6 +206,16 @@ void defos_set_window_title(const char *title_lua) SetWindowTextW(dmGraphics::GetNativeWindowsHWND(), CA2W(title_lua)); } +void defos_set_window_icon(const char *icon_path) +{ + HANDLE icon = LoadImage(NULL, icon_path, IMAGE_ICON, 32, 32, LR_LOADFROMFILE); + if (icon) + { + HWND window = dmGraphics::GetNativeWindowsHWND(); + SendMessage(window, (UINT)WM_SETICON, ICON_BIG, (LPARAM)icon); + } +} + WinRect defos_get_window_size() { HWND window = dmGraphics::GetNativeWindowsHWND(); diff --git a/example/example.gui b/example/example.gui index 220debf..c9f0e4a 100644 --- a/example/example.gui +++ b/example/example.gui @@ -2668,6 +2668,166 @@ nodes { text_leading: 1.0 text_tracking: 0.0 } +nodes { + position { + x: 861.0 + y: 389.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "set_icon" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/dirtylarry/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 88.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_BOX + blend_mode: BLEND_MODE_ALPHA + texture: "button/button_normal" + id: "set_icon/larrybutton" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "set_icon" + layer: "" + inherit_alpha: true + slice9 { + x: 32.0 + y: 32.0 + z: 32.0 + w: 32.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + size { + x: 250.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Set Icon" + font: "larryfont" + id: "set_icon/larrylabel" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: true + parent: "set_icon/larrybutton" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + overridden_fields: 4 + overridden_fields: 8 + overridden_fields: 18 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} material: "/builtins/materials/gui.material" adjust_reference: ADJUST_REFERENCE_LEGACY max_nodes: 512 diff --git a/example/example.gui_script b/example/example.gui_script index 6741156..8a01863 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -4,6 +4,13 @@ local cursor_url = require("example.html5_cursor") local system_name = sys.get_sys_info().system_name +--pls add the files using bundle_resources parameter in game.project https://www.defold.com/manuals/project-settings/ +local ICON_NAMES = { + ["Windows"] = "win.ico", + ["HTML5"] = "html5.ico", + ["Darwin"] = "/mac.png" +} + function window_callback(self, event, data) if event == window.WINDOW_EVENT_FOCUS_LOST then -- though after lost focus cursor clipping will restore, we should restore it @@ -204,6 +211,10 @@ function on_input(self, action_id, action) end end) + dirtylarry:button("set_icon", action_id, action, function() + defos.set_window_icon(ICON_NAMES[system_name]) + end) + dirtylarry:button("change_cursor", action_id, action, function() self.current_cursor = self.current_cursor + 1 diff --git a/game.project b/game.project index 36be68e..57620fb 100644 --- a/game.project +++ b/game.project @@ -3,6 +3,8 @@ title = DefOS version = 1.0.1 dependencies = https://github.com/andsve/dirtylarry/archive/master.zip custom_resources = resources/ +bundle_resources = /icons +write_log = 0 [bootstrap] main_collection = /example/example.collectionc diff --git a/icons/js-web/html5.ico b/icons/js-web/html5.ico new file mode 100644 index 0000000000000000000000000000000000000000..b260328beda79b11403ab5d7be7bea8acc9409d7 GIT binary patch literal 1150 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 literal 0 HcmV?d00001 diff --git a/icons/x86_64-osx/mac.png b/icons/x86_64-osx/mac.png new file mode 100644 index 0000000000000000000000000000000000000000..d285f2d10c4c3f9e0c8996251427ca39d34d175f GIT binary patch literal 2001 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 literal 0 HcmV?d00001