Skip to content

Commit

Permalink
put a tray icon and remove program tab from taskbar
Browse files Browse the repository at this point in the history
  • Loading branch information
Soar Qin committed Oct 28, 2021
1 parent 314788e commit b19fd48
Show file tree
Hide file tree
Showing 8 changed files with 562 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ Diablo II Resurrected map revealing tool.
* [inih](https://github.com/benhoyt/inih) for reading INI files.
* [JSON for Modern C++](https://github.com/nlohmann/json) for reading JSON files.
* [CascLib](https://github.com/ladislav-zezula/CascLib) for reading Casc Storage from Diablo II Resurrected.
* [tray](https://github.com/zserge/tray) for tray icon support
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
file(GLOB D2RMH_SRC_FILES *.cpp *.h)
file(GLOB D2RMH_SRC_FILES *.cpp *.h *.rc)
add_executable(D2RMH ${D2RMH_SRC_FILES})
target_include_directories(D2RMH PRIVATE ../d2mapapi)
target_link_libraries(D2RMH inih d2mapapi shlwapi)
Expand Down
Binary file added src/D2RMH.ico
Binary file not shown.
26 changes: 22 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "d2rprocess.h"
#include "cfg.h"
#include "ini.h"
#define TRAY_WINAPI 1
#include "tray/tray.h"
#include "../common/jsonlng.h"

#include "sokol/HandmadeMath.h"
Expand Down Expand Up @@ -360,17 +362,32 @@ static void initSokol() {
});
}

static void quit_cb(struct tray_menu *item) {
tray_exit();
}

static void init() {
mapstate.d2rProcess = new D2RProcess;
HWND hwnd = (HWND)sapp_win32_get_hwnd();
ShowWindow(hwnd, SW_HIDE);

DWORD style = WS_POPUP;
DWORD exStyle = WS_EX_LAYERED | WS_EX_TRANSPARENT;
DWORD exStyle = WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW;
SetWindowLong(hwnd, GWL_STYLE, style);
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle);
SetLayeredWindowAttributes(hwnd, 0, cfg->alpha, LWA_COLORKEY | LWA_ALPHA);

static tray_menu menu[] = {
{.text = (char*)"Quit", .cb = quit_cb},
{.text = nullptr}
};

static tray tmenu = {
.icon = "D2RMH.exe",
.menu = menu,
};
tray_init(&tmenu);

d2MapInit(cfg->d2Path.c_str());
initData();
initSokol();
Expand Down Expand Up @@ -762,6 +779,10 @@ static void checkForUpdate() {
}

static void frame() {
if (tray_loop(0) != 0) {
sapp_request_quit();
return;
}
checkForUpdate();
sg_begin_default_pass(&pass_action, sapp_width(), sapp_height());
if (mapstate.d2rProcess->available()) {
Expand Down Expand Up @@ -861,9 +882,6 @@ sapp_desc sokol_main(int argc, char *argv[]) {
.swap_interval = 1,
.alpha = true,
.window_title = "D2RMH",
.icon = {
.sokol_default = true,
},
.gl_force_gles2 = true,
};
}
1 change: 1 addition & 0 deletions src/res.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1 ICON "D2RMH.ico"
21 changes: 21 additions & 0 deletions src/tray/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2017 Serge Zaitsev

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
146 changes: 146 additions & 0 deletions src/tray/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
Tray
----

Cross-platform, single header, super tiny C99 implementation of a system tray icon with a popup menu.

Works well on:

* Linux/Gtk (libappindicator)
* Windows XP or newer (shellapi.h)
* MacOS (Cocoa/AppKit)

There is also a stub implementation that returns errors on attempt to create a tray menu.

# Setup

Before you can compile `tray`, you'll need to add an environment definition before the line where you include `tray.h`.

**For Windows:**
```c
#include <stdio.h>
#include <string.h>

#define TRAY_WINAPI 1

#include "tray.h"
...
```

**For Linux:**
```c
#include <stdio.h>
#include <string.h>

#define TRAY_APPINDICATOR 1

#include "tray.h"
...
```

**For Mac:**
```c
#include <stdio.h>
#include <string.h>

#define TRAY_APPKIT 1

#include "tray.h"
...
```

# Demo

The included example `.c` files can be compiled based on your environment.

For example, to compile and run the program on Windows:

```shell
$> gcc example_windows.c [Enter]
```

This will compile and build `a.out`. To run it:

```
$> a [Enter]
```

# Example

```c
struct tray tray = {
.icon = "icon.png",
.menu = (struct tray_menu[]){{"Toggle me", 0, 0, toggle_cb, NULL},
{"-", 0, 0, NULL, NULL},
{"Quit", 0, 0, quit_cb, NULL},
{NULL, 0, 0, NULL, NULL}},
};

void toggle_cb(struct tray_menu *item) {
item->checked = !item->checked;
tray_update(&tray);
}

void quit_cb(struct tray_menu *item) {
tray_exit();
}

...

tray_init(&tray);
while (tray_loop(1) == 0);
tray_exit();

```
# API
Tray structure defines an icon and a menu.
Menu is a NULL-terminated array of items.
Menu item defines menu text, menu checked and disabled (grayed) flags and a
callback with some optional context pointer.
```c
struct tray {
char *icon;
struct tray_menu *menu;
};
struct tray_menu {
char *text;
int disabled;
int checked;
void (*cb)(struct tray_menu *);
void *context;
struct tray_menu *submenu;
};
```

* `int tray_init(struct tray *)` - creates tray icon. Returns -1 if tray icon/menu can't be created.
* `void tray_update(struct tray *)` - updates tray icon and menu.
* `int tray_loop(int blocking)` - runs one iteration of the UI loop. Returns -1 if `tray_exit()` has been called.
* `void tray_exit()` - terminates UI loop.

All functions are meant to be called from the UI thread only.

Menu arrays must be terminated with a NULL item, e.g. the last item in the
array must have text field set to NULL.

## Roadmap

* [x] Cross-platform tray icon
* [x] Cross-platform tray popup menu
* [x] Separators in the menu
* [x] Disabled/enabled menu items
* [x] Checked/unchecked menu items
* [x] Nested menus
* [ ] Icons for menu items
* [x] Rewrite ObjC code in C using ObjC Runtime (now ObjC code breaks many linters and static analyzers)
* [ ] Call GTK code using dlopen/dlsym (to make binaries run safely if Gtk libraries are not available)

## License

This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php),
so feel free to integrate it in your commercial products.

Loading

0 comments on commit b19fd48

Please sign in to comment.