Fix several layout saving/loading issues

* Better support to load legacy timeline information: we have to
  estimate workspace bounds)
* Auto-save layouts after resizing a splitter/dock
* Fix resetting expansive widgets inside docks after switching tabs
* Load mirrored layout correctly if it was the last selected layout
This commit is contained in:
David Capello 2025-05-07 22:55:59 -03:00
parent 5570b8deee
commit 754c3cb7c6
3 changed files with 50 additions and 22 deletions

View File

@ -314,14 +314,11 @@ void Dock::onSizeHint(ui::SizeHintEvent& ev)
for (int i = 0; i < kSides; ++i) {
auto* widget = m_sides[i];
if (!widget || !widget->isVisible() || widget->isDecorative()) {
m_sizes[i] = gfx::Size(0, 0);
if (!widget || !widget->isVisible() || widget->isDecorative())
continue;
}
const int spacing = (m_aligns[i] & EXPANSIVE ? childSpacing() : 0);
const auto hint = m_sides[i]->sizeHint(fitIn);
m_sizes[i] = hint;
const auto hint = (m_aligns[i] & EXPANSIVE ? m_sizes[i] : widget->sizeHint(fitIn));
switch (i) {
case kTopIndex:
@ -633,6 +630,11 @@ bool Dock::onProcessMessage(ui::Message* msg)
m_dropzonePlaceholder = nullptr;
m_dragging = false;
// Call UserResizedDock signal after resizing a Dock splitter
if (m_hit.sideIndex >= 0)
onUserResizedDock();
m_hit = Hit();
}
break;

View File

@ -183,10 +183,6 @@ void MainWindow::initialize()
m_saveDockLayoutConn = m_customizableDock->UserResizedDock.connect(&MainWindow::saveActiveLayout,
this);
setDefaultLayout();
if (LayoutPtr layout = m_layoutSelector->activeLayout())
loadUserLayout(layout.get());
// Reconfigure workspace when the timeline position is changed.
auto& pref = Preferences::instance();
pref.general.timelinePosition.AfterChange.connect([this] { configureWorkspaceLayout(); });
@ -412,22 +408,32 @@ void MainWindow::setDefaultLayout()
const auto timelineSplitterPos =
get_config_double(kLegacyLayoutMainWindowSection, kLegacyLayoutTimelineSplitter, 75.0) / 100.0;
const auto timelinePos = Preferences::instance().general.timelinePosition();
const auto workspaceBounds = m_workspace->bounds();
// We calculate a estimate of the workspace bounds (as we don't yet
// know its size, because we're just constructing the dock where the
// workspace will be inside).
const int kLegacySplitterSeparation = 3 * ui::guiscale();
auto workspaceBounds = bounds();
workspaceBounds.w -= colorBarWidth + m_toolBar->sizeHint().w + 2 * kLegacySplitterSeparation;
workspaceBounds.h -= m_menuBar->sizeHint().h + m_tabsBar->sizeHint().h +
m_contextBar->sizeHint().h + m_statusBar->sizeHint().h;
int timelineSide;
switch (timelinePos) {
case gen::TimelinePosition::LEFT: timelineSide = ui::LEFT; break;
case gen::TimelinePosition::RIGHT: timelineSide = ui::LEFT; break;
default:
case gen::TimelinePosition::BOTTOM: timelineSide = ui::BOTTOM; break;
}
gfx::Size timelineSize(75, 75);
if ((timelineSide & RIGHT) || (timelineSide & LEFT)) {
timelineSize.w = (workspaceBounds.w * (1.0 - timelineSplitterPos)) / guiscale();
}
if ((timelineSide & BOTTOM) || (timelineSide & TOP)) {
timelineSize.h = (workspaceBounds.h * (1.0 - timelineSplitterPos)) / guiscale();
switch (timelinePos) {
case gen::TimelinePosition::LEFT:
timelineSide = ui::LEFT;
timelineSize.w = (workspaceBounds.w * (1.0 - timelineSplitterPos));
break;
case gen::TimelinePosition::RIGHT:
timelineSide = ui::RIGHT;
timelineSize.w = (workspaceBounds.w * (1.0 - timelineSplitterPos));
break;
default:
case gen::TimelinePosition::BOTTOM:
timelineSide = ui::BOTTOM;
timelineSize.h = (workspaceBounds.h * (1.0 - timelineSplitterPos));
break;
}
// Timeline config
@ -509,6 +515,25 @@ void MainWindow::onResize(ui::ResizeEvent& ev)
{
ui::Window::onResize(ev);
// Load default or user-selected layout after the first resize event
// is received.
if (m_firstResize) {
m_firstResize = false;
setDefaultLayout();
const std::string layoutId = m_layoutSelector->activeLayoutId();
if (layoutId != Layout::kDefault) {
// Load the mirror layout
if (layoutId == Layout::kMirroredDefault) {
setMirroredDefaultLayout();
}
// Or load an user defined layout
else if (LayoutPtr layout = m_layoutSelector->activeLayout()) {
loadUserLayout(layout.get());
}
}
}
os::Window* nativeWindow = (display() ? display()->nativeWindow() : nullptr);
if (nativeWindow && nativeWindow->screen()) {
const int scale = nativeWindow->scale() * ui::guiscale();

View File

@ -164,6 +164,7 @@ private:
obs::scoped_connection m_timelineResizeConn;
obs::scoped_connection m_colorBarResizeConn;
obs::scoped_connection m_saveDockLayoutConn;
bool m_firstResize = true;
};
} // namespace app