2013-08-09 08:01:20 +08:00
|
|
|
// Aseprite UI Library
|
2022-06-10 05:28:06 +08:00
|
|
|
// Copyright (C) 2018-2022 Igara Studio S.A.
|
2017-03-10 02:12:39 +08:00
|
|
|
// Copyright (C) 2001-2017 David Capello
|
2010-09-28 06:18:17 +08:00
|
|
|
//
|
2014-03-30 07:08:05 +08:00
|
|
|
// This file is released under the terms of the MIT license.
|
|
|
|
// Read LICENSE.txt for more information.
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2009-07-13 04:29:16 +08:00
|
|
|
#include "config.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#endif
|
2009-07-13 04:29:16 +08:00
|
|
|
|
2011-01-22 04:50:04 +08:00
|
|
|
#include "gfx/size.h"
|
2012-06-18 09:49:58 +08:00
|
|
|
#include "ui/box.h"
|
|
|
|
#include "ui/message.h"
|
2013-05-12 04:56:27 +08:00
|
|
|
#include "ui/resize_event.h"
|
2019-12-21 02:08:34 +08:00
|
|
|
#include "ui/size_hint_event.h"
|
2012-06-18 09:49:58 +08:00
|
|
|
#include "ui/theme.h"
|
2010-09-26 03:22:32 +08:00
|
|
|
|
2019-12-21 02:08:34 +08:00
|
|
|
#include <algorithm>
|
|
|
|
|
2012-06-18 09:02:54 +08:00
|
|
|
namespace ui {
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
using namespace gfx;
|
|
|
|
|
2013-04-04 09:07:24 +08:00
|
|
|
Box::Box(int align) : Widget(kBoxWidget)
|
2007-09-19 07:57:02 +08:00
|
|
|
{
|
2018-12-13 21:48:12 +08:00
|
|
|
enableFlags(IGNORE_MOUSE);
|
2011-01-25 06:48:09 +08:00
|
|
|
setAlign(align);
|
2011-02-15 20:00:29 +08:00
|
|
|
initTheme();
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
|
2015-12-04 08:50:05 +08:00
|
|
|
void Box::onSizeHint(SizeHintEvent& ev)
|
2007-09-19 07:57:02 +08:00
|
|
|
{
|
2019-12-21 02:08:34 +08:00
|
|
|
#define ADD_CHILD_SIZE(w, h) \
|
|
|
|
{ \
|
|
|
|
if (align() & HOMOGENEOUS) \
|
|
|
|
prefSize.w = std::max(prefSize.w, childSize.w); \
|
|
|
|
else \
|
|
|
|
prefSize.w += childSize.w; \
|
|
|
|
prefSize.h = std::max(prefSize.h, childSize.h); \
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
|
2015-06-24 09:46:05 +08:00
|
|
|
#define FINAL_ADJUSTMENT(w) \
|
|
|
|
{ \
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
if (align() & HOMOGENEOUS) \
|
2015-06-24 09:46:05 +08:00
|
|
|
prefSize.w *= visibleChildren; \
|
|
|
|
prefSize.w += childSpacing() * (visibleChildren - 1); \
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
|
2015-06-24 09:46:05 +08:00
|
|
|
int visibleChildren = 0;
|
2015-12-04 06:46:13 +08:00
|
|
|
for (auto child : children()) {
|
2015-06-24 03:07:41 +08:00
|
|
|
if (!child->hasFlags(HIDDEN))
|
2015-06-24 09:46:05 +08:00
|
|
|
++visibleChildren;
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-06-24 09:46:05 +08:00
|
|
|
Size prefSize(0, 0);
|
2015-12-04 06:46:13 +08:00
|
|
|
for (auto child : children()) {
|
2015-06-24 03:07:41 +08:00
|
|
|
if (child->hasFlags(HIDDEN))
|
2007-09-19 07:57:02 +08:00
|
|
|
continue;
|
|
|
|
|
2015-12-04 08:50:05 +08:00
|
|
|
Size childSize = child->sizeHint();
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
if (align() & HORIZONTAL) {
|
2015-06-24 09:46:05 +08:00
|
|
|
ADD_CHILD_SIZE(w, h);
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
else {
|
2015-06-24 09:46:05 +08:00
|
|
|
ADD_CHILD_SIZE(h, w);
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-24 09:46:05 +08:00
|
|
|
if (visibleChildren > 0) {
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
if (align() & HORIZONTAL) {
|
2015-06-24 09:46:05 +08:00
|
|
|
FINAL_ADJUSTMENT(w);
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
else {
|
2015-06-24 09:46:05 +08:00
|
|
|
FINAL_ADJUSTMENT(h);
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-24 09:46:05 +08:00
|
|
|
prefSize.w += border().width();
|
|
|
|
prefSize.h += border().height();
|
2011-01-25 06:48:09 +08:00
|
|
|
|
2015-12-04 08:50:05 +08:00
|
|
|
ev.setSizeHint(prefSize);
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
|
2013-05-12 04:56:27 +08:00
|
|
|
void Box::onResize(ResizeEvent& ev)
|
2007-09-19 07:57:02 +08:00
|
|
|
{
|
2016-09-10 07:21:33 +08:00
|
|
|
#define LAYOUT_CHILDREN(x, y, w, h) \
|
|
|
|
{ \
|
2015-06-24 09:46:05 +08:00
|
|
|
availExtraSize = availSize.w - prefSize.w; \
|
|
|
|
availSize.w -= childSpacing() * (visibleChildren - 1); \
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
if (align() & HOMOGENEOUS) \
|
2015-06-24 09:46:05 +08:00
|
|
|
homogeneousSize = availSize.w / visibleChildren; \
|
2012-01-06 06:45:03 +08:00
|
|
|
\
|
2016-09-10 07:21:33 +08:00
|
|
|
Rect defChildPos(childrenBounds()); \
|
2015-06-24 09:46:05 +08:00
|
|
|
int i = 0, j = 0; \
|
2015-12-04 06:46:13 +08:00
|
|
|
for (auto child : children()) { \
|
2015-06-24 09:46:05 +08:00
|
|
|
if (child->hasFlags(HIDDEN)) \
|
|
|
|
continue; \
|
2012-01-06 06:45:03 +08:00
|
|
|
\
|
2015-06-24 09:46:05 +08:00
|
|
|
int size = 0; \
|
2012-01-06 06:45:03 +08:00
|
|
|
\
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
if (align() & HOMOGENEOUS) { \
|
2015-06-24 09:46:05 +08:00
|
|
|
if (i < visibleChildren - 1) \
|
|
|
|
size = homogeneousSize; \
|
|
|
|
else \
|
|
|
|
size = availSize.w; \
|
|
|
|
} \
|
|
|
|
else { \
|
2015-12-04 08:50:05 +08:00
|
|
|
size = child->sizeHint().w; \
|
2012-01-06 06:45:03 +08:00
|
|
|
\
|
2015-06-24 09:46:05 +08:00
|
|
|
if (child->isExpansive()) { \
|
|
|
|
int extraSize = (availExtraSize / (expansiveChildren - j)); \
|
|
|
|
size += extraSize; \
|
|
|
|
availExtraSize -= extraSize; \
|
|
|
|
if (++j == expansiveChildren) \
|
|
|
|
size += availExtraSize; \
|
2012-01-06 06:45:03 +08:00
|
|
|
} \
|
|
|
|
} \
|
2015-06-24 09:46:05 +08:00
|
|
|
\
|
2016-09-10 07:21:33 +08:00
|
|
|
Rect childPos = defChildPos; \
|
2022-06-10 05:28:06 +08:00
|
|
|
childPos.w = size = std::clamp(size, child->minSize().w, child->maxSize().w); \
|
|
|
|
childPos.h = std::clamp(childPos.h, child->minSize().h, child->maxSize().h); \
|
2015-06-24 09:46:05 +08:00
|
|
|
child->setBounds(childPos); \
|
2016-09-10 07:21:33 +08:00
|
|
|
\
|
|
|
|
defChildPos.x += size + childSpacing(); \
|
2015-06-24 09:46:05 +08:00
|
|
|
availSize.w -= size; \
|
|
|
|
++i; \
|
2012-01-06 06:45:03 +08:00
|
|
|
} \
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
setBoundsQuietly(ev.bounds());
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2015-06-24 09:46:05 +08:00
|
|
|
int visibleChildren = 0;
|
|
|
|
int expansiveChildren = 0;
|
2015-12-04 06:46:13 +08:00
|
|
|
for (auto child : children()) {
|
2015-06-24 03:07:41 +08:00
|
|
|
if (!child->hasFlags(HIDDEN)) {
|
2015-06-24 09:46:05 +08:00
|
|
|
++visibleChildren;
|
2012-04-06 06:00:19 +08:00
|
|
|
if (child->isExpansive())
|
2015-06-24 09:46:05 +08:00
|
|
|
++expansiveChildren;
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-24 09:46:05 +08:00
|
|
|
if (visibleChildren > 0) {
|
2015-12-04 08:50:05 +08:00
|
|
|
Size prefSize(sizeHint());
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
Size availSize(childrenBounds().size());
|
2015-06-24 09:46:05 +08:00
|
|
|
int homogeneousSize = 0;
|
|
|
|
int availExtraSize = 0;
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2015-06-24 09:46:05 +08:00
|
|
|
prefSize.w -= border().width();
|
|
|
|
prefSize.h -= border().height();
|
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
if (align() & HORIZONTAL) {
|
2016-09-10 07:21:33 +08:00
|
|
|
LAYOUT_CHILDREN(x, y, w, h);
|
2015-06-24 09:46:05 +08:00
|
|
|
}
|
|
|
|
else {
|
2016-09-10 07:21:33 +08:00
|
|
|
LAYOUT_CHILDREN(y, x, h, w);
|
2015-06-24 09:46:05 +08:00
|
|
|
}
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
}
|
2012-06-18 09:02:54 +08:00
|
|
|
|
|
|
|
} // namespace ui
|