Rename panel widget to Splitter class.

This commit is contained in:
David Capello 2012-04-05 19:39:09 -03:00
parent 390c0136ad
commit aa0555e662
10 changed files with 313 additions and 332 deletions

View File

@ -30,7 +30,6 @@ add_library(gui-lib
menu.cpp
message.cpp
paint_event.cpp
panel.cpp
popup_frame.cpp
preferred_size_event.cpp
property.cpp
@ -39,6 +38,7 @@ add_library(gui-lib
scroll_bar.cpp
separator.cpp
slider.cpp
splitter.cpp
stream.cpp
system.cpp
textbox.cpp

View File

@ -90,7 +90,7 @@ enum {
JI_MENUBAR,
JI_MENUBOX,
JI_MENUITEM,
JI_PANEL,
JI_SPLITTER,
JI_RADIO,
JI_SEPARATOR,
JI_SLIDER,

View File

@ -34,7 +34,6 @@
#include "gui/menu.h"
#include "gui/message.h"
#include "gui/paint_event.h"
#include "gui/panel.h"
#include "gui/popup_frame.h"
#include "gui/preferred_size_event.h"
#include "gui/property.h"
@ -43,6 +42,7 @@
#include "gui/scroll_bar.h"
#include "gui/separator.h"
#include "gui/slider.h"
#include "gui/splitter.h"
#include "gui/stream.h"
#include "gui/system.h"
#include "gui/textbox.h"

View File

@ -1,300 +0,0 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#include "config.h"
#include "gfx/size.h"
#include "gui/list.h"
#include "gui/message.h"
#include "gui/rect.h"
#include "gui/system.h"
#include "gui/theme.h"
#include "gui/widget.h"
using namespace gfx;
struct Panel
{
double pos;
};
static bool panel_msg_proc(JWidget widget, Message* msg);
static void panel_request_size(JWidget widget, int *w, int *h);
static void panel_set_position(JWidget widget, JRect rect);
JWidget jpanel_new(int align)
{
Widget* widget = new Widget(JI_PANEL);
Panel *panel = new Panel;
jwidget_add_hook(widget, JI_PANEL, panel_msg_proc, panel);
widget->setAlign(align);
panel->pos = 50;
widget->initTheme();
return widget;
}
double jpanel_get_pos(JWidget widget)
{
Panel* panel = reinterpret_cast<Panel*>(jwidget_get_data(widget, JI_PANEL));
return panel->pos;
}
void jpanel_set_pos(JWidget widget, double pos)
{
Panel* panel = reinterpret_cast<Panel*>(jwidget_get_data(widget, JI_PANEL));
panel->pos = MID(0, pos, 100);
widget->invalidate();
}
static bool panel_msg_proc(JWidget widget, Message* msg)
{
switch (msg->type) {
case JM_DESTROY:
{
Panel* panel = reinterpret_cast<Panel*>(jwidget_get_data(widget, JI_PANEL));
delete panel;
}
break;
case JM_REQSIZE:
panel_request_size(widget, &msg->reqsize.w, &msg->reqsize.h);
return true;
case JM_SETPOS:
panel_set_position(widget, &msg->setpos.rect);
return true;
case JM_DRAW:
widget->getTheme()->draw_panel(widget, &msg->draw.rect);
return true;
case JM_BUTTONPRESSED:
if (widget->isEnabled()) {
JWidget c1, c2;
int x1, y1, x2, y2;
int bar, click_bar;
JLink link;
bar = click_bar = 0;
JI_LIST_FOR_EACH(widget->children, link) {
if (link->next != widget->children->end) {
c1 = reinterpret_cast<JWidget>(link->data);
c2 = reinterpret_cast<JWidget>(link->next->data);
++bar;
if (widget->getAlign() & JI_HORIZONTAL) {
x1 = c1->rc->x2;
y1 = widget->rc->y1;
x2 = c2->rc->x1;
y2 = widget->rc->y2;
}
else {
x1 = widget->rc->x1;
y1 = c1->rc->y2;
x2 = widget->rc->x2;
y2 = c2->rc->y1;
}
if ((msg->mouse.x >= x1) && (msg->mouse.x < x2) &&
(msg->mouse.y >= y1) && (msg->mouse.y < y2))
click_bar = bar;
}
}
if (!click_bar)
break;
widget->captureMouse();
/* Continue with motion message... */
}
else
break;
case JM_MOTION:
if (widget->hasCapture()) {
Panel* panel = reinterpret_cast<Panel*>(jwidget_get_data(widget, JI_PANEL));
if (widget->getAlign() & JI_HORIZONTAL) {
panel->pos =
100.0 * (msg->mouse.x-widget->rc->x1) / jrect_w(widget->rc);
}
else {
panel->pos =
100.0 * (msg->mouse.y-widget->rc->y1) / jrect_h(widget->rc);
}
panel->pos = MID(0, panel->pos, 100);
jwidget_set_rect(widget, widget->rc);
widget->invalidate();
return true;
}
break;
case JM_BUTTONRELEASED:
if (widget->hasCapture()) {
widget->releaseMouse();
return true;
}
break;
case JM_SETCURSOR:
if (widget->isEnabled()) {
JWidget c1, c2;
JLink link;
int x1, y1, x2, y2;
bool change_cursor = false;
JI_LIST_FOR_EACH(widget->children, link) {
if (link->next != widget->children->end) {
c1 = reinterpret_cast<JWidget>(link->data);
c2 = reinterpret_cast<JWidget>(link->next->data);
if (widget->getAlign() & JI_HORIZONTAL) {
x1 = c1->rc->x2;
y1 = widget->rc->y1;
x2 = c2->rc->x1;
y2 = widget->rc->y2;
}
else {
x1 = widget->rc->x1;
y1 = c1->rc->y2;
x2 = widget->rc->x2;
y2 = c2->rc->y1;
}
if ((msg->mouse.x >= x1) && (msg->mouse.x < x2) &&
(msg->mouse.y >= y1) && (msg->mouse.y < y2)) {
change_cursor = true;
break;
}
}
}
if (change_cursor) {
if (widget->getAlign() & JI_HORIZONTAL)
jmouse_set_cursor(JI_CURSOR_SIZE_L);
else
jmouse_set_cursor(JI_CURSOR_SIZE_T);
return true;
}
else
return false;
}
break;
}
return false;
}
static void panel_request_size(JWidget widget, int *w, int *h)
{
#define GET_CHILD_SIZE(w, h) \
do { \
*w = MAX(*w, reqSize.w); \
*h = MAX(*h, reqSize.h); \
} while(0)
#define FINAL_SIZE(w) \
do { \
*w *= nvis_children; \
*w += widget->child_spacing * (nvis_children-1); \
} while(0)
int nvis_children;
Size reqSize;
JWidget child;
JLink link;
nvis_children = 0;
JI_LIST_FOR_EACH(widget->children, link) {
child = (JWidget)link->data;
if (!(child->flags & JI_HIDDEN))
nvis_children++;
}
*w = *h = 0;
JI_LIST_FOR_EACH(widget->children, link) {
child = (JWidget)link->data;
if (child->flags & JI_HIDDEN)
continue;
reqSize = child->getPreferredSize();
if (widget->getAlign() & JI_HORIZONTAL)
GET_CHILD_SIZE(w, h);
else
GET_CHILD_SIZE(h, w);
}
if (nvis_children > 0) {
if (widget->getAlign() & JI_HORIZONTAL)
FINAL_SIZE(w);
else
FINAL_SIZE(h);
}
*w += widget->border_width.l + widget->border_width.r;
*h += widget->border_width.t + widget->border_width.b;
}
static void panel_set_position(JWidget widget, JRect rect)
{
#define FIXUP(x, y, w, h, l, t, r, b) \
do { \
avail = jrect_##w(widget->rc) - widget->child_spacing; \
\
pos->x##1 = widget->rc->x##1; \
pos->y##1 = widget->rc->y##1; \
pos->x##2 = pos->x##1 + avail*panel->pos/100; \
/* TODO uncomment this to make a restricted panel */ \
/* pos->w = MID(reqSize1.w, pos->w, avail-reqSize2.w); */ \
pos->y##2 = pos->y##1 + jrect_##h(widget->rc); \
\
jwidget_set_rect(child1, pos); \
\
pos->x##1 = child1->rc->x##1 + jrect_##w(child1->rc) \
+ widget->child_spacing; \
pos->y##1 = widget->rc->y##1; \
pos->x##2 = pos->x##1 + avail - jrect_##w(child1->rc); \
pos->y##2 = pos->y##1 + jrect_##h(widget->rc); \
\
jwidget_set_rect(child2, pos); \
} while(0)
JRect pos = jrect_new(0, 0, 0, 0);
Panel* panel = reinterpret_cast<Panel*>(jwidget_get_data(widget, JI_PANEL));
int avail;
jrect_copy(widget->rc, rect);
if (jlist_length(widget->children) == 2) {
JWidget child1 = reinterpret_cast<JWidget>(jlist_first(widget->children)->data);
JWidget child2 = reinterpret_cast<JWidget>(jlist_first(widget->children)->next->data);
//Size reqSize1 = child1->getPreferredSize();
//Size reqSize2 = child2->getPreferredSize();
if (widget->getAlign() & JI_HORIZONTAL)
FIXUP(x, y, w, h, l, t, r, b);
else
FIXUP(y, x, h, w, t, l, b, r);
}
jrect_free(pos);
}

View File

@ -1,17 +0,0 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef GUI_PANEL_H_INCLUDED
#define GUI_PANEL_H_INCLUDED
#include "gui/base.h"
JWidget jpanel_new(int align);
double jpanel_get_pos(JWidget panel);
void jpanel_set_pos(JWidget panel, double pos);
#endif

266
src/gui/splitter.cpp Normal file
View File

@ -0,0 +1,266 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#include "config.h"
#include "gui/splitter.h"
#include "gui/list.h"
#include "gui/message.h"
#include "gui/preferred_size_event.h"
#include "gui/system.h"
#include "gui/theme.h"
using namespace gfx;
Splitter::Splitter(int align)
: Widget(JI_SPLITTER)
, m_pos(50)
{
setAlign(align);
initTheme();
}
double Splitter::getPosition() const
{
return m_pos;
}
void Splitter::setPosition(double pos)
{
m_pos = MID(0, pos, 100);
invalidate();
}
bool Splitter::onProcessMessage(Message* msg)
{
switch (msg->type) {
case JM_SETPOS:
layoutMembers(&msg->setpos.rect);
return true;
case JM_DRAW:
getTheme()->draw_panel(this, &msg->draw.rect);
return true;
case JM_BUTTONPRESSED:
if (isEnabled()) {
JWidget c1, c2;
int x1, y1, x2, y2;
int bar, click_bar;
JLink link;
bar = click_bar = 0;
JI_LIST_FOR_EACH(this->children, link) {
if (link->next != this->children->end) {
c1 = reinterpret_cast<JWidget>(link->data);
c2 = reinterpret_cast<JWidget>(link->next->data);
++bar;
if (this->getAlign() & JI_HORIZONTAL) {
x1 = c1->rc->x2;
y1 = this->rc->y1;
x2 = c2->rc->x1;
y2 = this->rc->y2;
}
else {
x1 = this->rc->x1;
y1 = c1->rc->y2;
x2 = this->rc->x2;
y2 = c2->rc->y1;
}
if ((msg->mouse.x >= x1) && (msg->mouse.x < x2) &&
(msg->mouse.y >= y1) && (msg->mouse.y < y2))
click_bar = bar;
}
}
if (!click_bar)
break;
this->captureMouse();
/* Continue with motion message... */
}
else
break;
case JM_MOTION:
if (this->hasCapture()) {
if (this->getAlign() & JI_HORIZONTAL) {
m_pos = 100.0 * (msg->mouse.x-this->rc->x1) / jrect_w(this->rc);
}
else {
m_pos = 100.0 * (msg->mouse.y-this->rc->y1) / jrect_h(this->rc);
}
m_pos = MID(0, m_pos, 100);
jwidget_set_rect(this, this->rc);
invalidate();
return true;
}
break;
case JM_BUTTONRELEASED:
if (hasCapture()) {
releaseMouse();
return true;
}
break;
case JM_SETCURSOR:
if (isEnabled()) {
JWidget c1, c2;
JLink link;
int x1, y1, x2, y2;
bool change_cursor = false;
JI_LIST_FOR_EACH(this->children, link) {
if (link->next != this->children->end) {
c1 = reinterpret_cast<JWidget>(link->data);
c2 = reinterpret_cast<JWidget>(link->next->data);
if (this->getAlign() & JI_HORIZONTAL) {
x1 = c1->rc->x2;
y1 = this->rc->y1;
x2 = c2->rc->x1;
y2 = this->rc->y2;
}
else {
x1 = this->rc->x1;
y1 = c1->rc->y2;
x2 = this->rc->x2;
y2 = c2->rc->y1;
}
if ((msg->mouse.x >= x1) && (msg->mouse.x < x2) &&
(msg->mouse.y >= y1) && (msg->mouse.y < y2)) {
change_cursor = true;
break;
}
}
}
if (change_cursor) {
if (this->getAlign() & JI_HORIZONTAL)
jmouse_set_cursor(JI_CURSOR_SIZE_L);
else
jmouse_set_cursor(JI_CURSOR_SIZE_T);
return true;
}
else
return false;
}
break;
}
return Widget::onProcessMessage(msg);
}
void Splitter::onPreferredSize(PreferredSizeEvent& ev)
{
#define GET_CHILD_SIZE(w, h) \
do { \
w = MAX(w, reqSize.w); \
h = MAX(h, reqSize.h); \
} while(0)
#define FINAL_SIZE(w) \
do { \
w *= visibleChildren; \
w += this->child_spacing * (visibleChildren-1); \
} while(0)
int visibleChildren;
Size reqSize;
JWidget child;
JLink link;
visibleChildren = 0;
JI_LIST_FOR_EACH(this->children, link) {
child = (JWidget)link->data;
if (!(child->flags & JI_HIDDEN))
visibleChildren++;
}
int w, h;
w = h = 0;
JI_LIST_FOR_EACH(this->children, link) {
child = (JWidget)link->data;
if (child->flags & JI_HIDDEN)
continue;
reqSize = child->getPreferredSize();
if (this->getAlign() & JI_HORIZONTAL)
GET_CHILD_SIZE(w, h);
else
GET_CHILD_SIZE(h, w);
}
if (visibleChildren > 0) {
if (this->getAlign() & JI_HORIZONTAL)
FINAL_SIZE(w);
else
FINAL_SIZE(h);
}
w += this->border_width.l + this->border_width.r;
h += this->border_width.t + this->border_width.b;
ev.setPreferredSize(Size(w, h));
}
void Splitter::layoutMembers(JRect rect)
{
#define FIXUP(x, y, w, h, l, t, r, b) \
do { \
avail = jrect_##w(this->rc) - this->child_spacing; \
\
pos->x##1 = this->rc->x##1; \
pos->y##1 = this->rc->y##1; \
pos->x##2 = pos->x##1 + avail*m_pos/100; \
/* TODO uncomment this to make a restricted panel */ \
/* pos->w = MID(reqSize1.w, pos->w, avail-reqSize2.w); */ \
pos->y##2 = pos->y##1 + jrect_##h(this->rc); \
\
jwidget_set_rect(child1, pos); \
\
pos->x##1 = child1->rc->x##1 + jrect_##w(child1->rc) \
+ this->child_spacing; \
pos->y##1 = this->rc->y##1; \
pos->x##2 = pos->x##1 + avail - jrect_##w(child1->rc); \
pos->y##2 = pos->y##1 + jrect_##h(this->rc); \
\
jwidget_set_rect(child2, pos); \
} while(0)
JRect pos = jrect_new(0, 0, 0, 0);
int avail;
jrect_copy(this->rc, rect);
if (jlist_length(this->children) == 2) {
JWidget child1 = reinterpret_cast<JWidget>(jlist_first(this->children)->data);
JWidget child2 = reinterpret_cast<JWidget>(jlist_first(this->children)->next->data);
//Size reqSize1 = child1->getPreferredSize();
//Size reqSize2 = child2->getPreferredSize();
if (this->getAlign() & JI_HORIZONTAL)
FIXUP(x, y, w, h, l, t, r, b);
else
FIXUP(y, x, h, w, t, l, b, r);
}
jrect_free(pos);
}

32
src/gui/splitter.h Normal file
View File

@ -0,0 +1,32 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef GUI_SPLITTER_H_INCLUDED
#define GUI_SPLITTER_H_INCLUDED
#include "base/compiler_specific.h"
#include "gui/widget.h"
class Splitter : public Widget
{
public:
Splitter(int align);
double getPosition() const;
void setPosition(double pos);
protected:
// Events
bool onProcessMessage(Message* msg) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
private:
void layoutMembers(JRect rect);
double m_pos;
};
#endif

View File

@ -407,15 +407,15 @@ void split_editor(Editor* editor, int align)
}
View* view = View::getView(editor);
JWidget parent_box = view->getParent(); // Box or panel.
JWidget parent_box = view->getParent(); // Box or splitter.
// Create a new box to contain both editors, and a new view to put the new editor.
JWidget new_panel = jpanel_new(align);
JWidget new_splitter = new Splitter(align);
View* new_view = new EditorView(EditorView::CurrentEditorMode);
Editor* new_editor = create_new_editor();
// Insert the "new_box" in the same location that the view.
parent_box->replaceChild(view, new_panel);
parent_box->replaceChild(view, new_splitter);
// Append the new editor.
new_view->attachToView(new_editor);
@ -425,12 +425,12 @@ void split_editor(Editor* editor, int align)
new_editor->setZoom(editor->getZoom());
// Expansive widgets.
new_panel->setExpansive(true);
new_splitter->setExpansive(true);
new_view->setExpansive(true);
// Append both views to the "new_panel".
new_panel->addChild(view);
new_panel->addChild(new_view);
// Append both views to the "new_splitter".
new_splitter->addChild(view);
new_splitter->addChild(new_view);
// Same position.
{

View File

@ -570,7 +570,7 @@ void SkinTheme::init_widget(JWidget widget)
widget->child_spacing = 18 * scale;
break;
case JI_PANEL:
case JI_SPLITTER:
BORDER(0);
widget->child_spacing = 3 * scale;
break;

View File

@ -239,13 +239,13 @@ static Widget* convert_xmlelement_to_widget(TiXmlElement* elem, Widget* root)
widget = jlistitem_new(text ? TRANSLATE_ATTR(text): NULL);
}
/* panel */
else if (ustrcmp(elem_name, "panel") == 0) {
/* splitter */
else if (ustrcmp(elem_name, "splitter") == 0) {
bool horizontal = bool_attr_is_true(elem, "horizontal");
bool vertical = bool_attr_is_true(elem, "vertical");
widget = jpanel_new(horizontal ? JI_HORIZONTAL:
vertical ? JI_VERTICAL: 0);
widget = new Splitter(horizontal ? JI_HORIZONTAL:
vertical ? JI_VERTICAL: 0);
}
/* radio */
else if (ustrcmp(elem_name, "radio") == 0) {