feat: animated connecting icon
This commit is contained in:
parent
8c0b65220a
commit
9e37d72071
59
main.jai
59
main.jai
@ -10,6 +10,7 @@
|
||||
|
||||
// Custom constants
|
||||
TIMER_PROCESS_CHECK :: 1;
|
||||
TIMER_ANIMATION :: 2;
|
||||
|
||||
IDI_APPLICATION :: cast(*u16) 32512;
|
||||
IDI_SHIELD :: cast(*u16) 32518;
|
||||
@ -28,6 +29,12 @@ App_State :: struct {
|
||||
|
||||
icon_running: HICON;
|
||||
icon_stopped: HICON;
|
||||
|
||||
is_connecting: bool;
|
||||
connecting_ticks: int;
|
||||
is_updating: bool;
|
||||
animation_frame: int;
|
||||
icon_frames: [4] HICON;
|
||||
}
|
||||
|
||||
// Custom log print sending logs to OutputDebugStringW
|
||||
@ -133,7 +140,13 @@ update_tray :: (app: *App_State) {
|
||||
nid.uID = 1;
|
||||
nid.uFlags = NIF_ICON | NIF_TIP;
|
||||
|
||||
if app.singbox_running {
|
||||
if app.is_connecting {
|
||||
nid.hIcon = app.icon_frames[app.animation_frame];
|
||||
set_tray_tip(*nid, "Sing-box: Connecting...");
|
||||
} else if app.is_updating {
|
||||
nid.hIcon = app.icon_frames[app.animation_frame];
|
||||
set_tray_tip(*nid, "Sing-box: Updating Config...");
|
||||
} else if app.singbox_running {
|
||||
nid.hIcon = app.icon_running;
|
||||
set_tray_tip(*nid, "Sing-box: Running");
|
||||
} else {
|
||||
@ -218,6 +231,11 @@ start_singbox :: (app: *App_State) -> bool {
|
||||
app.singbox_job_handle = job;
|
||||
app.singbox_running = true;
|
||||
|
||||
app.is_connecting = true;
|
||||
app.connecting_ticks = 0;
|
||||
app.animation_frame = 0;
|
||||
SetTimer(app.hwnd, TIMER_ANIMATION, 250, null);
|
||||
|
||||
if app.use_system_proxy {
|
||||
set_windows_system_proxy(true, tprint("127.0.0.1:%", app.port));
|
||||
log_print("System proxy enabled on port %.\n", app.port);
|
||||
@ -229,6 +247,9 @@ start_singbox :: (app: *App_State) -> bool {
|
||||
}
|
||||
|
||||
stop_singbox :: (app: *App_State) {
|
||||
app.is_connecting = false;
|
||||
KillTimer(app.hwnd, TIMER_ANIMATION);
|
||||
|
||||
if !app.singbox_running return;
|
||||
|
||||
TerminateProcess(app.singbox_process_handle, 0);
|
||||
@ -279,7 +300,15 @@ check_process_status :: (app: *App_State) {
|
||||
}
|
||||
|
||||
trigger_immediate_update :: (app: *App_State) {
|
||||
app.is_updating = true;
|
||||
app.animation_frame = 0;
|
||||
SetTimer(app.hwnd, TIMER_ANIMATION, 150, null);
|
||||
update_tray(app);
|
||||
|
||||
changed, success, err_msg := perform_update();
|
||||
|
||||
app.is_updating = false;
|
||||
|
||||
if success {
|
||||
if changed {
|
||||
log_print("Config updated, restarting Sing-box...\n");
|
||||
@ -293,10 +322,15 @@ trigger_immediate_update :: (app: *App_State) {
|
||||
} else {
|
||||
if !app.singbox_running {
|
||||
start_singbox(app);
|
||||
} else {
|
||||
KillTimer(app.hwnd, TIMER_ANIMATION);
|
||||
update_tray(app);
|
||||
}
|
||||
MessageBoxW(app.hwnd, utf8_to_wide("Configuration is already up-to-date."), utf8_to_wide("Sing-box Tray"), MB_ICONINFORMATION);
|
||||
}
|
||||
} else {
|
||||
KillTimer(app.hwnd, TIMER_ANIMATION);
|
||||
update_tray(app);
|
||||
msg := tprint("Failed to download configuration.\nError: %", err_msg);
|
||||
MessageBoxW(app.hwnd, utf8_to_wide(msg), utf8_to_wide("Sing-box Tray"), MB_ICONERROR);
|
||||
}
|
||||
@ -464,6 +498,22 @@ app_wnd_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESUL
|
||||
case WM_TIMER; {
|
||||
if wparam == TIMER_PROCESS_CHECK {
|
||||
check_process_status(app);
|
||||
} else if wparam == TIMER_ANIMATION {
|
||||
if app.is_connecting {
|
||||
app.connecting_ticks += 1;
|
||||
app.animation_frame = (app.animation_frame + 1) % 4;
|
||||
update_tray(app);
|
||||
|
||||
// Stop connecting animation after 12 ticks (3 seconds at 250ms)
|
||||
if app.connecting_ticks >= 12 {
|
||||
app.is_connecting = false;
|
||||
KillTimer(hwnd, TIMER_ANIMATION);
|
||||
update_tray(app);
|
||||
}
|
||||
} else if app.is_updating {
|
||||
app.animation_frame = (app.animation_frame + 1) % 4;
|
||||
update_tray(app);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -504,6 +554,10 @@ main :: () {
|
||||
app_state: App_State;
|
||||
app_state.icon_running = load_stock_icon(SIID_WORLD);
|
||||
app_state.icon_stopped = load_stock_icon(SIID_ERROR);
|
||||
app_state.icon_frames[0] = load_stock_icon(SIID_SERVER);
|
||||
app_state.icon_frames[1] = load_stock_icon(SIID_DRIVENET);
|
||||
app_state.icon_frames[2] = load_stock_icon(SIID_WORLD);
|
||||
app_state.icon_frames[3] = load_stock_icon(SIID_INTERNET);
|
||||
|
||||
hwnd := CreateWindowExW(
|
||||
0,
|
||||
@ -593,4 +647,7 @@ main :: () {
|
||||
|
||||
if app_state.icon_running DestroyIcon(app_state.icon_running);
|
||||
if app_state.icon_stopped DestroyIcon(app_state.icon_stopped);
|
||||
for app_state.icon_frames {
|
||||
if it DestroyIcon(it);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user