Remove jwidget_get_rect() and jwidget_get_child_rect() functions

+ Added Widget::getClientChildrenBounds()
+ Replaced all member functions in Theme::draw_x() to Theme::paintX()
+ Move code to draw tabs from Tabs::onProcessMessage() to Tabs::onPaint().
This commit is contained in:
David Capello 2013-05-20 20:40:18 -03:00
parent 01dfe4d52e
commit e90f86727b
26 changed files with 406 additions and 454 deletions

View File

@ -69,6 +69,10 @@ protected:
closeWindow(); closeWindow();
} }
void onPaint(PaintEvent& ev) OVERRIDE {
static_cast<SkinTheme*>(getTheme())->paintWindowButton(ev);
}
bool onProcessMessage(Message* msg) OVERRIDE { bool onProcessMessage(Message* msg) OVERRIDE {
switch (msg->type) { switch (msg->type) {
@ -76,10 +80,6 @@ protected:
jmouse_set_cursor(kArrowCursor); jmouse_set_cursor(kArrowCursor);
return true; return true;
case kPaintMessage:
static_cast<SkinTheme*>(getTheme())->drawWindowButton(this, &msg->draw.rect);
return true;
case kKeyDownMessage: case kKeyDownMessage:
if (msg->key.scancode == KEY_ESC) { if (msg->key.scancode == KEY_ESC) {
setSelected(true); setSelected(true);
@ -834,13 +834,12 @@ void SkinTheme::paintBox(PaintEvent& ev)
void SkinTheme::paintButton(PaintEvent& ev) void SkinTheme::paintButton(PaintEvent& ev)
{ {
Graphics* g = ev.getGraphics();
ButtonBase* widget = static_cast<ButtonBase*>(ev.getSource()); ButtonBase* widget = static_cast<ButtonBase*>(ev.getSource());
IButtonIcon* iconInterface = widget->getIconInterface(); IButtonIcon* iconInterface = widget->getIconInterface();
struct jrect box, text, icon; struct jrect box, text, icon;
int x1, y1, x2, y2;
ui::Color fg, bg; ui::Color fg, bg;
int part_nw; int part_nw;
JRect crect;
jwidget_get_texticon_info(widget, &box, &text, &icon, jwidget_get_texticon_info(widget, &box, &text, &icon,
iconInterface ? iconInterface->getIconAlign(): 0, iconInterface ? iconInterface->getIconAlign(): 0,
@ -888,22 +887,15 @@ void SkinTheme::paintButton(PaintEvent& ev)
PART_BUTTON_NORMAL_NW); PART_BUTTON_NORMAL_NW);
} }
// widget position
x1 = widget->rc->x1;
y1 = widget->rc->y1;
x2 = widget->rc->x2-1;
y2 = widget->rc->y2-1;
// external background // external background
rectfill(ji_screen, x1, y1, x2, y2, to_system(BGCOLOR)); g->fillRect(BGCOLOR, g->getClipBounds());
// draw borders // draw borders
draw_bounds_nw(ji_screen, x1, y1, x2, y2, part_nw, bg); draw_bounds_nw(g, widget->getClientBounds(), part_nw, bg);
// text // text
crect = jwidget_get_child_rect(widget); drawTextString(g, NULL, fg, bg, false, widget,
draw_textstring(NULL, fg, bg, false, widget, crect, get_button_selected_offset()); widget->getClientChildrenBounds(), get_button_selected_offset());
jrect_free(crect);
// Paint the icon // Paint the icon
if (iconInterface) { if (iconInterface) {
@ -912,7 +904,9 @@ void SkinTheme::paintButton(PaintEvent& ev)
get_button_selected_offset(), get_button_selected_offset(),
get_button_selected_offset()); get_button_selected_offset());
paintIcon(widget, ev.getGraphics(), iconInterface, icon.x1-widget->rc->x1, icon.y1-widget->rc->y1); paintIcon(widget, ev.getGraphics(), iconInterface,
icon.x1-widget->rc->x1,
icon.y1-widget->rc->y1);
} }
} }
@ -946,7 +940,7 @@ void SkinTheme::paintCheckBox(PaintEvent& ev)
} }
// Text // Text
draw_textstring(NULL, ColorNone, bg, false, widget, &text, 0); drawTextStringDeprecated(NULL, ColorNone, bg, false, widget, &text, 0);
// Paint the icon // Paint the icon
if (iconInterface) if (iconInterface)
@ -966,6 +960,7 @@ void SkinTheme::paintGrid(PaintEvent& ev)
{ {
Widget* widget = static_cast<Widget*>(ev.getSource()); Widget* widget = static_cast<Widget*>(ev.getSource());
Graphics* g = ev.getGraphics(); Graphics* g = ev.getGraphics();
g->fillRect(BGCOLOR, g->getClipBounds()); g->fillRect(BGCOLOR, g->getClipBounds());
} }
@ -1091,7 +1086,7 @@ void SkinTheme::paintLinkLabel(PaintEvent& ev)
ui::Color bg = BGCOLOR; ui::Color bg = BGCOLOR;
jdraw_rectfill(widget->rc, bg); jdraw_rectfill(widget->rc, bg);
draw_textstring(NULL, getColor(ThemeColor::LinkText), bg, false, widget, widget->rc, 0); drawTextStringDeprecated(NULL, getColor(ThemeColor::LinkText), bg, false, widget, widget->rc, 0);
if (widget->hasMouseOver()) { if (widget->hasMouseOver()) {
int w = jwidget_get_text_length(widget); int w = jwidget_get_text_length(widget);
@ -1102,13 +1097,18 @@ void SkinTheme::paintLinkLabel(PaintEvent& ev)
} }
} }
void SkinTheme::draw_listbox(Widget* widget, JRect clip) void SkinTheme::paintListBox(PaintEvent& ev)
{ {
jdraw_rectfill(widget->rc, getColor(ThemeColor::Background)); Widget* widget = static_cast<Widget*>(ev.getSource());
Graphics* g = ev.getGraphics();
g->fillRect(getColor(ThemeColor::Background), g->getClipBounds());
} }
void SkinTheme::draw_listitem(Widget* widget, JRect clip) void SkinTheme::paintListItem(ui::PaintEvent& ev)
{ {
Widget* widget = static_cast<Widget*>(ev.getSource());
Graphics* g = ev.getGraphics();
ui::Color fg, bg; ui::Color fg, bg;
int x, y; int x, y;
@ -1148,16 +1148,20 @@ void SkinTheme::draw_listitem(Widget* widget, JRect clip)
} }
} }
void SkinTheme::draw_menu(Menu* widget, JRect clip) void SkinTheme::paintMenu(PaintEvent& ev)
{ {
jdraw_rectfill(widget->rc, BGCOLOR); Widget* widget = static_cast<Widget*>(ev.getSource());
Graphics* g = ev.getGraphics();
g->fillRect(BGCOLOR, g->getClipBounds());
} }
void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip) void SkinTheme::paintMenuItem(ui::PaintEvent& ev)
{ {
MenuItem* widget = static_cast<MenuItem*>(ev.getSource());
Graphics* g = ev.getGraphics();
ui::Color fg, bg; ui::Color fg, bg;
int x1, y1, x2, y2; int x1, y1, x2, y2;
JRect pos;
int c, bar; int c, bar;
// TODO ASSERT? // TODO ASSERT?
@ -1213,19 +1217,18 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip)
else else
widget->setAlign(JI_LEFT | JI_MIDDLE); widget->setAlign(JI_LEFT | JI_MIDDLE);
pos = jwidget_get_rect(widget); Rect pos = widget->getClientBounds();
if (!bar) if (!bar)
jrect_displace(pos, widget->child_spacing/2, 0); pos.offset(widget->child_spacing/2, 0);
draw_textstring(NULL, fg, bg, false, widget, pos, 0); drawTextString(g, NULL, fg, bg, false, widget, pos, 0);
jrect_free(pos);
/* for menu-box */ // For menu-box
if (!bar) { if (!bar) {
/* draw the arrown (to indicate which this menu has a sub-menu) */ // Draw the arrown (to indicate which this menu has a sub-menu)
if (widget->getSubmenu()) { if (widget->getSubmenu()) {
int scale = jguiscale(); int scale = jguiscale();
/* enabled */ // Enabled
if (widget->isEnabled()) { if (widget->isEnabled()) {
for (c=0; c<3*scale; c++) for (c=0; c<3*scale; c++)
vline(ji_screen, vline(ji_screen,
@ -1233,7 +1236,7 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip)
(widget->rc->y1+widget->rc->y2)/2-c, (widget->rc->y1+widget->rc->y2)/2-c,
(widget->rc->y1+widget->rc->y2)/2+c, to_system(fg)); (widget->rc->y1+widget->rc->y2)/2+c, to_system(fg));
} }
/* disabled */ // Disabled
else { else {
for (c=0; c<3*scale; c++) for (c=0; c<3*scale; c++)
vline(ji_screen, vline(ji_screen,
@ -1253,29 +1256,30 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip)
else if (widget->getAccel()) { else if (widget->getAccel()) {
int old_align = widget->getAlign(); int old_align = widget->getAlign();
pos = jwidget_get_rect(widget); pos = widget->getClientBounds();
pos->x2 -= widget->child_spacing/4; pos.w -= widget->child_spacing/4;
std::string buf = widget->getAccel()->toString(); std::string buf = widget->getAccel()->toString();
widget->setAlign(JI_RIGHT | JI_MIDDLE); widget->setAlign(JI_RIGHT | JI_MIDDLE);
draw_textstring(buf.c_str(), fg, bg, false, widget, pos, 0); drawTextString(g, buf.c_str(), fg, bg, false, widget, pos, 0);
widget->setAlign(old_align); widget->setAlign(old_align);
jrect_free(pos);
} }
} }
} }
void SkinTheme::drawSplitter(PaintEvent& ev) void SkinTheme::paintSplitter(PaintEvent& ev)
{ {
Splitter* splitter = static_cast<Splitter*>(ev.getSource()); Splitter* splitter = static_cast<Splitter*>(ev.getSource());
jdraw_rectfill(splitter->rc, getColor(ThemeColor::SplitterNormalFace)); Graphics* g = ev.getGraphics();
g->fillRect(getColor(ThemeColor::SplitterNormalFace), g->getClipBounds());
} }
void SkinTheme::paintRadioButton(PaintEvent& ev) void SkinTheme::paintRadioButton(PaintEvent& ev)
{ {
ButtonBase* widget = static_cast<ButtonBase*>(ev.getSource()); ButtonBase* widget = static_cast<ButtonBase*>(ev.getSource());
Graphics* g = ev.getGraphics();
IButtonIcon* iconInterface = widget->getIconInterface(); IButtonIcon* iconInterface = widget->getIconInterface();
struct jrect box, text, icon; struct jrect box, text, icon;
ui::Color bg = BGCOLOR; ui::Color bg = BGCOLOR;
@ -1285,10 +1289,10 @@ void SkinTheme::paintRadioButton(PaintEvent& ev)
iconInterface ? iconInterface->getWidth() : 0, iconInterface ? iconInterface->getWidth() : 0,
iconInterface ? iconInterface->getHeight() : 0); iconInterface ? iconInterface->getHeight() : 0);
/* background */ // Background
jdraw_rectfill(widget->rc, bg); g->fillRect(bg, g->getClipBounds());
/* mouse */ // Mouse
if (widget->isEnabled()) { if (widget->isEnabled()) {
if (widget->hasMouseOver()) if (widget->hasMouseOver())
jdraw_rectfill(widget->rc, bg = getColor(ThemeColor::RadioHotFace)); jdraw_rectfill(widget->rc, bg = getColor(ThemeColor::RadioHotFace));
@ -1296,12 +1300,12 @@ void SkinTheme::paintRadioButton(PaintEvent& ev)
jdraw_rectfill(widget->rc, bg = getColor(ThemeColor::RadioFocusFace)); jdraw_rectfill(widget->rc, bg = getColor(ThemeColor::RadioFocusFace));
} }
/* text */ // Text
draw_textstring(NULL, ColorNone, bg, false, widget, &text, 0); drawTextStringDeprecated(NULL, ColorNone, bg, false, widget, &text, 0);
// Paint the icon // Paint the icon
if (iconInterface) if (iconInterface)
paintIcon(widget, ev.getGraphics(), iconInterface, icon.x1-widget->rc->x1, icon.y1-widget->rc->y1); paintIcon(widget, g, iconInterface, icon.x1-widget->rc->x1, icon.y1-widget->rc->y1);
// draw focus // draw focus
if (widget->hasFocus()) { if (widget->hasFocus()) {
@ -1313,8 +1317,10 @@ void SkinTheme::paintRadioButton(PaintEvent& ev)
} }
} }
void SkinTheme::draw_separator(Widget* widget, JRect clip) void SkinTheme::paintSeparator(ui::PaintEvent& ev)
{ {
Widget* widget = static_cast<Widget*>(ev.getSource());
Graphics* g = ev.getGraphics();
int x1, y1, x2, y2; int x1, y1, x2, y2;
// position // position
@ -1345,8 +1351,10 @@ void SkinTheme::draw_separator(Widget* widget, JRect clip)
// text // text
if (widget->hasText()) { if (widget->hasText()) {
int h = jwidget_get_text_height(widget); int h = jwidget_get_text_height(widget);
struct jrect r = { x1+h/2, y1-h/2, x2+1-h, y2+1+h }; Rect r(Point(x1+h/2, y1-h/2),
draw_textstring(NULL, getColor(ThemeColor::Selected), BGCOLOR, false, widget, &r, 0); Point(x2+1-h, y2+1+h));
drawTextString(g, NULL, getColor(ThemeColor::Selected), BGCOLOR, false, widget, r, 0);
} }
} }
@ -1463,23 +1471,24 @@ void SkinTheme::paintSlider(PaintEvent& ev)
widget->setTextQuiet(buf); widget->setTextQuiet(buf);
if (IntersectClip clip = IntersectClip(g, Rect(rc.x, rc.y, x-rc.x, rc.h))) { if (IntersectClip clip = IntersectClip(g, Rect(rc.x, rc.y, x-rc.x, rc.h))) {
draw_textstring(g, NULL, drawTextString(g, NULL,
getColor(ThemeColor::SliderFullText), getColor(ThemeColor::SliderFullText),
getColor(ThemeColor::SliderFullFace), false, widget, rc, 0); getColor(ThemeColor::SliderFullFace), false, widget, rc, 0);
} }
if (IntersectClip clip = IntersectClip(g, Rect(x+1, rc.y, rc.w-(x-rc.x+1), rc.h))) { if (IntersectClip clip = IntersectClip(g, Rect(x+1, rc.y, rc.w-(x-rc.x+1), rc.h))) {
draw_textstring(g, NULL, drawTextString(g, NULL,
getColor(ThemeColor::SliderEmptyText), getColor(ThemeColor::SliderEmptyText),
getColor(ThemeColor::SliderEmptyFace), false, widget, rc, 0); getColor(ThemeColor::SliderEmptyFace), false, widget, rc, 0);
} }
widget->setTextQuiet(old_text.c_str()); widget->setTextQuiet(old_text.c_str());
} }
} }
void SkinTheme::draw_combobox_entry(Entry* widget, JRect clip) void SkinTheme::paintComboBoxEntry(ui::PaintEvent& ev)
{ {
Entry* widget = static_cast<Entry*>(ev.getSource());
bool password = widget->isPassword(); bool password = widget->isPassword();
int scroll, caret, state, selbeg, selend; int scroll, caret, state, selbeg, selend;
const char *text = widget->getText(); const char *text = widget->getText();
@ -1598,8 +1607,9 @@ void SkinTheme::paintComboBoxButton(PaintEvent& ev)
} }
} }
void SkinTheme::draw_textbox(Widget* widget, JRect clip) void SkinTheme::paintTextBox(ui::PaintEvent& ev)
{ {
Widget* widget = static_cast<Widget*>(ev.getSource());
drawTextBox(ji_screen, widget, NULL, NULL, drawTextBox(ji_screen, widget, NULL, NULL,
getColor(ThemeColor::TextBoxFace), getColor(ThemeColor::TextBoxFace),
getColor(ThemeColor::TextBoxText)); getColor(ThemeColor::TextBoxText));
@ -1659,45 +1669,36 @@ void SkinTheme::paintViewViewport(PaintEvent& ev)
void SkinTheme::paintWindow(PaintEvent& ev) void SkinTheme::paintWindow(PaintEvent& ev)
{ {
Graphics* g = ev.getGraphics();
Window* window = static_cast<Window*>(ev.getSource()); Window* window = static_cast<Window*>(ev.getSource());
JRect pos = jwidget_get_rect(window); Rect pos = window->getClientBounds();
JRect cpos = jwidget_get_child_rect(window); Rect cpos = window->getClientChildrenBounds();
if (!window->isDesktop()) { if (!window->isDesktop()) {
// window frame // window frame
if (window->hasText()) { if (window->hasText()) {
draw_bounds_nw(ji_screen, draw_bounds_nw(g, pos, PART_WINDOW_NW,
pos->x1,
pos->y1,
pos->x2-1,
pos->y2-1, PART_WINDOW_NW,
getColor(ThemeColor::WindowFace)); getColor(ThemeColor::WindowFace));
pos->y2 = cpos->y1; pos.h = cpos.y - pos.y;
// titlebar // titlebar
jdraw_text(ji_screen, window->getFont(), window->getText(), g->setFont(window->getFont());
cpos->x1, g->drawString(window->getText(), ThemeColor::Background, ColorNone,
pos->y1+jrect_h(pos)/2-text_height(window->getFont())/2, false,
getColor(ThemeColor::Background), ColorNone, false, jguiscale()); gfx::Point(cpos.x,
pos.y + pos.h/2 - text_height(window->getFont())/2));
} }
// menubox // menubox
else { else {
draw_bounds_nw(ji_screen, draw_bounds_nw(g, pos, PART_MENU_NW,
pos->x1,
pos->y1,
pos->x2-1,
pos->y2-1, PART_MENU_NW,
getColor(ThemeColor::WindowFace)); getColor(ThemeColor::WindowFace));
} }
} }
// desktop // desktop
else { else {
jdraw_rectfill(pos, getColor(ThemeColor::Desktop)); g->fillRect(ThemeColor::Desktop, pos);
} }
jrect_free(pos);
jrect_free(cpos);
} }
void SkinTheme::paintPopupWindow(PaintEvent& ev) void SkinTheme::paintPopupWindow(PaintEvent& ev)
@ -1718,8 +1719,11 @@ void SkinTheme::paintPopupWindow(PaintEvent& ev)
window->getAlign()); window->getAlign());
} }
void SkinTheme::drawWindowButton(ButtonBase* widget, JRect clip) void SkinTheme::paintWindowButton(ui::PaintEvent& ev)
{ {
ButtonBase* widget = static_cast<ButtonBase*>(ev.getSource());
Graphics* g = ev.getGraphics();
Rect rc = widget->getClientBounds();
int part; int part;
if (widget->isSelected()) if (widget->isSelected())
@ -1729,8 +1733,7 @@ void SkinTheme::drawWindowButton(ButtonBase* widget, JRect clip)
else else
part = PART_WINDOW_CLOSE_BUTTON_NORMAL; part = PART_WINDOW_CLOSE_BUTTON_NORMAL;
set_alpha_blender(); g->drawAlphaBitmap(m_part[part], rc.x, rc.y);
draw_trans_sprite(ji_screen, m_part[part], widget->rc->x1, widget->rc->y1);
} }
void SkinTheme::paintTooltip(PaintEvent& ev) void SkinTheme::paintTooltip(PaintEvent& ev)
@ -1801,9 +1804,9 @@ ui::Color SkinTheme::getWidgetBgColor(Widget* widget)
getColor(ThemeColor::Face))); getColor(ThemeColor::Face)));
} }
void SkinTheme::draw_textstring(const char *t, ui::Color fg_color, ui::Color bg_color, void SkinTheme::drawTextStringDeprecated(const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, Widget* widget, const JRect rect, bool fill_bg, Widget* widget, const JRect rect,
int selected_offset) int selected_offset)
{ {
if (t || widget->hasText()) { if (t || widget->hasText()) {
int x, y, w, h; int x, y, w, h;
@ -1870,9 +1873,9 @@ void SkinTheme::draw_textstring(const char *t, ui::Color fg_color, ui::Color bg_
} }
} }
void SkinTheme::draw_textstring(Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color, void SkinTheme::drawTextString(Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, Widget* widget, const Rect& rc, bool fill_bg, Widget* widget, const Rect& rc,
int selected_offset) int selected_offset)
{ {
if (t || widget->hasText()) { if (t || widget->hasText()) {
Rect textrc; Rect textrc;
@ -2179,6 +2182,42 @@ void SkinTheme::draw_part_as_vline(BITMAP* bmp, int x1, int y1, int x2, int y2,
} }
} }
void SkinTheme::draw_part_as_hline(ui::Graphics* g, const gfx::Rect& rc, int part)
{
int x;
set_alpha_blender();
for (x = rc.x;
x < rc.x2()-m_part[part]->w;
x += m_part[part]->w) {
g->drawAlphaBitmap(m_part[part], x, rc.y);
}
if (x < rc.x2()) {
Rect rc2(x, rc.y, rc.w-(x-rc.x), m_part[part]->h);
if (IntersectClip clip = IntersectClip(g, rc2))
g->drawAlphaBitmap(m_part[part], x, rc.y);
}
}
void SkinTheme::draw_part_as_vline(ui::Graphics* g, const gfx::Rect& rc, int part)
{
int y;
for (y = rc.y;
y < rc.y2()-m_part[part]->h;
y += m_part[part]->h) {
g->drawAlphaBitmap(m_part[part], rc.x, y);
}
if (y < rc.y2()) {
Rect rc2(rc.x, y, m_part[part]->w, rc.h-(y-rc.y));
if (IntersectClip clip = IntersectClip(g, rc2))
g->drawAlphaBitmap(m_part[part], rc.x, y);
}
}
void SkinTheme::drawProgressBar(BITMAP* bmp, int x1, int y1, int x2, int y2, float progress) void SkinTheme::drawProgressBar(BITMAP* bmp, int x1, int y1, int x2, int y2, float progress)
{ {
int w = x2 - x1 + 1; int w = x2 - x1 + 1;

View File

@ -32,6 +32,7 @@
#include <allegro/color.h> #include <allegro/color.h>
namespace ui { namespace ui {
class Entry;
class Graphics; class Graphics;
class IButtonIcon; class IButtonIcon;
} }
@ -133,23 +134,23 @@ public:
void paintGrid(ui::PaintEvent& ev); void paintGrid(ui::PaintEvent& ev);
void paintLabel(ui::PaintEvent& ev); void paintLabel(ui::PaintEvent& ev);
void paintLinkLabel(ui::PaintEvent& ev); void paintLinkLabel(ui::PaintEvent& ev);
void draw_listbox(ui::Widget* widget, ui::JRect clip); void paintListBox(ui::PaintEvent& ev);
void draw_listitem(ui::Widget* widget, ui::JRect clip); void paintListItem(ui::PaintEvent& ev);
void draw_menu(ui::Menu* menu, ui::JRect clip); void paintMenu(ui::PaintEvent& ev);
void draw_menuitem(ui::MenuItem* menuitem, ui::JRect clip); void paintMenuItem(ui::PaintEvent& ev);
void drawSplitter(ui::PaintEvent& ev); void paintSplitter(ui::PaintEvent& ev);
void paintRadioButton(ui::PaintEvent& ev); void paintRadioButton(ui::PaintEvent& ev);
void draw_separator(ui::Widget* widget, ui::JRect clip); void paintSeparator(ui::PaintEvent& ev);
void paintSlider(ui::PaintEvent& ev); void paintSlider(ui::PaintEvent& ev);
void draw_combobox_entry(ui::Entry* widget, ui::JRect clip); void paintComboBoxEntry(ui::PaintEvent& ev);
void paintComboBoxButton(ui::PaintEvent& ev); void paintComboBoxButton(ui::PaintEvent& ev);
void draw_textbox(ui::Widget* widget, ui::JRect clip); void paintTextBox(ui::PaintEvent& ev);
void paintView(ui::PaintEvent& ev); void paintView(ui::PaintEvent& ev);
void paintViewScrollbar(ui::PaintEvent& ev); void paintViewScrollbar(ui::PaintEvent& ev);
void paintViewViewport(ui::PaintEvent& ev); void paintViewViewport(ui::PaintEvent& ev);
void paintWindow(ui::PaintEvent& ev); void paintWindow(ui::PaintEvent& ev);
void paintPopupWindow(ui::PaintEvent& ev); void paintPopupWindow(ui::PaintEvent& ev);
void drawWindowButton(ui::ButtonBase* widget, ui::JRect clip); void paintWindowButton(ui::PaintEvent& ev);
void paintTooltip(ui::PaintEvent& ev); void paintTooltip(ui::PaintEvent& ev);
int get_button_selected_offset() const { return 0; } // TODO Configurable in xml int get_button_selected_offset() const { return 0; } // TODO Configurable in xml
@ -165,6 +166,8 @@ public:
void draw_bounds_nw2(ui::Graphics* g, const gfx::Rect& rc, int x_mid, int nw1, int nw2, ui::Color bg1, ui::Color bg2); void draw_bounds_nw2(ui::Graphics* g, const gfx::Rect& rc, int x_mid, int nw1, int nw2, ui::Color bg1, ui::Color bg2);
void draw_part_as_hline(BITMAP* bmp, int x1, int y1, int x2, int y2, int part); void draw_part_as_hline(BITMAP* bmp, int x1, int y1, int x2, int y2, int part);
void draw_part_as_vline(BITMAP* bmp, int x1, int y1, int x2, int y2, int part); void draw_part_as_vline(BITMAP* bmp, int x1, int y1, int x2, int y2, int part);
void draw_part_as_hline(ui::Graphics* g, const gfx::Rect& rc, int part);
void draw_part_as_vline(ui::Graphics* g, const gfx::Rect& rc, int part);
// Wrapper to use the new "Rect" class (x, y, w, h) // Wrapper to use the new "Rect" class (x, y, w, h)
void draw_bounds_nw(BITMAP* bmp, const gfx::Rect& rc, int nw, ui::Color bg) { void draw_bounds_nw(BITMAP* bmp, const gfx::Rect& rc, int nw, ui::Color bg) {
@ -184,12 +187,12 @@ private:
BITMAP* cropPartFromSheet(BITMAP* bmp, int x, int y, int w, int h); BITMAP* cropPartFromSheet(BITMAP* bmp, int x, int y, int w, int h);
ui::Color getWidgetBgColor(ui::Widget* widget); ui::Color getWidgetBgColor(ui::Widget* widget);
void draw_textstring(const char *t, ui::Color fg_color, ui::Color bg_color, void drawTextStringDeprecated(const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, ui::Widget* widget, const ui::JRect rect, bool fill_bg, ui::Widget* widget, const ui::JRect rect,
int selected_offset); int selected_offset);
void draw_textstring(ui::Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color, void drawTextString(ui::Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, ui::Widget* widget, const gfx::Rect& rc, bool fill_bg, ui::Widget* widget, const gfx::Rect& rc,
int selected_offset); int selected_offset);
void draw_entry_caret(ui::Entry* widget, int x, int y); void draw_entry_caret(ui::Entry* widget, int x, int y);
void paintIcon(ui::Widget* widget, ui::Graphics* g, ui::IButtonIcon* iconInterface, int x, int y); void paintIcon(ui::Widget* widget, ui::Graphics* g, ui::IButtonIcon* iconInterface, int x, int y);

View File

@ -38,6 +38,7 @@ public:
protected: protected:
bool onProcessMessage(Message* msg) OVERRIDE; bool onProcessMessage(Message* msg) OVERRIDE;
void onPaint(PaintEvent& ev) OVERRIDE;
private: private:
ComboBox* m_comboBox; ComboBox* m_comboBox;
@ -407,15 +408,16 @@ bool ComboBoxEntry::onProcessMessage(Message* msg)
return true; return true;
break; break;
case kPaintMessage:
getTheme()->draw_combobox_entry(this, &msg->draw.rect);
return true;
} }
return Entry::onProcessMessage(msg); return Entry::onProcessMessage(msg);
} }
void ComboBoxEntry::onPaint(PaintEvent& ev)
{
getTheme()->paintComboBoxEntry(ev);
}
bool ComboBoxListBox::onProcessMessage(Message* msg) bool ComboBoxListBox::onProcessMessage(Message* msg)
{ {
switch (msg->type) { switch (msg->type) {

View File

@ -125,10 +125,6 @@ bool ListBox::onProcessMessage(Message* msg)
{ {
switch (msg->type) { switch (msg->type) {
case kPaintMessage:
this->getTheme()->draw_listbox(this, &msg->draw.rect);
return true;
case kOpenMessage: case kOpenMessage:
centerScroll(); centerScroll();
break; break;
@ -256,6 +252,11 @@ bool ListBox::onProcessMessage(Message* msg)
return Widget::onProcessMessage(msg); return Widget::onProcessMessage(msg);
} }
void ListBox::onPaint(PaintEvent& ev)
{
getTheme()->paintListBox(ev);
}
void ListBox::onResize(ResizeEvent& ev) void ListBox::onResize(ResizeEvent& ev)
{ {
setBoundsQuietly(ev.getBounds()); setBoundsQuietly(ev.getBounds());

View File

@ -35,6 +35,7 @@ namespace ui {
protected: protected:
virtual bool onProcessMessage(Message* msg) OVERRIDE; virtual bool onProcessMessage(Message* msg) OVERRIDE;
virtual void onPaint(PaintEvent& ev) OVERRIDE;
virtual void onResize(ResizeEvent& ev) OVERRIDE; virtual void onResize(ResizeEvent& ev) OVERRIDE;
virtual void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE; virtual void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
virtual void onChangeSelectedItem(); virtual void onChangeSelectedItem();

View File

@ -26,16 +26,9 @@ ListItem::ListItem(const char* text)
initTheme(); initTheme();
} }
bool ListItem::onProcessMessage(Message* msg) void ListItem::onPaint(PaintEvent& ev)
{ {
switch (msg->type) { getTheme()->paintListItem(ev);
case kPaintMessage:
this->getTheme()->draw_listitem(this, &msg->draw.rect);
return true;
}
return Widget::onProcessMessage(msg);
} }
void ListItem::onResize(ResizeEvent& ev) void ListItem::onResize(ResizeEvent& ev)

View File

@ -18,7 +18,7 @@ namespace ui {
ListItem(const char* text); ListItem(const char* text);
protected: protected:
bool onProcessMessage(Message* msg) OVERRIDE; void onPaint(PaintEvent& ev) OVERRIDE;
void onResize(ResizeEvent& ev) OVERRIDE; void onResize(ResizeEvent& ev) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE; void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
}; };

View File

@ -961,17 +961,15 @@ void Manager::onPreferredSize(PreferredSizeEvent& ev)
h = jrect_h(this->rc); h = jrect_h(this->rc);
} }
else { else {
JRect cpos, pos = jwidget_get_child_rect(this->getParent()); gfx::Rect pos = getParent()->getChildrenBounds();
UI_FOREACH_WIDGET(getChildren(), it) { UI_FOREACH_WIDGET(getChildren(), it) {
cpos = jwidget_get_rect(*it); gfx::Rect cpos = (*it)->getBounds();
jrect_union(pos, cpos); pos = pos.createUnion(cpos);
jrect_free(cpos);
} }
w = jrect_w(pos); w = pos.w;
h = jrect_h(pos); h = pos.h;
jrect_free(pos);
} }
ev.setPreferredSize(gfx::Size(w, h)); ev.setPreferredSize(gfx::Size(w, h));

View File

@ -290,17 +290,9 @@ void Menu::showPopup(int x, int y)
delete window; delete window;
} }
bool Menu::onProcessMessage(Message* msg) void Menu::onPaint(PaintEvent& ev)
{ {
switch (msg->type) { getTheme()->paintMenu(ev);
case kPaintMessage:
getTheme()->draw_menu(this, &msg->draw.rect);
return true;
}
return Widget::onProcessMessage(msg);
} }
void Menu::onResize(ResizeEvent& ev) void Menu::onResize(ResizeEvent& ev)
@ -669,10 +661,6 @@ bool MenuItem::onProcessMessage(Message* msg)
{ {
switch (msg->type) { switch (msg->type) {
case kPaintMessage:
getTheme()->draw_menuitem(this, &msg->draw.rect);
return true;
case kMouseEnterMessage: case kMouseEnterMessage:
// TODO theme specific!! // TODO theme specific!!
invalidate(); invalidate();
@ -696,14 +684,13 @@ bool MenuItem::onProcessMessage(Message* msg)
default: default:
if (msg->type == kOpenMenuItemMessage) { if (msg->type == kOpenMenuItemMessage) {
MenuBaseData* base = get_base(this); MenuBaseData* base = get_base(this);
JRect pos;
bool select_first = msg->user.a ? true: false; bool select_first = msg->user.a ? true: false;
ASSERT(base != NULL); ASSERT(base != NULL);
ASSERT(base->is_processing); ASSERT(base->is_processing);
ASSERT(hasSubmenu()); ASSERT(hasSubmenu());
JRect old_pos = jwidget_get_rect(this->getParent()->getParent()); Rect old_pos = getParent()->getParent()->getBounds();
MenuBox* menubox = new MenuBox(); MenuBox* menubox = new MenuBox();
m_submenu_menubox = menubox; m_submenu_menubox = menubox;
@ -713,48 +700,40 @@ bool MenuItem::onProcessMessage(Message* msg)
Window* window = new CustomizedWindowForMenuBox(menubox); Window* window = new CustomizedWindowForMenuBox(menubox);
// Menubox position // Menubox position
pos = jwidget_get_rect(window); Rect pos = window->getBounds();
if (this->getParent()->getParent()->type == kMenuBarWidget) { if (this->getParent()->getParent()->type == kMenuBarWidget) {
jrect_moveto(pos, pos.x = MID(0, this->rc->x1, JI_SCREEN_W-pos.w);
MID(0, this->rc->x1, JI_SCREEN_W-jrect_w(pos)), pos.y = MID(0, this->rc->y2, JI_SCREEN_H-pos.h);
MID(0, this->rc->y2, JI_SCREEN_H-jrect_h(pos)));
} }
else { else {
int x_left = this->rc->x1-jrect_w(pos); int x_left = this->rc->x1-pos.w;
int x_right = this->rc->x2; int x_right = this->rc->x2;
int x, y = this->rc->y1; int x, y = this->rc->y1;
struct jrect r1, r2; Rect r1(0, 0, pos.w, pos.h), r2(0, 0, pos.w, pos.h);
int s1, s2;
r1.x1 = x_left = MID(0, x_left, JI_SCREEN_W-jrect_w(pos)); r1.x = x_left = MID(0, x_left, JI_SCREEN_W-pos.w);
r2.x1 = x_right = MID(0, x_right, JI_SCREEN_W-jrect_w(pos)); r2.x = x_right = MID(0, x_right, JI_SCREEN_W-pos.w);
r1.y = r2.y = y = MID(0, y, JI_SCREEN_H-pos.h);
r1.y1 = r2.y1 = y = MID(0, y, JI_SCREEN_H-jrect_h(pos));
r1.x2 = r1.x1+jrect_w(pos);
r1.y2 = r1.y1+jrect_h(pos);
r2.x2 = r2.x1+jrect_w(pos);
r2.y2 = r2.y1+jrect_h(pos);
// Calculate both intersections // Calculate both intersections
s1 = jrect_intersect(&r1, old_pos); gfx::Rect s1 = r1.createIntersect(old_pos);
s2 = jrect_intersect(&r2, old_pos); gfx::Rect s2 = r2.createIntersect(old_pos);
if (!s2) if (s2.isEmpty())
x = x_right; // Use the right because there aren't intersection with it x = x_right; // Use the right because there aren't intersection with it
else if (!s1) else if (s1.isEmpty())
x = x_left; // Use the left because there are not intersection x = x_left; // Use the left because there are not intersection
else if (jrect_w(&r2)*jrect_h(&r2) <= jrect_w(&r1)*jrect_h(&r1)) else if (r2.w*r2.h <= r1.w*r1.h)
x = x_right; // Use the right because there are less intersection area x = x_right; // Use the right because there are less intersection area
else else
x = x_left; // Use the left because there are less intersection area x = x_left; // Use the left because there are less intersection area
jrect_moveto(pos, x, y); pos.x = x;
pos.y = y;
} }
window->positionWindow(pos->x1, pos->y1); window->positionWindow(pos.x, pos.y);
jrect_free(pos);
// Set the focus to the new menubox // Set the focus to the new menubox
menubox->setFocusMagnet(true); menubox->setFocusMagnet(true);
@ -789,7 +768,6 @@ bool MenuItem::onProcessMessage(Message* msg)
base->is_processing = false; base->is_processing = false;
jrect_free(old_pos);
return true; return true;
} }
else if (msg->type == kCloseMenuItemMessage) { else if (msg->type == kCloseMenuItemMessage) {
@ -859,6 +837,11 @@ bool MenuItem::onProcessMessage(Message* msg)
return Widget::onProcessMessage(msg); return Widget::onProcessMessage(msg);
} }
void MenuItem::onPaint(PaintEvent& ev)
{
getTheme()->paintMenuItem(ev);
}
void MenuItem::onClick() void MenuItem::onClick()
{ {
// Fire new Click() signal. // Fire new Click() signal.

View File

@ -34,7 +34,7 @@ namespace ui {
} }
protected: protected:
virtual bool onProcessMessage(Message* msg) OVERRIDE; virtual void onPaint(PaintEvent& ev) OVERRIDE;
virtual void onResize(ResizeEvent& ev) OVERRIDE; virtual void onResize(ResizeEvent& ev) OVERRIDE;
virtual void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE; virtual void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
@ -126,6 +126,7 @@ namespace ui {
protected: protected:
virtual bool onProcessMessage(Message* msg) OVERRIDE; virtual bool onProcessMessage(Message* msg) OVERRIDE;
virtual void onPaint(PaintEvent& ev) OVERRIDE;
virtual void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE; virtual void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
virtual void onClick(); virtual void onClick();

View File

@ -25,16 +25,9 @@ Separator::Separator(const char* text, int align)
initTheme(); initTheme();
} }
bool Separator::onProcessMessage(Message* msg) void Separator::onPaint(PaintEvent& ev)
{ {
switch (msg->type) { getTheme()->paintSeparator(ev);
case kPaintMessage:
getTheme()->draw_separator(this, &msg->draw.rect);
return true;
}
return Widget::onProcessMessage(msg);
} }
void Separator::onPreferredSize(PreferredSizeEvent& ev) void Separator::onPreferredSize(PreferredSizeEvent& ev)

View File

@ -18,7 +18,7 @@ namespace ui {
Separator(const char* text, int align); Separator(const char* text, int align);
protected: protected:
bool onProcessMessage(Message* msg) OVERRIDE; void onPaint(PaintEvent& ev) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE; void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
}; };

View File

@ -86,22 +86,22 @@ bool Slider::onProcessMessage(Message* msg)
setupSliderCursor(); setupSliderCursor();
/* continue to kMouseMoveMessage */ // Continue to kMouseMoveMessage...
case kMouseMoveMessage: case kMouseMoveMessage:
if (hasCapture()) { if (hasCapture()) {
int value, accuracy, range; int value, accuracy, range;
JRect rc = jwidget_get_child_rect(this); gfx::Rect rc = getChildrenBounds();
range = m_max - m_min + 1; range = m_max - m_min + 1;
/* with left click */ // With left click
if (slider_press_left) { if (slider_press_left) {
value = m_min + range * (msg->mouse.x - rc->x1) / jrect_w(rc); value = m_min + range * (msg->mouse.x - rc.x) / rc.w;
} }
/* with right click */ // With right click
else { else {
accuracy = MID(1, jrect_w(rc) / range, jrect_w(rc)); accuracy = MID(1, rc.w / range, rc.w);
value = slider_press_value + value = slider_press_value +
(msg->mouse.x - slider_press_x) / accuracy; (msg->mouse.x - slider_press_x) / accuracy;
@ -110,29 +110,28 @@ bool Slider::onProcessMessage(Message* msg)
value = MID(m_min, value, m_max); value = MID(m_min, value, m_max);
if (m_value != value) { if (m_value != value) {
this->setValue(value); setValue(value);
onChange(); onChange();
} }
/* for left click */ // For left click
if (slider_press_left) { if (slider_press_left) {
int x = jmouse_x(0); int x = jmouse_x(0);
if (x < rc->x1-1) if (x < rc.x-1)
x = rc->x1-1; x = rc.x-1;
else if (x > rc->x2) else if (x > rc.x2())
x = rc->x2; x = rc.x2();
if (x != jmouse_x(0)) if (x != jmouse_x(0))
jmouse_set_position(x, jmouse_y(0)); jmouse_set_position(x, jmouse_y(0));
} }
/* for right click */ // For right click
else if (jmouse_control_infinite_scroll(getBounds() - getBorder())) { else if (jmouse_control_infinite_scroll(getBounds() - getBorder())) {
slider_press_x = jmouse_x(0); slider_press_x = jmouse_x(0);
slider_press_value = m_value; slider_press_value = m_value;
} }
jrect_free(rc);
return true; return true;
} }
break; break;

View File

@ -228,7 +228,7 @@ void Splitter::onResize(ResizeEvent& ev)
void Splitter::onPaint(PaintEvent& ev) void Splitter::onPaint(PaintEvent& ev)
{ {
getTheme()->drawSplitter(ev); getTheme()->paintSplitter(ev);
} }
void Splitter::onPreferredSize(PreferredSizeEvent& ev) void Splitter::onPreferredSize(PreferredSizeEvent& ev)

View File

@ -33,10 +33,6 @@ bool TextBox::onProcessMessage(Message* msg)
{ {
switch (msg->type) { switch (msg->type) {
case kPaintMessage:
getTheme()->draw_textbox(this, &msg->draw.rect);
return true;
case kKeyDownMessage: case kKeyDownMessage:
if (hasFocus()) { if (hasFocus()) {
View* view = View::getView(this); View* view = View::getView(this);
@ -147,6 +143,11 @@ bool TextBox::onProcessMessage(Message* msg)
return Widget::onProcessMessage(msg); return Widget::onProcessMessage(msg);
} }
void TextBox::onPaint(PaintEvent& ev)
{
getTheme()->paintTextBox(ev);
}
void TextBox::onPreferredSize(PreferredSizeEvent& ev) void TextBox::onPreferredSize(PreferredSizeEvent& ev)
{ {
int w = 0; int w = 0;

View File

@ -19,6 +19,7 @@ namespace ui {
protected: protected:
bool onProcessMessage(Message* msg) OVERRIDE; bool onProcessMessage(Message* msg) OVERRIDE;
void onPaint(PaintEvent& ev) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE; void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
void onSetText() OVERRIDE; void onSetText() OVERRIDE;
}; };

View File

@ -26,7 +26,7 @@ namespace ui {
static Theme* current_theme = NULL; static Theme* current_theme = NULL;
static void draw_text(BITMAP *bmp, FONT *f, const char* text, int x, int y, static void draw_text(BITMAP *bmp, FONT *f, const char* text, int x, int y,
ui::Color fg_color, ui::Color bg_color, bool fill_bg); Color fg_color, Color bg_color, bool fill_bg);
Theme::Theme() Theme::Theme()
{ {
@ -95,7 +95,7 @@ BITMAP* ji_apply_guiscale(BITMAP* original)
} }
void drawTextBox(BITMAP* bmp, Widget* widget, void drawTextBox(BITMAP* bmp, Widget* widget,
int* w, int* h, ui::Color bg, ui::Color fg) int* w, int* h, Color bg, Color fg)
{ {
View* view = View::getView(widget); View* view = View::getView(widget);
char *text = (char*)widget->getText(); // TODO warning: removing const modifier char *text = (char*)widget->getText(); // TODO warning: removing const modifier
@ -254,7 +254,7 @@ void drawTextBox(BITMAP* bmp, Widget* widget,
} }
static void draw_text(BITMAP *bmp, FONT *f, const char *text, int x, int y, static void draw_text(BITMAP *bmp, FONT *f, const char *text, int x, int y,
ui::Color fg_color, ui::Color bg_color, bool fill_bg) Color fg_color, Color bg_color, bool fill_bg)
{ {
// TODO Optional anti-aliased textout // TODO Optional anti-aliased textout
ji_font_set_aa_mode(f, to_system(bg_color)); ji_font_set_aa_mode(f, to_system(bg_color));

View File

@ -19,11 +19,7 @@ namespace gfx {
namespace ui { namespace ui {
class ButtonBase;
class Cursor; class Cursor;
class Entry;
class Menu;
class MenuItem;
class PaintEvent; class PaintEvent;
class Widget; class Widget;
@ -42,8 +38,8 @@ namespace ui {
virtual Cursor* getCursor(CursorType type) = 0; virtual Cursor* getCursor(CursorType type) = 0;
virtual void initWidget(Widget* widget) = 0; virtual void initWidget(Widget* widget) = 0;
virtual void getWindowMask(ui::Widget* widget, gfx::Region& region) = 0; virtual void getWindowMask(Widget* widget, gfx::Region& region) = 0;
virtual void setDecorativeWidgetBounds(ui::Widget* widget) = 0; virtual void setDecorativeWidgetBounds(Widget* widget) = 0;
virtual void paintDesktop(PaintEvent& ev) = 0; virtual void paintDesktop(PaintEvent& ev) = 0;
virtual void paintBox(PaintEvent& ev) = 0; virtual void paintBox(PaintEvent& ev) = 0;
@ -53,17 +49,17 @@ namespace ui {
virtual void paintGrid(PaintEvent& ev) = 0; virtual void paintGrid(PaintEvent& ev) = 0;
virtual void paintLabel(PaintEvent& ev) = 0; virtual void paintLabel(PaintEvent& ev) = 0;
virtual void paintLinkLabel(PaintEvent& ev) = 0; virtual void paintLinkLabel(PaintEvent& ev) = 0;
virtual void draw_listbox(Widget* widget, JRect clip) = 0; virtual void paintListBox(PaintEvent& ev) = 0;
virtual void draw_listitem(Widget* widget, JRect clip) = 0; virtual void paintListItem(PaintEvent& ev) = 0;
virtual void draw_menu(Menu* menu, JRect clip) = 0; virtual void paintMenu(PaintEvent& ev) = 0;
virtual void draw_menuitem(MenuItem* menuitem, JRect clip) = 0; virtual void paintMenuItem(PaintEvent& ev) = 0;
virtual void drawSplitter(PaintEvent& ev) = 0; virtual void paintSplitter(PaintEvent& ev) = 0;
virtual void paintRadioButton(PaintEvent& ev) = 0; virtual void paintRadioButton(PaintEvent& ev) = 0;
virtual void draw_separator(Widget* widget, JRect clip) = 0; virtual void paintSeparator(PaintEvent& ev) = 0;
virtual void paintSlider(PaintEvent& ev) = 0; virtual void paintSlider(PaintEvent& ev) = 0;
virtual void draw_combobox_entry(Entry* widget, JRect clip) = 0; virtual void paintComboBoxEntry(PaintEvent& ev) = 0;
virtual void paintComboBoxButton(PaintEvent& ev) = 0; virtual void paintComboBoxButton(PaintEvent& ev) = 0;
virtual void draw_textbox(Widget* widget, JRect clip) = 0; virtual void paintTextBox(PaintEvent& ev) = 0;
virtual void paintView(PaintEvent& ev) = 0; virtual void paintView(PaintEvent& ev) = 0;
virtual void paintViewScrollbar(PaintEvent& ev) = 0; virtual void paintViewScrollbar(PaintEvent& ev) = 0;
virtual void paintViewViewport(PaintEvent& ev) = 0; virtual void paintViewViewport(PaintEvent& ev) = 0;

View File

@ -579,6 +579,14 @@ Rect Widget::getChildrenBounds() const
jrect_h(rc) - border_width.t - border_width.b); jrect_h(rc) - border_width.t - border_width.b);
} }
Rect Widget::getClientChildrenBounds() const
{
return Rect(border_width.l,
border_width.t,
jrect_w(rc) - border_width.l - border_width.r,
jrect_h(rc) - border_width.t - border_width.b);
}
void Widget::setBounds(const Rect& rc) void Widget::setBounds(const Rect& rc)
{ {
ResizeEvent ev(this, rc); ResizeEvent ev(this, rc);
@ -706,25 +714,6 @@ void Widget::getDrawableRegion(gfx::Region& region, DrawableRegionFlags flags)
} }
} }
/* gets the position of the widget */
JRect jwidget_get_rect(Widget* widget)
{
ASSERT_VALID_WIDGET(widget);
return jrect_new_copy(widget->rc);
}
/* gets the position for children of the widget */
JRect jwidget_get_child_rect(Widget* widget)
{
ASSERT_VALID_WIDGET(widget);
return jrect_new(widget->rc->x1 + widget->border_width.l,
widget->rc->y1 + widget->border_width.t,
widget->rc->x2 - widget->border_width.r,
widget->rc->y2 - widget->border_width.b);
}
int jwidget_get_text_length(const Widget* widget) int jwidget_get_text_length(const Widget* widget)
{ {
#if 1 #if 1

View File

@ -43,8 +43,6 @@ namespace ui {
// Position and geometry // Position and geometry
JRect jwidget_get_rect(Widget* widget);
JRect jwidget_get_child_rect(Widget* widget);
int jwidget_get_text_length(const Widget* widget); int jwidget_get_text_length(const Widget* widget);
int jwidget_get_text_height(const Widget* widget); int jwidget_get_text_height(const Widget* widget);
void jwidget_get_texticon_info(Widget* widget, void jwidget_get_texticon_info(Widget* widget,
@ -259,6 +257,7 @@ namespace ui {
} }
gfx::Rect getChildrenBounds() const; gfx::Rect getChildrenBounds() const;
gfx::Rect getClientChildrenBounds() const;
// Sets the bounds of the widget generating a onResize() event. // Sets the bounds of the widget generating a onResize() event.
void setBounds(const gfx::Rect& rc); void setBounds(const gfx::Rect& rc);

View File

@ -117,47 +117,47 @@ void Window::onHitTest(HitTestEvent& ev)
int x = ev.getPoint().x; int x = ev.getPoint().x;
int y = ev.getPoint().y; int y = ev.getPoint().y;
JRect pos = jwidget_get_rect(this); gfx::Rect pos = getBounds();
JRect cpos = jwidget_get_child_rect(this); gfx::Rect cpos = getChildrenBounds();
// Move // Move
if ((this->hasText()) if ((this->hasText())
&& (((x >= cpos->x1) && && (((x >= cpos.x) &&
(x < cpos->x2) && (x < cpos.x2()) &&
(y >= pos->y1+this->border_width.b) && (y >= pos.y+this->border_width.b) &&
(y < cpos->y1)))) { (y < cpos.y)))) {
ht = HitTestCaption; ht = HitTestCaption;
} }
// Resize // Resize
else if (m_isSizeable) { else if (m_isSizeable) {
if ((x >= pos->x1) && (x < cpos->x1)) { if ((x >= pos.x) && (x < cpos.x)) {
if ((y >= pos->y1) && (y < cpos->y1)) if ((y >= pos.y) && (y < cpos.y))
ht = HitTestBorderNW; ht = HitTestBorderNW;
else if ((y > cpos->y2-1) && (y <= pos->y2-1)) else if ((y > cpos.y2()-1) && (y <= pos.y2()-1))
ht = HitTestBorderSW; ht = HitTestBorderSW;
else else
ht = HitTestBorderW; ht = HitTestBorderW;
} }
else if ((y >= pos->y1) && (y < cpos->y1)) { else if ((y >= pos.y) && (y < cpos.y)) {
if ((x >= pos->x1) && (x < cpos->x1)) if ((x >= pos.x) && (x < cpos.x))
ht = HitTestBorderNW; ht = HitTestBorderNW;
else if ((x > cpos->x2-1) && (x <= pos->x2-1)) else if ((x > cpos.x2()-1) && (x <= pos.x2()-1))
ht = HitTestBorderNE; ht = HitTestBorderNE;
else else
ht = HitTestBorderN; ht = HitTestBorderN;
} }
else if ((x > cpos->x2-1) && (x <= pos->x2-1)) { else if ((x > cpos.x2()-1) && (x <= pos.x2()-1)) {
if ((y >= pos->y1) && (y < cpos->y1)) if ((y >= pos.y) && (y < cpos.y))
ht = HitTestBorderNE; ht = HitTestBorderNE;
else if ((y > cpos->y2-1) && (y <= pos->y2-1)) else if ((y > cpos.y2()-1) && (y <= pos.y2()-1))
ht = HitTestBorderSE; ht = HitTestBorderSE;
else else
ht = HitTestBorderE; ht = HitTestBorderE;
} }
else if ((y > cpos->y2-1) && (y <= pos->y2-1)) { else if ((y > cpos.y2()-1) && (y <= pos.y2()-1)) {
if ((x >= pos->x1) && (x < cpos->x1)) if ((x >= pos.x) && (x < cpos.x))
ht = HitTestBorderSW; ht = HitTestBorderSW;
else if ((x > cpos->x2-1) && (x <= pos->x2-1)) else if ((x > cpos.x2()-1) && (x <= pos.x2()-1))
ht = HitTestBorderSE; ht = HitTestBorderSE;
else else
ht = HitTestBorderS; ht = HitTestBorderS;
@ -168,9 +168,6 @@ void Window::onHitTest(HitTestEvent& ev)
ht = HitTestClient; ht = HitTestClient;
} }
jrect_free(pos);
jrect_free(cpos);
ev.setHit(ht); ev.setHit(ht);
} }
@ -525,17 +522,15 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
Region new_drawable_region; Region new_drawable_region;
Region manager_refresh_region; // A region to refresh the manager later Region manager_refresh_region; // A region to refresh the manager later
Region window_refresh_region; // A new region to refresh the window later Region window_refresh_region; // A new region to refresh the window later
JRect old_pos;
JRect man_pos;
Message* msg; Message* msg;
manager->dispatchMessages(); manager->dispatchMessages();
/* get the window's current position */ // Get the window's current position
old_pos = jrect_new_copy(this->rc); Rect old_pos = getBounds();
/* get the manager's current position */ // Get the manager's current position
man_pos = jwidget_get_rect(manager); Rect man_pos = manager->getBounds();
/* sent a kWinMoveMessage message to the window */ /* sent a kWinMoveMessage message to the window */
msg = jmessage_new(kWinMoveMessage); msg = jmessage_new(kWinMoveMessage);
@ -546,8 +541,8 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
getDrawableRegion(old_drawable_region, FLAGS); getDrawableRegion(old_drawable_region, FLAGS);
// If the size of the window changes... // If the size of the window changes...
if (jrect_w(old_pos) != rect.w || if (old_pos.w != rect.w ||
jrect_h(old_pos) != rect.h) { old_pos.h != rect.h) {
// We have to change the position of all children. // We have to change the position of all children.
windowSetPosition(rect); windowSetPosition(rect);
} }
@ -555,8 +550,8 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
// We can just displace all the widgets by a delta (new_position - // We can just displace all the widgets by a delta (new_position -
// old_position)... // old_position)...
displace_widgets(this, displace_widgets(this,
rect.x - old_pos->x1, rect.x - old_pos.x,
rect.y - old_pos->y1); rect.y - old_pos.y);
} }
// Get the new drawable region of the window (it's new because we // Get the new drawable region of the window (it's new because we
@ -584,32 +579,29 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
// Add a region to draw areas which were outside of the screen // Add a region to draw areas which were outside of the screen
reg1 = new_drawable_region; reg1 = new_drawable_region;
reg1.offset(old_pos->x1 - this->rc->x1, reg1.offset(old_pos.x - this->rc->x1,
old_pos->y1 - this->rc->y1); old_pos.y - this->rc->y1);
moveable_region.createIntersection(old_drawable_region, reg1); moveable_region.createIntersection(old_drawable_region, reg1);
reg1.createSubtraction(reg1, moveable_region); reg1.createSubtraction(reg1, moveable_region);
reg1.offset(this->rc->x1 - old_pos->x1, reg1.offset(this->rc->x1 - old_pos.x,
this->rc->y1 - old_pos->y1); this->rc->y1 - old_pos.y);
window_refresh_region.createUnion(window_refresh_region, reg1); window_refresh_region.createUnion(window_refresh_region, reg1);
// Move the window's graphics // Move the window's graphics
jmouse_hide(); jmouse_hide();
set_clip_rect(ji_screen, set_clip_rect(ji_screen,
man_pos->x1, man_pos->y1, man_pos->x2-1, man_pos->y2-1); man_pos.x, man_pos.y, man_pos.x2()-1, man_pos.y2()-1);
ji_move_region(moveable_region, ji_move_region(moveable_region,
this->rc->x1 - old_pos->x1, this->rc->x1 - old_pos.x,
this->rc->y1 - old_pos->y1); this->rc->y1 - old_pos.y);
set_clip_rect(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1); set_clip_rect(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1);
jmouse_show(); jmouse_show();
} }
manager->invalidateDisplayRegion(manager_refresh_region); manager->invalidateDisplayRegion(manager_refresh_region);
invalidateRegion(window_refresh_region); invalidateRegion(window_refresh_region);
jrect_free(old_pos);
jrect_free(man_pos);
} }
static void displace_widgets(Widget* widget, int x, int y) static void displace_widgets(Widget* widget, int x, int y)

View File

@ -52,7 +52,6 @@ bool EditorView::onProcessMessage(Message* msg)
{ {
Widget* viewport = getViewport(); Widget* viewport = getViewport();
Widget* child = UI_FIRST_WIDGET(viewport->getChildren()); Widget* child = UI_FIRST_WIDGET(viewport->getChildren());
JRect pos = jwidget_get_rect(this);
SkinTheme* theme = static_cast<SkinTheme*>(getTheme()); SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
bool selected = false; bool selected = false;
@ -70,14 +69,10 @@ bool EditorView::onProcessMessage(Message* msg)
} }
theme->draw_bounds_nw(ji_screen, theme->draw_bounds_nw(ji_screen, getBounds(),
pos->x1, pos->y1,
pos->x2-1, pos->y2-1,
selected ? PART_EDITOR_SELECTED_NW: selected ? PART_EDITOR_SELECTED_NW:
PART_EDITOR_NORMAL_NW, PART_EDITOR_NORMAL_NW,
ColorNone); ColorNone);
jrect_free(pos);
} }
return true; return true;

View File

@ -163,7 +163,7 @@ void PaletteView::getSelectedEntries(SelectedEntries& entries) const
app::Color PaletteView::getColorByPosition(int target_x, int target_y) app::Color PaletteView::getColorByPosition(int target_x, int target_y)
{ {
Palette* palette = get_current_palette(); Palette* palette = get_current_palette();
JRect cpos = jwidget_get_child_rect(this); gfx::Rect cpos = getChildrenBounds();
div_t d = div(Palette::MaxColors, m_columns); div_t d = div(Palette::MaxColors, m_columns);
int cols = m_columns; int cols = m_columns;
int rows = d.quot + ((d.rem)? 1: 0); int rows = d.quot + ((d.rem)? 1: 0);
@ -173,11 +173,11 @@ app::Color PaletteView::getColorByPosition(int target_x, int target_y)
request_size(&req_w, &req_h); request_size(&req_w, &req_h);
y = cpos->y1; y = cpos.y;
c = 0; c = 0;
for (v=0; v<rows; v++) { for (v=0; v<rows; v++) {
x = cpos->x1; x = cpos.x;
for (u=0; u<cols; u++) { for (u=0; u<cols; u++) {
if (c >= palette->size()) if (c >= palette->size())
@ -194,7 +194,6 @@ app::Color PaletteView::getColorByPosition(int target_x, int target_y)
y += m_boxsize+this->child_spacing; y += m_boxsize+this->child_spacing;
} }
jrect_free(cpos);
return app::Color::fromMask(); return app::Color::fromMask();
} }
@ -267,15 +266,13 @@ bool PaletteView::onProcessMessage(Message* msg)
/* continue... */ /* continue... */
case kMouseMoveMessage: { case kMouseMoveMessage: {
JRect cpos = jwidget_get_child_rect(this); gfx::Rect cpos = getChildrenBounds();
int req_w, req_h; int req_w, req_h;
request_size(&req_w, &req_h); request_size(&req_w, &req_h);
int mouse_x = MID(cpos->x1, msg->mouse.x, cpos->x1+req_w-this->border_width.r-1); int mouse_x = MID(cpos.x, msg->mouse.x, cpos.x+req_w-this->border_width.r-1);
int mouse_y = MID(cpos->y1, msg->mouse.y, cpos->y1+req_h-this->border_width.b-1); int mouse_y = MID(cpos.y, msg->mouse.y, cpos.y+req_h-this->border_width.b-1);
jrect_free(cpos);
app::Color color = getColorByPosition(mouse_x, mouse_y); app::Color color = getColorByPosition(mouse_x, mouse_y);
if (color.getType() == app::Color::IndexType) { if (color.getType() == app::Color::IndexType) {

View File

@ -476,21 +476,17 @@ bool StatusBar::onProcessMessage(Message* msg)
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme()); SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
ui::Color text_color = theme->getColor(ThemeColor::Text); ui::Color text_color = theme->getColor(ThemeColor::Text);
ui::Color face_color = theme->getColor(ThemeColor::Face); ui::Color face_color = theme->getColor(ThemeColor::Face);
JRect rc = jwidget_get_rect(this); Rect rc = getBounds();
BITMAP* doublebuffer = create_bitmap(jrect_w(&msg->draw.rect), BITMAP* doublebuffer = create_bitmap(jrect_w(&msg->draw.rect),
jrect_h(&msg->draw.rect)); jrect_h(&msg->draw.rect));
jrect_displace(rc, rc.offset(-msg->draw.rect.x1, -msg->draw.rect.y1);
-msg->draw.rect.x1,
-msg->draw.rect.y1);
clear_to_color(doublebuffer, to_system(face_color)); clear_to_color(doublebuffer, to_system(face_color));
rc->x1 += 2*jguiscale(); rc.shrink(Border(2*jguiscale(), 1*jguiscale(),
rc->y1 += 1*jguiscale(); 2*jguiscale(), 2*jguiscale()));
rc->x2 -= 2*jguiscale();
rc->y2 -= 2*jguiscale();
int x = rc->x1+4*jguiscale(); int x = rc.x + 4*jguiscale();
// Color // Color
if (m_state == SHOW_COLOR) { if (m_state == SHOW_COLOR) {
@ -499,13 +495,13 @@ bool StatusBar::onProcessMessage(Message* msg)
if (icon) { if (icon) {
set_alpha_blender(); set_alpha_blender();
draw_trans_sprite(doublebuffer, icon, draw_trans_sprite(doublebuffer, icon,
x, (rc->y1+rc->y2)/2-icon->h/2); x, rc.y + rc.h/2 - icon->h/2);
x += icon->w + 4*jguiscale(); x += icon->w + 4*jguiscale();
} }
// Draw color // Draw color
draw_color_button(doublebuffer, Rect(x, rc->y1, 32*jguiscale(), rc->y2-rc->y1), draw_color_button(doublebuffer, Rect(x, rc.y, 32*jguiscale(), rc.h),
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
app_get_current_pixel_format(), m_color, app_get_current_pixel_format(), m_color,
@ -523,7 +519,7 @@ bool StatusBar::onProcessMessage(Message* msg)
} }
textout_ex(doublebuffer, this->getFont(), str.c_str(), textout_ex(doublebuffer, this->getFont(), str.c_str(),
x, (rc->y1+rc->y2)/2-text_height(this->getFont())/2, x, rc.y + rc.h/2 - text_height(this->getFont())/2,
to_system(text_color), -1); to_system(text_color), -1);
x += ji_font_text_len(this->getFont(), str.c_str()) + 4*jguiscale(); x += ji_font_text_len(this->getFont(), str.c_str()) + 4*jguiscale();
@ -535,9 +531,7 @@ bool StatusBar::onProcessMessage(Message* msg)
BITMAP* icon = theme->get_toolicon(m_tool->getId().c_str()); BITMAP* icon = theme->get_toolicon(m_tool->getId().c_str());
if (icon) { if (icon) {
set_alpha_blender(); set_alpha_blender();
draw_trans_sprite(doublebuffer, icon, draw_trans_sprite(doublebuffer, icon, x, rc.y + rc.h/2 - icon->h/2);
x, (rc->y1+rc->y2)/2-icon->h/2);
x += icon->w + 4*jguiscale(); x += icon->w + 4*jguiscale();
} }
} }
@ -546,7 +540,7 @@ bool StatusBar::onProcessMessage(Message* msg)
if (this->getTextSize() > 0) { if (this->getTextSize() > 0) {
textout_ex(doublebuffer, this->getFont(), this->getText(), textout_ex(doublebuffer, this->getFont(), this->getText(),
x, x,
(rc->y1+rc->y2)/2-text_height(this->getFont())/2, rc.y + rc.h/2 - text_height(this->getFont())/2,
to_system(text_color), -1); to_system(text_color), -1);
x += ji_font_text_len(this->getFont(), this->getText()) + 4*jguiscale(); x += ji_font_text_len(this->getFont(), this->getText()) + 4*jguiscale();
@ -556,10 +550,10 @@ bool StatusBar::onProcessMessage(Message* msg)
if (!m_progress.empty()) { if (!m_progress.empty()) {
int width = 64; int width = 64;
int y1, y2; int y1, y2;
int x = rc->x2 - (width+4); int x = rc.x2() - (width+4);
y1 = rc->y1; y1 = rc.y;
y2 = rc->y2-1; y2 = rc.y2()-1;
for (ProgressList::iterator it = m_progress.begin(); it != m_progress.end(); ++it) { for (ProgressList::iterator it = m_progress.begin(); it != m_progress.end(); ++it) {
Progress* progress = *it; Progress* progress = *it;
@ -574,11 +568,11 @@ bool StatusBar::onProcessMessage(Message* msg)
// Show layers only when we are not moving pixels // Show layers only when we are not moving pixels
else if (!hasChild(m_movePixelsBox)) { else if (!hasChild(m_movePixelsBox)) {
// Available width for layers buttons // Available width for layers buttons
int width = jrect_w(rc)/4; int width = rc.w/4;
// Draw layers // Draw layers
try { try {
--rc->y2; --rc.h;
const ContextReader reader(UIContext::instance()); const ContextReader reader(UIContext::instance());
const Sprite* sprite(reader.sprite()); const Sprite* sprite(reader.sprite());
@ -595,13 +589,13 @@ bool StatusBar::onProcessMessage(Message* msg)
char buf[256]; char buf[256];
for (int c=0; it != end; ++it, ++c) { for (int c=0; it != end; ++it, ++c) {
int x1 = rc->x2-width + c*width/count; int x1 = rc.x2() - width + c*width/count;
int x2 = rc->x2-width + (c+1)*width/count; int x2 = rc.x2() - width + (c+1)*width/count;
bool hot = ((*it == reader.layer()) bool hot = ((*it == reader.layer())
|| (LayerIndex(c) == m_hot_layer)); || (LayerIndex(c) == m_hot_layer));
theme->draw_bounds_nw(doublebuffer, theme->draw_bounds_nw(doublebuffer,
x1, rc->y1, x2, rc->y2, x1, rc.y, x2, rc.y2(),
hot ? PART_TOOLBUTTON_HOT_NW: hot ? PART_TOOLBUTTON_HOT_NW:
PART_TOOLBUTTON_NORMAL_NW, PART_TOOLBUTTON_NORMAL_NW,
hot ? theme->getColor(ThemeColor::ButtonHotFace): hot ? theme->getColor(ThemeColor::ButtonHotFace):
@ -619,7 +613,7 @@ bool StatusBar::onProcessMessage(Message* msg)
textout_centre_ex(doublebuffer, this->getFont(), buf, textout_centre_ex(doublebuffer, this->getFont(), buf,
(x1+x2)/2, (x1+x2)/2,
(rc->y1+rc->y2)/2-text_height(this->getFont())/2, rc.y + rc.h/2 - text_height(this->getFont())/2,
to_system(hot ? theme->getColor(ThemeColor::ButtonHotText): to_system(hot ? theme->getColor(ThemeColor::ButtonHotText):
theme->getColor(ThemeColor::ButtonNormalText)), theme->getColor(ThemeColor::ButtonNormalText)),
-1); -1);
@ -637,8 +631,6 @@ bool StatusBar::onProcessMessage(Message* msg)
} }
} }
jrect_free(rc);
blit(doublebuffer, ji_screen, 0, 0, blit(doublebuffer, ji_screen, 0, 0,
msg->draw.rect.x1, msg->draw.rect.x1,
msg->draw.rect.y1, msg->draw.rect.y1,
@ -679,19 +671,15 @@ bool StatusBar::onProcessMessage(Message* msg)
} }
case kMouseMoveMessage: { case kMouseMoveMessage: {
JRect rc = jwidget_get_rect(this); gfx::Rect rc = getBounds().shrink(gfx::Border(2*jguiscale(), 1*jguiscale(),
2*jguiscale(), 2*jguiscale()));
rc->x1 += 2*jguiscale();
rc->y1 += 1*jguiscale();
rc->x2 -= 2*jguiscale();
rc->y2 -= 2*jguiscale();
// Available width for layers buttons // Available width for layers buttons
int width = jrect_w(rc)/4; int width = rc.w/4;
// Check layers bounds // Check layers bounds
try { try {
--rc->y2; --rc.h;
LayerIndex hot_layer = LayerIndex(-1); LayerIndex hot_layer = LayerIndex(-1);
@ -705,12 +693,12 @@ bool StatusBar::onProcessMessage(Message* msg)
int count = folder->getLayersCount(); int count = folder->getLayersCount();
for (int c=0; it != end; ++it, ++c) { for (int c=0; it != end; ++it, ++c) {
int x1 = rc->x2-width + c*width/count; int x1 = rc.x2()-width + c*width/count;
int x2 = rc->x2-width + (c+1)*width/count; int x2 = rc.x2()-width + (c+1)*width/count;
if (Rect(Point(x1, rc->y1), if (Rect(Point(x1, rc.y),
Point(x2, rc->y2)).contains(Point(msg->mouse.x, Point(x2, rc.y2())).contains(Point(msg->mouse.x,
msg->mouse.y))) { msg->mouse.y))) {
hot_layer = LayerIndex(c); hot_layer = LayerIndex(c);
break; break;
} }
@ -718,12 +706,12 @@ bool StatusBar::onProcessMessage(Message* msg)
} }
// Check if the "Donate" button has the mouse over // Check if the "Donate" button has the mouse over
else { else {
int x1 = rc->x2-width; int x1 = rc.x2()-width;
int x2 = rc->x2; int x2 = rc.x2();
if (Rect(Point(x1, rc->y1), if (Rect(Point(x1, rc.y),
Point(x2, rc->y2)).contains(Point(msg->mouse.x, Point(x2, rc.y2())).contains(Point(msg->mouse.x,
msg->mouse.y))) { msg->mouse.y))) {
hot_layer = LayerIndex(0); hot_layer = LayerIndex(0);
} }
} }
@ -736,8 +724,6 @@ bool StatusBar::onProcessMessage(Message* msg)
catch (LockedDocumentException&) { catch (LockedDocumentException&) {
// Do nothing... // Do nothing...
} }
jrect_free(rc);
break; break;
} }

View File

@ -72,6 +72,8 @@ Tabs::Tabs(TabsDelegate* delegate)
, m_delegate(delegate) , m_delegate(delegate)
, m_timer(1000/60, this) , m_timer(1000/60, this)
{ {
setDoubleBuffered(true);
m_hot = NULL; m_hot = NULL;
m_selected = NULL; m_selected = NULL;
m_scrollX = 0; m_scrollX = 0;
@ -244,93 +246,6 @@ bool Tabs::onProcessMessage(Message* msg)
{ {
switch (msg->type) { switch (msg->type) {
case kPaintMessage: {
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
BITMAP *doublebuffer = create_bitmap(jrect_w(&msg->draw.rect),
jrect_h(&msg->draw.rect));
JRect rect = jwidget_get_rect(this);
jrect_displace(rect, -msg->draw.rect.x1, -msg->draw.rect.y1);
JRect box = jrect_new(rect->x1-m_scrollX,
rect->y1,
rect->x1-m_scrollX+2*jguiscale(),
rect->y1+theme->get_part(PART_TAB_FILLER)->h);
clear_to_color(doublebuffer, to_system(theme->getColor(ThemeColor::WindowFace)));
theme->draw_part_as_hline(doublebuffer, box->x1, box->y1, box->x2-1, box->y2-1, PART_TAB_FILLER);
theme->draw_part_as_hline(doublebuffer, box->x1, box->y2, box->x2-1, rect->y2-1, PART_TAB_BOTTOM_NORMAL);
box->x1 = box->x2;
// For each tab...
TabsListIterator it, end = m_list_of_tabs.end();
for (it = m_list_of_tabs.begin(); it != end; ++it) {
Tab* tab = *it;
box->x2 = box->x1 + tab->width;
int x_delta = 0;
int y_delta = 0;
// Y-delta for animating tabs (intros and outros)
if (m_ani == ANI_ADDING_TAB && m_selected == tab) {
y_delta = (box->y2 - box->y1) * (ANI_ADDING_TAB_TICKS - m_ani_t) / ANI_ADDING_TAB_TICKS;
}
else if (m_ani == ANI_REMOVING_TAB && m_nextTabOfTheRemovedOne == tab) {
x_delta += m_removedTab->width - m_removedTab->width*(1.0-std::exp(-10.0 * m_ani_t / (double)ANI_REMOVING_TAB_TICKS));
x_delta = MID(0, x_delta, m_removedTab->width);
// Draw deleted tab
if (m_removedTab) {
JRect box2 = jrect_new(box->x1, box->y1, box->x1+x_delta, box->y2);
drawTab(doublebuffer, box2, m_removedTab, 0, false);
jrect_free(box2);
}
}
box->x1 += x_delta;
box->x2 += x_delta;
drawTab(doublebuffer, box, tab, y_delta, (tab == m_selected));
box->x1 = box->x2;
}
if (m_ani == ANI_REMOVING_TAB && m_nextTabOfTheRemovedOne == NULL) {
// Draw deleted tab
if (m_removedTab) {
int x_delta = m_removedTab->width - m_removedTab->width*(1.0-std::exp(-10.0 * m_ani_t / (double)ANI_REMOVING_TAB_TICKS));
x_delta = MID(0, x_delta, m_removedTab->width);
JRect box2 = jrect_new(box->x1, box->y1, box->x1+x_delta, box->y2);
drawTab(doublebuffer, box2, m_removedTab, 0, false);
jrect_free(box2);
box->x1 += x_delta;
box->x2 = box->x1;
}
}
/* fill the gap to the right-side */
if (box->x1 < rect->x2) {
theme->draw_part_as_hline(doublebuffer, box->x1, box->y1, rect->x2-1, box->y2-1, PART_TAB_FILLER);
theme->draw_part_as_hline(doublebuffer, box->x1, box->y2, rect->x2-1, rect->y2-1, PART_TAB_BOTTOM_NORMAL);
}
jrect_free(rect);
jrect_free(box);
blit(doublebuffer, ji_screen, 0, 0,
msg->draw.rect.x1,
msg->draw.rect.y1,
doublebuffer->w,
doublebuffer->h);
destroy_bitmap(doublebuffer);
return true;
}
case kMouseEnterMessage: case kMouseEnterMessage:
case kMouseMoveMessage: case kMouseMoveMessage:
calculateHot(); calculateHot();
@ -425,6 +340,76 @@ bool Tabs::onProcessMessage(Message* msg)
return Widget::onProcessMessage(msg); return Widget::onProcessMessage(msg);
} }
void Tabs::onPaint(PaintEvent& ev)
{
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
Graphics* g = ev.getGraphics();
gfx::Rect rect = getClientBounds();
gfx::Rect box(rect.x-m_scrollX,
rect.y,
2*jguiscale(),
theme->get_part(PART_TAB_FILLER)->h);
g->fillRect(theme->getColor(ThemeColor::WindowFace), g->getClipBounds());
theme->draw_part_as_hline(g, box, PART_TAB_FILLER);
theme->draw_part_as_hline(g, gfx::Rect(box.x, box.y2(), box.w, rect.y2()-box.y2()), PART_TAB_BOTTOM_NORMAL);
box.x = box.x2();
// For each tab...
TabsListIterator it, end = m_list_of_tabs.end();
for (it = m_list_of_tabs.begin(); it != end; ++it) {
Tab* tab = *it;
box.w = tab->width;
int x_delta = 0;
int y_delta = 0;
// Y-delta for animating tabs (intros and outros)
if (m_ani == ANI_ADDING_TAB && m_selected == tab) {
y_delta = box.h * (ANI_ADDING_TAB_TICKS - m_ani_t) / ANI_ADDING_TAB_TICKS;
}
else if (m_ani == ANI_REMOVING_TAB && m_nextTabOfTheRemovedOne == tab) {
x_delta += m_removedTab->width - m_removedTab->width*(1.0-std::exp(-10.0 * m_ani_t / (double)ANI_REMOVING_TAB_TICKS));
x_delta = MID(0, x_delta, m_removedTab->width);
// Draw deleted tab
if (m_removedTab) {
gfx::Rect box2(box.x, box.y, x_delta, box.h);
drawTab(g, box2, m_removedTab, 0, false);
}
}
box.x += x_delta;
drawTab(g, box, tab, y_delta, (tab == m_selected));
box.x = box.x2();
}
if (m_ani == ANI_REMOVING_TAB && m_nextTabOfTheRemovedOne == NULL) {
// Draw deleted tab
if (m_removedTab) {
int x_delta = m_removedTab->width - m_removedTab->width*(1.0-std::exp(-10.0 * m_ani_t / (double)ANI_REMOVING_TAB_TICKS));
x_delta = MID(0, x_delta, m_removedTab->width);
gfx::Rect box2(box.x, box.y, x_delta, box.h);
drawTab(g, box2, m_removedTab, 0, false);
box.x += x_delta;
box.w = 0;
}
}
// Fill the gap to the right-side
if (box.x < rect.x2()) {
theme->draw_part_as_hline(g, gfx::Rect(box.x, box.y, rect.x2()-box.x, box.h), PART_TAB_FILLER);
theme->draw_part_as_hline(g, gfx::Rect(box.x, box.y2(), rect.x2()-box.x, rect.y2()-box.y2()), PART_TAB_BOTTOM_NORMAL);
}
}
void Tabs::onResize(ResizeEvent& ev) void Tabs::onResize(ResizeEvent& ev)
{ {
setBoundsQuietly(ev.getBounds()); setBoundsQuietly(ev.getBounds());
@ -467,10 +452,10 @@ void Tabs::selectTabInternal(Tab* tab)
invalidate(); invalidate();
} }
void Tabs::drawTab(BITMAP* bmp, JRect box, Tab* tab, int y_delta, bool selected) void Tabs::drawTab(Graphics* g, const gfx::Rect& box, Tab* tab, int y_delta, bool selected)
{ {
// Is the tab outside the bounds of the widget? // Is the tab outside the bounds of the widget?
if (box->x1 >= this->rc->x2 || box->x2 <= this->rc->x1) if (box.x >= this->rc->x2 || box.x2() <= this->rc->x1)
return; return;
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme()); SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
@ -488,37 +473,33 @@ void Tabs::drawTab(BITMAP* bmp, JRect box, Tab* tab, int y_delta, bool selected)
face_color = theme->getColor(ThemeColor::TabNormalFace); face_color = theme->getColor(ThemeColor::TabNormalFace);
} }
if (jrect_w(box) > 2) { if (box.w > 2) {
theme->draw_bounds_nw(bmp, theme->draw_bounds_nw(g,
box->x1, box->y1+y_delta, box->x2-1, box->y2-1, gfx::Rect(box.x, box.y+y_delta, box.w, box.h),
(selected) ? PART_TAB_SELECTED_NW: (selected) ? PART_TAB_SELECTED_NW:
PART_TAB_NORMAL_NW, PART_TAB_NORMAL_NW,
face_color); face_color);
jdraw_text(bmp, this->getFont(), tab->text.c_str(), g->drawString(tab->text, text_color, face_color, false,
box->x1+4*jguiscale(), gfx::Point(box.x + 4*jguiscale(),
(box->y1+box->y2)/2-text_height(this->getFont())/2+1 + y_delta, box.y + box.h/2 - text_height(this->getFont())/2+1 + y_delta));
text_color, face_color, false, jguiscale());
} }
if (selected) { if (selected) {
theme->draw_bounds_nw(bmp, theme->draw_bounds_nw(g, gfx::Rect(box.x, box.y2(), box.w, this->rc->y2-box.y2()),
box->x1, box->y2, box->x2-1, this->rc->y2-1,
PART_TAB_BOTTOM_SELECTED_NW, PART_TAB_BOTTOM_SELECTED_NW,
theme->getColor(ThemeColor::TabSelectedFace)); theme->getColor(ThemeColor::TabSelectedFace));
} }
else { else {
theme->draw_part_as_hline(bmp, theme->draw_part_as_hline(g, gfx::Rect(box.x, box.y2(), box.w, this->rc->y2-box.y2()),
box->x1, box->y2, box->x2-1, this->rc->y2-1,
PART_TAB_BOTTOM_NORMAL); PART_TAB_BOTTOM_NORMAL);
} }
#ifdef CLOSE_BUTTON_IN_EACH_TAB #ifdef CLOSE_BUTTON_IN_EACH_TAB
BITMAP* close_icon = theme->get_part(PART_WINDOW_CLOSE_BUTTON_NORMAL); BITMAP* close_icon = theme->get_part(PART_WINDOW_CLOSE_BUTTON_NORMAL);
set_alpha_blender(); g->drawAlphaBitmap(close_icon,
draw_trans_sprite(doublebuffer, close_icon, box.x2() - 4*jguiscale() - close_icon->w,
box->x2-4*jguiscale()-close_icon->w, box.y + box.h/2 - close_icon->h/2+1 * jguiscale());
(box->y1+box->y2)/2-close_icon->h/2+1*jguiscale());
#endif #endif
} }
@ -626,8 +607,8 @@ void Tabs::setScrollX(int scroll_x)
void Tabs::calculateHot() void Tabs::calculateHot()
{ {
JRect rect = jwidget_get_rect(this); gfx::Rect rect = getBounds();
JRect box = jrect_new(rect->x1-m_scrollX, rect->y1, 0, rect->y2-1); gfx::Rect box(rect.x-m_scrollX, rect.y, 0, rect.h-1);
Tab *hot = NULL; Tab *hot = NULL;
TabsListIterator it, end = m_list_of_tabs.end(); TabsListIterator it, end = m_list_of_tabs.end();
@ -635,14 +616,14 @@ void Tabs::calculateHot()
for (it = m_list_of_tabs.begin(); it != end; ++it) { for (it = m_list_of_tabs.begin(); it != end; ++it) {
Tab* tab = *it; Tab* tab = *it;
box->x2 = box->x1 + tab->width; box.w = tab->width;
if (jrect_point_in(box, jmouse_x(0), jmouse_y(0))) { if (box.contains(gfx::Point(jmouse_x(0), jmouse_y(0)))) {
hot = tab; hot = tab;
break; break;
} }
box->x1 = box->x2; box.x += box.w;
} }
if (m_hot != hot) { if (m_hot != hot) {
@ -653,9 +634,6 @@ void Tabs::calculateHot()
invalidate(); invalidate();
} }
jrect_free(rect);
jrect_free(box);
} }
void Tabs::calcTabWidth(Tab* tab) void Tabs::calcTabWidth(Tab* tab)

View File

@ -27,6 +27,10 @@
class Tabs; class Tabs;
namespace ui {
class Graphics;
}
// Required interface to be implemented by each new tab that is added // Required interface to be implemented by each new tab that is added
// in the Tabs widget. // in the Tabs widget.
class TabView class TabView
@ -94,6 +98,7 @@ public:
protected: protected:
bool onProcessMessage(ui::Message* msg) OVERRIDE; bool onProcessMessage(ui::Message* msg) OVERRIDE;
void onPaint(ui::PaintEvent& ev) OVERRIDE;
void onResize(ui::ResizeEvent& ev) OVERRIDE; void onResize(ui::ResizeEvent& ev) OVERRIDE;
void onPreferredSize(ui::PreferredSizeEvent& ev) OVERRIDE; void onPreferredSize(ui::PreferredSizeEvent& ev) OVERRIDE;
void onInitTheme(ui::InitThemeEvent& ev) OVERRIDE; void onInitTheme(ui::InitThemeEvent& ev) OVERRIDE;
@ -104,7 +109,7 @@ private:
void stopAni(); void stopAni();
void selectTabInternal(Tab* tab); void selectTabInternal(Tab* tab);
void drawTab(BITMAP* bmp, ui::JRect box, Tab* tab, int y_delta, bool selected); void drawTab(ui::Graphics* g, const gfx::Rect& box, Tab* tab, int y_delta, bool selected);
TabsListIterator getTabIteratorByView(TabView* tabView); TabsListIterator getTabIteratorByView(TabView* tabView);
Tab* getTabByView(TabView* tabView); Tab* getTabByView(TabView* tabView);
int getMaxScrollX(); int getMaxScrollX();