Skip to content

Commit 5b646f8

Browse files
Added functions for setting the window icon (#926)
* [dx] Added functions to set an icon from bytes * [sdl] Added support for setIcon * [dx] Fix typo in Icon
1 parent d862deb commit 5b646f8

5 files changed

Lines changed: 102 additions & 19 deletions

File tree

libs/directx/dx/Icon.hx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package dx;
2+
3+
private typedef IconPtr = hl.Abstract<"dx_icon">;
4+
5+
abstract Icon(IconPtr) {
6+
@:hlNative("?directx","create_icon")
7+
public static function createIcon( width : Int, height : Int, pixels : hl.Bytes) : Icon {
8+
return null;
9+
}
10+
11+
public function destroy() {
12+
destroyIcon(this);
13+
}
14+
15+
@:hlNative("?directx","destroy_icon")
16+
static function destroyIcon( ptr : IconPtr) {
17+
}
18+
19+
}

libs/directx/dx/Window.hx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class Window {
5454
public var vsync : Bool;
5555
public var dragAndDropEnabled(default, set) : Bool;
5656

57+
var icon : Icon = null;
58+
5759
public function new( title : String, width : Int, height : Int, x : Int = CW_USEDEFAULT, y : Int = CW_USEDEFAULT, windowFlags : Int = RESIZABLE ) {
5860
win = winCreateEx(x, y, width, height, windowFlags);
5961
this.title = title;
@@ -138,6 +140,10 @@ class Window {
138140
public function destroy() {
139141
winDestroy(win);
140142
win = null;
143+
if (icon != null) {
144+
icon.destroy();
145+
icon = null;
146+
}
141147
windows.remove(this);
142148
}
143149

@@ -157,6 +163,20 @@ class Window {
157163
winSetFocus(win);
158164
}
159165

166+
public function setIcon(width : Int, height: Int, pixels : hl.Bytes) {
167+
var newIcon = Icon.createIcon(width, height, pixels);
168+
if (newIcon == null)
169+
return;
170+
171+
winSetIcon(win, newIcon);
172+
173+
if (icon != null) {
174+
icon.destroy();
175+
}
176+
177+
icon = newIcon;
178+
}
179+
160180
public function getNextEvent( e : Event ) : Bool {
161181
return winGetNextEvent(win, e);
162182
}
@@ -409,4 +429,8 @@ class Window {
409429
return null;
410430
}
411431

432+
@:hlNative("?directx", "win_set_icon")
433+
static function winSetIcon(win: WinPtr, icon: Icon) : Void {
434+
}
435+
412436
}

libs/directx/window.c

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ static bool capture_mouse = false;
9393
static bool relative_mouse = false;
9494

9595
typedef HCURSOR dx_cursor;
96+
typedef HICON dx_icon;
97+
98+
#define TICON _ABSTRACT(dx_icon)
9699

97100
static dx_cursor cur_cursor = NULL;
98101
static bool show_cursor = true;
@@ -957,6 +960,11 @@ HL_PRIM int HL_NAME(win_change_display_setting)(wchar_t* device, vdynamic* ds) {
957960
return ChangeDisplaySettingsExW(device, found ? &devMode : NULL, NULL, found ? CDS_FULLSCREEN : 0, NULL);
958961
}
959962

963+
HL_PRIM void HL_NAME(win_set_icon)(HWND wnd, dx_icon icon) {
964+
SendMessage(wnd, WM_SETICON, ICON_SMALL, (LPARAM)icon);
965+
SendMessage(wnd, WM_SETICON, ICON_BIG, (LPARAM)icon);
966+
}
967+
960968
#define TWIN _ABSTRACT(dx_window)
961969
DEFINE_PRIM(TWIN, win_create_ex, _I32 _I32 _I32 _I32 _I32);
962970
DEFINE_PRIM(TWIN, win_create, _I32 _I32);
@@ -990,6 +998,7 @@ DEFINE_PRIM(_DYN, win_get_current_display_setting, _BYTES _BOOL);
990998
DEFINE_PRIM(_I32, win_change_display_setting, _BYTES _DYN);
991999
DEFINE_PRIM(_ARR, win_get_monitors, _NO_ARG);
9921000
DEFINE_PRIM(_BYTES, win_get_monitor_from_window, TWIN);
1001+
DEFINE_PRIM(_VOID, win_set_icon, TWIN TICON);
9931002
DEFINE_PRIM(_VOID, win_set_dark_mode, TWIN _BOOL);
9941003

9951004
DEFINE_PRIM(_I32, get_screen_width, _NO_ARG);
@@ -999,38 +1008,40 @@ HL_PRIM dx_cursor HL_NAME(load_cursor)( int res ) {
9991008
return LoadCursor(NULL,MAKEINTRESOURCE(res));
10001009
}
10011010

1002-
HL_PRIM dx_cursor HL_NAME(create_cursor)( int width, int height, vbyte *data, int hotX, int hotY ) {
1011+
static HICON create_icon_internal(int width, int height, vbyte* data, bool icon, int hotX, int hotY) {
10031012
int pad = sizeof(void*) << 3;
10041013
HICON hicon;
10051014
HDC hdc = GetDC(NULL);
10061015
BITMAPV4HEADER bmh;
1007-
void *pixels;
1008-
void *maskbits;
1016+
void* pixels;
1017+
void* maskbits;
10091018
int maskbitslen;
10101019
ICONINFO ii;
10111020

1012-
ZeroMemory(&bmh,sizeof(bmh));
1021+
ZeroMemory(&bmh, sizeof(bmh));
10131022
bmh.bV4Size = sizeof(bmh);
10141023
bmh.bV4Width = width;
10151024
bmh.bV4Height = -height;
10161025
bmh.bV4Planes = 1;
10171026
bmh.bV4BitCount = 32;
10181027
bmh.bV4V4Compression = BI_BITFIELDS;
10191028
bmh.bV4AlphaMask = 0xFF000000;
1020-
bmh.bV4RedMask = 0x00FF0000;
1029+
bmh.bV4RedMask = 0x00FF0000;
10211030
bmh.bV4GreenMask = 0x0000FF00;
1022-
bmh.bV4BlueMask = 0x000000FF;
1031+
bmh.bV4BlueMask = 0x000000FF;
10231032

1024-
maskbitslen = ((width + (-width)%pad) >> 3) * height;
1033+
maskbitslen = ((width + (-width) % pad) >> 3) * height;
10251034
maskbits = malloc(maskbitslen);
1026-
if( maskbits == NULL )
1035+
if (maskbits == NULL)
10271036
return NULL;
1028-
memset(maskbits,0xFF,maskbitslen);
1037+
memset(maskbits, 0xFF, maskbitslen);
10291038

1030-
memset(&ii,0,sizeof(ii));
1031-
ii.fIcon = FALSE;
1032-
ii.xHotspot = (DWORD)hotX;
1033-
ii.yHotspot = (DWORD)hotY;
1039+
memset(&ii, 0, sizeof(ii));
1040+
ii.fIcon = icon;
1041+
if (icon) {
1042+
ii.xHotspot = (DWORD)hotX;
1043+
ii.yHotspot = (DWORD)hotY;
1044+
}
10341045
ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, DIB_RGB_COLORS, &pixels, NULL, 0);
10351046
ii.hbmMask = CreateBitmap(width, height, 1, 1, maskbits);
10361047
ReleaseDC(NULL, hdc);
@@ -1044,10 +1055,23 @@ HL_PRIM dx_cursor HL_NAME(create_cursor)( int width, int height, vbyte *data, in
10441055
return hicon;
10451056
}
10461057

1058+
1059+
HL_PRIM dx_cursor HL_NAME(create_cursor)( int width, int height, vbyte *data, int hotX, int hotY ) {
1060+
return create_icon_internal(width, height, data, false, hotX, hotY);
1061+
}
1062+
1063+
HL_PRIM dx_icon HL_NAME(create_icon)(int width, int height, vbyte* data) {
1064+
return create_icon_internal(width, height, data, true, 0, 0);
1065+
}
1066+
10471067
HL_PRIM void HL_NAME(destroy_cursor)( dx_cursor c ) {
10481068
DestroyIcon(c);
10491069
}
10501070

1071+
HL_PRIM void HL_NAME(destroy_icon)(dx_icon i) {
1072+
DestroyIcon(i);
1073+
}
1074+
10511075
HL_PRIM void HL_NAME(set_cursor)( dx_cursor c ) {
10521076
cur_cursor = c;
10531077
if( CURSOR_VISIBLE )
@@ -1066,7 +1090,9 @@ HL_PRIM bool HL_NAME(is_cursor_visible)() {
10661090
#define TCURSOR _ABSTRACT(dx_cursor)
10671091
DEFINE_PRIM(TCURSOR, load_cursor, _I32);
10681092
DEFINE_PRIM(TCURSOR, create_cursor, _I32 _I32 _BYTES _I32 _I32);
1093+
DEFINE_PRIM(TICON, create_icon, _I32 _I32 _BYTES);
10691094
DEFINE_PRIM(_VOID, destroy_cursor, TCURSOR);
1095+
DEFINE_PRIM(_VOID, destroy_icon, TICON);
10701096
DEFINE_PRIM(_VOID, set_cursor, TCURSOR);
10711097
DEFINE_PRIM(_VOID, show_cursor, _BOOL);
10721098
DEFINE_PRIM(_BOOL, is_cursor_visible, _NO_ARG);

libs/sdl/sdl.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#define TWIN _ABSTRACT(sdl_window)
2323
#define TGL _ABSTRACT(sdl_gl)
24+
#define _SURF _ABSTRACT(sdl_surface)
2425

2526
typedef struct {
2627
int x;
@@ -101,6 +102,7 @@ typedef struct {
101102

102103
static bool isGlOptionsSet = false;
103104

105+
104106
HL_PRIM bool HL_NAME(init_once)() {
105107
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
106108
if( SDL_Init(SDL_INIT_EVERYTHING) != 0 ) {
@@ -634,6 +636,10 @@ HL_PRIM void HL_NAME(win_set_title)(SDL_Window *win, vbyte *title) {
634636
SDL_SetWindowTitle(win, (char*)title);
635637
}
636638

639+
HL_PRIM void HL_NAME(win_set_icon)(SDL_Window *win, SDL_Surface *s) {
640+
SDL_SetWindowIcon(win, s);
641+
}
642+
637643
HL_PRIM void HL_NAME(win_set_position)(SDL_Window *win, int x, int y) {
638644
SDL_SetWindowPosition(win, x, y);
639645
}
@@ -738,6 +744,7 @@ DEFINE_PRIM(_I32, win_display_handle, TWIN);
738744
DEFINE_PRIM(_VOID, win_resize, TWIN _I32);
739745
DEFINE_PRIM(_VOID, win_raise, TWIN);
740746
DEFINE_PRIM(_VOID, win_set_title, TWIN _BYTES);
747+
DEFINE_PRIM(_VOID, win_set_icon, TWIN _SURF);
741748
DEFINE_PRIM(_VOID, win_set_position, TWIN _I32 _I32);
742749
DEFINE_PRIM(_VOID, win_get_position, TWIN _REF(_I32) _REF(_I32));
743750
DEFINE_PRIM(_VOID, win_set_size, TWIN _I32 _I32);
@@ -870,7 +877,6 @@ HL_PRIM void HL_NAME(free_surface)( SDL_Surface *s ) {
870877
SDL_FreeSurface(s);
871878
}
872879

873-
#define _SURF _ABSTRACT(sdl_surface)
874880
DEFINE_PRIM(_SURF, surface_from, _BYTES _I32 _I32 _I32 _I32 _I32 _I32 _I32 _I32);
875881
DEFINE_PRIM(_VOID, free_surface, _SURF);
876882

libs/sdl/sdl/Window.hx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ class Window {
160160
return visible = b;
161161
}
162162

163+
public function setIcon(surface: Surface) {
164+
winSetIcon(win, surface);
165+
}
166+
163167
public function resize( width : Int, height : Int ) {
164168
winSetSize(win, width, height);
165169
}
@@ -258,16 +262,16 @@ class Window {
258262
winSetOpacity(win, v);
259263
return v;
260264
}
261-
265+
262266
function get_grab() {
263267
return getWindowGrab(win);
264268
}
265-
269+
266270
function set_grab(v) {
267271
setWindowGrab(win, v);
268272
return v;
269273
}
270-
274+
271275
function get_id() {
272276
return winGetId(win);
273277
}
@@ -320,6 +324,10 @@ class Window {
320324
static function winSetTitle( win : WinPtr, title : hl.Bytes ) {
321325
}
322326

327+
@:hlNative("?sdl", "win_set_icon")
328+
static function winSetIcon(win : WinPtr, surface: Surface) {
329+
}
330+
323331
static function winSetPosition( win : WinPtr, width : Int, height : Int ) {
324332
}
325333

@@ -396,11 +404,11 @@ class Window {
396404

397405
static function setWindowGrab( win : WinPtr, grab : Bool ) {
398406
}
399-
407+
400408
static function getWindowGrab( win : WinPtr ) : Bool {
401409
return false;
402410
}
403-
411+
404412
static function warpMouseInWindow( win : WinPtr, x : Int, y : Int ) : Void {
405413
}
406414

0 commit comments

Comments
 (0)