aseprite/src/gui/box.cpp

216 lines
8.0 KiB
C++
Raw Normal View History

// ASEPRITE gui library
2012-01-06 03:52:11 +00:00
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
2007-09-18 23:57:02 +00:00
/* Based on code from GTK+ 2.1.2 (gtk+/gtk/gtkhbox.c) */
2009-07-12 20:29:16 +00:00
#include "config.h"
#include "gfx/size.h"
2011-01-24 22:48:09 +00:00
#include "gui/box.h"
#include "gui/list.h"
#include "gui/message.h"
#include "gui/rect.h"
2011-01-24 22:48:09 +00:00
#include "gui/preferred_size_event.h"
#include "gui/theme.h"
using namespace gfx;
2007-09-18 23:57:02 +00:00
static bool box_msg_proc(JWidget widget, Message* msg);
2007-09-18 23:57:02 +00:00
static void box_request_size(JWidget widget, int *w, int *h);
static void box_set_position(JWidget widget, JRect rect);
2011-01-24 22:48:09 +00:00
Box::Box(int align)
: Widget(JI_BOX)
2007-09-18 23:57:02 +00:00
{
2011-01-24 22:48:09 +00:00
setAlign(align);
initTheme();
2007-09-18 23:57:02 +00:00
}
bool Box::onProcessMessage(Message* msg)
2007-09-18 23:57:02 +00:00
{
switch (msg->type) {
2007-09-18 23:57:02 +00:00
case JM_SETPOS:
2011-01-24 22:48:09 +00:00
box_set_position(&msg->setpos.rect);
return true;
2007-09-18 23:57:02 +00:00
}
2011-01-24 22:48:09 +00:00
return Widget::onProcessMessage(msg);
2007-09-18 23:57:02 +00:00
}
2011-01-24 22:48:09 +00:00
void Box::onPreferredSize(PreferredSizeEvent& ev)
2007-09-18 23:57:02 +00:00
{
#define GET_CHILD_SIZE(w, h) \
{ \
if (getAlign() & JI_HOMOGENEOUS) \
w = MAX(w, reqSize.w); \
else \
w += reqSize.w; \
\
h = MAX(h, reqSize.h); \
2007-09-18 23:57:02 +00:00
}
#define FINAL_SIZE(w) \
{ \
if (getAlign() & JI_HOMOGENEOUS) \
w *= nvis_children; \
\
w += child_spacing * (nvis_children-1); \
2007-09-18 23:57:02 +00:00
}
2011-01-24 22:48:09 +00:00
int w, h, nvis_children;
2007-09-18 23:57:02 +00:00
JWidget child;
JLink link;
nvis_children = 0;
2011-01-24 22:48:09 +00:00
JI_LIST_FOR_EACH(this->children, link) {
2007-09-18 23:57:02 +00:00
child = (JWidget)link->data;
if (!(child->flags & JI_HIDDEN))
2007-09-18 23:57:02 +00:00
nvis_children++;
}
2011-01-24 22:48:09 +00:00
w = h = 0;
2007-09-18 23:57:02 +00:00
2011-01-24 22:48:09 +00:00
JI_LIST_FOR_EACH(this->children, link) {
2007-09-18 23:57:02 +00:00
child = (JWidget)link->data;
if (child->flags & JI_HIDDEN)
2007-09-18 23:57:02 +00:00
continue;
Size reqSize = child->getPreferredSize();
2007-09-18 23:57:02 +00:00
2011-01-24 22:48:09 +00:00
if (this->getAlign() & JI_HORIZONTAL) {
2007-09-18 23:57:02 +00:00
GET_CHILD_SIZE(w, h);
}
else {
GET_CHILD_SIZE(h, w);
}
}
if (nvis_children > 0) {
2011-01-24 22:48:09 +00:00
if (this->getAlign() & JI_HORIZONTAL) {
2007-09-18 23:57:02 +00:00
FINAL_SIZE(w);
}
else {
FINAL_SIZE(h);
}
}
2011-01-24 22:48:09 +00:00
w += border_width.l + border_width.r;
h += border_width.t + border_width.b;
ev.setPreferredSize(Size(w, h));
2007-09-18 23:57:02 +00:00
}
void Box::onPaint(PaintEvent& ev)
{
getTheme()->paintBox(ev);
}
2011-01-24 22:48:09 +00:00
void Box::box_set_position(JRect rect)
2007-09-18 23:57:02 +00:00
{
#define FIXUP(x, y, w, h, l, t, r, b) \
{ \
if (nvis_children > 0) { \
if (getAlign() & JI_HOMOGENEOUS) { \
width = (jrect_##w(this->rc) \
- this->border_width.l \
- this->border_width.r \
- this->child_spacing * (nvis_children - 1)); \
extra = width / nvis_children; \
} \
else if (nexpand_children > 0) { \
width = jrect_##w(this->rc) - reqSize.w; \
extra = width / nexpand_children; \
} \
else { \
width = 0; \
extra = 0; \
} \
\
x = this->rc->x##1 + this->border_width.l; \
y = this->rc->y##1 + this->border_width.t; \
h = MAX(1, jrect_##h(this->rc) \
- this->border_width.t \
- this->border_width.b); \
\
JI_LIST_FOR_EACH(this->children, link) { \
child = (JWidget)link->data; \
\
if (!(child->flags & JI_HIDDEN)) { \
if (this->getAlign() & JI_HOMOGENEOUS) { \
if (nvis_children == 1) \
child_width = width; \
else \
child_width = extra; \
\
--nvis_children; \
width -= extra; \
} \
else { \
reqSize = child->getPreferredSize(); \
\
child_width = reqSize.w; \
\
if (jwidget_is_expansive(child)) { \
if (nexpand_children == 1) \
child_width += width; \
else \
child_width += extra; \
\
--nexpand_children; \
width -= extra; \
} \
} \
\
w = MAX(1, child_width); \
\
if (this->getAlign() & JI_HORIZONTAL) \
jrect_replace(&cpos, x, y, x+w, y+h); \
else \
jrect_replace(&cpos, y, x, y+h, x+w); \
\
jwidget_set_rect(child, &cpos); \
\
x += child_width + this->child_spacing; \
} \
} \
} \
2007-09-18 23:57:02 +00:00
}
struct jrect cpos;
2011-01-24 22:48:09 +00:00
Widget* child;
2007-09-18 23:57:02 +00:00
int nvis_children = 0;
int nexpand_children = 0;
int child_width;
JLink link;
int width;
int extra;
int x, y, w, h;
2011-01-24 22:48:09 +00:00
jrect_copy(this->rc, rect);
2007-09-18 23:57:02 +00:00
2011-01-24 22:48:09 +00:00
JI_LIST_FOR_EACH(this->children, link) {
2007-09-18 23:57:02 +00:00
child = (JWidget)link->data;
if (!(child->flags & JI_HIDDEN)) {
2007-09-18 23:57:02 +00:00
nvis_children++;
if (jwidget_is_expansive(child))
nexpand_children++;
2007-09-18 23:57:02 +00:00
}
}
2011-01-24 22:48:09 +00:00
Size reqSize = this->getPreferredSize();
2007-09-18 23:57:02 +00:00
2011-01-24 22:48:09 +00:00
if (this->getAlign() & JI_HORIZONTAL) {
2007-09-18 23:57:02 +00:00
FIXUP(x, y, w, h, l, t, r, b);
}
else {
FIXUP(y, x, h, w, t, l, b, r);
}
}