Skip to content

Fix inconsistent header and colors in frame extraction dialog#1089

Open
dylantirandaz wants to merge 12 commits into
MrNeRF:masterfrom
dylantirandaz:fix/frame-extraction-header
Open

Fix inconsistent header and colors in frame extraction dialog#1089
dylantirandaz wants to merge 12 commits into
MrNeRF:masterfrom
dylantirandaz:fix/frame-extraction-header

Conversation

@dylantirandaz

Copy link
Copy Markdown
Contributor

Summary

  • Replaced all hardcoded ImVec4 text colors in the video extractor dialog with theme palette references (palette.text_dim, palette.warning, palette.success, palette.error) so the dialog respects the active theme
  • Wrapped the dialog content in a proper ImGui::Begin/End window with modal styling and a title-bar close button, matching the presentation of other floating panels (Input Settings, Marketplace)
  • The dialog can now be closed via the standard window close button in addition to the existing Cancel button

Test plan

  • Open the Frame Extraction dialog from the menu
  • Verify it now has a proper window title bar with an × close button
  • Confirm the close button dismisses the dialog
  • Check that secondary text (file paths, resolution preview, estimated frames) uses the theme's dimmed text color
  • Verify warning/success/error messages use the correct theme colors
  • Switch themes and confirm the dialog colors update accordingly
  • Confirm the Cancel button still works as before

Closes #1005

Copilot AI review requested due to automatic review settings April 8, 2026 15:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Video Extractor “Frame Extraction” UI to better match other floating/modal panels and to respect the active theme, addressing issue #1005 (inconsistent styling and inability to close).

Changes:

  • Replaced hardcoded ImVec4 colors in the extractor dialog with theme palette colors (dim/warning/success/error).
  • Wrapped the extractor widget in a proper ImGui::Begin/End floating window with modal styling and a standard title-bar close button.
  • Ensured the panel disables itself when closed via the window close button (or when the widget requests closure).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/visualizer/gui/windows/video_extractor_dialog.cpp Swaps hardcoded text/status colors to theme palette references inside the extractor widget rendering.
src/visualizer/gui/native_panels.cpp Hosts the extractor widget in a self-managed ImGui window using modal theme styling and an open close button.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +692 to +695
const char* ext = format_selection_ == 0 ? ".png" : ".jpg";
char preview[128];
std::snprintf(preview, sizeof(preview), filename_pattern_.data(), 1);
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), LOC(VideoExtractor::EXAMPLE), preview, ext);
ImGui::TextColored(t.palette.text_dim, LOC(VideoExtractor::EXAMPLE), preview, ext);

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filename_pattern_ is user-editable and is being passed directly as the std::snprintf format string for the preview. If the user enters an invalid/hostile printf pattern (e.g. "%s", "%n", or mismatched specifiers), this is undefined behavior and can crash or worse. Consider generating the preview without treating user input as a format string (e.g. replace a known token like "%d"/"{frame}" manually), or validate/sanitize the pattern so only an allowed placeholder is accepted before calling snprintf.

Copilot uses AI. Check for mistakes.
Comment thread src/visualizer/gui/native_panels.cpp Outdated
Comment on lines +42 to +47
if (ImGui::Begin(LOC(lichtfeld::Strings::VideoExtractor::TITLE), &open)) {
if (!widget_->render())
open = false;
}
ImGui::End();
t.popModalStyle();

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t.pushModalStyle()/t.popModalStyle() are not exception-safe. PanelRegistry::draw_panels() catches exceptions from panel->draw(), so if widget_->render() throws, the style stack will remain unbalanced and can corrupt styling for the rest of the frame. Please ensure popModalStyle() executes on all exit paths (e.g. wrap the Begin/render/End in a try/catch that pops then rethrows, or use a small scope-guard RAII helper).

Suggested change
if (ImGui::Begin(LOC(lichtfeld::Strings::VideoExtractor::TITLE), &open)) {
if (!widget_->render())
open = false;
}
ImGui::End();
t.popModalStyle();
bool began = false;
try {
const bool visible = ImGui::Begin(LOC(lichtfeld::Strings::VideoExtractor::TITLE), &open);
began = true;
if (visible) {
if (!widget_->render())
open = false;
}
ImGui::End();
began = false;
t.popModalStyle();
} catch (...) {
if (began)
ImGui::End();
t.popModalStyle();
throw;
}

