X Tutup
Skip to content

Continue with some extra dockable UI features (#5327)#5563

Draft
dacap wants to merge 3 commits intoaseprite:betafrom
dacap:dock
Draft

Continue with some extra dockable UI features (#5327)#5563
dacap wants to merge 3 commits intoaseprite:betafrom
dacap:dock

Conversation

@dacap
Copy link
Member

@dacap dacap commented Nov 28, 2025

From #5327 we'll try to implement the possibility to dock any widget in any dock. And to make floating windows from docks (even the "preview window" should be dockable).

We want to fix #2299 too adding a notch for completely collapsed widgets in splitters.

@dacap dacap self-assigned this Nov 28, 2025
Copy link
Collaborator

@aseprite-bot aseprite-bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

m_display->dirtyRect(m_floatingUILayer->bounds());
}

void Dock::DraggingFeedback::paint(Graphics* g, gfx::Rect bounds)
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: method 'paint' can be made const [readability-make-member-function-const]

src/app/ui/dock.h:95:

-     void paint(ui::Graphics* g, gfx::Rect bounds);
+     void paint(ui::Graphics* g, gfx::Rect bounds) const;
Suggested change
void Dock::DraggingFeedback::paint(Graphics* g, gfx::Rect bounds)
void Dock::DraggingFeedback::paint(Graphics* g, gfx::Rect bounds) const


gfx::Path path;
path.moveTo(bounds.center());
switch (m_hit.targetSide) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: switching on non-enum value without default case may not cover all cases [bugprone-switch-missing-default-case]

  switch (m_hit.targetSide) {
  ^

int handleSide = 0;
if (auto* dockable = dynamic_cast<Dockable*>(widget))
handleSide = dockable->dockHandleSide();
switch (handleSide) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: switching on non-enum value without default case may not cover all cases [bugprone-switch-missing-default-case]

                  switch (handleSide) {
                  ^

gfx::Rect dropBounds = target.bounds();
if (!dropBounds.isEmpty()) {
gfx::PointF diff(pos - dropBounds.center());
if (dropBounds.w / 2.0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: implicit conversion 'double' -> 'bool' [readability-implicit-bool-conversion]

Suggested change
if (dropBounds.w / 2.0)
if ((dropBounds.w / 2.0) != 0.0)

gfx::PointF diff(pos - dropBounds.center());
if (dropBounds.w / 2.0)
diff.x /= dropBounds.w / 2.0f;
if (dropBounds.h / 2.0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: implicit conversion 'double' -> 'bool' [readability-implicit-bool-conversion]

Suggested change
if (dropBounds.h / 2.0)
if ((dropBounds.h / 2.0) != 0.0)


// Drop the widget to a new dock
if (m_dragging && m_draggingFeedback) {
Hit target = m_draggingFeedback->hit();
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: variable 'target' of type 'Hit' can be declared 'const' [misc-const-correctness]

Suggested change
Hit target = m_draggingFeedback->hit();
Hit const target = m_draggingFeedback->hit();

@@ -94,13 +115,7 @@ class Dock : public ui::Widget {

bool hasVisibleSide(const int i) const { return (m_sides[i] && m_sides[i]->isVisible()); }
void redockWidget(app::Dock* widgetDock, ui::Widget* dockableWidget, const int side);
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: function 'app::Dock::redockWidget' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  void redockWidget(app::Dock* widgetDock, ui::Widget* dockableWidget, const int side);
       ^
Additional context

src/app/ui/dock.cpp:882: the definition seen here

void Dock::redockWidget(app::Dock* newDock, ui::Widget* dockableWidget, const int side)
           ^

src/app/ui/dock.h:116: differing parameters are named here: ('widgetDock'), in definition: ('newDock')

  void redockWidget(app::Dock* widgetDock, ui::Widget* dockableWidget, const int side);
       ^

}

void Widget::paint(Graphics* graphics, const gfx::Region& drawRegion, const bool isBg)
void Widget::paint(Graphics* graphics,
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: function 'paint' is within a recursive call chain [misc-no-recursion]

void Widget::paint(Graphics* graphics,
             ^
Additional context

src/ui/widget.cpp:1240: example recursive call chain, starting from function 'paintEvent'

bool Widget::paintEvent(Graphics* graphics, const bool isBg)
             ^

src/ui/widget.cpp:1286: Frame #1: function 'paintEvent' calls function 'paint' here:

      parentWidget->paint(&graphics2, rgn, true, kCutTopWindows);
      ^

src/ui/widget.cpp:1235: Frame #2: function 'paint' calls function 'paintEvent' here:

      widget->paintEvent(&graphics2, isBg);
      ^

src/ui/widget.cpp:1235: ... which was the starting point of the recursive call chain; there may be other cycles

      widget->paintEvent(&graphics2, isBg);
      ^

src/ui/widget.h Outdated
// in the same coordinates as the bounds() field.
void paint(Graphics* graphics,
const gfx::Region& drawRegion,
const bool isBg,
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: parameter 'isBg' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]

Suggested change
const bool isBg,
bool isBg,

src/ui/widget.h Outdated
void paint(Graphics* graphics,
const gfx::Region& drawRegion,
const bool isBg,
const DrawableRegionFlags flags);
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: parameter 'flags' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]

Suggested change
const DrawableRegionFlags flags);
DrawableRegionFlags flags);

This patch fixes an issue painting top windows (e.g. preview window)
on the floating dock. This was done painting the dock in the
UILayer. To do so Widget::paint()/paintEvent() required a fix handling
the coordinates of subgraphics correctly.

This feature is not yet complete, there are some bugs docking widgets
at the correct side of other widgets.
Copy link
Collaborator

@aseprite-bot aseprite-bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

case ui::BOTTOM: return kBottomIndex;
case ui::LEFT: return kLeftIndex;
case ui::RIGHT: return kRightIndex;
switch (sideFlag) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: switching on non-enum value without default case may not cover all cases [bugprone-switch-missing-default-case]

  switch (sideFlag) {
  ^

}

void Dock::dock(int side, ui::Widget* widget, const gfx::Size& prefSize)
void Dock::dock(const int sideFlag, ui::Widget* widget, const gfx::Size& prefSize)
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: function 'dock' is within a recursive call chain [misc-no-recursion]

void Dock::dock(const int sideFlag, ui::Widget* widget, const gfx::Size& prefSize)
           ^

}

const gfx::Size Dock::getUserDefinedSizeAtSide(int side) const
const gfx::Size Dock::getUserDefinedSizeAtSide(const int sideFlag) const
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: return type 'const gfx::Size' (aka 'const SizeT') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type]

src/app/ui/dock.h:55:

-   const gfx::Size getUserDefinedSizeAtSide(int sideFlag) const;
+   gfx::Size getUserDefinedSizeAtSide(int sideFlag) const;
Suggested change
const gfx::Size Dock::getUserDefinedSizeAtSide(const int sideFlag) const
gfx::Size Dock::getUserDefinedSizeAtSide(const int sideFlag) const

const gfx::Size Dock::getUserDefinedSizeAtSide(const int sideFlag) const
{
int i = side_index(side);
SideIndex i = side_index(sideFlag);
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: variable 'i' of type 'SideIndex' can be declared 'const' [misc-const-correctness]

Suggested change
SideIndex i = side_index(sideFlag);
SideIndex const i = side_index(sideFlag);

gfx::Point m_mouseOffset;
ui::UILayerRef m_floatingUILayer;
};
enum SideIndex { kTopIndex, kBottomIndex, kLeftIndex, kRightIndex, kCenterIndex, kSides };
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: enum 'SideIndex' uses a larger base type ('unsigned int', size: 4 bytes) than necessary for its value set, consider using 'std::uint8_t' (1 byte) as the base type to reduce its size [performance-enum-size]

  enum SideIndex { kTopIndex, kBottomIndex, kLeftIndex, kRightIndex, kCenterIndex, kSides };
       ^

Copy link
Collaborator

@aseprite-bot aseprite-bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

return ui::TOP | ui::BOTTOM | ui::LEFT | ui::RIGHT | ui::EXPANSIVE;
}

obs::signal<void()> Resize;
Copy link
Collaborator

Choose a reason for hiding this comment

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

warning: member variable 'Resize' has public visibility [misc-non-private-member-variables-in-classes]

  obs::signal<void()> Resize;
                      ^

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.

2 participants

X Tutup