Skip to content

Commit 3ff7356

Browse files
committed
Add multi-view workspace and shared library
Introduce MultiViewWorkspace and ImageLibraryState to support multiple image view windows and a shared loaded-image queue/recent list. Update many APIs and actions to accept the shared ImageLibraryState (and viewer lists where needed), move loaded-image and recent-image management into the shared library, and keep per-view interaction state in ViewerState. Add an Image List window UI, new view creation (double-click/new view), menu shortcuts, drag-and-drop handling, and per-workspace sync logic. Add a multi-view regression test and helper script, update CMake and README/docs to describe the feature, and adjust rendering/windowing code to handle multiple Image N windows and docking behavior. Note: preview controls (exposure, gamma, OCIO, etc.) remain global and are left for a follow-up.
1 parent 9263ef4 commit 3ff7356

17 files changed

Lines changed: 993 additions & 213 deletions

src/doc/imiv_dev.rst

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -188,19 +188,38 @@ new work easier to reason about.
188188
`ViewerState`
189189
-------------
190190

191-
`ViewerState` in `src/imiv/imiv_viewer.h` is the runtime model for the loaded
192-
image and its current interaction state. It owns:
191+
`ViewerState` in `src/imiv/imiv_viewer.h` is the per-view runtime model for the
192+
currently displayed image and its interaction state. It owns:
193193

194194
* the current `LoadedImage`;
195195
* status and error text;
196196
* zoom, scroll, zoom pivot, and fit behavior;
197197
* selection and area-probe state;
198-
* the loaded-image list and recent-image list;
198+
* the current loaded-image index within the shared library;
199199
* windowed/fullscreen placement;
200200
* the current `RendererTexture`.
201201

202-
If state is tied to the currently loaded image or to navigation through that
203-
image, it usually belongs here.
202+
If state is tied to one image pane and its navigation state, it usually
203+
belongs here.
204+
205+
`ImageLibraryState` and `MultiViewWorkspace`
206+
--------------------------------------------
207+
208+
The first multi-view slice introduces two more shared state buckets in
209+
`src/imiv/imiv_viewer.h`:
210+
211+
* `ImageLibraryState`
212+
owns the shared loaded-image queue, recent-image history, and sort mode;
213+
* `MultiViewWorkspace`
214+
owns the open image windows, the active view id, and Image List visibility.
215+
216+
Each `ImageViewWindow` owns one `ViewerState`. The main `Image` window is the
217+
primary view. Additional `Image N` windows are created from
218+
`File -> New view from current image` or by double-clicking entries in the
219+
Image List window.
220+
221+
This split matters: queue history is now global to the workspace, but image
222+
interaction state remains per view.
204223

205224
`PlaceholderUiState`
206225
--------------------
@@ -217,6 +236,12 @@ image, it usually belongs here.
217236
If state describes how the UI should look or how preview rendering should be
218237
configured across launches, it usually belongs here.
219238

239+
At the moment, this also means preview controls are still shared across all
240+
open image views. Exposure, gamma, offset, interpolation, and OCIO selection
241+
remain global UI state rather than per-view state. Splitting those controls
242+
into per-view state is a follow-up task, not part of the first multi-view
243+
milestone.
244+
220245
`DeveloperUiState`
221246
------------------
222247

@@ -241,8 +266,8 @@ layout state together in a single `imiv.inf` file.
241266

242267
* the Dear ImGui `.ini` text first, straight from
243268
`ImGui::SaveIniSettingsToMemory()`;
244-
* then an `ImivApp` settings section with `PlaceholderUiState` and a small
245-
amount of `ViewerState`.
269+
* then an `ImivApp` settings section with `PlaceholderUiState`,
270+
`ImageLibraryState`, and a small amount of `ViewerState`.
246271

247272
This is worth preserving. It gives :program:`imiv` one file for:
248273

@@ -273,10 +298,11 @@ The current order is:
273298
6. execute queued state mutations with `execute_viewer_frame_actions()`;
274299
7. process drag and drop and auto-subimage work;
275300
8. clamp UI state;
276-
9. update the renderer preview texture from the current preview controls;
301+
9. update the renderer preview texture for the active view from the current
302+
preview controls;
277303
10. build the dockspace host window;
278-
11. draw the main image window;
279-
12. draw auxiliary windows and popups;
304+
11. draw the main image window and any secondary `Image N` windows;
305+
12. draw the Image List window, auxiliary windows, and popups;
280306
13. draw developer-mode Dear ImGui diagnostic windows and the drag overlay.
281307

282308
Two design choices here are important:
@@ -309,6 +335,14 @@ The main image window:
309335
* is assigned to the dockspace with `ImGui::SetNextWindowDockID()`;
310336
* uses `ImGuiWindowClass` to request `ImGuiDockNodeFlags_AutoHideTabBar`.
311337

338+
Secondary image windows:
339+
340+
* are named `Image N`;
341+
* are created as ordinary Dear ImGui windows with the same image-window class;
342+
* are forced into the main dockspace on first creation;
343+
* currently use `ImGuiDockNodeFlags_NoUndocking`;
344+
* inherit the same shared preview/renderer policy as the primary view.
345+
312346
Why there is no `DockBuilder`
313347
-----------------------------
314348

