Skip to content

Commit 811a89d

Browse files
committed
feat(filmstrip): add trigger height, dwell time, exit delay configs and new badges
1 parent faa349d commit 811a89d

7 files changed

Lines changed: 94 additions & 11 deletions

File tree

‎QuickView/AppStrings.cpp‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,9 @@ const wchar_t *Settings_Option_GalleryTriggerDelay = nullptr;
542542
const wchar_t *Settings_Option_GalleryTriggerClick = nullptr;
543543
const wchar_t *Settings_Option_GalleryTriggerDisable = nullptr;
544544
const wchar_t *Settings_Tooltip_GalleryTrigger = nullptr;
545+
const wchar_t *Settings_Label_GalleryTriggerAreaHeight = nullptr;
546+
const wchar_t *Settings_Label_GalleryDwellTime = nullptr;
547+
const wchar_t *Settings_Label_GalleryExitDelay = nullptr;
545548

546549
const wchar_t *OSD_SlideshowStarted = nullptr;
547550
const wchar_t *OSD_SlideshowStopped = nullptr;
@@ -1086,6 +1089,9 @@ struct LanguageTable {
10861089
const wchar_t *Settings_Option_GalleryTriggerClick;
10871090
const wchar_t *Settings_Option_GalleryTriggerDisable;
10881091
const wchar_t *Settings_Tooltip_GalleryTrigger;
1092+
const wchar_t *Settings_Label_GalleryTriggerAreaHeight;
1093+
const wchar_t *Settings_Label_GalleryDwellTime;
1094+
const wchar_t *Settings_Label_GalleryExitDelay;
10891095

10901096
const wchar_t *OSD_SlideshowStarted;
10911097
const wchar_t *OSD_SlideshowStopped;
@@ -1633,6 +1639,9 @@ static const LanguageTable Table_EN = {
16331639
L"Click Hotspot", // Settings_Option_GalleryTriggerClick
16341640
L"Disabled", // Settings_Option_GalleryTriggerDisable
16351641
L"This feature is automatically disabled when the window is smaller than 600x450.", // Settings_Tooltip_GalleryTrigger
1642+
L"Trigger Area Height", // Settings_Label_GalleryTriggerAreaHeight
1643+
L"Dwell Time", // Settings_Label_GalleryDwellTime
1644+
L"Exit Delay", // Settings_Label_GalleryExitDelay
16361645

16371646
L"Slideshow Started", // OSD_SlideshowStarted
16381647
L"Slideshow Stopped", // OSD_SlideshowStopped
@@ -2180,6 +2189,9 @@ static const LanguageTable Table_CN = {
21802189
L"点击热点", // Settings_Option_GalleryTriggerClick
21812190
L"停用", // Settings_Option_GalleryTriggerDisable
21822191
L"该功能在窗口小于 600x450 时将自动禁用。", // Settings_Tooltip_GalleryTrigger
2192+
L"触发区域高度", // Settings_Label_GalleryTriggerAreaHeight
2193+
L"停留时长", // Settings_Label_GalleryDwellTime
2194+
L"退出延迟", // Settings_Label_GalleryExitDelay
21832195

21842196
L"开始播放幻灯片", // OSD_SlideshowStarted
21852197
L"停止播放幻灯片", // OSD_SlideshowStopped
@@ -2727,6 +2739,9 @@ static const LanguageTable Table_TW = {
27272739
L"點擊熱點", // Settings_Option_GalleryTriggerClick
27282740
L"停用", // Settings_Option_GalleryTriggerDisable
27292741
L"該功能在視窗小於 600x450 時將自動禁用。", // Settings_Tooltip_GalleryTrigger
2742+
L"觸發區域高度", // Settings_Label_GalleryTriggerAreaHeight
2743+
L"停留時長", // Settings_Label_GalleryDwellTime
2744+
L"退出延遲", // Settings_Label_GalleryExitDelay
27302745

27312746
L"開始播放幻燈片", // OSD_SlideshowStarted
27322747
L"停止播放幻燈片", // OSD_SlideshowStopped
@@ -3274,6 +3289,9 @@ static const LanguageTable Table_JA = {
32743289
L"ホットスポットクリック", // Settings_Option_GalleryTriggerClick
32753290
L"無効", // Settings_Option_GalleryTriggerDisable
32763291
L"この機能はウィンドウサイズが 600x450 未満の場合、自動的に無効になります。", // Settings_Tooltip_GalleryTrigger
3292+
L"トリガーエリアの高さ", // Settings_Label_GalleryTriggerAreaHeight
3293+
L"ホバー滞在時間", // Settings_Label_GalleryDwellTime
3294+
L"退出ディレイ", // Settings_Label_GalleryExitDelay
32773295

32783296
L"スライドショーを開始", // OSD_SlideshowStarted
32793297
L"スライドショーを停止", // OSD_SlideshowStopped
@@ -3821,6 +3839,9 @@ static const LanguageTable Table_RU = {
38213839
L"Щелчок по точке", // Settings_Option_GalleryTriggerClick
38223840
L"Отключено", // Settings_Option_GalleryTriggerDisable
38233841
L"Эта функция автоматически отключается, если размер окна меньше 600x450 пкс.", // Settings_Tooltip_GalleryTrigger
3842+
L"Высота зоны триггера", // Settings_Label_GalleryTriggerAreaHeight
3843+
L"Время задержки", // Settings_Label_GalleryDwellTime
3844+
L"Задержка выхода", // Settings_Label_GalleryExitDelay
38243845

38253846
L"Слайд-шоу запущено", // OSD_SlideshowStarted
38263847
L"Слайд-шоу остановлено", // OSD_SlideshowStopped
@@ -4368,6 +4389,9 @@ static const LanguageTable Table_DE = {
43684389
L"Hotspot-Klick", // Settings_Option_GalleryTriggerClick
43694390
L"Deaktiviert", // Settings_Option_GalleryTriggerDisable
43704391
L"Diese Funktion wird automatisch deaktiviert, wenn das Fenster kleiner als 600x450 ist.", // Settings_Tooltip_GalleryTrigger
4392+
L"Höhe des Auslösebereichs", // Settings_Label_GalleryTriggerAreaHeight
4393+
L"Verweilzeit", // Settings_Label_GalleryDwellTime
4394+
L"Verzögerung beim Beenden", // Settings_Label_GalleryExitDelay
43714395

43724396
L"Diashow gestartet", // OSD_SlideshowStarted
43734397
L"Diashow gestoppt", // OSD_SlideshowStopped
@@ -4915,6 +4939,9 @@ static const LanguageTable Table_ES = {
49154939
L"Clic en punto caliente", // Settings_Option_GalleryTriggerClick
49164940
L"Deshabilitado", // Settings_Option_GalleryTriggerDisable
49174941
L"Esta función se desactiva automáticamente cuando la ventana es menor de 600x450.", // Settings_Tooltip_GalleryTrigger
4942+
L"Altura del área de activación", // Settings_Label_GalleryTriggerAreaHeight
4943+
L"Tiempo de permanencia", // Settings_Label_GalleryDwellTime
4944+
L"Retardo de salida", // Settings_Label_GalleryExitDelay
49184945

49194946
L"Presentación iniciada", // OSD_SlideshowStarted
49204947
L"Presentación detenida", // OSD_SlideshowStopped
@@ -5462,6 +5489,9 @@ static const LanguageTable Table_FR = {
54625489
L"Clic sur le point chaud", // Settings_Option_GalleryTriggerClick
54635490
L"Désactivé", // Settings_Option_GalleryTriggerDisable
54645491
L"Cette fonctionnalité est automatiquement désactivée lorsque la fenêtre est plus petite que 600x450.", // Settings_Tooltip_GalleryTrigger
5492+
L"Hauteur de la zone de déclenchement", // Settings_Label_GalleryTriggerAreaHeight
5493+
L"Temps de maintien", // Settings_Label_GalleryDwellTime
5494+
L"Délai de sortie", // Settings_Label_GalleryExitDelay
54655495

54665496
L"Diaporama démarré", // OSD_SlideshowStarted
54675497
L"Diaporama arrêté", // OSD_SlideshowStopped
@@ -6013,6 +6043,9 @@ void Apply(const LanguageTable& t) {
60136043
Settings_Option_GalleryTriggerClick = t.Settings_Option_GalleryTriggerClick;
60146044
Settings_Option_GalleryTriggerDisable = t.Settings_Option_GalleryTriggerDisable;
60156045
Settings_Tooltip_GalleryTrigger = t.Settings_Tooltip_GalleryTrigger;
6046+
Settings_Label_GalleryTriggerAreaHeight = t.Settings_Label_GalleryTriggerAreaHeight;
6047+
Settings_Label_GalleryDwellTime = t.Settings_Label_GalleryDwellTime;
6048+
Settings_Label_GalleryExitDelay = t.Settings_Label_GalleryExitDelay;
60166049

60176050
OSD_SlideshowStarted = t.OSD_SlideshowStarted;
60186051
OSD_SlideshowStopped = t.OSD_SlideshowStopped;

‎QuickView/AppStrings.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ namespace AppStrings {
254254
extern const wchar_t* Settings_Option_GalleryTriggerClick;
255255
extern const wchar_t* Settings_Option_GalleryTriggerDisable;
256256
extern const wchar_t* Settings_Tooltip_GalleryTrigger;
257+
extern const wchar_t* Settings_Label_GalleryTriggerAreaHeight;
258+
extern const wchar_t* Settings_Label_GalleryDwellTime;
259+
extern const wchar_t* Settings_Label_GalleryExitDelay;
257260

258261

259262
extern const wchar_t* Settings_Group_Foundation;

‎QuickView/EditState.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,9 @@ struct AppConfig {
626626
bool DisableEdgeNavInCompare = true;
627627
int NavIndicator = 0; // 0=Arrow
628628
int GalleryTriggerMode = 1; // 0=Hover Auto, 1=Hover Hotspot Delay, 2=Click Hotspot
629+
float GalleryTriggerAreaHeight = 20.0f; // Auto hover trigger zone height in logical pixels (5 ~ 100)
630+
float GalleryDwellTime = 0.18f; // Dwell time for hotspot hover / expand hotspot in seconds (0.05 ~ 2.0)
631+
float GalleryExitDelay = 0.80f; // Exit dismissal delay in seconds (0.10 ~ 3.0)
629632
int GalleryThumbnailSize = 0; // 0=Auto(140px), 80~300=explicit pixel size
630633
float GalleryFilmstripHeight = 140.0f; // Preferred height of filmstrip in logical pixels
631634
int PrefetchGear = 1; // 0=Off, 1=Auto, 2=Eco, 3=Balanced, 4=Ultra

‎QuickView/GalleryOverlay.cpp‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ void GalleryOverlay::Update(float deltaTime, HWND hwnd) {
253253
// 6. Hover Hotspot Delay Timer (Trigger Mode 1)
254254
if (g_config.GalleryTriggerMode == 1 && m_hoveringHotspot && m_mode == GalleryMode::Hidden) {
255255
m_hoverDelayTimer += deltaTime;
256-
if (m_hoverDelayTimer >= 0.18f) { // 180ms delay
256+
if (m_hoverDelayTimer >= g_config.GalleryDwellTime) { // Configurable dwell time
257257
Open(m_selectedIndex >= 0 ? m_selectedIndex : 0, GalleryMode::Filmstrip);
258258
m_hoverDelayTimer = 0.0f;
259259
m_hoveringHotspot = false;
@@ -269,7 +269,7 @@ void GalleryOverlay::Update(float deltaTime, HWND hwnd) {
269269
if ((g_config.GalleryTriggerMode == 0 || g_config.GalleryTriggerMode == 1) &&
270270
m_mode == GalleryMode::Filmstrip && m_bottomHintHover && m_gridProgress < 0.01f) {
271271
m_expandHoverTimer += deltaTime;
272-
if (m_expandHoverTimer >= 0.50f) { // 500ms delay, giving user clear perception of pause/hover
272+
if (m_expandHoverTimer >= g_config.GalleryDwellTime) { // Configurable dwell time for expand hotspot
273273
SetMode(GalleryMode::FullGrid);
274274
m_expandHoverTimer = 0.0f;
275275
}
@@ -278,7 +278,7 @@ void GalleryOverlay::Update(float deltaTime, HWND hwnd) {
278278
m_expandHoverTimer = 0.0f;
279279
}
280280

281-
// 7. Auto Dismissal Delay Timer (300ms) with global physical cursor polling & tolerance
281+
// 7. Auto Dismissal Delay Timer with global physical cursor polling & tolerance
282282
if (m_mode != GalleryMode::Hidden) {
283283
float width = m_lastSize.width;
284284
float height = m_lastSize.height;
@@ -323,7 +323,7 @@ void GalleryOverlay::Update(float deltaTime, HWND hwnd) {
323323
extern bool g_isDraggingFilmstrip;
324324
if (!m_mouseInGallery && !m_isPinned && !g_isDraggingFilmstrip && !g_imagePath.empty() && m_mode != GalleryMode::FullGrid && m_targetGridProgress < 0.5f) {
325325
m_dismissalTimer += deltaTime;
326-
if (m_dismissalTimer >= 0.8f) {
326+
if (m_dismissalTimer >= g_config.GalleryExitDelay) {
327327
Close(true);
328328
m_dismissalTimer = 0.0f;
329329
}

‎QuickView/QuickView.rc‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
// Version Information - This sets the display name in Windows
1414
VS_VERSION_INFO VERSIONINFO
15-
FILEVERSION 6,27,3,7
16-
PRODUCTVERSION 6,27,3,7
15+
FILEVERSION 6,28,0,0
16+
PRODUCTVERSION 6,28,0,0
1717
FILEFLAGSMASK 0x3fL
1818
FILEFLAGS 0x0L
1919
FILEOS 0x40004L
@@ -26,12 +26,12 @@ BEGIN
2626
BEGIN
2727
VALUE "CompanyName", "QuickView"
2828
VALUE "FileDescription", "QuickView"
29-
VALUE "FileVersion", "6.27.3.7"
29+
VALUE "FileVersion", "6.28.0.0"
3030
VALUE "InternalName", "QuickView"
3131
VALUE "LegalCopyright", "Copyright (C) 2026"
3232
VALUE "OriginalFilename", "QuickView.exe"
3333
VALUE "ProductName", "QuickView"
34-
VALUE "ProductVersion", "6.27.3.7"
34+
VALUE "ProductVersion", "6.28.0.0"
3535
END
3636
END
3737
BLOCK "VarFileInfo"

‎QuickView/SettingsOverlay.cpp‎

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1910,10 +1910,40 @@ void SettingsOverlay::BuildMenu() {
19101910
AppStrings::Settings_Option_GalleryTriggerDisable
19111911
};
19121912
itemGalleryTrigger.tooltipText = AppStrings::Settings_Tooltip_GalleryTrigger;
1913-
itemGalleryTrigger.onChange = []([[maybe_unused]] SettingsOverlay* overlay, [[maybe_unused]] SettingsItem* item) { SaveConfig(); };
1913+
itemGalleryTrigger.onChange = [](SettingsOverlay* overlay, [[maybe_unused]] SettingsItem* item) {
1914+
SaveConfig();
1915+
overlay->BuildMenu();
1916+
};
19141917
tabControl.items.push_back(itemGalleryTrigger);
19151918

1919+
if (g_config.GalleryTriggerMode == 0) {
1920+
SettingsItem itemAreaHeight = { AppStrings::Settings_Label_GalleryTriggerAreaHeight, OptionType::Slider, nullptr, &g_config.GalleryTriggerAreaHeight };
1921+
itemAreaHeight.minVal = 5.0f;
1922+
itemAreaHeight.maxVal = 100.0f;
1923+
itemAreaHeight.step = 1.0f;
1924+
itemAreaHeight.displayFormat = L"%.0f px";
1925+
itemAreaHeight.isNewOption = true;
1926+
itemAreaHeight.onChange = []([[maybe_unused]] SettingsOverlay* overlay, [[maybe_unused]] SettingsItem* item) { SaveConfig(); };
1927+
tabControl.items.push_back(itemAreaHeight);
1928+
} else if (g_config.GalleryTriggerMode == 1) {
1929+
SettingsItem itemDwell = { AppStrings::Settings_Label_GalleryDwellTime, OptionType::Slider, nullptr, &g_config.GalleryDwellTime };
1930+
itemDwell.minVal = 0.05f;
1931+
itemDwell.maxVal = 2.00f;
1932+
itemDwell.step = 0.01f;
1933+
itemDwell.displayFormat = L"%.2f s";
1934+
itemDwell.isNewOption = true;
1935+
itemDwell.onChange = []([[maybe_unused]] SettingsOverlay* overlay, [[maybe_unused]] SettingsItem* item) { SaveConfig(); };
1936+
tabControl.items.push_back(itemDwell);
1937+
}
19161938

1939+
SettingsItem itemExitDelay = { AppStrings::Settings_Label_GalleryExitDelay, OptionType::Slider, nullptr, &g_config.GalleryExitDelay };
1940+
itemExitDelay.minVal = 0.10f;
1941+
itemExitDelay.maxVal = 3.00f;
1942+
itemExitDelay.step = 0.05f;
1943+
itemExitDelay.displayFormat = L"%.2f s";
1944+
itemExitDelay.isNewOption = true;
1945+
itemExitDelay.onChange = []([[maybe_unused]] SettingsOverlay* overlay, [[maybe_unused]] SettingsItem* item) { SaveConfig(); };
1946+
tabControl.items.push_back(itemExitDelay);
19171947
}
19181948
m_tabs.push_back(tabControl);
19191949

‎QuickView/main.cpp‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4411,6 +4411,9 @@ void SaveConfig() {
44114411
WriteConfigInt(L"Controls", L"MiddleClickAction", (int)g_config.MiddleClickAction, iniPath.c_str());
44124412
WriteConfigBool(L"Controls", L"EdgeNavClick", g_config.EdgeNavClick, iniPath.c_str());
44134413
WriteConfigInt(L"Controls", L"GalleryTriggerMode", g_config.GalleryTriggerMode, iniPath.c_str());
4414+
WriteConfigFloat(L"Controls", L"GalleryTriggerAreaHeight", g_config.GalleryTriggerAreaHeight, iniPath.c_str());
4415+
WriteConfigFloat(L"Controls", L"GalleryDwellTime", g_config.GalleryDwellTime, iniPath.c_str());
4416+
WriteConfigFloat(L"Controls", L"GalleryExitDelay", g_config.GalleryExitDelay, iniPath.c_str());
44144417
WriteConfigInt(L"Controls", L"GalleryThumbnailSize", g_config.GalleryThumbnailSize, iniPath.c_str());
44154418
WriteConfigInt(L"Controls", L"GalleryFilmstripHeight", g_config.GalleryFilmstripHeight, iniPath.c_str());
44164419
// NavIndicator moved to View section
@@ -4729,6 +4732,12 @@ void LoadConfig() {
47294732
g_config.MiddleClickIndex = (g_config.MiddleClickAction == MouseAction::ExitApp) ? 1 : 0;
47304733
g_config.EdgeNavClick = GetPrivateProfileIntW(L"Controls", L"EdgeNavClick", 1, iniPath.c_str()) != 0;
47314734
g_config.GalleryTriggerMode = GetPrivateProfileIntW(L"Controls", L"GalleryTriggerMode", 1, iniPath.c_str());
4735+
GetPrivateProfileStringW(L"Controls", L"GalleryTriggerAreaHeight", L"20.0", buf, 64, iniPath.c_str());
4736+
g_config.GalleryTriggerAreaHeight = std::clamp((float)_wtof(buf), 5.0f, 100.0f);
4737+
GetPrivateProfileStringW(L"Controls", L"GalleryDwellTime", L"0.18", buf, 64, iniPath.c_str());
4738+
g_config.GalleryDwellTime = std::clamp((float)_wtof(buf), 0.05f, 2.00f);
4739+
GetPrivateProfileStringW(L"Controls", L"GalleryExitDelay", L"0.80", buf, 64, iniPath.c_str());
4740+
g_config.GalleryExitDelay = std::clamp((float)_wtof(buf), 0.10f, 3.00f);
47324741
g_config.GalleryThumbnailSize = std::clamp((int)GetPrivateProfileIntW(L"Controls", L"GalleryThumbnailSize", 0, iniPath.c_str()), 0, 300);
47334742
GetPrivateProfileStringW(L"Controls", L"GalleryFilmstripHeight", L"-1.0", buf, 64, iniPath.c_str());
47344743
{
@@ -8173,8 +8182,13 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
81738182

81748183
bool inGalleryTriggerZone = false;
81758184
if (g_config.GalleryTriggerMode == 0) {
8176-
// Mode 0: Wide auto hover zone (400px wide, 20px high)
8177-
inGalleryTriggerZone = (pt.y >= 0 && pt.y < 20.0f * g_uiScale && pt.x >= cx - 200.0f * g_uiScale && pt.x <= cx + 200.0f * g_uiScale);
8185+
// Mode 0: Auto hover zone dynamically scaled across window width, avoiding top-right caption buttons
8186+
float ctrlW = g_uiRenderer ? g_uiRenderer->GetWindowControlsWidth() : 120.0f * g_uiScale;
8187+
if (ctrlW < 100.0f * g_uiScale) ctrlW = 120.0f * g_uiScale;
8188+
float rightBound = (float)w - ctrlW - 6.0f * g_uiScale;
8189+
float leftBound = 0.0f;
8190+
float triggerH = g_config.GalleryTriggerAreaHeight * g_uiScale;
8191+
inGalleryTriggerZone = (pt.y >= 0 && pt.y < triggerH && pt.x >= leftBound && pt.x <= rightBound);
81788192
} else if (g_config.GalleryTriggerMode == 1) {
81798193
// Mode 1: Hotspot Hover. Trigger ONLY when mouse is near the center button (comfort area symmetry: 30px wide, 32px high)
81808194
float iconSize = 18.0f * g_uiScale;

0 commit comments

Comments
 (0)