diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..b818c75
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,43 @@
+name: Build
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Add MSBuild to PATH
+ uses: microsoft/setup-msbuild@v2
+
+ - name: Build x64
+ run: msbuild vs2026/voidImageViewer.sln /p:Configuration=Release /p:Platform=x64 /p:PlatformToolset=v143
+
+ - name: Build x86
+ run: msbuild vs2026/voidImageViewer.sln /p:Configuration=Release /p:Platform=Win32 /p:PlatformToolset=v143
+
+ - name: Setup NSIS
+ run: |
+ choco install nsis -y
+ "C:\Program Files (x86)\NSIS" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+
+ - name: Build Installer x64
+ run: powershell -File nsis/build_installer.ps1 -Arch x64 -VsVersion vs2026 -BuildConfig Release -Lang English
+
+ - name: Build Installer x86
+ run: powershell -File nsis/build_installer.ps1 -Arch x86 -VsVersion vs2026 -BuildConfig Release -Lang English
+
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: voidImageViewer-build
+ path: |
+ voidImageViewer/x64/Release/voidImageViewer.exe
+ voidImageViewer/Release/voidImageViewer.exe
+ nsis/voidImageViewer-*-setup.exe
diff --git a/README.md b/README.md
index 1d27215..4ac632c 100644
--- a/README.md
+++ b/README.md
@@ -26,25 +26,51 @@ void Image Viewer main window:
void Image Viewer General Options:
-
+
void Image Viewer View Options:
-
+
void Image Viewer Controls Options:
-
+
+## Changelog
+
+### Version 1.1.0.0 (Latest)
+- **New Feature: Zoom Options Tab & Calculation Engine**
+ - Added dedicated **Zoom options** tab in Options dialog (`IDD_ZOOM`).
+ - Added customizable zoom calculation methods:
+ - **Relative step:** Multiplicative scaling using configured zoom step % (default: 10%).
+ - **Absolute step:** Additive scaling by fixed percentage point steps.
+ - **Fixed table:** Step-by-step navigation through a user-defined list of zoom percentage levels (default: `1;2;3;10;14;16;19;21;25;28;33;38;43;50;57;66;76;87;100;115;132;150;174;200;230;260;300;350;400;450;500;600;700;800;900;1000;1200;1400;1600;2000;3000;`).
+ - Added **Load default table** button to quickly restore default values.
+- **Improved Zoom Handling:** Pixel under cursor remains stationary during mouse wheel and shortcut zooms across all zoom methods.
+- **Expanded Localization:** Added full UI translations for the Zoom options page in English (`en-US`), Indonesian (`id-ID`), and Simplified Chinese (`zh-CN`).
+- **Configuration Persistence:** Zoom settings (`zoom_calc_method`, `zoom_step`, `zoom_fixed_table`) automatically saved to and loaded from `voidImageViewer.ini`.
+
+| Feature / Behavior | Before (v1.0.1.0) | After (v1.1.0.0) |
+| :--- | :--- | :--- |
+| **Zoom Calculation Method** | Hardcoded fixed exponential power steps (`_viv_zoom_pos` from 0 to 63) | Choice between **Relative step (%)**, **Absolute step (%)**, or customizable **Fixed table** |
+| **Zoom Step Config** | Fixed / non-configurable | Configurable zoom step percentage (default `10%`) |
+| **Fixed Table Values** | Not available | Semicolon-delimited custom table support (up to 50 ordered values) with default reset |
+| **Settings UI** | 3 tabs (*General*, *View*, *Controls*) | 4 tabs (*General*, *View*, *Controls*, ***Zoom options***) |
+| **Localization** | Dialog strings for 3 tabs | Full multilingual translations for all 4 tabs (English, Indonesian, Chinese) |
+| **INI Storage** | No zoom calculation preferences saved | Saves `zoom_calc_method`, `zoom_step`, `zoom_fixed_table` to INI |
+
+
+
See also
--------
https://www.voidtools.com/forum/viewtopic.php?t=5623
+
diff --git a/comments.json b/comments.json
new file mode 100644
index 0000000..a65ec5f
Binary files /dev/null and b/comments.json differ
diff --git a/issues.json b/issues.json
new file mode 100644
index 0000000..811c766
Binary files /dev/null and b/issues.json differ
diff --git a/nsis/version.nsh b/nsis/version.nsh
index 6e65d04..211bac8 100644
--- a/nsis/version.nsh
+++ b/nsis/version.nsh
@@ -1,3 +1,3 @@
-!define VERSION "1.0.0.15"
+!define VERSION "1.1.0.0"
!define BETAVERSION ""
!define VERSIONYEAR "2026"
diff --git a/res/resource.h b/res/resource.h
index e3639f7..32e2144 100644
--- a/res/resource.h
+++ b/res/resource.h
@@ -25,6 +25,7 @@
#define IDD_RENAME 127
#define IDD_JUMPTO 128
#define IDD_EVERYTHING 129
+#define IDD_ZOOM 130
#define IDC_TAB1 1003
#define IDC_BMP 1006
#define IDC_GIF 1007
@@ -90,15 +91,43 @@
#define IDC_TITLE_BAR_FORMAT 1052
#define IDC_SHRINK_BLIT_MODE_STATIC 1053
#define IDC_MAGNIFY_BLIT_MODE_STATIC 1054
+#define IDC_RESET_WINDOW 1055
+#define IDC_LANGUAGE_STATIC 1056
+#define IDC_LANGUAGE_COMBOBOX 1057
+#define IDC_LOOP_ANIMATIONS_ONCE_STATIC 1058
+#define IDC_PRELOAD_NEXT_IMAGE_STATIC 1059
+#define IDC_CACHE_LAST_IMAGE_STATIC 1060
+#define IDC_WINDOWEDBACKGROUNDCOLOR_STATIC 1061
+#define IDC_FULLSCREENBACKGROUNDCOLOR_STATIC 1062
+#define IDC_LEFT_CLICK_ACTION_STATIC 1063
+#define IDC_RIGHT_CLICK_ACTION_STATIC 1064
+#define IDC_MOUSE_WHEEL_ACTION_STATIC 1065
+#define IDC_COMMANDS_STATIC 1066
+#define IDC_SETTINGS_FOR_SELECTED_COMMAND_STATIC 1067
+#define IDC_TITLE_BAR_FORMAT_STATIC 1068
+#define IDC_AUTO_SIZE_WINDOW_STATIC 1069
+#define IDC_EDIT_KEYBOARD_SHORTCUT_KEY_STATIC 1070
+#define IDC_EDIT_KEYBOARD_SHORTCUT_KEY_CURRENTLY_USED_BY_STATIC 1071
+#define IDC_CUSTOM_RATE_STATIC 1072
+#define IDC_TAB4 1073
+#define IDC_ZOOM_STEP_STATIC 1074
+#define IDC_ZOOM_STEP_EDIT 1075
+#define IDC_ZOOM_STEP_PERCENT_STATIC 1076
+#define IDC_ZOOM_STEP_DEFAULT_STATIC 1077
+#define IDC_ZOOM_CALC_METHOD_STATIC 1078
+#define IDC_ZOOM_CALC_RELATIVE_RADIO 1079
+#define IDC_ZOOM_CALC_ABSOLUTE_RADIO 1080
+#define IDC_ZOOM_CALC_FIXED_TABLE_RADIO 1081
+#define IDC_ZOOM_FIXED_TABLE_EDIT 1082
+#define IDC_ZOOM_LOAD_DEFAULT_TABLE_BUTTON 1083
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
-#define _APS_NEXT_RESOURCE_VALUE 130
+#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_COMMAND_VALUE 40048
-#define _APS_NEXT_CONTROL_VALUE 1055
-#define _APS_NEXT_SYMED_VALUE 109
+#define _APS_NEXT_CONTROL_VALUE 1084
#endif
#endif
diff --git a/res/voidImageViewer.rc b/res/voidImageViewer.rc
index b138421..4d974b8 100644
--- a/res/voidImageViewer.rc
+++ b/res/voidImageViewer.rc
@@ -26,86 +26,109 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// Dialog
//
-IDD_GENERAL DIALOGEX 0, 0, 194, 180
+IDD_GENERAL DIALOGEX 0, 0, 244, 200
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
+ LTEXT "&Language:",IDC_LANGUAGE_STATIC,0,2,50,12,SS_CENTERIMAGE
+ COMBOBOX IDC_LANGUAGE_COMBOBOX,54,0,135,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "&Store settings in %APPDATA%\\voidImageViewer",IDC_APPDATA,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,0,186,10
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,20,186,10
CONTROL "Allow multiple &instances",IDC_MULTIPLE_INSTANCES,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,18,186,10
- CONTROL "Start &menu shortcuts",IDC_STARTMENU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,36,186,10
- GROUPBOX "Associations",IDC_STATIC,0,54,54,124
- CONTROL "&BMP",IDC_BMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,66,42,10
- CONTROL "&GIF",IDC_GIF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,78,42,10
- CONTROL "IC&O",IDC_ICO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,90,42,10
- CONTROL "JP&EG",IDC_JPEG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,102,42,10
- CONTROL "&JPG",IDC_JPG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,114,42,10
- CONTROL "&PNG",IDC_PNG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,126,42,10
- CONTROL "&TIF",IDC_TIF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,138,42,10
- CONTROL "TIF&F",IDC_TIFF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,150,42,10
- CONTROL "&WEBP",IDC_WEBP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,162,42,10
- PUSHBUTTON "Check &All",IDC_CHECKALL,60,60,54,14
- PUSHBUTTON "Check &None",IDC_CHECKNONE,60,78,54,14
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,38,186,10
+ CONTROL "Start &menu shortcuts",IDC_STARTMENU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,56,186,10
+ GROUPBOX "Associations",IDC_STATIC,0,74,54,124
+ CONTROL "&BMP",IDC_BMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,86,42,10
+ CONTROL "&GIF",IDC_GIF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,98,42,10
+ CONTROL "IC&O",IDC_ICO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,110,42,10
+ CONTROL "JP&EG",IDC_JPEG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,122,42,10
+ CONTROL "&JPG",IDC_JPG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,134,42,10
+ CONTROL "&PNG",IDC_PNG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,146,42,10
+ CONTROL "&TIF",IDC_TIF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,158,42,10
+ CONTROL "TIF&F",IDC_TIFF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,170,42,10
+ CONTROL "&WEBP",IDC_WEBP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,182,42,10
+ PUSHBUTTON "Check &All",IDC_CHECKALL,60,80,54,14
+ PUSHBUTTON "Check &None",IDC_CHECKNONE,60,98,54,14
END
-IDD_OPTIONS DIALOGEX 0, 0, 310, 271
+IDD_OPTIONS DIALOGEX 0, 0, 360, 271
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTROLPARENT
CAPTION "Options - Void Image Viewer"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- DEFPUSHBUTTON "OK",IDOK,198,252,50,14,WS_GROUP
- PUSHBUTTON "Cancel",IDCANCEL,252,252,50,14
+ DEFPUSHBUTTON "OK",IDOK,248,252,50,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,302,252,50,14
CONTROL "",IDC_TREE1,"SysTreeView32",TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,6,6,84,240
- CONTROL "",IDC_TAB1,"SysTabControl32",WS_TABSTOP,96,6,210,240
- CONTROL "",IDC_TAB2,"SysTabControl32",WS_TABSTOP,96,6,210,240
- CONTROL "",IDC_TAB3,"SysTabControl32",WS_TABSTOP,96,6,210,240
- LTEXT "Static",IDC_PAGEPLACEHOLDER,106,26,186,214,NOT WS_VISIBLE
+ CONTROL "",IDC_TAB1,"SysTabControl32",WS_TABSTOP,96,6,260,240
+ CONTROL "",IDC_TAB2,"SysTabControl32",WS_TABSTOP,96,6,260,240
+ CONTROL "",IDC_TAB3,"SysTabControl32",WS_TABSTOP,96,6,260,240
+ CONTROL "",IDC_TAB4,"SysTabControl32",WS_TABSTOP,96,6,260,240
+ LTEXT "Static",IDC_PAGEPLACEHOLDER,106,26,236,214,NOT WS_VISIBLE
END
-IDD_VIEW DIALOGEX 0, 0, 194, 183
+IDD_VIEW DIALOGEX 0, 0, 244, 183
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- LTEXT "&Shrink blit mode:",IDC_SHRINK_BLIT_MODE_STATIC,0,0,74,12,SS_CENTERIMAGE
- COMBOBOX IDC_COMBO1,74,0,119,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "&Magnify blit mode:",IDC_MAGNIFY_BLIT_MODE_STATIC,0,19,74,8
- COMBOBOX IDC_COMBO2,74,17,119,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "&Title bar format:",IDC_STATIC,0,36,74,8
- COMBOBOX IDC_TITLE_BAR_FORMAT,74,34,119,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- CONTROL "Auto si&ze window:",IDC_AUTO_ZOOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,53,74,10
- COMBOBOX IDC_COMBO4,74,51,60,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- CONTROL "&Play animations at least once in slideshow",IDC_LOOP_ANIMATIONS_ONCE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,70,192,10
- CONTROL "Preload &next image",IDC_PRELOAD_NEXT_IMAGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,87,192,10
- CONTROL "Cache &last image",IDC_CACHE_LAST_IMAGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,103,192,10
- LTEXT "&Windowed background color:",IDC_STATIC,0,122,96,8
- PUSHBUTTON "",IDC_WINDOWEDBACKGROUNDCOLOR,96,120,50,14,BS_BITMAP
- LTEXT "&Fullscreen background color:",IDC_STATIC,0,140,96,8
- PUSHBUTTON "",IDC_FULLSCREENBACKGROUNDCOLOR,96,138,50,14,BS_BITMAP
+ LTEXT "&Shrink blit mode:",IDC_SHRINK_BLIT_MODE_STATIC,0,0,100,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO1,104,0,135,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Magnify blit mode:",IDC_MAGNIFY_BLIT_MODE_STATIC,0,19,100,8
+ COMBOBOX IDC_COMBO2,104,17,135,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Title bar format:",IDC_TITLE_BAR_FORMAT_STATIC,0,36,100,8
+ COMBOBOX IDC_TITLE_BAR_FORMAT,104,34,135,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Auto si&ze window:",IDC_AUTO_ZOOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,53,100,10
+ COMBOBOX IDC_COMBO4,104,51,60,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "&Play animations at least once in slideshow",IDC_LOOP_ANIMATIONS_ONCE_STATIC,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,70,236,10
+ CONTROL "Preload &next image",IDC_PRELOAD_NEXT_IMAGE_STATIC,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,87,236,10
+ CONTROL "Cache &last image",IDC_CACHE_LAST_IMAGE_STATIC,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,103,236,10
+ LTEXT "&Windowed background color:",IDC_WINDOWEDBACKGROUNDCOLOR_STATIC,0,122,120,8
+ PUSHBUTTON "",IDC_WINDOWEDBACKGROUNDCOLOR,124,120,50,14,BS_BITMAP
+ LTEXT "&Fullscreen background color:",IDC_FULLSCREENBACKGROUNDCOLOR_STATIC,0,140,120,8
+ PUSHBUTTON "",IDC_FULLSCREENBACKGROUNDCOLOR,124,138,50,14,BS_BITMAP
+ PUSHBUTTON "Reset Window Size && Position",IDC_RESET_WINDOW,0,158,150,14
END
-IDD_CONTROLS DIALOGEX 0, 0, 194, 216
+IDD_CONTROLS DIALOGEX 0, 0, 244, 216
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- LTEXT "&Left click action:",IDC_STATIC,0,0,54,12,SS_CENTERIMAGE
- COMBOBOX IDC_LEFTCLICKACTION,74,0,119,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "&Right click action:",IDC_STATIC,0,19,63,8
- COMBOBOX IDC_RIGHTCLICKACTION,74,17,119,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "&Mouse wheel action:",IDC_STATIC,0,36,72,8
- COMBOBOX IDC_MOUSEWHEELACTION,74,34,119,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "&Commands:",IDC_STATIC,0,53,57,8
- LISTBOX IDC_COMMANDS_LIST,0,64,193,78,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Settings for selected command",IDC_STATIC,0,148,193,67
+ LTEXT "&Left click action:",IDC_LEFT_CLICK_ACTION_STATIC,0,0,70,12,SS_CENTERIMAGE
+ COMBOBOX IDC_LEFTCLICKACTION,74,0,165,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Right click action:",IDC_RIGHT_CLICK_ACTION_STATIC,0,19,70,8
+ COMBOBOX IDC_RIGHTCLICKACTION,74,17,165,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Mouse wheel action:",IDC_MOUSE_WHEEL_ACTION_STATIC,0,36,70,8
+ COMBOBOX IDC_MOUSEWHEELACTION,74,34,165,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Commands:",IDC_COMMANDS_STATIC,0,53,70,8
+ LISTBOX IDC_COMMANDS_LIST,0,64,244,78,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Settings for selected command",IDC_SETTINGS_FOR_SELECTED_COMMAND_STATIC,0,148,244,67
LISTBOX IDC_KEYS_LIST,7,158,125,50,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
- PUSHBUTTON "&Add...",IDC_ADD_KEY,138,158,50,14
- PUSHBUTTON "&Edit...",IDC_EDIT_KEY,137,177,50,14
- PUSHBUTTON "Remo&ve",IDC_REMOVE_KEY,137,195,50,14
+ PUSHBUTTON "&Add...",IDC_ADD_KEY,188,158,50,14
+ PUSHBUTTON "&Edit...",IDC_EDIT_KEY,187,177,50,14
+ PUSHBUTTON "Remo&ve",IDC_REMOVE_KEY,187,195,50,14
+END
+
+IDD_ZOOM DIALOGEX 0, 0, 244, 200
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LTEXT "Zoom &step:",IDC_ZOOM_STEP_STATIC,0,2,42,12,SS_CENTERIMAGE
+ EDITTEXT IDC_ZOOM_STEP_EDIT,46,2,24,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "%",IDC_ZOOM_STEP_PERCENT_STATIC,73,2,8,12,SS_CENTERIMAGE
+ LTEXT "(default: 10 %)",IDC_ZOOM_STEP_DEFAULT_STATIC,86,2,100,12,SS_CENTERIMAGE
+ LTEXT "Zoom calculation method:",IDC_ZOOM_CALC_METHOD_STATIC,0,22,244,10
+ CONTROL "&Relative step",IDC_ZOOM_CALC_RELATIVE_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,10,36,220,10
+ CONTROL "&Absolute step",IDC_ZOOM_CALC_ABSOLUTE_RADIO,"Button",BS_AUTORADIOBUTTON,10,50,220,10
+ CONTROL "Use &fixed table: (for experts: max. 50 ordered values from 3 to 4000)",IDC_ZOOM_CALC_FIXED_TABLE_RADIO,"Button",BS_AUTORADIOBUTTON,10,64,234,10
+ EDITTEXT IDC_ZOOM_FIXED_TABLE_EDIT,18,78,140,14,ES_AUTOHSCROLL | WS_TABSTOP
+ PUSHBUTTON "&Load default table",IDC_ZOOM_LOAD_DEFAULT_TABLE_BUTTON,162,78,76,14,WS_TABSTOP
END
IDD_CUSTOM_RATE DIALOGEX 0, 0, 202, 63
@@ -205,8 +228,8 @@ IDI_BESTFIT ICON "bestfit.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,15
- PRODUCTVERSION 1,0,0,15
+ FILEVERSION 1,1,0,0
+ PRODUCTVERSION 1,1,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -222,12 +245,12 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "voidImageViewer"
- VALUE "FileVersion", "1.0.0.15"
+ VALUE "FileVersion", "1.1.0.0"
VALUE "InternalName", "voidImageViewer"
- VALUE "LegalCopyright", "Copyright © 2026 voidtools"
+ VALUE "LegalCopyright", "Copyright © 2026 voidtools"
VALUE "OriginalFilename", "voidImageViewer.exe"
VALUE "ProductName", "voidImageViewer"
- VALUE "ProductVersion", "1.0.0.15"
+ VALUE "ProductVersion", "1.1.0.0"
END
END
BLOCK "VarFileInfo"
@@ -287,3 +310,5 @@ END
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
+
+
diff --git a/res/voidImageViewer_utf8.rc b/res/voidImageViewer_utf8.rc
new file mode 100644
index 0000000..3dafd1d
--- /dev/null
+++ b/res/voidImageViewer_utf8.rc
@@ -0,0 +1,312 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_GENERAL DIALOGEX 0, 0, 244, 200
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LTEXT "&Language:",IDC_LANGUAGE_STATIC,0,2,50,12,SS_CENTERIMAGE
+ COMBOBOX IDC_LANGUAGE_COMBOBOX,54,0,135,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "&Store settings in %APPDATA%\\voidImageViewer",IDC_APPDATA,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,20,186,10
+ CONTROL "Allow multiple &instances",IDC_MULTIPLE_INSTANCES,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,38,186,10
+ CONTROL "Start &menu shortcuts",IDC_STARTMENU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,56,186,10
+ GROUPBOX "Associations",IDC_STATIC,0,74,54,124
+ CONTROL "&BMP",IDC_BMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,86,42,10
+ CONTROL "&GIF",IDC_GIF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,98,42,10
+ CONTROL "IC&O",IDC_ICO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,110,42,10
+ CONTROL "JP&EG",IDC_JPEG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,122,42,10
+ CONTROL "&JPG",IDC_JPG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,134,42,10
+ CONTROL "&PNG",IDC_PNG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,146,42,10
+ CONTROL "&TIF",IDC_TIF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,158,42,10
+ CONTROL "TIF&F",IDC_TIFF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,170,42,10
+ CONTROL "&WEBP",IDC_WEBP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,182,42,10
+ PUSHBUTTON "Check &All",IDC_CHECKALL,60,80,54,14
+ PUSHBUTTON "Check &None",IDC_CHECKNONE,60,98,54,14
+END
+
+IDD_OPTIONS DIALOGEX 0, 0, 360, 271
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Options - Void Image Viewer"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,248,252,50,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,302,252,50,14
+ CONTROL "",IDC_TREE1,"SysTreeView32",TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,6,6,84,240
+ CONTROL "",IDC_TAB1,"SysTabControl32",WS_TABSTOP,96,6,260,240
+ CONTROL "",IDC_TAB2,"SysTabControl32",WS_TABSTOP,96,6,260,240
+ CONTROL "",IDC_TAB3,"SysTabControl32",WS_TABSTOP,96,6,260,240
+ CONTROL "",IDC_TAB4,"SysTabControl32",WS_TABSTOP,96,6,260,240
+ LTEXT "Static",IDC_PAGEPLACEHOLDER,106,26,236,214,NOT WS_VISIBLE
+END
+
+IDD_VIEW DIALOGEX 0, 0, 244, 183
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LTEXT "&Shrink blit mode:",IDC_SHRINK_BLIT_MODE_STATIC,0,0,100,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO1,104,0,135,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Magnify blit mode:",IDC_MAGNIFY_BLIT_MODE_STATIC,0,19,100,8
+ COMBOBOX IDC_COMBO2,104,17,135,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Title bar format:",IDC_TITLE_BAR_FORMAT_STATIC,0,36,100,8
+ COMBOBOX IDC_TITLE_BAR_FORMAT,104,34,135,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Auto si&ze window:",IDC_AUTO_ZOOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,53,100,10
+ COMBOBOX IDC_COMBO4,104,51,60,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "&Play animations at least once in slideshow",IDC_LOOP_ANIMATIONS_ONCE_STATIC,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,70,236,10
+ CONTROL "Preload &next image",IDC_PRELOAD_NEXT_IMAGE_STATIC,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,87,236,10
+ CONTROL "Cache &last image",IDC_CACHE_LAST_IMAGE_STATIC,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,103,236,10
+ LTEXT "&Windowed background color:",IDC_WINDOWEDBACKGROUNDCOLOR_STATIC,0,122,120,8
+ PUSHBUTTON "",IDC_WINDOWEDBACKGROUNDCOLOR,124,120,50,14,BS_BITMAP
+ LTEXT "&Fullscreen background color:",IDC_FULLSCREENBACKGROUNDCOLOR_STATIC,0,140,120,8
+ PUSHBUTTON "",IDC_FULLSCREENBACKGROUNDCOLOR,124,138,50,14,BS_BITMAP
+ PUSHBUTTON "Reset Window Size && Position",IDC_RESET_WINDOW,0,158,150,14
+END
+
+IDD_CONTROLS DIALOGEX 0, 0, 244, 216
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LTEXT "&Left click action:",IDC_LEFT_CLICK_ACTION_STATIC,0,0,70,12,SS_CENTERIMAGE
+ COMBOBOX IDC_LEFTCLICKACTION,74,0,165,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Right click action:",IDC_RIGHT_CLICK_ACTION_STATIC,0,19,70,8
+ COMBOBOX IDC_RIGHTCLICKACTION,74,17,165,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Mouse wheel action:",IDC_MOUSE_WHEEL_ACTION_STATIC,0,36,70,8
+ COMBOBOX IDC_MOUSEWHEELACTION,74,34,165,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Commands:",IDC_COMMANDS_STATIC,0,53,70,8
+ LISTBOX IDC_COMMANDS_LIST,0,64,244,78,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Settings for selected command",IDC_SETTINGS_FOR_SELECTED_COMMAND_STATIC,0,148,244,67
+ LISTBOX IDC_KEYS_LIST,7,158,125,50,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "&Add...",IDC_ADD_KEY,188,158,50,14
+ PUSHBUTTON "&Edit...",IDC_EDIT_KEY,187,177,50,14
+ PUSHBUTTON "Remo&ve",IDC_REMOVE_KEY,187,195,50,14
+END
+
+IDD_ZOOM DIALOGEX 0, 0, 244, 200
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LTEXT "Zoom &step:",IDC_ZOOM_STEP_STATIC,0,2,42,12,SS_CENTERIMAGE
+ EDITTEXT IDC_ZOOM_STEP_EDIT,46,2,24,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "%",IDC_ZOOM_STEP_PERCENT_STATIC,73,2,8,12,SS_CENTERIMAGE
+ LTEXT "(default: 10 %)",IDC_ZOOM_STEP_DEFAULT_STATIC,86,2,100,12,SS_CENTERIMAGE
+ LTEXT "Zoom calculation method:",IDC_ZOOM_CALC_METHOD_STATIC,0,22,244,10
+ CONTROL "&Relative step",IDC_ZOOM_CALC_RELATIVE_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,10,36,220,10
+ CONTROL "&Absolute step",IDC_ZOOM_CALC_ABSOLUTE_RADIO,"Button",BS_AUTORADIOBUTTON,10,50,220,10
+ CONTROL "Use &fixed table: (for experts: max. 50 ordered values from 3 to 4000)",IDC_ZOOM_CALC_FIXED_TABLE_RADIO,"Button",BS_AUTORADIOBUTTON,10,64,234,10
+ EDITTEXT IDC_ZOOM_FIXED_TABLE_EDIT,18,78,140,14,ES_AUTOHSCROLL | WS_TABSTOP
+ PUSHBUTTON "&Load default table",IDC_ZOOM_LOAD_DEFAULT_TABLE_BUTTON,162,78,76,14,WS_TABSTOP
+END
+
+IDD_CUSTOM_RATE DIALOGEX 0, 0, 202, 63
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
+CAPTION "Set Custom Rate"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_CUSTOM_RATE_EDIT,54,12,66,12,ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ DEFPUSHBUTTON "OK",IDOK,90,36,48,14
+ PUSHBUTTON "Cancel",IDCANCEL,144,36,48,14
+ LTEXT "&Custom rate:",IDC_STATIC,6,14,45,8
+ COMBOBOX IDC_CUSTOM_RATE_TYPE_COMBO,126,12,66,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+END
+
+IDD_ABOUT DIALOGEX 0, 0, 228, 189
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
+CAPTION "About void Image Viewer"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,120,168,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,174,168,50,14
+ LTEXT "",IDC_ABOUTBACK,0,0,228,54
+ EDITTEXT IDC_ABOUTTITLE,30,18,192,30,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_ABOUTVOIDIMAGEVIEWER,30,66,192,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_ABOUTVERSION,30,84,192,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_ABOUTCOPYRIGHT,30,102,192,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_ABOUTEMAIL,30,120,192,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_ABOUTWEBSITE,30,138,192,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+END
+
+IDD_EDIT_KEY DIALOGEX 0, 0, 186, 119
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Edit Keyboard Shortcut"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Shortcut &key:",IDC_STATIC,7,7,44,8
+ EDITTEXT IDC_EDIT_KEY_EDIT,7,17,172,14,ES_AUTOHSCROLL | ES_WANTRETURN
+ LTEXT "Shortcut key currently used by:",IDC_STATIC,7,36,102,8
+ LISTBOX IDC_EDIT_KEY_CURRENTLY_USED_BY_LIST,7,47,172,43,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,70,98,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,129,98,50,14
+END
+
+IDD_RENAME DIALOGEX 0, 0, 186, 51
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Rename"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_RENAME_EDIT,7,7,172,14,ES_AUTOHSCROLL
+ DEFPUSHBUTTON "OK",IDOK,74,30,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,129,30,50,14
+ EDITTEXT IDC_RENAME_OLD_EDIT,7,30,40,14,ES_AUTOHSCROLL | NOT WS_VISIBLE
+END
+
+IDD_JUMPTO DIALOGEX 0, 0, 187, 229
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Jump To"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_JUMPTO_EDIT,7,7,173,14,ES_AUTOHSCROLL | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
+ LISTBOX IDC_JUMPTO_LIST,7,29,173,170,WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,74,208,50,14,WS_CLIPSIBLINGS | WS_CLIPCHILDREN
+ PUSHBUTTON "Cancel",IDCANCEL,130,208,50,14,WS_CLIPSIBLINGS | WS_CLIPCHILDREN
+END
+
+IDD_EVERYTHING DIALOGEX 0, 0, 186, 63
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Search Everything"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EVERYTHING_EDIT,6,6,173,14,ES_AUTOHSCROLL
+ CONTROL "Randomize",IDC_SEARCH_EVERYTHING_RANDOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,24,51,10
+ DEFPUSHBUTTON "OK",IDOK,72,42,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,127,42,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON "voidImageViewer.ico"
+IDI_PREV ICON "prev.ico"
+IDI_PLAY ICON "play.ico"
+IDI_NEXT ICON "next.ico"
+IDI_PAUSE ICON "pause.ico"
+IDI_1TO1 ICON "1to1-8bit.ico"
+IDI_BESTFIT ICON "bestfit.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,0,0
+ PRODUCTVERSION 1,1,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x0L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "voidImageViewer"
+ VALUE "FileVersion", "1.1.0.0"
+ VALUE "InternalName", "voidImageViewer"
+ VALUE "LegalCopyright", "Copyright © 2026 voidtools"
+ VALUE "OriginalFilename", "voidImageViewer.exe"
+ VALUE "ProductName", "voidImageViewer"
+ VALUE "ProductVersion", "1.1.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Australia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/scratch_version.ps1 b/scratch_version.ps1
new file mode 100644
index 0000000..91d9bb8
--- /dev/null
+++ b/scratch_version.ps1
@@ -0,0 +1,4 @@
+$c = Get-Content res\voidImageViewer.rc -Raw
+$c = $c -replace '1,0,0,15', '1,0,1,0'
+$c = $c -replace '1\.0\.0\.15', '1.0.1.0'
+Set-Content res\voidImageViewer.rc $c -Encoding Default
diff --git a/src/config.c b/src/config.c
index 719eb0c..c728519 100644
--- a/src/config.c
+++ b/src/config.c
@@ -29,7 +29,8 @@ static void _config_write_string(HANDLE h,const char *ascii_key,const wchar_t *s
static void _config_write_utf8(HANDLE h,const utf8_t *s);
static void _config_save_settings_by_location(const wchar_t *path,int is_root);
-BYTE config_appdata = 0; // store settings in %APPDATA%\voidimageviewer or in the same location as voidimageviewer.exe
+BYTE config_appdata = 1; // store settings in %APPDATA%\voidimageviewer or in the same location as voidimageviewer.exe
+BYTE config_language = 255; // 255 = auto
BYTE config_keep_centered = 1; // when zooming out, don't recenter the image. (keep cursor under the same pixel)
int config_x = 0;
int config_y = 0;
@@ -40,8 +41,8 @@ int config_slideshow_rate = 5000;
BYTE config_allow_shrinking = 1; // prevent resizing an image below 100%
BYTE config_shrink_blit_mode = CONFIG_SHRINK_BLIT_MODE_HALFTONE; // shrink filter
BYTE config_mag_filter = CONFIG_MAG_FILTER_COLORONCOLOR; // magnify filter
-BYTE config_nav_sort = CONFIG_NAV_SORT_DATE_MODIFIED; // current navigation sort.
-BYTE config_nav_sort_ascending = 0; // sort navigation ascending or descending.
+BYTE config_nav_sort = CONFIG_NAV_SORT_NAME; // current navigation sort.
+BYTE config_nav_sort_ascending = 1; // sort navigation ascending or descending.
BYTE config_keep_aspect_ratio = 1; // stretch images with the original aspect ratio.
BYTE config_fill_window = 0; // stretch the image to fill the window
BYTE config_fullscreen_fill_window = 1; // same as fill_window, except this setting is used when we are fullscreen
@@ -90,6 +91,9 @@ BYTE config_pixel_info = 0;
BYTE config_orientation = 1;
BYTE config_title_bar_format = 1; // 0=full path, 1=filename, 2=none
int config_add_command_line_timeout = 500; // in milliseconds
+BYTE config_zoom_calc_method = CONFIG_ZOOM_CALC_RELATIVE;
+int config_zoom_step = CONFIG_ZOOM_DEFAULT_STEP;
+wchar_t config_zoom_fixed_table[STRING_SIZE] = CONFIG_ZOOM_DEFAULT_FIXED_TABLE;
static void _config_load_settings_by_location(const wchar_t *path,int is_root)
{
@@ -102,6 +106,7 @@ static void _config_load_settings_by_location(const wchar_t *path,int is_root)
if (ini)
{
config_x = ini_get_int(ini,(const utf8_t *)"x",config_x);
+ config_language = ini_get_int(ini,(const utf8_t *)"language",config_language);
config_y = ini_get_int(ini,(const utf8_t *)"y",config_y);
config_wide = ini_get_int(ini,(const utf8_t *)"wide",config_wide);
config_high = ini_get_int(ini,(const utf8_t *)"high",config_high);
@@ -161,6 +166,15 @@ static void _config_load_settings_by_location(const wchar_t *path,int is_root)
config_toolbar_move_window = ini_get_int(ini,(const utf8_t *)"toolbar_move_window",config_toolbar_move_window);
config_title_bar_format = ini_get_int(ini,(const utf8_t *)"title_bar_format",config_title_bar_format);
config_add_command_line_timeout = ini_get_int(ini,(const utf8_t *)"add_command_line_timeout",config_add_command_line_timeout);
+ config_zoom_calc_method = ini_get_int(ini,(const utf8_t *)"zoom_calc_method",config_zoom_calc_method);
+ config_zoom_step = ini_get_int(ini,(const utf8_t *)"zoom_step",config_zoom_step);
+ {
+ const utf8_t *fixed_table = ini_get_string(ini,(const utf8_t *)"zoom_fixed_table");
+ if (fixed_table && *fixed_table)
+ {
+ string_copy_utf8_string(config_zoom_fixed_table,fixed_table);
+ }
+ }
if (is_root)
{
@@ -286,6 +300,7 @@ static void _config_save_settings_by_location(const wchar_t *path,int is_root)
else
{
_config_write_int(h,"x",config_x);
+ _config_write_int(h,"language",config_language);
_config_write_int(h,"y",config_y);
_config_write_int(h,"wide",config_wide);
_config_write_int(h,"high",config_high);
@@ -345,6 +360,9 @@ static void _config_save_settings_by_location(const wchar_t *path,int is_root)
_config_write_int(h,"toolbar_move_window",config_toolbar_move_window);
_config_write_int(h,"title_bar_format",config_title_bar_format);
_config_write_int(h,"add_command_line_timeout",config_add_command_line_timeout);
+ _config_write_int(h,"zoom_calc_method",config_zoom_calc_method);
+ _config_write_int(h,"zoom_step",config_zoom_step);
+ _config_write_string(h,"zoom_fixed_table",config_zoom_fixed_table);
// save keys
{
diff --git a/src/config.h b/src/config.h
index 6a6afa1..953bb92 100644
--- a/src/config.h
+++ b/src/config.h
@@ -55,10 +55,19 @@ typedef struct config_key_s
#define CONFIG_MAG_FILTER_COLORONCOLOR 0
#define CONFIG_MAG_FILTER_HALFTONE 1
+#define CONFIG_ZOOM_CALC_RELATIVE 0
+#define CONFIG_ZOOM_CALC_ABSOLUTE 1
+#define CONFIG_ZOOM_CALC_FIXED_TABLE 2
+
+#define CONFIG_ZOOM_DEFAULT_STEP 10
+#define CONFIG_ZOOM_DEFAULT_FIXED_TABLE L"1;2;3;10;14;16;19;21;25;28;33;38;43;50;57;66;76;87;100;115;132;150;174;200;230;260;300;350;400;450;500;600;700;800;900;1000;1200;1400;1600;2000;3000;"
+#define CONFIG_ZOOM_DEFAULT_FIXED_TABLE_A "1;2;3;10;14;16;19;21;25;28;33;38;43;50;57;66;76;87;100;115;132;150;174;200;230;260;300;350;400;450;500;600;700;800;900;1000;1200;1400;1600;2000;3000;"
+
void config_load_settings(void);
void config_save_settings(int appdata);
extern BYTE config_appdata;
+extern BYTE config_language;
extern BYTE config_keep_centered;
extern int config_x;
extern int config_y;
@@ -115,11 +124,13 @@ extern BYTE config_show_caption;
extern BYTE config_show_thickframe;
extern BYTE config_toolbar_move_window;
extern BYTE config_windowed_hide_cursor;
-extern BYTE config_auto_zoom;
extern BYTE config_pixel_info;
extern BYTE config_orientation;
extern BYTE config_title_bar_format;
extern int config_add_command_line_timeout;
+extern BYTE config_zoom_calc_method;
+extern int config_zoom_step;
+extern wchar_t config_zoom_fixed_table[STRING_SIZE];
#ifdef __cplusplus
}
diff --git a/src/localization.c b/src/localization.c
index 691e471..9e58b29 100644
--- a/src/localization.c
+++ b/src/localization.c
@@ -24,11 +24,13 @@
#include "viv.h"
#include "localization_en_us.h"
#include "localization_zh_cn.h"
+#include "localization_id_id.h"
static const utf8_t **_localization_language_array[LOCALIZATION_LANGUAGE_COUNT] =
{
_localization_string_array_en_us, // LOCALIZATION_LANGUAGE_ENGLISH
_localization_string_array_zh_cn, // LOCALIZATION_LANGUAGE_CHINESE_SIMPLIFIED
+ _localization_string_array_id_id, // LOCALIZATION_LANGUAGE_INDONESIAN
};
BYTE localization_language = LOCALIZATION_LANGUAGE_ENGLISH;
@@ -54,6 +56,16 @@ const utf8_t *localization_get_en_us_string(localization_id_t localization_id)
void localization_init(void)
{
+ // If config_language is not Auto, use it
+ if (config_language != 255)
+ {
+ if (config_language < LOCALIZATION_LANGUAGE_COUNT)
+ {
+ localization_language = config_language;
+ return;
+ }
+ }
+
// Detect system language
if (os_GetUserDefaultUILanguage)
{
@@ -69,5 +81,23 @@ void localization_init(void)
{
localization_language = LOCALIZATION_LANGUAGE_CHINESE_SIMPLIFIED;
}
+ else if (langid == 0x0421) // Indonesian
+ {
+ localization_language = LOCALIZATION_LANGUAGE_INDONESIAN;
+ }
+ else
+ {
+ localization_language = LOCALIZATION_LANGUAGE_ENGLISH;
+ }
}
}
+
+const utf8_t *localization_get_language_name(BYTE language)
+{
+ if (language < LOCALIZATION_LANGUAGE_COUNT)
+ {
+ return _localization_language_array[language][LOCALIZATION_ID_LANGUAGE];
+ }
+
+ return (const utf8_t *)"";
+}
diff --git a/src/localization.h b/src/localization.h
index 99248c5..5a93426 100644
--- a/src/localization.h
+++ b/src/localization.h
@@ -29,6 +29,7 @@ enum
{
LOCALIZATION_LANGUAGE_ENGLISH = 0,
LOCALIZATION_LANGUAGE_CHINESE_SIMPLIFIED,
+ LOCALIZATION_LANGUAGE_INDONESIAN,
LOCALIZATION_LANGUAGE_COUNT,
};
@@ -40,6 +41,7 @@ typedef BYTE localization_id_t;
// Returns UTF-8 encoded string
const utf8_t *localization_get_string(localization_id_t localization_id);
const utf8_t *localization_get_en_us_string(localization_id_t localization_id);
+const utf8_t *localization_get_language_name(BYTE language);
// Initialize language system (detects system language)
void localization_init(void);
@@ -49,6 +51,8 @@ enum
{
// Localization
LOCALIZATION_ID_LANGUAGE = 0,
+ LOCALIZATION_ID_LANGUAGE_STATIC,
+ LOCALIZATION_ID_LANGUAGE_AUTO,
// Application name
LOCALIZATION_ID_APP_NAME,
@@ -233,6 +237,7 @@ enum
LOCALIZATION_ID_OPTIONS_GENERAL_DIALOG,
LOCALIZATION_ID_OPTIONS_VIEW_DIALOG,
LOCALIZATION_ID_OPTIONS_CONTROLS_DIALOG,
+ LOCALIZATION_ID_OPTIONS_ZOOM_DIALOG,
LOCALIZATION_ID_OK_BUTTON,
LOCALIZATION_ID_CANCEL_BUTTON,
LOCALIZATION_ID_STORE_SETTINGS_APPDATA,
@@ -255,6 +260,7 @@ enum
LOCALIZATION_ID_CACHE_LAST_IMAGE_STATIC,
LOCALIZATION_ID_WINDOWED_BACKGROUND_COLOR_STATIC,
LOCALIZATION_ID_FULLSCREEN_BACKGROUND_COLOR_STATIC,
+ LOCALIZATION_ID_OPTIONS_VIEW_RESET_WINDOW_BUTTON,
LOCALIZATION_ID_LEFT_CLICK_ACTION_STATIC,
LOCALIZATION_ID_RIGHT_CLICK_ACTION_STATIC,
LOCALIZATION_ID_MOUSE_WHEEL_ACTION_STATIC,
@@ -300,6 +306,13 @@ enum
LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_FULL_PATH_COMBOBOXITEM,
LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_FILENAME_ONLY_COMBOBOXITEM,
LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_NONE_COMBOBOXITEM,
+ LOCALIZATION_ID_OPTIONS_ZOOM_STEP_STATIC,
+ LOCALIZATION_ID_OPTIONS_ZOOM_STEP_DEFAULT_STATIC,
+ LOCALIZATION_ID_OPTIONS_ZOOM_CALC_METHOD_STATIC,
+ LOCALIZATION_ID_OPTIONS_ZOOM_CALC_RELATIVE_RADIO,
+ LOCALIZATION_ID_OPTIONS_ZOOM_CALC_ABSOLUTE_RADIO,
+ LOCALIZATION_ID_OPTIONS_ZOOM_CALC_FIXED_TABLE_RADIO,
+ LOCALIZATION_ID_OPTIONS_ZOOM_LOAD_DEFAULT_TABLE_BUTTON,
LOCALIZATION_ID_EVERYTHING_NOT_AVAILABLE_MESSAGE,
LOCALIZATION_ID_EVERYTHING_ADD_EVERYTHING_SEARCH_CAPTION,
LOCALIZATION_ID_EVERYTHING_LOAD_EVERYTHING_SEARCH_CAPTION,
diff --git a/src/localization_en_us.h b/src/localization_en_us.h
index 5747262..f03a6e7 100644
--- a/src/localization_en_us.h
+++ b/src/localization_en_us.h
@@ -26,6 +26,8 @@ static const utf8_t *_localization_string_array_en_us[LOCALIZATION_ID_COUNT] =
{
// Application name
"English (US)", // LOCALIZATION_ID_LANGUAGE
+ "&Language:", // LOCALIZATION_ID_LANGUAGE_STATIC
+ "System Default", // LOCALIZATION_ID_LANGUAGE_AUTO
// Application name
"void Image Viewer", // LOCALIZATION_ID_APP_NAME
@@ -210,6 +212,7 @@ static const utf8_t *_localization_string_array_en_us[LOCALIZATION_ID_COUNT] =
"General", // LOCALIZATION_ID_OPTIONS_GENERAL_DIALOG,
"View", // LOCALIZATION_ID_OPTIONS_VIEW_DIALOG,
"Controls", // LOCALIZATION_ID_OPTIONS_CONTROLS_DIALOG,
+ "Zoom options", // LOCALIZATION_ID_OPTIONS_ZOOM_DIALOG,
"OK", // LOCALIZATION_ID_OK_BUTTON,
"Cancel", // LOCALIZATION_ID_CANCEL_BUTTON,
"&Store settings in %APPDATA%\\voidImageViewer", // LOCALIZATION_ID_STORE_SETTINGS_APPDATA,
@@ -232,6 +235,7 @@ static const utf8_t *_localization_string_array_en_us[LOCALIZATION_ID_COUNT] =
"Cache &last image", // LOCALIZATION_ID_CACHE_LAST_IMAGE_STATIC,
"&Windowed background color:", // LOCALIZATION_ID_WINDOWED_BACKGROUND_COLOR_STATIC,
"&Fullscreen background color:", // LOCALIZATION_ID_FULLSCREEN_BACKGROUND_COLOR_STATIC,
+ "Reset Window Size & Position", // LOCALIZATION_ID_OPTIONS_VIEW_RESET_WINDOW_BUTTON,
"&Left click action:", // LOCALIZATION_ID_LEFT_CLICK_ACTION_STATIC,
"&Right click action:", // LOCALIZATION_ID_RIGHT_CLICK_ACTION_STATIC,
"&Mouse wheel action:", // LOCALIZATION_ID_MOUSE_WHEEL_ACTION_STATIC,
@@ -277,6 +281,13 @@ static const utf8_t *_localization_string_array_en_us[LOCALIZATION_ID_COUNT] =
"Full Path", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_FULL_PATH_COMBOBOXITEM,
"Filename Only", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_FILENAME_ONLY_COMBOBOXITEM,
"None", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_NONE_COMBOBOXITEM,
+ "Zoom &step:", // LOCALIZATION_ID_OPTIONS_ZOOM_STEP_STATIC,
+ "(default: 10 %)", // LOCALIZATION_ID_OPTIONS_ZOOM_STEP_DEFAULT_STATIC,
+ "Zoom calculation method:", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_METHOD_STATIC,
+ "&Relative step", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_RELATIVE_RADIO,
+ "&Absolute step", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_ABSOLUTE_RADIO,
+ "Use &fixed table: (for experts: max. 50 ordered values from 3 to 4000)", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_FIXED_TABLE_RADIO,
+ "&Load default table", // LOCALIZATION_ID_OPTIONS_ZOOM_LOAD_DEFAULT_TABLE_BUTTON,
"Everything not available", // LOCALIZATION_ID_EVERYTHING_NOT_AVAILABLE_MESSAGE,
"Add Everything Search", // LOCALIZATION_ID_EVERYTHING_ADD_EVERYTHING_SEARCH_CAPTION,
"Load Everything Search", // LOCALIZATION_ID_EVERYTHING_LOAD_EVERYTHING_SEARCH_CAPTION,
diff --git a/src/localization_id_id.h b/src/localization_id_id.h
new file mode 100644
index 0000000..0c1e93e
--- /dev/null
+++ b/src/localization_id_id.h
@@ -0,0 +1,308 @@
+//
+// Copyright 2026 hesphoros
+//
+// 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.
+//
+// Indonesian localization
+// Save as UTF-8 without BOM.
+
+static const utf8_t *_localization_string_array_id_id[LOCALIZATION_ID_COUNT] =
+{
+ // Nama bahasa
+ "Bahasa Indonesia", // LOCALIZATION_ID_LANGUAGE
+ "&Bahasa:", // LOCALIZATION_ID_LANGUAGE_STATIC
+ "Default Sistem", // LOCALIZATION_ID_LANGUAGE_AUTO
+
+ // Nama aplikasi
+ "void Image Viewer", // LOCALIZATION_ID_APP_NAME
+
+ // Menu Berkas
+ "&Berkas", // LOCALIZATION_ID_FILE,
+ "&Buka Berkas...", // LOCALIZATION_ID_OPEN_FILE,
+ "Buka &Folder...", // LOCALIZATION_ID_OPEN_FOLDER,
+ "Buka Pencarian &Everything...", // LOCALIZATION_ID_OPEN_EVERYTHING_SEARCH,
+ "&Tambah Berkas...", // LOCALIZATION_ID_ADD_FILE,
+ "Tambah Folder...", // LOCALIZATION_ID_ADD_FOLDER,
+ "Tambah Pencarian Everything...", // LOCALIZATION_ID_ADD_EVERYTHING_SEARCH,
+ "Buka &Lokasi Berkas...", // LOCALIZATION_ID_OPEN_FILE_LOCATION,
+ "&Ubah...", // LOCALIZATION_ID_EDIT,
+ "P&ratinjau...", // LOCALIZATION_ID_PREVIEW,
+ "&Cetak...", // LOCALIZATION_ID_PRINT,
+ "Jadikan Wallpaper Des&ktop", // LOCALIZATION_ID_SET_DESKTOP_WALLPAPER,
+ "&Tutup", // LOCALIZATION_ID_CLOSE,
+ "&Hapus", // LOCALIZATION_ID_DELETE,
+ "Hapus (Tong Sampah)", // LOCALIZATION_ID_DELETE_RECYCLE,
+ "Hapus (Permanen)", // LOCALIZATION_ID_DELETE_PERMANENTLY,
+ "Ubah &Nama", // LOCALIZATION_ID_RENAME,
+ "P&roperti", // LOCALIZATION_ID_PROPERTIES,
+ "&Keluar", // LOCALIZATION_ID_EXIT,
+
+ // Menu Ubah
+ "&Ubah", // LOCALIZATION_ID_EDIT_MENU,
+ "Po&tong", // LOCALIZATION_ID_CUT,
+ "&Salin", // LOCALIZATION_ID_COPY,
+ "Salin Nama Berkas", // LOCALIZATION_ID_COPY_FILENAME,
+ "Salin &Gambar", // LOCALIZATION_ID_COPY_IMAGE,
+ "&Tempel", // LOCALIZATION_ID_PASTE,
+ "Putar Se&arah Jarum Jam", // LOCALIZATION_ID_ROTATE_CLOCKWISE,
+ "Putar Ber&lawanan Jarum Jam", // LOCALIZATION_ID_ROTATE_COUNTERCLOCKWISE,
+ "Salin ke &Folder...", // LOCALIZATION_ID_COPY_TO,
+ "Pi&ndah ke Folder...", // LOCALIZATION_ID_MOVE_TO,
+
+ // Menu Tampilan
+ "&Tampilan", // LOCALIZATION_ID_VIEW,
+ "Keterangan", // LOCALIZATION_ID_CAPTION,
+ "Bingkai", // LOCALIZATION_ID_FRAME,
+ "&Menu", // LOCALIZATION_ID_MENU,
+ "Bilah &Status", // LOCALIZATION_ID_STATUS_BAR,
+ "K&ontrol", // LOCALIZATION_ID_CONTROLS,
+ "&Preset", // LOCALIZATION_ID_PRESET,
+ "&Minimalis", // LOCALIZATION_ID_MINIMAL,
+ "&Ringkas", // LOCALIZATION_ID_COMPACT,
+ "&Normal", // LOCALIZATION_ID_NORMAL,
+ "&Layar Penuh", // LOCALIZATION_ID_FULLSCREEN,
+ "&Slideshow", // LOCALIZATION_ID_SLIDESHOW,
+ "&Ukuran Jendela", // LOCALIZATION_ID_VIEW_WINDOW_SIZE,
+ "50%", // LOCALIZATION_ID_VIEW_WINDOW_SIZE_50_PERCENT,
+ "100%", // LOCALIZATION_ID_VIEW_WINDOW_SIZE_100_PERCENT,
+ "200%", // LOCALIZATION_ID_VIEW_WINDOW_SIZE_200_PERCENT,
+ "&Pas Otomatis", // LOCALIZATION_ID_VIEW_WINDOW_SIZE_AUTO_FIT,
+ "&Segarkan", // LOCALIZATION_ID_REFRESH,
+ "&Izinkan Pengecilan", // LOCALIZATION_ID_ALLOW_SHRINKING,
+ "&Pertahankan Rasio Aspek", // LOCALIZATION_ID_KEEP_ASPECT_RATIO,
+ "&Isi Jendela", // LOCALIZATION_ID_FILL_WINDOW,
+ "1:1", // LOCALIZATION_ID_ONE_TO_ONE,
+ "Paling &Pas", // LOCALIZATION_ID_BEST_FIT,
+ "Geser && &Pindai", // LOCALIZATION_ID_PAN_SCAN,
+ "&Perbesar Ukuran", // LOCALIZATION_ID_INCREASE_SIZE,
+ "&Perkecil Ukuran", // LOCALIZATION_ID_DECREASE_SIZE,
+ "Pe&rlebar", // LOCALIZATION_ID_INCREASE_WIDTH,
+ "Pe&nyempit", // LOCALIZATION_ID_DECREASE_WIDTH,
+ "Per&tinggi", // LOCALIZATION_ID_INCREASE_HEIGHT,
+ "Per&pendek", // LOCALIZATION_ID_DECREASE_HEIGHT,
+ "&Zoom", // LOCALIZATION_ID_ZOOM,
+ "Zoom &Masuk", // LOCALIZATION_ID_ZOOM_IN,
+ "Zoom &Keluar", // LOCALIZATION_ID_ZOOM_OUT,
+ "&Atur Ulang", // LOCALIZATION_ID_RESET,
+ "Geser Ke &Atas", // LOCALIZATION_ID_MOVE_UP,
+ "Geser Ke &Bawah", // LOCALIZATION_ID_MOVE_DOWN,
+ "Geser Ke &Kiri", // LOCALIZATION_ID_MOVE_LEFT,
+ "Geser Ke &Kanan", // LOCALIZATION_ID_MOVE_RIGHT,
+ "Geser Atas Kiri", // LOCALIZATION_ID_MOVE_UP_LEFT,
+ "Geser Atas Kanan", // LOCALIZATION_ID_MOVE_UP_RIGHT,
+ "Geser Bawah Kiri", // LOCALIZATION_ID_MOVE_DOWN_LEFT,
+ "Geser Bawah Kanan", // LOCALIZATION_ID_MOVE_DOWN_RIGHT,
+ "Geser ke &Tengah", // LOCALIZATION_ID_MOVE_CENTER,
+ "Atur &Ulang", // LOCALIZATION_ID_PANSCAN_RESET,
+ "Selalu di &Atas", // LOCALIZATION_ID_ON_TOP,
+ "&Selalu", // LOCALIZATION_ID_ALWAYS,
+ "S&aat Memutar Slideshow atau Animasi", // LOCALIZATION_ID_WHILE_PLAYING_OR_ANIMATING,
+ "&Jangan Pernah", // LOCALIZATION_ID_NEVER,
+ "&Opsi...", // LOCALIZATION_ID_OPTIONS,
+
+ // Menu Slideshow
+ "&Slideshow", // LOCALIZATION_ID_SLIDESHOW_MENU,
+ "&Putar/Jeda", // LOCALIZATION_ID_PLAY_PAUSE,
+ "&Kecepatan", // LOCALIZATION_ID_RATE,
+ "&Kurangi Kecepatan", // LOCALIZATION_ID_DECREASE_RATE,
+ "&Tambah Kecepatan", // LOCALIZATION_ID_INCREASE_RATE,
+ "250 Milidetik", // LOCALIZATION_ID_RATE_250_MILLISECONDS,
+ "500 Milidetik", // LOCALIZATION_ID_RATE_500_MILLISECONDS,
+ "&1 Detik", // LOCALIZATION_ID_RATE_1_SECOND,
+ "&2 Detik", // LOCALIZATION_ID_RATE_2_SECONDS,
+ "&3 Detik", // LOCALIZATION_ID_RATE_3_SECONDS,
+ "&4 Detik", // LOCALIZATION_ID_RATE_4_SECONDS,
+ "&5 Detik", // LOCALIZATION_ID_RATE_5_SECONDS,
+ "&6 Detik", // LOCALIZATION_ID_RATE_6_SECONDS,
+ "&7 Detik", // LOCALIZATION_ID_RATE_7_SECONDS,
+ "&8 Detik", // LOCALIZATION_ID_RATE_8_SECONDS,
+ "&9 Detik", // LOCALIZATION_ID_RATE_9_SECONDS,
+ "1&0 Detik", // LOCALIZATION_ID_RATE_10_SECONDS,
+ "20 Detik", // LOCALIZATION_ID_RATE_20_SECONDS,
+ "30 Detik", // LOCALIZATION_ID_RATE_30_SECONDS,
+ "40 Detik", // LOCALIZATION_ID_RATE_40_SECONDS,
+ "50 Detik", // LOCALIZATION_ID_RATE_50_SECONDS,
+ "1 Menit", // LOCALIZATION_ID_RATE_1_MINUTE,
+ "Kustom...", // LOCALIZATION_ID_CUSTOM,
+
+ // Menu Animasi
+ "&Animasi", // LOCALIZATION_ID_ANIMATION,
+ "&Putar/Jeda", // LOCALIZATION_ID_ANIMATION_PLAY_PAUSE,
+ "Lompat ke &Depan", // LOCALIZATION_ID_ANIMATION_JUMP_FORWARD,
+ "Lompat ke &Belakang", // LOCALIZATION_ID_ANIMATION_JUMP_BACKWARD,
+ "Lompat Pendek ke &Depan", // LOCALIZATION_ID_ANIMATION_SHORT_JUMP_FORWARD,
+ "Lompat Pendek ke &Belakang", // LOCALIZATION_ID_ANIMATION_SHORT_JUMP_BACKWARD,
+ "Lompat Jauh ke &Depan", // LOCALIZATION_ID_ANIMATION_LONG_JUMP_FORWARD,
+ "Lompat Jauh ke &Belakang", // LOCALIZATION_ID_ANIMATION_LONG_JUMP_BACKWARD,
+ "Langkah &Frame", // LOCALIZATION_ID_ANIMATION_FRAME_STEP,
+ "Frame &Sebelumnya", // LOCALIZATION_ID_ANIMATION_PREVIOUS_FRAME,
+ "Frame Per&tama", // LOCALIZATION_ID_ANIMATION_FIRST_FRAME,
+ "Frame Ter&akhir", // LOCALIZATION_ID_ANIMATION_LAST_FRAME,
+ "&Kurangi Kecepatan", // LOCALIZATION_ID_ANIMATION_DECREASE_RATE,
+ "&Tambah Kecepatan", // LOCALIZATION_ID_ANIMATION_INCREASE_RATE,
+ "Atur &Ulang Kecepatan", // LOCALIZATION_ID_ANIMATION_RESET_RATE,
+
+ // Menu Navigasi
+ "&Navigasi", // LOCALIZATION_ID_NAVIGATE,
+ "&Selanjutnya", // LOCALIZATION_ID_NEXT,
+ "&Sebelumnya", // LOCALIZATION_ID_PREVIOUS,
+ "&Home", // LOCALIZATION_ID_HOME,
+ "&End", // LOCALIZATION_ID_END,
+ "&Urutkan", // LOCALIZATION_ID_SORT,
+ "&Nama", // LOCALIZATION_ID_SORT_NAME,
+ "&Path Lengkap", // LOCALIZATION_ID_SORT_FULL_PATH,
+ "&Ukuran", // LOCALIZATION_ID_SORT_SIZE,
+ "Tanggal &Modifikasi", // LOCALIZATION_ID_SORT_DATE_MODIFIED,
+ "Tanggal &Dibuat", // LOCALIZATION_ID_SORT_DATE_CREATED,
+ "&Menaik (Ascending)", // LOCALIZATION_ID_SORT_ASCENDING,
+ "&Menurun (Descending)", // LOCALIZATION_ID_SORT_DESCENDING,
+ "Acak", // LOCALIZATION_ID_SHUFFLE,
+ "&Lompat Ke...", // LOCALIZATION_ID_JUMP_TO,
+
+ // Menu Bantuan
+ "&Bantuan", // LOCALIZATION_ID_HELP,
+ "&Bantuan", // LOCALIZATION_ID_HELP_MENU,
+ "&Opsi Command Line", // LOCALIZATION_ID_COMMAND_LINE_OPTIONS,
+ "&Halaman Utama", // LOCALIZATION_ID_HOME_PAGE,
+ "&Donasi", // LOCALIZATION_ID_DONATE,
+ "&Tentang", // LOCALIZATION_ID_ABOUT,
+ "https://www.voidtools.com/support/voidimageviewer/", // LOCALIZATION_ID_HELP_SUPPORT_URL,
+ "https://www.voidtools.com/donate/", // LOCALIZATION_ID_HELP_DONATE_URL,
+ "https://www.voidtools.com/", // LOCALIZATION_ID_HELP_WEBSITE_URL,
+
+ // Bilah Alat (Toolbar)
+ "Gambar Sebelumnya", // LOCALIZATION_ID_TOOLBAR_PREVIOUS_IMAGE_BUTTON,
+ "Gambar Selanjutnya", // LOCALIZATION_ID_TOOLBAR_NEXT_IMAGE_BUTTON,
+ "Putar Slideshow", // LOCALIZATION_ID_TOOLBAR_PLAY_SLIDESHOW_BUTTON,
+ "Jeda Slideshow", // LOCALIZATION_ID_TOOLBAR_PAUSE_SLIDESHOW_BUTTON,
+ "Paling Pas", // LOCALIZATION_ID_TOOLBAR_BEST_FIT_BUTTON,
+ "Ukuran Asli", // LOCALIZATION_ID_TOOLBAR_ACTUAL_SIZE_BUTTON,
+
+ // Bilah Status
+ "PRAPEMUATAN", // LOCALIZATION_ID_STATUS_BAR_PRELOAD,
+ "Memuat...", // LOCALIZATION_ID_STATUS_BAR_LOADING,
+ "Berkas tidak ditemukan.", // LOCALIZATION_ID_STATUS_BAR_FILE_NOT_FOUND,
+ "Gagal memuat gambar.", // LOCALIZATION_ID_STATUS_BAR_FAILED_TO_LOAD_IMAGE,
+ "Slideshow diputar", // LOCALIZATION_ID_STATUS_BAR_SLIDESHOW_PLAYING,
+ "Pos %0.3f %0.3f, Zoom %0.3f %0.3f, Rasio Aspek %0.3f", // LOCALIZATION_ID_STATUS_BAR_POS_ZOOM_FORMAT,
+ "Kecepatan animasi %0.3f", // LOCALIZATION_ID_STATUS_BAR_ANIMATION_RATE_FORMAT,
+ "Kecepatan slideshow %d %s", // LOCALIZATION_ID_STATUS_BAR_SLIDESHOW_RATE_FORMAT,
+ "menit", // LOCALIZATION_ID_STATUS_BAR_MINUTES,
+ "detik", // LOCALIZATION_ID_STATUS_BAR_SECONDS,
+ "milidetik", // LOCALIZATION_ID_STATUS_BAR_MILLISECONDS,
+
+ // Dialog Opsi
+ "Opsi - void Image Viewer", // LOCALIZATION_ID_OPTIONS_CAPTION,
+ "Umum", // LOCALIZATION_ID_OPTIONS_GENERAL_DIALOG,
+ "Tampilan", // LOCALIZATION_ID_OPTIONS_VIEW_DIALOG,
+ "Kontrol", // LOCALIZATION_ID_OPTIONS_CONTROLS_DIALOG,
+ "Opsi zoom", // LOCALIZATION_ID_OPTIONS_ZOOM_DIALOG,
+ "OK", // LOCALIZATION_ID_OK_BUTTON,
+ "Batal", // LOCALIZATION_ID_CANCEL_BUTTON,
+ "&Simpan pengaturan di %APPDATA%\\voidImageViewer", // LOCALIZATION_ID_STORE_SETTINGS_APPDATA,
+ "Izinkan beberapa &instansi", // LOCALIZATION_ID_ALLOW_MULTIPLE_INSTANCES,
+ "Pintasan &menu Start", // LOCALIZATION_ID_STARTMENU_SHORTCUTS,
+ "Asosiasi", // LOCALIZATION_ID_ASSOCIATIONS,
+ "Pilih &Semua", // LOCALIZATION_ID_CHECK_ALL,
+ "Pilih &Tidak Ada", // LOCALIZATION_ID_CHECK_NONE,
+ "Mode blit &pengecilan:", // LOCALIZATION_ID_SHRINK_BLIT_MODE_STATIC,
+ "Mode blit &pembesaran:", // LOCALIZATION_ID_MAGNIFY_BLIT_MODE,
+ "Nearest", // LOCALIZATION_ID_BLIT_MODE_NEAREST_COMBOBOXITEM,
+ "Linear", // LOCALIZATION_ID_BLIT_MODE_LINEAR_COMBOBOXITEM,
+ "Ukuran jendela &otomatis:", // LOCALIZATION_ID_OPTIONS_VIEW_AUTO_SIZE_WINDOW_STATIC,
+ "50%", // LOCALIZATION_ID_OPTIONS_VIEW_AUTO_SIZE_WINDOW_50_PERCENT_COMBOBOXITEM,
+ "100%", // LOCALIZATION_ID_OPTIONS_VIEW_AUTO_SIZE_WINDOW_100_PERCENT_COMBOBOXITEM,
+ "200%", // LOCALIZATION_ID_OPTIONS_VIEW_AUTO_SIZE_WINDOW_200_PERCENT_COMBOBOXITEM,
+ "Pas Otomatis", // LOCALIZATION_ID_OPTIONS_VIEW_AUTO_SIZE_WINDOW_AUTO_FIT_COMBOBOXITEM,
+ "&Putar animasi setidaknya sekali dalam slideshow", // LOCALIZATION_ID_PLAY_ANIMATIONS_ONCE_STATIC,
+ "Prapemuatan gambar &selanjutnya", // LOCALIZATION_ID_PRELOAD_NEXT_IMAGE_STATIC,
+ "Simpan gambar &terakhir di cache", // LOCALIZATION_ID_CACHE_LAST_IMAGE_STATIC,
+ "Warna latar &jendela:", // LOCALIZATION_ID_WINDOWED_BACKGROUND_COLOR_STATIC,
+ "Warna latar &layar penuh:", // LOCALIZATION_ID_FULLSCREEN_BACKGROUND_COLOR_STATIC,
+ "Atur Ulang Ukuran && Posisi Jendela", // LOCALIZATION_ID_OPTIONS_VIEW_RESET_WINDOW_BUTTON,
+ "Aksi klik &kiri:", // LOCALIZATION_ID_LEFT_CLICK_ACTION_STATIC,
+ "Aksi klik &kanan:", // LOCALIZATION_ID_RIGHT_CLICK_ACTION_STATIC,
+ "Aksi roda &mouse:", // LOCALIZATION_ID_MOUSE_WHEEL_ACTION_STATIC,
+ "&Perintah:", // LOCALIZATION_ID_COMMANDS_STATIC,
+ "Pengaturan untuk perintah terpilih", // LOCALIZATION_ID_SETTINGS_FOR_SELECTED_COMMAND,
+ "&Tambah...", // LOCALIZATION_ID_ADD_KEY_BUTTON,
+ "&Ubah...", // LOCALIZATION_ID_EDIT_KEY_BUTTON,
+ "&Hapus", // LOCALIZATION_ID_REMOVE_KEY_BUTTON,
+ "Tambah Pintasan Keyboard", // LOCALIZATION_ID_ADD_KEYBOARD_SHORTCUT_CAPTION,
+ "Ubah Pintasan Keyboard", // LOCALIZATION_ID_EDIT_KEYBOARD_SHORTCUT_CAPTION,
+ "&Tombol pintasan:", // LOCALIZATION_ID_SHORTCUT_KEY,
+ "Tombol pintasan sedang digunakan oleh:", // LOCALIZATION_ID_SHORTCUT_KEY_CURRENTLY_USED_BY,
+ "&Hapus", // LOCALIZATION_ID_REMOVE,
+ "Atur Kecepatan Kustom", // LOCALIZATION_ID_SET_CUSTOM_RATE_CAPTION,
+ "Kecepatan &kustom:", // LOCALIZATION_ID_CUSTOM_RATE_STATIC,
+ "menit", // LOCALIZATION_ID_CUSTOM_RATE_MINUTES,
+ "detik", // LOCALIZATION_ID_CUSTOM_RATE_SECONDS,
+ "milidetik", // LOCALIZATION_ID_CUSTOM_RATE_MILLISECONDS,
+ "Tentang void Image Viewer", // LOCALIZATION_ID_ABOUT_CAPTION,
+ "Ubah Nama", // LOCALIZATION_ID_RENAME_CAPTION,
+ "Lompat Ke", // LOCALIZATION_ID_JUMP_TO_TITLE,
+ "Pencarian Everything", // LOCALIZATION_ID_SEARCH_EVERYTHING,
+ "Hak Cipta \xC2\xA9 %d voidtools", // LOCALIZATION_ID_ABOUT_COPYRIGHT_FORMAT,
+ "support@voidtools.com", // LOCALIZATION_ID_ABOUT_EMAIL,
+ "www.voidtools.com", // LOCALIZATION_ID_ABOUT_WEBSITE,
+ "Buka Gambar", // LOCALIZATION_ID_OPEN_IMAGE_CAPTION,
+ "Semua Berkas Gambar", // LOCALIZATION_ID_OPEN_ALL_IMAGE_FILES,
+ "Semua Berkas", // LOCALIZATION_ID_OPEN_ALL_FILES,
+ "Gulir", // LOCALIZATION_ID_OPTIONS_ACTION_SCROLL_COMBOBOXITEM,
+ "Putar/Jeda Slideshow", // LOCALIZATION_ID_OPTIONS_ACTION_PLAY_PAUSE_SLIDESHOW_COMBOBOXITEM,
+ "Putar/Jeda Animasi", // LOCALIZATION_ID_OPTIONS_ACTION_PLAY_PAUSE_ANIMATION_COMBOBOXITEM,
+ "Zoom Masuk", // LOCALIZATION_ID_OPTIONS_ACTION_ZOOM_IN_COMBOBOXITEM,
+ "Gambar Selanjutnya", // LOCALIZATION_ID_OPTIONS_ACTION_NEXT_IMAGE_COMBOBOXITEM,
+ "Gulir 1:1", // LOCALIZATION_ID_OPTIONS_ACTION_ONE_TO_ONE_SCROLL_COMBOBOXITEM,
+ "Gulir/Pindah Jendela", // LOCALIZATION_ID_OPTIONS_ACTION_SCROLL_MOVE_WINDOW_COMBOBOXITEM,
+ "Menu Konteks", // LOCALIZATION_ID_OPTIONS_ACTION_CONTEXT_MENU_COMBOBOXITEM,
+ "Zoom Keluar", // LOCALIZATION_ID_OPTIONS_ACTION_ZOOM_OUT_COMBOBOXITEM,
+ "Gambar Sebelumnya", // LOCALIZATION_ID_OPTIONS_ACTION_PREVIOUS_IMAGE_COMBOBOXITEM,
+ "Zoom", // LOCALIZATION_ID_OPTIONS_ACTION_ZOOM_COMBOBOXITEM,
+ "Selanjutnya/Sebelumnya", // LOCALIZATION_ID_OPTIONS_ACTION_NEXT_PREV_COMBOBOXITEM,
+ "Sebelumnya/Selanjutnya", // LOCALIZATION_ID_OPTIONS_ACTION_PREV_NEXT_COMBOBOXITEM,
+ "Format bilah &judul:", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_STATIC,
+ "Path Lengkap", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_FULL_PATH_COMBOBOXITEM,
+ "Hanya Nama Berkas", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_FILENAME_ONLY_COMBOBOXITEM,
+ "Tidak Ada", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_NONE_COMBOBOXITEM,
+ "Langkah &zoom:", // LOCALIZATION_ID_OPTIONS_ZOOM_STEP_STATIC,
+ "(standar: 10 %)", // LOCALIZATION_ID_OPTIONS_ZOOM_STEP_DEFAULT_STATIC,
+ "Metode kalkulasi zoom:", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_METHOD_STATIC,
+ "Langkah &relatif", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_RELATIVE_RADIO,
+ "Langkah &absolut", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_ABSOLUTE_RADIO,
+ "Gunakan tabel &tetap: (khusus ahli: maks. 50 nilai terurut dari 3 ke 4000)", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_FIXED_TABLE_RADIO,
+ "Muat tabel &standar", // LOCALIZATION_ID_OPTIONS_ZOOM_LOAD_DEFAULT_TABLE_BUTTON,
+ "Everything tidak tersedia", // LOCALIZATION_ID_EVERYTHING_NOT_AVAILABLE_MESSAGE,
+ "Tambah Pencarian Everything", // LOCALIZATION_ID_EVERYTHING_ADD_EVERYTHING_SEARCH_CAPTION,
+ "Muat Pencarian Everything", // LOCALIZATION_ID_EVERYTHING_LOAD_EVERYTHING_SEARCH_CAPTION,
+ "Acak", // LOCALIZATION_ID_RANDOMIZE,
+ "Salin Ke", // LOCALIZATION_ID_COPY_TO_CAPTION,
+ "Pindah Ke", // LOCALIZATION_ID_MOVE_TO_CAPTION,
+
+ // Deskripsi Asosiasi
+ "Gambar Bitmap",
+ "Gambar GIF Animasi",
+ "Berkas Ikon",
+ "Gambar JPEG",
+ "Gambar JPEG",
+ "Gambar PNG",
+ "Gambar TIFF",
+ "Gambar TIFF",
+ "Gambar WebP",
+};
diff --git a/src/localization_zh_cn.h b/src/localization_zh_cn.h
index 3d13569..a4a4606 100644
--- a/src/localization_zh_cn.h
+++ b/src/localization_zh_cn.h
@@ -26,6 +26,8 @@ static const utf8_t *_localization_string_array_zh_cn[LOCALIZATION_ID_COUNT] =
{
// Language
"ç®€ä½“ä¸æ–‡", // LOCALIZATION_ID_LANGUAGE
+ "è¯è¨€(&L):", // LOCALIZATION_ID_LANGUAGE_STATIC
+ "系统默认", // LOCALIZATION_ID_LANGUAGE_AUTO
// Application name
"void Image Viewer", // LOCALIZATION_ID_APP_NAME
@@ -211,6 +213,7 @@ static const utf8_t *_localization_string_array_zh_cn[LOCALIZATION_ID_COUNT] =
"常规", // LOCALIZATION_ID_OPTIONS_GENERAL_DIALOG,
"视图", // LOCALIZATION_ID_OPTIONS_VIEW_DIALOG,
"控件", // LOCALIZATION_ID_OPTIONS_CONTROLS_DIALOG,
+ "缩放选项", // LOCALIZATION_ID_OPTIONS_ZOOM_DIALOG,
"确定", // LOCALIZATION_ID_OK_BUTTON,
"å–æ¶ˆ", // LOCALIZATION_ID_CANCEL_BUTTON,
"在 %APPDATA%\\voidImageViewer ä¸å˜å‚¨è®¾ç½®(&S)", // LOCALIZATION_ID_STORE_SETTINGS_APPDATA,
@@ -233,6 +236,7 @@ static const utf8_t *_localization_string_array_zh_cn[LOCALIZATION_ID_COUNT] =
"ç¼“å˜æœ€åŽä¸€å¼ 图åƒ(&L)", // LOCALIZATION_ID_CACHE_LAST_IMAGE_STATIC,
"窗å£èƒŒæ™¯é¢œè‰²(&W):", // LOCALIZATION_ID_WINDOWED_BACKGROUND_COLOR_STATIC,
"å…¨å±èƒŒæ™¯é¢œè‰²(&F):", // LOCALIZATION_ID_FULLSCREEN_BACKGROUND_COLOR_STATIC,
+ "é‡ç½®çª—å£å¤§å°å’Œä½ç½®", // LOCALIZATION_ID_OPTIONS_VIEW_RESET_WINDOW_BUTTON,
"左键æ“作(&L):", // LOCALIZATION_ID_LEFT_CLICK_ACTION_STATIC,
"å³é”®æ“作(&R):", // LOCALIZATION_ID_RIGHT_CLICK_ACTION_STATIC,
"é¼ æ ‡æ»šè½®æ“作(&M):", // LOCALIZATION_ID_MOUSE_WHEEL_ACTION_STATIC,
@@ -278,6 +282,13 @@ static const utf8_t *_localization_string_array_zh_cn[LOCALIZATION_ID_COUNT] =
"完整路径", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_FULL_PATH_COMBOBOXITEM,
"仅文件å", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_FILENAME_ONLY_COMBOBOXITEM,
"æ— ", // LOCALIZATION_ID_OPTIONS_TITLE_BAR_FORMAT_NONE_COMBOBOXITEM,
+ "缩放æ¥é•¿(&S):", // LOCALIZATION_ID_OPTIONS_ZOOM_STEP_STATIC,
+ "(默认: 10 %)", // LOCALIZATION_ID_OPTIONS_ZOOM_STEP_DEFAULT_STATIC,
+ "缩放计算方å¼:", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_METHOD_STATIC,
+ "相对æ¥é•¿(&R)", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_RELATIVE_RADIO,
+ "ç»å¯¹æ¥é•¿(&A)", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_ABSOLUTE_RADIO,
+ "使用固定表(&F): (专家级: 3 到 4000 之间的最多 50 个有åºå€¼)", // LOCALIZATION_ID_OPTIONS_ZOOM_CALC_FIXED_TABLE_RADIO,
+ "åŠ è½½é»˜è®¤è¡¨(&L)", // LOCALIZATION_ID_OPTIONS_ZOOM_LOAD_DEFAULT_TABLE_BUTTON,
"Everything ä¸å¯ç”¨", // LOCALIZATION_ID_EVERYTHING_NOT_AVAILABLE_MESSAGE,
"æ·»åŠ Everything æœç´¢", // LOCALIZATION_ID_EVERYTHING_ADD_EVERYTHING_SEARCH_CAPTION,
"åŠ è½½ Everything æœç´¢", // LOCALIZATION_ID_EVERYTHING_LOAD_EVERYTHING_SEARCH_CAPTION,
diff --git a/src/version.h b/src/version.h
index ea4550e..a0fb2e6 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,6 +1,6 @@
#define VERSION_YEAR 2026
#define VERSION_MAJOR 1
-#define VERSION_MINOR 0
+#define VERSION_MINOR 1
#define VERSION_REVISION 0
-#define VERSION_BUILD 15
+#define VERSION_BUILD 0
#define VERSION_TYPE ""
diff --git a/src/viv.c b/src/viv.c
index deff452..7422955 100644
--- a/src/viv.c
+++ b/src/viv.c
@@ -257,7 +257,7 @@
#define _VIV_ASSOCIATION_TIFF 0x00000080
#define _VIV_ASSOCIATION_WEBP 0x00000100
-#define _VIV_ZOOM_MAX 16
+#define _VIV_ZOOM_MAX 64
#define BCM_SETSHIELD 0x0000160C
@@ -444,7 +444,7 @@ typedef struct _viv_webp_s
typedef struct _viv_name_mapping_s
{
UINT count;
- SHNAMEMAPPING *mappings;
+ SHNAMEMAPPING mappings[1];
}_viv_name_mapping_t;
static void _viv_update_title(void);
@@ -496,6 +496,9 @@ static INT_PTR CALLBACK _viv_options_proc(HWND hwndDlg,UINT uMsg,WPARAM wParam,L
static INT_PTR CALLBACK _viv_options_general_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
static INT_PTR CALLBACK _viv_options_view_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
static INT_PTR CALLBACK _viv_options_controls_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+static INT_PTR CALLBACK _viv_options_zoom_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+static double _viv_calculate_next_zoom(double current_percent,int zoom_in);
+static int _viv_parse_fixed_table(const wchar_t *table_str,double *values,int max_values);
static void _viv_install_association_by_extension(const char *association,const char *description,const char *icon_location);
static void _viv_uninstall_association_by_extension(const char *association);
static int _viv_is_association(const char *association);
@@ -608,6 +611,7 @@ static int _viv_compare_id(const WIN32_FIND_DATA *a,const WIN32_FIND_DATA *b);
static int _viv_fd_compare_name(const WIN32_FIND_DATA *a,const WIN32_FIND_DATA *b);
static int _viv_fd_compare_path_and_name(const WIN32_FIND_DATA *a,const WIN32_FIND_DATA *b);
static void _viv_update_1to1_scroll(int x,int y);
+static HBITMAP _viv_create_bitmap(HDC hdc, int width, int height);
static HBITMAP _viv_orientate_hbitmap(HBITMAP hbitmap,int counterclockwise);
static void _viv_send_random_everything_search(void);
static void _viv_do_mousewheel_action(int action,int delta,int x,int y);
@@ -674,6 +678,10 @@ static BYTE _viv_animation_play = 1; // play or pause animations
static BYTE _viv_1to1 = 0; // temporarily show the image with 100% scaling
static BYTE _viv_have_old_zoom = 0; // restore this zoom level after leaving 1:1 mode.
static int _viv_old_zoom_pos = 0; // restore this zoom level after leaving 1:1 mode.
+static BYTE _viv_is_custom_zoom = 0; // custom zoom level active
+static double _viv_custom_zoom_percent = 100.0; // custom zoom in percent
+static BYTE _viv_old_is_custom_zoom = 0;
+static double _viv_old_custom_zoom_percent = 100.0;
WIN32_FIND_DATA *_viv_current_fd = 0; // the current image find data including the full path and filename.
WIN32_FIND_DATA *_viv_preload_fd = 0;
static int _viv_view_x = 0; // the current image offset in pixels
@@ -681,8 +689,6 @@ static int _viv_view_y = 0; // the current image offset in pixels
static double _viv_view_ix = 0.0; // the current image offset in percent, used when resizing the window
static double _viv_view_iy = 0.0; // the current image offset in percent, used when resizing the window
static int _viv_zoom_pos = 0; // the current zoom level
-//static float _viv_zoom_presets[_VIV_ZOOM_MAX] = {0.004815f,0.019215f,0.043060f,0.076120f,0.118079f,0.168530f,0.226989f,0.292893f,0.365607f,0.444430f,0.528603f,0.617316f,0.709715f,0.804909f,0.901983f,1.000000f}; // (1 - cos(((float)(x+1) * 1.570796f) / _VIV_ZOOM_MAX)) // this is missing cos((1 * 1.570796f) / _VIV_ZOOM_MAX), which is too small
-static float _viv_zoom_presets[_VIV_ZOOM_MAX] = {0.0000,0.0100,0.0225,0.0379,0.0569,0.0806,0.1098,0.1461,0.1909,0.2465,0.3154,0.4007,0.5063,0.6372,0.7993,1.0000}; // 0.01 - 0.2 curve
static ULONG_PTR os_GdiplusToken; // gdiplus handle
static int _viv_image_wide = 0; // current image width
@@ -733,12 +739,12 @@ static volatile int _viv_load_image_terminate = 0;
static _viv_reply_t *_viv_reply_start = 0;
static _viv_reply_t *_viv_reply_last = 0;
static wchar_t *_viv_status_temp_text = 0;
-static localization_id_t _viv_options_page_localization_id_array[] = {LOCALIZATION_ID_OPTIONS_GENERAL_DIALOG,LOCALIZATION_ID_OPTIONS_VIEW_DIALOG,LOCALIZATION_ID_OPTIONS_CONTROLS_DIALOG};
-static int _viv_options_tab_ids[] = {IDC_TAB1,IDC_TAB2,IDC_TAB3};
-static int _viv_options_dialog_ids[] = {IDD_GENERAL,IDD_VIEW,IDD_CONTROLS};
+static localization_id_t _viv_options_page_localization_id_array[] = {LOCALIZATION_ID_OPTIONS_GENERAL_DIALOG,LOCALIZATION_ID_OPTIONS_VIEW_DIALOG,LOCALIZATION_ID_OPTIONS_CONTROLS_DIALOG,LOCALIZATION_ID_OPTIONS_ZOOM_DIALOG};
+static int _viv_options_tab_ids[] = {IDC_TAB1,IDC_TAB2,IDC_TAB3,IDC_TAB4};
+static int _viv_options_dialog_ids[] = {IDD_GENERAL,IDD_VIEW,IDD_CONTROLS,IDD_ZOOM};
#define _VIV_OPTIONS_PAGE_COUNT (sizeof(_viv_options_dialog_ids) / sizeof(int))
-static int _viv_options_page_ids[] = {VIV_ID_OPTIONS_GENERAL,VIV_ID_OPTIONS_VIEW,VIV_ID_OPTIONS_CONTROLS};
-static DLGPROC _viv_options_page_procs[] = {_viv_options_general_proc,_viv_options_view_proc,_viv_options_controls_proc};
+static int _viv_options_page_ids[] = {VIV_ID_OPTIONS_GENERAL,VIV_ID_OPTIONS_VIEW,VIV_ID_OPTIONS_CONTROLS,VIV_ID_OPTIONS_ZOOM};
+static DLGPROC _viv_options_page_procs[] = {_viv_options_general_proc,_viv_options_view_proc,_viv_options_controls_proc,_viv_options_zoom_proc};
static HFONT _viv_about_hfont = 0;
static wchar_t *_viv_last_open_file = 0;
static wchar_t *_viv_last_open_folder = 0;
@@ -988,9 +994,7 @@ _viv_default_key_t _viv_default_keys[] =
{VIV_ID_EDIT_COPY,CONFIG_KEYFLAG_CTRL | 'C'},
{VIV_ID_EDIT_COPY_FILENAME,CONFIG_KEYFLAG_CTRL | CONFIG_KEYFLAG_SHIFT | 'C'},
{VIV_ID_EDIT_PASTE,CONFIG_KEYFLAG_CTRL | 'V'},
- {VIV_ID_VIEW_PRESET_1,'1'},
- {VIV_ID_VIEW_PRESET_2,'2'},
- {VIV_ID_VIEW_PRESET_3,'3'},
+
{VIV_ID_VIEW_1TO1,CONFIG_KEYFLAG_CTRL | CONFIG_KEYFLAG_ALT | '0'},
{VIV_ID_VIEW_FULLSCREEN,CONFIG_KEYFLAG_ALT | VK_RETURN},
{VIV_ID_VIEW_SLIDESHOW,VK_F11},
@@ -1280,12 +1284,16 @@ static void _viv_clear(void)
_viv_frame_count = 0;
_viv_frame_loaded_count = 0;
_viv_zoom_pos = 0;
+ _viv_is_custom_zoom = 0;
+ _viv_custom_zoom_percent = 100.0;
_viv_view_x = 0;
_viv_view_y = 0;
_viv_view_ix = 0.0;
_viv_view_iy = 0.0;
_viv_1to1 = 0;
_viv_have_old_zoom = 0;
+ _viv_old_is_custom_zoom = 0;
+ _viv_old_custom_zoom_percent = 100.0;
_viv_image_wide = 0;
_viv_image_high = 0;
_viv_animation_play = 1;
@@ -1675,9 +1683,12 @@ static void _viv_command_with_is_key_repeat(int command_id,int is_key_repeat)
case VIV_ID_VIEW_ZOOM_RESET:
_viv_1to1 = 0;
+ _viv_is_custom_zoom = 0;
+ _viv_custom_zoom_percent = 100.0;
_viv_zoom_pos = 0;
_viv_view_set(_viv_view_x,_viv_view_y,1);
InvalidateRect(_viv_hwnd,0,FALSE);
+ _viv_toolbar_update_buttons();
break;
case VIV_ID_HELP_HELP:
@@ -5260,6 +5271,7 @@ static int _viv_init(int nCmdShow)
// load settings
config_load_settings();
+ localization_init();
// config_maximized will be overwritten when we show are normal window
// so save it now and apply it later.
@@ -6881,6 +6893,19 @@ static void _viv_get_render_size(int *prw,int *prh)
return;
}
+ if (_viv_is_custom_zoom)
+ {
+ rw = (int)((double)_viv_image_wide * _viv_custom_zoom_percent / 100.0 + 0.5);
+ rh = (int)((double)_viv_image_high * _viv_custom_zoom_percent / 100.0 + 0.5);
+ if (rw <= 0) rw = 1;
+ if (rh <= 0) rh = 1;
+
+ *prw = rw;
+ *prh = rh;
+
+ return;
+ }
+
if (_viv_is_fullscreen)
{
fill_window = config_fullscreen_fill_window;
@@ -6975,23 +7000,11 @@ static void _viv_get_render_size(int *prw,int *prh)
if (config_keep_aspect_ratio)
{
- if (rw > _viv_image_wide)
- {
- max_zoom_wide = rw * 16;
- }
- else
- {
- max_zoom_wide = _viv_image_wide * 16;
- }
+ max_zoom_wide = rw * 16;
+ if (max_zoom_wide < _viv_image_wide * 16) max_zoom_wide = _viv_image_wide * 16;
- if (rh > _viv_image_high)
- {
- max_zoom_high = rh * 16;
- }
- else
- {
- max_zoom_high = _viv_image_high * 16;
- }
+ max_zoom_high = rh * 16;
+ if (max_zoom_high < _viv_image_high * 16) max_zoom_high = _viv_image_high * 16;
}
else
{
@@ -7011,8 +7024,9 @@ static void _viv_get_render_size(int *prw,int *prh)
*/
if (_viv_zoom_pos)
{
- rw = rw + (int)((max_zoom_wide - rw) * _viv_zoom_presets[_viv_zoom_pos]);
- rh = rh + (int)((max_zoom_high - rh) * _viv_zoom_presets[_viv_zoom_pos]);
+ double zoom_factor = pow((double)max_zoom_wide / (double)rw, (double)_viv_zoom_pos / (double)(_VIV_ZOOM_MAX - 1));
+ rw = (int)((double)rw * zoom_factor);
+ rh = (int)((double)rh * zoom_factor);
}
*prw = rw;
@@ -7212,7 +7226,7 @@ static void _viv_delete(int permanently)
fo.hwnd = _viv_hwnd;
fo.wFunc = FO_DELETE;
fo.pFrom = filename_list;
- fo.fFlags = permanently ? 0 : FOF_ALLOWUNDO;
+ fo.fFlags = permanently ? FOF_WANTNUKEWARNING : FOF_ALLOWUNDO;
if (SHFileOperation(&fo) == 0)
{
@@ -7295,8 +7309,8 @@ static INT_PTR CALLBACK _viv_rename_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM
fo.pTo = new_filename_list;
fo.fFlags = FOF_ALLOWUNDO | FOF_WANTMAPPINGHANDLE;
- // returns ERROR_CANCELLED if user cancelled.
- if (SHFileOperation(&fo) == 0)
+ int sh_ret = SHFileOperation(&fo);
+ if (sh_ret == 0)
{
if (fo.fAnyOperationsAborted)
{
@@ -7316,7 +7330,7 @@ static INT_PTR CALLBACK _viv_rename_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM
mappings = (_viv_name_mapping_t *)fo.hNameMappings;
- if (mappings->count == 1)
+ if (mappings->count >= 1)
{
// use the resolved name incase there was a rename collision.
file_op_new_name = mappings->mappings[0].pszNewPath;
@@ -7340,6 +7354,11 @@ static INT_PTR CALLBACK _viv_rename_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM
SHFreeNameMappings(fo.hNameMappings);
}
}
+ else
+ {
+ // returned non-zero (user cancelled or clicked No)
+ dont_end_dialog = 1;
+ }
}
if (!dont_end_dialog)
@@ -7505,7 +7524,7 @@ static void _viv_set_clipboard_image(void)
{
HBITMAP mem1_hbitmap;
- mem1_hbitmap = CreateCompatibleBitmap(screen_hdc,_viv_image_wide,_viv_image_high);
+ mem1_hbitmap = _viv_create_bitmap(screen_hdc,_viv_image_wide,_viv_image_high);
if (mem1_hbitmap)
{
HGDIOBJ last_mem1_hbitmap;
@@ -7936,8 +7955,26 @@ static INT_PTR CALLBACK _viv_options_general_proc(HWND hwnd,UINT msg,WPARAM wPar
case WM_INITDIALOG:
{
int exti;
-
os_SetDlgItemText_localization_id(hwnd,IDC_APPDATA,LOCALIZATION_ID_STORE_SETTINGS_APPDATA);
+ os_SetDlgItemText_localization_id(hwnd,IDC_LANGUAGE_STATIC,LOCALIZATION_ID_LANGUAGE_STATIC);
+
+ {
+ HWND hLanguage = GetDlgItem(hwnd,IDC_LANGUAGE_COMBOBOX);
+ int index;
+
+ index = os_ComboBox_AddString_localization_id(hwnd,IDC_LANGUAGE_COMBOBOX,LOCALIZATION_ID_LANGUAGE_AUTO);
+ ComboBox_SetItemData(hLanguage,index,255);
+ if (config_language == 255) ComboBox_SetCurSel(hLanguage,index);
+
+ for(int i=0;i= L'0') && (*p <= L'9')) || (*p == L'.'))
+ {
+ double val = 0.0;
+ double frac = 0.0;
+ double div = 10.0;
+
+ while ((*p >= L'0') && (*p <= L'9'))
+ {
+ val = (val * 10.0) + (*p - L'0');
+ p++;
+ }
+ if (*p == L'.')
+ {
+ p++;
+ while ((*p >= L'0') && (*p <= L'9'))
+ {
+ frac += (*p - L'0') / div;
+ div *= 10.0;
+ p++;
+ }
+ }
+ val += frac;
+ if (val > 0.0)
+ {
+ values[count++] = val;
+ }
+ }
+ else
+ {
+ p++;
+ }
+ }
+
+ {
+ int i, j;
+ for (i = 0; i < count - 1; i++)
+ {
+ for (j = i + 1; j < count; j++)
+ {
+ if (values[j] < values[i])
+ {
+ double tmp = values[i];
+ values[i] = values[j];
+ values[j] = tmp;
+ }
+ }
+ }
+ }
+
+ return count;
+}
+
+static double _viv_calculate_next_zoom(double current_percent,int zoom_in)
+{
+ double new_percent = current_percent;
+ int step = config_zoom_step > 0 ? config_zoom_step : CONFIG_ZOOM_DEFAULT_STEP;
+
+ if (config_zoom_calc_method == CONFIG_ZOOM_CALC_RELATIVE)
+ {
+ if (zoom_in)
+ {
+ new_percent = current_percent * (1.0 + ((double)step / 100.0));
+ }
+ else
+ {
+ new_percent = current_percent / (1.0 + ((double)step / 100.0));
+ }
+ }
+ else if (config_zoom_calc_method == CONFIG_ZOOM_CALC_ABSOLUTE)
+ {
+ if (zoom_in)
+ {
+ new_percent = current_percent + (double)step;
+ }
+ else
+ {
+ new_percent = current_percent - (double)step;
+ }
+ }
+ else if (config_zoom_calc_method == CONFIG_ZOOM_CALC_FIXED_TABLE)
+ {
+ double table_values[64];
+ int table_count = _viv_parse_fixed_table(config_zoom_fixed_table, table_values, 64);
+ if (table_count <= 0)
+ {
+ table_count = _viv_parse_fixed_table(CONFIG_ZOOM_DEFAULT_FIXED_TABLE, table_values, 64);
+ }
+
+ if (table_count > 0)
+ {
+ int i;
+ if (zoom_in)
+ {
+ new_percent = table_values[table_count - 1];
+ for (i = 0; i < table_count; i++)
+ {
+ if (table_values[i] > current_percent + 0.001)
+ {
+ new_percent = table_values[i];
+ break;
+ }
+ }
+ }
+ else
+ {
+ new_percent = table_values[0];
+ for (i = table_count - 1; i >= 0; i--)
+ {
+ if (table_values[i] < current_percent - 0.001)
+ {
+ new_percent = table_values[i];
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (new_percent < 0.1) new_percent = 0.1;
+ if (new_percent > 10000.0) new_percent = 10000.0;
+
+ return new_percent;
+}
+
+static INT_PTR CALLBACK _viv_options_zoom_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ wchar_t wbuf[STRING_SIZE];
+
+ os_SetDlgItemText_localization_id(hwnd,IDC_ZOOM_STEP_STATIC,LOCALIZATION_ID_OPTIONS_ZOOM_STEP_STATIC);
+ os_SetDlgItemText_localization_id(hwnd,IDC_ZOOM_STEP_DEFAULT_STATIC,LOCALIZATION_ID_OPTIONS_ZOOM_STEP_DEFAULT_STATIC);
+ os_SetDlgItemText_localization_id(hwnd,IDC_ZOOM_CALC_METHOD_STATIC,LOCALIZATION_ID_OPTIONS_ZOOM_CALC_METHOD_STATIC);
+ os_SetDlgItemText_localization_id(hwnd,IDC_ZOOM_CALC_RELATIVE_RADIO,LOCALIZATION_ID_OPTIONS_ZOOM_CALC_RELATIVE_RADIO);
+ os_SetDlgItemText_localization_id(hwnd,IDC_ZOOM_CALC_ABSOLUTE_RADIO,LOCALIZATION_ID_OPTIONS_ZOOM_CALC_ABSOLUTE_RADIO);
+ os_SetDlgItemText_localization_id(hwnd,IDC_ZOOM_CALC_FIXED_TABLE_RADIO,LOCALIZATION_ID_OPTIONS_ZOOM_CALC_FIXED_TABLE_RADIO);
+ os_SetDlgItemText_localization_id(hwnd,IDC_ZOOM_LOAD_DEFAULT_TABLE_BUTTON,LOCALIZATION_ID_OPTIONS_ZOOM_LOAD_DEFAULT_TABLE_BUTTON);
+
+ string_format_number(wbuf,config_zoom_step);
+ SetDlgItemText(hwnd,IDC_ZOOM_STEP_EDIT,wbuf);
+
+ if (config_zoom_calc_method == CONFIG_ZOOM_CALC_RELATIVE)
+ {
+ CheckRadioButton(hwnd,IDC_ZOOM_CALC_RELATIVE_RADIO,IDC_ZOOM_CALC_FIXED_TABLE_RADIO,IDC_ZOOM_CALC_RELATIVE_RADIO);
+ }
+ else if (config_zoom_calc_method == CONFIG_ZOOM_CALC_ABSOLUTE)
+ {
+ CheckRadioButton(hwnd,IDC_ZOOM_CALC_RELATIVE_RADIO,IDC_ZOOM_CALC_FIXED_TABLE_RADIO,IDC_ZOOM_CALC_ABSOLUTE_RADIO);
+ }
+ else
+ {
+ CheckRadioButton(hwnd,IDC_ZOOM_CALC_RELATIVE_RADIO,IDC_ZOOM_CALC_FIXED_TABLE_RADIO,IDC_ZOOM_CALC_FIXED_TABLE_RADIO);
+ }
+
+ SetDlgItemText(hwnd,IDC_ZOOM_FIXED_TABLE_EDIT,config_zoom_fixed_table);
+
+ return FALSE;
+ }
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDC_ZOOM_LOAD_DEFAULT_TABLE_BUTTON:
+ SetDlgItemText(hwnd,IDC_ZOOM_FIXED_TABLE_EDIT,CONFIG_ZOOM_DEFAULT_FIXED_TABLE);
+ break;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
static void _viv_options_treeview_changed(HWND hwnd)
{
TV_ITEM tvi;
@@ -8649,6 +8912,17 @@ static INT_PTR CALLBACK _viv_options_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARA
general_page = GetDlgItem(hwnd,VIV_ID_OPTIONS_GENERAL);
view_page = GetDlgItem(hwnd,VIV_ID_OPTIONS_VIEW);
controls_page = GetDlgItem(hwnd,VIV_ID_OPTIONS_CONTROLS);
+
+ {
+ BYTE new_language = (BYTE)ComboBox_GetItemData(GetDlgItem(general_page,IDC_LANGUAGE_COMBOBOX),ComboBox_GetCurSel(GetDlgItem(general_page,IDC_LANGUAGE_COMBOBOX)));
+ if (new_language != config_language)
+ {
+ config_language = new_language;
+ localization_init();
+ // Note: full UI refresh might be needed for dynamic change, but for now we just save it.
+ }
+ }
+
config_multiple_instances = 0;
if (IsDlgButtonChecked(general_page,IDC_APPDATA) == BST_CHECKED)
@@ -8774,6 +9048,38 @@ static INT_PTR CALLBACK _viv_options_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARA
config_loop_animations_once = IsDlgButtonChecked(view_page,IDC_LOOP_ANIMATIONS_ONCE_STATIC) == BST_CHECKED ? 1 : 0;
config_preload_next = IsDlgButtonChecked(view_page,IDC_PRELOAD_NEXT_IMAGE_STATIC) == BST_CHECKED ? 1 : 0;
config_cache_last = IsDlgButtonChecked(view_page,IDC_CACHE_LAST_IMAGE_STATIC) == BST_CHECKED ? 1 : 0;
+
+ {
+ HWND zoom_page;
+ zoom_page = GetDlgItem(hwnd,VIV_ID_OPTIONS_ZOOM);
+ if (zoom_page)
+ {
+ wchar_t wbuf[STRING_SIZE];
+ int step;
+
+ GetDlgItemText(zoom_page,IDC_ZOOM_STEP_EDIT,wbuf,STRING_SIZE);
+ step = string_to_int(wbuf);
+ if (step > 0)
+ {
+ config_zoom_step = step;
+ }
+
+ if (IsDlgButtonChecked(zoom_page,IDC_ZOOM_CALC_RELATIVE_RADIO) == BST_CHECKED)
+ {
+ config_zoom_calc_method = CONFIG_ZOOM_CALC_RELATIVE;
+ }
+ else if (IsDlgButtonChecked(zoom_page,IDC_ZOOM_CALC_ABSOLUTE_RADIO) == BST_CHECKED)
+ {
+ config_zoom_calc_method = CONFIG_ZOOM_CALC_ABSOLUTE;
+ }
+ else if (IsDlgButtonChecked(zoom_page,IDC_ZOOM_CALC_FIXED_TABLE_RADIO) == BST_CHECKED)
+ {
+ config_zoom_calc_method = CONFIG_ZOOM_CALC_FIXED_TABLE;
+ }
+
+ GetDlgItemText(zoom_page,IDC_ZOOM_FIXED_TABLE_EDIT,config_zoom_fixed_table,STRING_SIZE);
+ }
+ }
// copy keys.
_viv_key_list_copy(_viv_key_list,(_viv_key_list_t *)GetWindowLongPtr(GetDlgItem(controls_page,IDC_COMMANDS_LIST),GWLP_USERDATA));
@@ -9321,9 +9627,12 @@ static void _viv_view_1to1(void)
if (_viv_have_old_zoom)
{
_viv_1to1 = 0;
+ _viv_is_custom_zoom = _viv_old_is_custom_zoom;
+ _viv_custom_zoom_percent = _viv_old_custom_zoom_percent;
_viv_zoom_pos = _viv_old_zoom_pos;
_viv_view_set(_viv_view_x,_viv_view_y,1);
InvalidateRect(_viv_hwnd,0,FALSE);
+ _viv_toolbar_update_buttons();
return;
}
@@ -9331,11 +9640,15 @@ static void _viv_view_1to1(void)
_viv_have_old_zoom = 1;
_viv_old_zoom_pos = _viv_zoom_pos;
+ _viv_old_is_custom_zoom = _viv_is_custom_zoom;
+ _viv_old_custom_zoom_percent = _viv_custom_zoom_percent;
_viv_1to1 = 1;
+ _viv_is_custom_zoom = 0;
_viv_zoom_pos = 0;
_viv_view_set(_viv_view_x,_viv_view_y,1);
InvalidateRect(_viv_hwnd,0,FALSE);
+ _viv_toolbar_update_buttons();
}
static void _viv_playlist_add_current_if_empty(void)
@@ -10260,7 +10573,7 @@ static int _viv_webp_frame_proc(_viv_webp_t *viv_webp,BYTE *pixels,int delay)
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
- hbitmap = CreateCompatibleBitmap(viv_webp->screen_hdc,viv_webp->wide,viv_webp->high);
+ hbitmap = _viv_create_bitmap(viv_webp->screen_hdc,viv_webp->wide,viv_webp->high);
// Set RGB data to the bitmap
if (hbitmap)
@@ -10612,7 +10925,7 @@ static DWORD WINAPI _viv_load_image_thread_proc(void *param)
break;
}
- hbitmap = CreateCompatibleBitmap(screen_hdc,load_wide,load_high);
+ hbitmap = _viv_create_bitmap(screen_hdc,load_wide,load_high);
if (hbitmap)
{
UINT image_flags;
@@ -11692,7 +12005,7 @@ static void _viv_toolbar_update_buttons(void)
tbbinfo.cbSize = sizeof(TBBUTTONINFO);
tbbinfo.dwMask = TBIF_STATE;
- tbbinfo.fsState = ((_viv_zoom_pos == 0) && (!_viv_1to1)) ? (0) : (TBSTATE_ENABLED);
+ tbbinfo.fsState = ((!_viv_is_custom_zoom) && (_viv_zoom_pos == 0) && (!_viv_1to1)) ? (0) : (TBSTATE_ENABLED);
SendMessage(_viv_toolbar_hwnd,TB_SETBUTTONINFO,VIV_ID_VIEW_BESTFIT,(LPARAM)&tbbinfo);
}
@@ -11974,7 +12287,7 @@ static void _viv_update_color_button_bitmap(HWND hwnd)
screen_hdc = GetDC(0);
mem_hdc = CreateCompatibleDC(screen_hdc);
- hbitmap = CreateCompatibleBitmap(screen_hdc,wide,high);
+ hbitmap = _viv_create_bitmap(screen_hdc,wide,high);
last_hbitmap = SelectObject(mem_hdc,hbitmap);
@@ -13668,6 +13981,22 @@ static void _viv_update_1to1_scroll(int x,int y)
// #define PHOTO_ORIENTATION_ROTATE270 6u
// #define PHOTO_ORIENTATION_TRANSVERSE 7u
// #define PHOTO_ORIENTATION_ROTATE90 8u
+static HBITMAP _viv_create_bitmap(HDC hdc, int width, int height)
+{
+ BITMAPINFO bmi;
+ void* bits;
+
+ ZeroMemory(&bmi, sizeof(BITMAPINFO));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = width;
+ bmi.bmiHeader.biHeight = -height;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ return CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
+}
+
static HBITMAP _viv_orientate_hbitmap(HBITMAP hbitmap,int orientation)
{
BITMAP bitmap;
@@ -13706,7 +14035,7 @@ static HBITMAP _viv_orientate_hbitmap(HBITMAP hbitmap,int orientation)
break;
}
- ret_hbitmap = CreateCompatibleBitmap(screen_hdc,ret_wide,ret_high);
+ ret_hbitmap = _viv_create_bitmap(screen_hdc,ret_wide,ret_high);
if (ret_hbitmap)
{
int ret;
@@ -14008,70 +14337,42 @@ static void _viv_do_mousewheel_action(int action,int delta,int x,int y)
if (_viv_1to1)
{
_viv_1to1 = 0;
-
- if (delta > 0)
+ }
+
+ {
+ double current_percent;
+ double new_percent;
+
+ if (_viv_image_wide > 0)
{
- for(_viv_zoom_pos = 0;_viv_zoom_pos<_VIV_ZOOM_MAX;_viv_zoom_pos++)
- {
- _viv_get_render_size(&rw,&rh);
-
- if (rw > old_rw)
- {
- break;
- }
- }
+ current_percent = ((double)old_rw / (double)_viv_image_wide) * 100.0;
}
else
{
- for(_viv_zoom_pos = _VIV_ZOOM_MAX-1;_viv_zoom_pos>=0;_viv_zoom_pos--)
- {
- _viv_get_render_size(&rw,&rh);
-
- if (rw < old_rw)
- {
- break;
- }
- }
+ current_percent = 100.0;
}
- }
- else
- {
+
if (delta > 0)
{
- _viv_zoom_pos++;
+ new_percent = _viv_calculate_next_zoom(current_percent, 1);
}
- else
+ else if (delta < 0)
{
- _viv_zoom_pos--;
+ new_percent = _viv_calculate_next_zoom(current_percent, 0);
}
- }
-
- if (_viv_zoom_pos < 0) _viv_zoom_pos = 0;
- if (_viv_zoom_pos > _VIV_ZOOM_MAX-1) _viv_zoom_pos = _VIV_ZOOM_MAX-1;
-
- if (_viv_zoom_pos != old_zoom_pos)
- {
- _viv_get_render_size(&rw,&rh);
- /*
- if (_viv_zoom_pos == 1)
+ else
{
- if ((rw < _viv_image_wide) || (rw < _viv_image_wide))
- {
- rw = _viv_image_wide;
- rh = _viv_image_high;
- }
+ new_percent = current_percent;
}
- */
- //
- // new_cursor_x =
- // rx = (wide / 2) - (rw / 2)
- //debug_printf("%d %d\n",(wide / 2) - (rw / 2),(high / 2) - (rh / 2));
- //debug_printf("%d %d\n",old_cursor_px,(old_cursor_px * 100) / old_rw);
-
- //debug_printf("old %d %d new %d %d\n",old_cursor_px,old_cursor_py,(wide / 2) - (rw / 2) - cursor_x + ((old_cursor_px * rw) / old_rw),(high / 2) - (rh / 2) - cursor_y + ((old_cursor_py * rh) / old_rh)) ;
- //debug_printf("wide / 2 = %d, rw/2=%d, old_cursor_px * rw=%d\n",wide/2,rw/2,old_cursor_px * rw) ;
+ _viv_is_custom_zoom = 1;
+ _viv_custom_zoom_percent = new_percent;
+ }
+
+ _viv_get_render_size(&rw,&rh);
+ if ((rw != old_rw) || (rh != old_rh))
+ {
if (old_rw)
{
new_cursor_x = ((__int64)old_cursor_px * (__int64)rw) / (__int64)old_rw;
@@ -14093,6 +14394,7 @@ static void _viv_do_mousewheel_action(int action,int delta,int x,int y)
_viv_view_set((wide / 2) - (rw / 2) - cursor_x + new_cursor_x,(high / 2) - (rh / 2) - cursor_y + new_cursor_y,1);
InvalidateRect(_viv_hwnd,0,FALSE);
+ _viv_toolbar_update_buttons();
}
}
else
@@ -14223,7 +14525,7 @@ static HBITMAP _viv_get_mipmap(HBITMAP hbitmap,int image_wide,int image_high,int
if (mem2_hdc)
{
(*pmip)->mipmap = NULL;
- (*pmip)->hbitmap = CreateCompatibleBitmap(screen_hdc,mip_wide,mip_high);
+ (*pmip)->hbitmap = _viv_create_bitmap(screen_hdc,mip_wide,mip_high);
last_hbitmap = SelectObject(mem_hdc,(*pmip)->hbitmap);
last2_hbitmap = SelectObject(mem2_hdc,best_hbitmap);
@@ -14883,7 +15185,7 @@ static void _viv_stretch_blt(HDC dst_hdc,int dst_x,int dst_y,int dst_wide,int ds
{
HBITMAP dst_hbitmap;
- dst_hbitmap = CreateCompatibleBitmap(dst_hdc,clip_wide,clip_high);
+ dst_hbitmap = _viv_create_bitmap(dst_hdc,clip_wide,clip_high);
if (dst_hbitmap)
{
HGDIOBJ last_dst_hbitmap;
@@ -15321,3 +15623,4 @@ static int _viv_safe_copy_data(const void *base,SIZE_T src_size,const void *src,
return 1;
}
+
diff --git a/src/viv.h b/src/viv.h
index 16daba6..e914218 100644
--- a/src/viv.h
+++ b/src/viv.h
@@ -57,9 +57,25 @@ typedef unsigned __int64 VIV_UINT64;
#include
#include
//#include
+#define IDC_STATIC -1
+#define IDC_ASSOCIATIONS_GROUPBOX IDC_STATIC
+#define IDC_ADD_KEY_BUTTON IDC_ADD_KEY
+#define IDC_EDIT_KEY_BUTTON IDC_EDIT_KEY
+#define IDC_REMOVE_KEY_BUTTON IDC_REMOVE_KEY
+#define IDC_LEFTCLICKACTION_COMBOBOX IDC_LEFTCLICKACTION
+#define IDC_RIGHTCLICKACTION_COMBOBOX IDC_RIGHTCLICKACTION
+#define IDC_MOUSEWHEELACTION_COMBOBOX IDC_MOUSEWHEELACTION
+#define IDC_SHRINK_BLIT_MODE_COMBOBOX IDC_COMBO1
+#define IDC_MAGNIFY_BLIT_MODE_COMBOBOX IDC_COMBO2
+#define IDC_TITLE_BAR_FORMAT_COMBOBOX IDC_TITLE_BAR_FORMAT
+#define IDC_AUTO_SIZE_WINDOW_COMBOBOX IDC_COMBO4
+#define IDC_WINDOWEDBACKGROUNDCOLOR_BUTTON IDC_WINDOWEDBACKGROUNDCOLOR
+#define IDC_FULLSCREENBACKGROUNDCOLOR_BUTTON IDC_FULLSCREENBACKGROUNDCOLOR
+#define IDC_CUSTOM_RATE_TYPE_COMBOBOX IDC_CUSTOM_RATE_TYPE_COMBO
+#define IDC_SEARCH_EVERYTHING_RANDOM_CHECKBOX IDC_SEARCH_EVERYTHING_RANDOM
#include "../res/resource.h"
//#include
-//#include
+#include
//#include
//#include
#include // OPENFILENAME
@@ -200,6 +216,7 @@ enum
VIV_ID_OPTIONS_GENERAL,
VIV_ID_OPTIONS_VIEW,
VIV_ID_OPTIONS_CONTROLS,
+ VIV_ID_OPTIONS_ZOOM,
VIV_ID_FILE_OPEN_FILE,
VIV_ID_FILE_OPEN_FOLDER,
diff --git a/test_math.c b/test_math.c
new file mode 100644
index 0000000..441c4d4
--- /dev/null
+++ b/test_math.c
@@ -0,0 +1,6 @@
+#include
+#include
+int main() {
+ printf("%f\n", pow(2.0, 3.0));
+ return 0;
+}
diff --git a/vs2026/voidImageViewer.vcxproj b/vs2026/voidImageViewer.vcxproj
index a5f40a8..8d6323f 100644
--- a/vs2026/voidImageViewer.vcxproj
+++ b/vs2026/voidImageViewer.vcxproj
@@ -465,7 +465,7 @@
/MP %(AdditionalOptions)
Disabled
..\libwebp;%(AdditionalIncludeDirectories)
- BZ_NO_STDIO;VERSION_DEBUG;BZ_NO_STDIO;%(PreprocessorDefinitions)
+ WIN32;_DEBUG;_WINDOWS;BZ_NO_STDIO;VERSION_DEBUG;VERSION_X86;%(PreprocessorDefinitions)
false
Async
MultiThreadedDebug
@@ -606,7 +606,7 @@
false
true
..\libwebp;%(AdditionalIncludeDirectories)
- BZ_NO_STDIO;BZ_NO_STDIO;%(PreprocessorDefinitions)
+ WIN32;NDEBUG;_WINDOWS;BZ_NO_STDIO;VERSION_X86;%(PreprocessorDefinitions)
true
MultiThreaded
Fast