@@ -331,6 +365,8 @@ The main windows are:
331365

332366
* the dockspace host window;
333367
* the `Image` window;
368+
* zero or more `Image N` windows;
369+
* `Image List`;
334370
* `iv Info`;
335371
* `iv Preferences`;
336372
* `Preview`;

src/doc/imiv_tests.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ already includes fields such as:
260260

261261
* `image_loaded`, `image_path`, `zoom`, and `fit_image_to_window`
262262
* selection and Area Sample state
263+
* multi-view state (`view_count`, `active_view_id`, `active_view_docked`)
263264
* backend state (`active`, `requested`, `next_launch`, compiled backends)
264265
* OCIO state (requested source, resolved source, resolved config path,
265266
display/view, available menus)
@@ -270,6 +271,9 @@ Example excerpt::
270271
"image_loaded": true,
271272
"zoom": 1.000000,
272273
"selection_active": false,
274+
"view_count": 2,
275+
"active_view_id": 2,
276+
"active_view_docked": true,
273277
"backend": {
274278
"active": "vulkan",
275279
"requested": "auto",
@@ -355,6 +359,10 @@ Run a focused UI regression::
355359

356360
ctest --test-dir build_u -V -R '^imiv_ux_actions_regression$'
357361

362+
Run the focused multi-view regression::
363+
364+
ctest --test-dir build_u -V -R '^imiv_multiview_regression$'
365+
358366
Run the backend-preference regression::
359367

360368
ctest --test-dir build_u -V -R '^imiv_backend_preferences_regression$'

src/doc/imiv_user.rst

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,36 @@ Common shortcuts:
177177
The `Tools` menu also exposes slideshow, sort-order, and orientation actions.
178178

179179

180+
Multiple views and image list
181+
=============================
182+
183+
The current multi-view workflow is centered on shared loaded-image history and
184+
per-window image panes.
185+
186+
Useful actions:
187+
188+
* `File -> New view from current image`
189+
duplicates the current image into a new `Image N` window.
190+
* `View -> Image List`
191+
opens a dockable window showing the current loaded-image queue.
192+
193+
The `Image List` window currently supports:
194+
195+
* single-click
196+
load the chosen image into the active image view;
197+
* double-click
198+
open the chosen image in a new image view window.
199+
200+
The main `Image` window remains the primary docked image pane. Additional
201+
`Image N` windows are currently created docked into the main dockspace.
202+
Undocking those image views is intentionally disabled in this first slice.
203+
204+
This is the first multi-view milestone. View windows already have independent
205+
loaded images, zoom, scroll, and selection state, but preview controls are
206+
still shared. Exposure, gamma, offset, interpolation, and OCIO display/view
207+
choices are not yet stored per window.
208+
209+
180210
Color management
181211
================
182212

@@ -248,10 +278,12 @@ Current limitations
248278

249279
At the time of this writing, notable differences from :program:`iv` include:
250280

251-
* `Move to new window` is still a placeholder action.
252281
* Fullscreen behavior does not yet exactly match :program:`iv`.
253282
* Opening the same file repeatedly does not currently create duplicate loaded
254283
image entries.
284+
* Multi-view image windows are available, but preview controls such as
285+
exposure, gamma, offset, interpolation, and OCIO display/view are still
286+
shared state rather than per-view state.
255287
* Some older :program:`iv` mouse modes are not yet a priority for the Dear
256288
ImGui port.
257289

src/imiv/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,22 @@ if (TARGET imiv
13151315
LABELS "imiv;gui"
13161316
TIMEOUT 360)
13171317

1318+
add_test (
1319+
NAME imiv_multiview_regression
1320+
COMMAND
1321+
"${Python3_EXECUTABLE}"
1322+
"${CMAKE_CURRENT_SOURCE_DIR}/tools/imiv_multiview_regression.py"
1323+
--bin "$<TARGET_FILE:imiv>"
1324+
--cwd "$<TARGET_FILE_DIR:imiv>"
1325+
${_imiv_ctest_default_backend_args}
1326+
--env-script "${CMAKE_BINARY_DIR}/imiv_env.sh"
1327+
--out-dir "${CMAKE_BINARY_DIR}/imiv_captures/multiview_regression"
1328+
--open "${PROJECT_SOURCE_DIR}/ASWF/logos/openimageio-stacked-gradient.png")
1329+
set_tests_properties (
1330+
imiv_multiview_regression PROPERTIES
1331+
LABELS "imiv;gui;imiv_multiview"
1332+
TIMEOUT 180)
1333+
13181334
add_test (
13191335
NAME imiv_rgb_input_regression
13201336
COMMAND

src/imiv/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ Focused backend-selector regression from a multi-backend build:
114114
ctest --test-dir build_u -V -R '^imiv_backend_preferences_regression$'
115115
```
116116

117+
Focused multi-view regression:
118+
119+
```bash
120+
ctest --test-dir build_u -V -R '^imiv_multiview_regression$'
121+
```
122+
117123
Focused developer-menu regression:
118124

119125
```bash

0 commit comments

Comments
 (0)