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 Options General](https://www.voidtools.com/voidImageViewer.Options.General10.png) +image


void Image Viewer View Options: -![Void Image Viewer Options View](https://www.voidtools.com/voidImageViewer.Options.View10.png) +image


void Image Viewer Controls Options: -![Void Image Viewer Image Controls](https://www.voidtools.com/voidImageViewer.Options.Controls10.png) +image


+## 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