Copilot uses AI. Check for mistakes.
@shadygm

shadygm commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator

Similar to my previous comments.

I was not able to test it since the mesh-2-splat doesn't open, please make sure to sync with master and provide some screenshots of the before and after the UI to make it a bit easier to review :p Thanks!

@dylantirandaz dylantirandaz force-pushed the fix/frame-extraction-header branch from f30ab46 to dca534d Compare April 8, 2026 19:32
@shadygm shadygm self-requested a review April 9, 2026 08:48

@shadygm shadygm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No UI change.

Image

Please make sure that you test your PRs and ask questions for comprehension before setting them for review (:

@dylantirandaz dylantirandaz force-pushed the fix/frame-extraction-header branch from dca534d to 6284324 Compare April 9, 2026 20:12
@dylantirandaz

Copy link
Copy Markdown
Contributor Author

Okay i figured out the issue for this, going to fix so the checks pass but attached is a screenshot to make sure im correctly understanding what you are looking for
Screenshot 2026-04-09 223120

@MrNeRF

MrNeRF commented Apr 10, 2026

Copy link
Copy Markdown
Owner

basically move away from imgui to rmlui. At the current state this implementation kills the entire preview Window. It should match the old version just in rmlui!

@MrNeRF MrNeRF self-requested a review April 10, 2026 12:19
@dylantirandaz dylantirandaz force-pushed the fix/frame-extraction-header branch from 23cee8e to 6284324 Compare April 10, 2026 16:16
@dylantirandaz

Copy link
Copy Markdown
Contributor Author
Screenshot 2026-04-10 124642 is this good?

@dylantirandaz dylantirandaz force-pushed the fix/frame-extraction-header branch from 3fdd397 to 7e11da0 Compare April 10, 2026 17:59
@MrNeRF

MrNeRF commented Apr 10, 2026

Copy link
Copy Markdown
Owner

I think so. I can't test now. I will check it tomorrow.

@dylantirandaz

Copy link
Copy Markdown
Contributor Author

Sounds good

@MrNeRF

MrNeRF commented Apr 11, 2026

Copy link
Copy Markdown
Owner

This is how it used to look like:
Screenshot from 2026-04-11 07-24-22

and this is the current state on this branch:
image

Currently, it doesn't do anything on loading a video. Of course, the functionality must be restored.

@dylantirandaz

Copy link
Copy Markdown
Contributor Author

okay sounds good, im still working on it u can ignore the latest push i havent tested yet and its late here so ill finish tmrw

@dylantirandaz

Copy link
Copy Markdown
Contributor Author

fixed, ran into some issues with rewind/fast forward but i fixed those too

@MrNeRF

MrNeRF commented Apr 12, 2026

Copy link
Copy Markdown
Owner

Closer but still looks very different. The playback is also 4x slower etc.
image

@dylantirandaz

Copy link
Copy Markdown
Contributor Author

Okay fixed the playback, not sure if I am able to recreate the UI one of one though

@shadygm

shadygm commented May 6, 2026

Copy link
Copy Markdown
Collaborator

@dylantirandaz, apologies for my late reply on this PR. Could you please check the builds and resolve the conflicts. Thanks!

Replace all hardcoded ImGui text colors with theme palette references
so the dialog respects the active theme (dark, light, gruvbox, etc.):
- Secondary/info text now uses palette.text_dim instead of inline grays
- Warning, success, and error messages use palette.warning/success/error

Wrap the dialog content in a proper ImGui::Begin/End window with modal
styling and a title-bar close button, matching how other floating panels
(Input Settings, Marketplace) present themselves.

Closes MrNeRF#1005
Replace the native ImGui video extractor panel with a Python-managed
RmlUI panel. Add a custom VideoPreviewElement for GL texture rendering
with aspect-ratio letterboxing via CallbackTextureSource. Wire video
player and frame extraction through python_runtime callbacks so the
Python module avoids linking lfs_video directly.
- Fix locale keys to use correct translation strings
- Add separator line styling on section headers
- Make transport controls always visible (not just when video open)
- Use 28dp round buttons with triangle icons matching old ImGui
- Set panel width to 750dp matching old ImGui window size
- Set preview area to 300dp with dark background and border
- Add test data files to .gitignore
Video player functions are registered on the lichtfeld.io submodule
but the panel was calling them on the root lichtfeld module, causing
AttributeError on video load. Use lf.io.* prefix for all video
player, feed_preview, and video_extract calls.
VideoPlayer::update() expects wall clock time (seconds since
reference point), not delta time. The old ImGui code passed
ImGui::GetTime(). Fix the callback to use steady_clock relative
to app start.

Also fix preview updates after step/seek by adding a
_needs_preview_update flag that triggers feed_preview_element
even when the player isn't playing.
Drive playback from Python using seek-based frame advancing
instead of VideoPlayer::update() which auto-pauses at EOF.
Fix CallbackTextureSource recreation causing black frames.
Fix step forward/backward using seek with 1/fps offset.
Drive playback from Python using stepForward with frame-rate
accumulator instead of broken VideoPlayer::update(). Fix seek-
based rewind with retry for keyframe snapping. Fix EOF auto-
pause by seeking to current position before play. Fix texture
source recreation causing black frames during playback.
@dylantirandaz dylantirandaz force-pushed the fix/frame-extraction-header branch from 6ec922d to 078fa3f Compare May 9, 2026 21:59
@MrNeRF

MrNeRF commented May 10, 2026

Copy link
Copy Markdown
Owner

Hey @dylantirandaz what's the state here given your last commits?

Replace direct OpenGL texture management (glad/glGenTextures/
glTexImage2D) with Rml::CallbackTextureInterface::GenerateTexture
so the element works with the project's Vulkan rmlui backend.

Frame data is converted from RGB to RGBA in CPU and uploaded
through a freshly-constructed CallbackTextureSource whenever
new pixels arrive. The previous source is released by move-assign,
freeing the cached backend texture.
@dylantirandaz

Copy link
Copy Markdown
Contributor Author

Im working on fixing some stuff but Im swamped with final exams so not sure on the timeline, just pushing code when I have free time

@shadygm

shadygm commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

hey @dylantirandaz, I was wondering if you have any updates regarding this PR (:

@dylantirandaz

Copy link
Copy Markdown
Contributor Author
  • Migrated the video extractor from the old native ImGui panel to a Python-managed RmlUI panel: LichtFeld-Studio/src/python/lfs_plugins/
    video_extractor_panel.py:74

  • Added the RmlUI layout and styling for the panel: LichtFeld-Studio/src/visualizer/gui/rmlui/resources/video_extractor_panel.rml:1, LichtFeld-Studio/src/
    visualizer/gui/rmlui/resources/video_extractor_panel.rcss:1

  • Added a custom video-preview RmlUI element so the panel can display video frames inside RmlUI: LichtFeld-Studio/src/visualizer/gui/rmlui/elements/
    video_preview_element.hpp:19

  • Registered that custom RmlUI element with the UI system: LichtFeld-Studio/src/visualizer/gui/rmlui/rmlui_manager.cpp:150

  • Wired the File menu to open lfs.video_extractor instead of the native ImGui panel: LichtFeld-Studio/src/python/lfs_plugins/file_menu.py:119

  • Exposed video player and extraction functions to Python/RmlUI through lichtfeld.io: LichtFeld-Studio/src/python/lfs/py_io.cpp:601

  • Hooked the Python callbacks back into the C++ video player/extractor implementation: LichtFeld-Studio/src/visualizer/visualizer_impl.cpp:321

  • Fixed unsafe filename pattern handling so user input is no longer passed directly to snprintf: LichtFeld-Studio/src/io/video_frame_extractor.cpp:90

  • Kept the old ImGui fallback safer by using the same filename helper and exception-safe modal style cleanup.

  • Added regression tests for the filename pattern behavior and RmlUI preview example: LichtFeld-Studio/tests/python/test_video_extractor_panel.py:1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistent Header in frame extraction tab

4 participants