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();
}
void onPaint(PaintEvent& ev) OVERRIDE {
static_cast<SkinTheme*>(getTheme())->paintWindowButton(ev);
}
bool onProcessMessage(Message* msg) OVERRIDE {
switch (msg->type) {
@ -76,10 +80,6 @@ protected:
jmouse_set_cursor(kArrowCursor);
return true;
case kPaintMessage:
static_cast<SkinTheme*>(getTheme())->drawWindowButton(this, &msg->draw.rect);
return true;
case kKeyDownMessage:
if (msg->key.scancode == KEY_ESC) {
setSelected(true);
@ -834,13 +834,12 @@ void SkinTheme::paintBox(PaintEvent& ev)
void SkinTheme::paintButton(PaintEvent& ev)
{
Graphics* g = ev.getGraphics();
ButtonBase* widget = static_cast<ButtonBase*>(ev.getSource());
IButtonIcon* iconInterface = widget->getIconInterface();
struct jrect box, text, icon;
int x1, y1, x2, y2;
ui::Color fg, bg;
int part_nw;
JRect crect;
jwidget_get_texticon_info(widget, &box, &text, &icon,
iconInterface ? iconInterface->getIconAlign(): 0,
@ -888,22 +887,15 @@ void SkinTheme::paintButton(PaintEvent& ev)
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
rectfill(ji_screen, x1, y1, x2, y2, to_system(BGCOLOR));
g->fillRect(BGCOLOR, g->getClipBounds());
// draw borders
draw_bounds_nw(ji_screen, x1, y1, x2, y2, part_nw, bg);
draw_bounds_nw(g, widget->getClientBounds(), part_nw, bg);
// text
crect = jwidget_get_child_rect(widget);
draw_textstring(NULL, fg, bg, false, widget, crect, get_button_selected_offset());
jrect_free(crect);
drawTextString(g, NULL, fg, bg, false, widget,
widget->getClientChildrenBounds(), get_button_selected_offset());
// Paint the icon
if (iconInterface) {
@ -912,7 +904,9 @@ void SkinTheme::paintButton(PaintEvent& ev)
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
draw_textstring(NULL, ColorNone, bg, false, widget, &text, 0);
drawTextStringDeprecated(NULL, ColorNone, bg, false, widget, &text, 0);
// Paint the icon
if (iconInterface)
@ -966,6 +960,7 @@ void SkinTheme::paintGrid(PaintEvent& ev)
{
Widget* widget = static_cast<Widget*>(ev.getSource());
Graphics* g = ev.getGraphics();
g->fillRect(BGCOLOR, g->getClipBounds());
}
@ -1091,7 +1086,7 @@ void SkinTheme::paintLinkLabel(PaintEvent& ev)
ui::Color bg = BGCOLOR;
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()) {
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;
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;
int x1, y1, x2, y2;
JRect pos;
int c, bar;
// TODO ASSERT?
@ -1213,19 +1217,18 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip)
else
widget->setAlign(JI_LEFT | JI_MIDDLE);
pos = jwidget_get_rect(widget);
Rect pos = widget->getClientBounds();
if (!bar)
jrect_displace(pos, widget->child_spacing/2, 0);
draw_textstring(NULL, fg, bg, false, widget, pos, 0);
jrect_free(pos);
pos.offset(widget->child_spacing/2, 0);
drawTextString(g, NULL, fg, bg, false, widget, pos, 0);
/* for menu-box */
// For menu-box
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()) {
int scale = jguiscale();
/* enabled */
// Enabled
if (widget->isEnabled()) {
for (c=0; c<3*scale; c++)
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, to_system(fg));
}
/* disabled */
// Disabled
else {
for (c=0; c<3*scale; c++)
vline(ji_screen,
@ -1253,29 +1256,30 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip)
else if (widget->getAccel()) {
int old_align = widget->getAlign();
pos = jwidget_get_rect(widget);
pos->x2 -= widget->child_spacing/4;
pos = widget->getClientBounds();
pos.w -= widget->child_spacing/4;
std::string buf = widget->getAccel()->toString();
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);
jrect_free(pos);
}
}
}
void SkinTheme::drawSplitter(PaintEvent& ev)
void SkinTheme::paintSplitter(PaintEvent& ev)
{
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)
{
ButtonBase* widget = static_cast<ButtonBase*>(ev.getSource());
Graphics* g = ev.getGraphics();
IButtonIcon* iconInterface = widget->getIconInterface();
struct jrect box, text, icon;
ui::Color bg = BGCOLOR;
@ -1285,10 +1289,10 @@ void SkinTheme::paintRadioButton(PaintEvent& ev)
iconInterface ? iconInterface->getWidth() : 0,
iconInterface ? iconInterface->getHeight() : 0);
/* background */
jdraw_rectfill(widget->rc, bg);
// Background
g->fillRect(bg, g->getClipBounds());
/* mouse */
// Mouse
if (widget->isEnabled()) {
if (widget->hasMouseOver())
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));
}
/* text */
draw_textstring(NULL, ColorNone, bg, false, widget, &text, 0);
// Text
drawTextStringDeprecated(NULL, ColorNone, bg, false, widget, &text, 0);
// Paint the icon
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
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;
// position
@ -1345,8 +1351,10 @@ void SkinTheme::draw_separator(Widget* widget, JRect clip)
// text
if (widget->hasText()) {
int h = jwidget_get_text_height(widget);
struct jrect r = { x1+h/2, y1-h/2, x2+1-h, y2+1+h };
draw_textstring(NULL, getColor(ThemeColor::Selected), BGCOLOR, false, widget, &r, 0);
Rect r(Point(x1+h/2, y1-h/2),
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);
if (IntersectClip clip = IntersectClip(g, Rect(rc.x, rc.y, x-rc.x, rc.h))) {
draw_textstring(g, NULL,
getColor(ThemeColor::SliderFullText),
getColor(ThemeColor::SliderFullFace), false, widget, rc, 0);
drawTextString(g, NULL,
getColor(ThemeColor::SliderFullText),
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))) {
draw_textstring(g, NULL,
getColor(ThemeColor::SliderEmptyText),
getColor(ThemeColor::SliderEmptyFace), false, widget, rc, 0);
drawTextString(g, NULL,
getColor(ThemeColor::SliderEmptyText),
getColor(ThemeColor::SliderEmptyFace), false, widget, rc, 0);
}
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();
int scroll, caret, state, selbeg, selend;
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,
getColor(ThemeColor::TextBoxFace),
getColor(ThemeColor::TextBoxText));
@ -1659,45 +1669,36 @@ void SkinTheme::paintViewViewport(PaintEvent& ev)
void SkinTheme::paintWindow(PaintEvent& ev)
{
Graphics* g = ev.getGraphics();
Window* window = static_cast<Window*>(ev.getSource());
JRect pos = jwidget_get_rect(window);
JRect cpos = jwidget_get_child_rect(window);
Rect pos = window->getClientBounds();
Rect cpos = window->getClientChildrenBounds();
if (!window->isDesktop()) {
// window frame
if (window->hasText()) {
draw_bounds_nw(ji_screen,
pos->x1,
pos->y1,
pos->x2-1,
pos->y2-1, PART_WINDOW_NW,
draw_bounds_nw(g, pos, PART_WINDOW_NW,
getColor(ThemeColor::WindowFace));
pos->y2 = cpos->y1;
pos.h = cpos.y - pos.y;
// titlebar
jdraw_text(ji_screen, window->getFont(), window->getText(),
cpos->x1,
pos->y1+jrect_h(pos)/2-text_height(window->getFont())/2,
getColor(ThemeColor::Background), ColorNone, false, jguiscale());
g->setFont(window->getFont());
g->drawString(window->getText(), ThemeColor::Background, ColorNone,
false,
gfx::Point(cpos.x,
pos.y + pos.h/2 - text_height(window->getFont())/2));
}
// menubox
else {
draw_bounds_nw(ji_screen,
pos->x1,
pos->y1,
pos->x2-1,
pos->y2-1, PART_MENU_NW,
draw_bounds_nw(g, pos, PART_MENU_NW,
getColor(ThemeColor::WindowFace));
}
}
// desktop
else {
jdraw_rectfill(pos, getColor(ThemeColor::Desktop));
g->fillRect(ThemeColor::Desktop, pos);
}
jrect_free(pos);
jrect_free(cpos);
}
void SkinTheme::paintPopupWindow(PaintEvent& ev)
@ -1718,8 +1719,11 @@ void SkinTheme::paintPopupWindow(PaintEvent& ev)
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;
if (widget->isSelected())
@ -1729,8 +1733,7 @@ void SkinTheme::drawWindowButton(ButtonBase* widget, JRect clip)
else
part = PART_WINDOW_CLOSE_BUTTON_NORMAL;
set_alpha_blender();
draw_trans_sprite(ji_screen, m_part[part], widget->rc->x1, widget->rc->y1);
g->drawAlphaBitmap(m_part[part], rc.x, rc.y);
}
void SkinTheme::paintTooltip(PaintEvent& ev)
@ -1801,9 +1804,9 @@ ui::Color SkinTheme::getWidgetBgColor(Widget* widget)
getColor(ThemeColor::Face)));
}
void SkinTheme::draw_textstring(const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, Widget* widget, const JRect rect,
int selected_offset)
void SkinTheme::drawTextStringDeprecated(const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, Widget* widget, const JRect rect,
int selected_offset)
{
if (t || widget->hasText()) {
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,
bool fill_bg, Widget* widget, const Rect& rc,
int selected_offset)
void SkinTheme::drawTextString(Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, Widget* widget, const Rect& rc,
int selected_offset)
{
if (t || widget->hasText()) {
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)
{
int w = x2 - x1 + 1;

View File

@ -32,6 +32,7 @@
#include <allegro/color.h>
namespace ui {
class Entry;
class Graphics;
class IButtonIcon;
}
@ -133,23 +134,23 @@ public:
void paintGrid(ui::PaintEvent& ev);
void paintLabel(ui::PaintEvent& ev);
void paintLinkLabel(ui::PaintEvent& ev);
void draw_listbox(ui::Widget* widget, ui::JRect clip);
void draw_listitem(ui::Widget* widget, ui::JRect clip);
void draw_menu(ui::Menu* menu, ui::JRect clip);
void draw_menuitem(ui::MenuItem* menuitem, ui::JRect clip);
void drawSplitter(ui::PaintEvent& ev);
void paintListBox(ui::PaintEvent& ev);
void paintListItem(ui::PaintEvent& ev);
void paintMenu(ui::PaintEvent& ev);
void paintMenuItem(ui::PaintEvent& ev);
void paintSplitter(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 draw_combobox_entry(ui::Entry* widget, ui::JRect clip);
void paintComboBoxEntry(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 paintViewScrollbar(ui::PaintEvent& ev);
void paintViewViewport(ui::PaintEvent& ev);
void paintWindow(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);
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_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_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)
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);
ui::Color getWidgetBgColor(ui::Widget* widget);
void draw_textstring(const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, ui::Widget* widget, const ui::JRect rect,
int selected_offset);
void draw_textstring(ui::Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, ui::Widget* widget, const gfx::Rect& rc,
int selected_offset);
void drawTextStringDeprecated(const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, ui::Widget* widget, const ui::JRect rect,
int selected_offset);
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,
int selected_offset);
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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,7 +26,7 @@ namespace ui {
static Theme* current_theme = NULL;
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()
{
@ -95,7 +95,7 @@ BITMAP* ji_apply_guiscale(BITMAP* original)
}
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);
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,
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
ji_font_set_aa_mode(f, to_system(bg_color));

View File

@ -19,11 +19,7 @@ namespace gfx {
namespace ui {
class ButtonBase;
class Cursor;
class Entry;
class Menu;
class MenuItem;
class PaintEvent;
class Widget;
@ -42,8 +38,8 @@ namespace ui {
virtual Cursor* getCursor(CursorType type) = 0;
virtual void initWidget(Widget* widget) = 0;
virtual void getWindowMask(ui::Widget* widget, gfx::Region& region) = 0;
virtual void setDecorativeWidgetBounds(ui::Widget* widget) = 0;
virtual void getWindowMask(Widget* widget, gfx::Region& region) = 0;
virtual void setDecorativeWidgetBounds(Widget* widget) = 0;
virtual void paintDesktop(PaintEvent& ev) = 0;
virtual void paintBox(PaintEvent& ev) = 0;
@ -53,17 +49,17 @@ namespace ui {
virtual void paintGrid(PaintEvent& ev) = 0;
virtual void paintLabel(PaintEvent& ev) = 0;
virtual void paintLinkLabel(PaintEvent& ev) = 0;
virtual void draw_listbox(Widget* widget, JRect clip) = 0;
virtual void draw_listitem(Widget* widget, JRect clip) = 0;
virtual void draw_menu(Menu* menu, JRect clip) = 0;
virtual void draw_menuitem(MenuItem* menuitem, JRect clip) = 0;
virtual void drawSplitter(PaintEvent& ev) = 0;
virtual void paintListBox(PaintEvent& ev) = 0;
virtual void paintListItem(PaintEvent& ev) = 0;
virtual void paintMenu(PaintEvent& ev) = 0;
virtual void paintMenuItem(PaintEvent& ev) = 0;
virtual void paintSplitter(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 draw_combobox_entry(Entry* widget, JRect clip) = 0;
virtual void paintComboBoxEntry(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 paintViewScrollbar(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);
}
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)
{
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)
{
#if 1

View File

@ -43,8 +43,6 @@ namespace ui {
// 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_height(const Widget* widget);
void jwidget_get_texticon_info(Widget* widget,
@ -259,6 +257,7 @@ namespace ui {
}
gfx::Rect getChildrenBounds() const;
gfx::Rect getClientChildrenBounds() const;
// Sets the bounds of the widget generating a onResize() event.
void setBounds(const gfx::Rect& rc);

View File

@ -117,47 +117,47 @@ void Window::onHitTest(HitTestEvent& ev)
int x = ev.getPoint().x;
int y = ev.getPoint().y;
JRect pos = jwidget_get_rect(this);
JRect cpos = jwidget_get_child_rect(this);
gfx::Rect pos = getBounds();
gfx::Rect cpos = getChildrenBounds();
// Move
if ((this->hasText())
&& (((x >= cpos->x1) &&
(x < cpos->x2) &&
(y >= pos->y1+this->border_width.b) &&
(y < cpos->y1)))) {
&& (((x >= cpos.x) &&
(x < cpos.x2()) &&
(y >= pos.y+this->border_width.b) &&
(y < cpos.y)))) {
ht = HitTestCaption;
}
// Resize
else if (m_isSizeable) {
if ((x >= pos->x1) && (x < cpos->x1)) {
if ((y >= pos->y1) && (y < cpos->y1))
if ((x >= pos.x) && (x < cpos.x)) {
if ((y >= pos.y) && (y < cpos.y))
ht = HitTestBorderNW;
else if ((y > cpos->y2-1) && (y <= pos->y2-1))
else if ((y > cpos.y2()-1) && (y <= pos.y2()-1))
ht = HitTestBorderSW;
else
ht = HitTestBorderW;
}
else if ((y >= pos->y1) && (y < cpos->y1)) {
if ((x >= pos->x1) && (x < cpos->x1))
else if ((y >= pos.y) && (y < cpos.y)) {
if ((x >= pos.x) && (x < cpos.x))
ht = HitTestBorderNW;
else if ((x > cpos->x2-1) && (x <= pos->x2-1))
else if ((x > cpos.x2()-1) && (x <= pos.x2()-1))
ht = HitTestBorderNE;
else
ht = HitTestBorderN;
}
else if ((x > cpos->x2-1) && (x <= pos->x2-1)) {
if ((y >= pos->y1) && (y < cpos->y1))
else if ((x > cpos.x2()-1) && (x <= pos.x2()-1)) {
if ((y >= pos.y) && (y < cpos.y))
ht = HitTestBorderNE;
else if ((y > cpos->y2-1) && (y <= pos->y2-1))
else if ((y > cpos.y2()-1) && (y <= pos.y2()-1))
ht = HitTestBorderSE;
else
ht = HitTestBorderE;
}
else if ((y > cpos->y2-1) && (y <= pos->y2-1)) {
if ((x >= pos->x1) && (x < cpos->x1))
else if ((y > cpos.y2()-1) && (y <= pos.y2()-1)) {
if ((x >= pos.x) && (x < cpos.x))
ht = HitTestBorderSW;
else if ((x > cpos->x2-1) && (x <= pos->x2-1))
else if ((x > cpos.x2()-1) && (x <= pos.x2()-1))
ht = HitTestBorderSE;
else
ht = HitTestBorderS;
@ -168,9 +168,6 @@ void Window::onHitTest(HitTestEvent& ev)
ht = HitTestClient;
}
jrect_free(pos);
jrect_free(cpos);
ev.setHit(ht);
}
@ -525,17 +522,15 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
Region new_drawable_region;
Region manager_refresh_region; // A region to refresh the manager later
Region window_refresh_region; // A new region to refresh the window later
JRect old_pos;
JRect man_pos;
Message* msg;
manager->dispatchMessages();
/* get the window's current position */
old_pos = jrect_new_copy(this->rc);
// Get the window's current position
Rect old_pos = getBounds();
/* get the manager's current position */
man_pos = jwidget_get_rect(manager);
// Get the manager's current position
Rect man_pos = manager->getBounds();
/* sent a kWinMoveMessage message to the window */
msg = jmessage_new(kWinMoveMessage);
@ -546,8 +541,8 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
getDrawableRegion(old_drawable_region, FLAGS);
// If the size of the window changes...
if (jrect_w(old_pos) != rect.w ||
jrect_h(old_pos) != rect.h) {
if (old_pos.w != rect.w ||
old_pos.h != rect.h) {
// We have to change the position of all children.
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 -
// old_position)...
displace_widgets(this,
rect.x - old_pos->x1,
rect.y - old_pos->y1);
rect.x - old_pos.x,
rect.y - old_pos.y);
}
// 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
reg1 = new_drawable_region;
reg1.offset(old_pos->x1 - this->rc->x1,
old_pos->y1 - this->rc->y1);
reg1.offset(old_pos.x - this->rc->x1,
old_pos.y - this->rc->y1);
moveable_region.createIntersection(old_drawable_region, reg1);
reg1.createSubtraction(reg1, moveable_region);
reg1.offset(this->rc->x1 - old_pos->x1,
this->rc->y1 - old_pos->y1);
reg1.offset(this->rc->x1 - old_pos.x,
this->rc->y1 - old_pos.y);
window_refresh_region.createUnion(window_refresh_region, reg1);
// Move the window's graphics
jmouse_hide();
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,
this->rc->x1 - old_pos->x1,
this->rc->y1 - old_pos->y1);
this->rc->x1 - old_pos.x,
this->rc->y1 - old_pos.y);
set_clip_rect(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1);
jmouse_show();
}
manager->invalidateDisplayRegion(manager_refresh_region);
invalidateRegion(window_refresh_region);
jrect_free(old_pos);
jrect_free(man_pos);
}
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* child = UI_FIRST_WIDGET(viewport->getChildren());
JRect pos = jwidget_get_rect(this);
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
bool selected = false;
@ -70,14 +69,10 @@ bool EditorView::onProcessMessage(Message* msg)
}
theme->draw_bounds_nw(ji_screen,
pos->x1, pos->y1,
pos->x2-1, pos->y2-1,
theme->draw_bounds_nw(ji_screen, getBounds(),
selected ? PART_EDITOR_SELECTED_NW:
PART_EDITOR_NORMAL_NW,
ColorNone);
jrect_free(pos);
}
return true;

View File

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

View File

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

View File

@ -72,6 +72,8 @@ Tabs::Tabs(TabsDelegate* delegate)
, m_delegate(delegate)
, m_timer(1000/60, this)
{
setDoubleBuffered(true);
m_hot = NULL;
m_selected = NULL;
m_scrollX = 0;
@ -244,93 +246,6 @@ bool Tabs::onProcessMessage(Message* msg)
{
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 kMouseMoveMessage:
calculateHot();
@ -425,6 +340,76 @@ bool Tabs::onProcessMessage(Message* 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)
{
setBoundsQuietly(ev.getBounds());
@ -467,10 +452,10 @@ void Tabs::selectTabInternal(Tab* tab)
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?
if (box->x1 >= this->rc->x2 || box->x2 <= this->rc->x1)
if (box.x >= this->rc->x2 || box.x2() <= this->rc->x1)
return;
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);
}
if (jrect_w(box) > 2) {
theme->draw_bounds_nw(bmp,
box->x1, box->y1+y_delta, box->x2-1, box->y2-1,
if (box.w > 2) {
theme->draw_bounds_nw(g,
gfx::Rect(box.x, box.y+y_delta, box.w, box.h),
(selected) ? PART_TAB_SELECTED_NW:
PART_TAB_NORMAL_NW,
face_color);
jdraw_text(bmp, this->getFont(), tab->text.c_str(),
box->x1+4*jguiscale(),
(box->y1+box->y2)/2-text_height(this->getFont())/2+1 + y_delta,
text_color, face_color, false, jguiscale());
g->drawString(tab->text, text_color, face_color, false,
gfx::Point(box.x + 4*jguiscale(),
box.y + box.h/2 - text_height(this->getFont())/2+1 + y_delta));
}
if (selected) {
theme->draw_bounds_nw(bmp,
box->x1, box->y2, box->x2-1, this->rc->y2-1,
theme->draw_bounds_nw(g, gfx::Rect(box.x, box.y2(), box.w, this->rc->y2-box.y2()),
PART_TAB_BOTTOM_SELECTED_NW,
theme->getColor(ThemeColor::TabSelectedFace));
}
else {
theme->draw_part_as_hline(bmp,
box->x1, box->y2, box->x2-1, this->rc->y2-1,
theme->draw_part_as_hline(g, gfx::Rect(box.x, box.y2(), box.w, this->rc->y2-box.y2()),
PART_TAB_BOTTOM_NORMAL);
}
#ifdef CLOSE_BUTTON_IN_EACH_TAB
BITMAP* close_icon = theme->get_part(PART_WINDOW_CLOSE_BUTTON_NORMAL);
set_alpha_blender();
draw_trans_sprite(doublebuffer, close_icon,
box->x2-4*jguiscale()-close_icon->w,
(box->y1+box->y2)/2-close_icon->h/2+1*jguiscale());
g->drawAlphaBitmap(close_icon,
box.x2() - 4*jguiscale() - close_icon->w,
box.y + box.h/2 - close_icon->h/2+1 * jguiscale());
#endif
}
@ -626,8 +607,8 @@ void Tabs::setScrollX(int scroll_x)
void Tabs::calculateHot()
{
JRect rect = jwidget_get_rect(this);
JRect box = jrect_new(rect->x1-m_scrollX, rect->y1, 0, rect->y2-1);
gfx::Rect rect = getBounds();
gfx::Rect box(rect.x-m_scrollX, rect.y, 0, rect.h-1);
Tab *hot = NULL;
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) {
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;
break;
}
box->x1 = box->x2;
box.x += box.w;
}
if (m_hot != hot) {
@ -653,9 +634,6 @@ void Tabs::calculateHot()
invalidate();
}
jrect_free(rect);
jrect_free(box);
}
void Tabs::calcTabWidth(Tab* tab)

View File

@ -27,6 +27,10 @@
class Tabs;
namespace ui {
class Graphics;
}
// Required interface to be implemented by each new tab that is added
// in the Tabs widget.
class TabView
@ -94,6 +98,7 @@ public:
protected:
bool onProcessMessage(ui::Message* msg) OVERRIDE;
void onPaint(ui::PaintEvent& ev) OVERRIDE;
void onResize(ui::ResizeEvent& ev) OVERRIDE;
void onPreferredSize(ui::PreferredSizeEvent& ev) OVERRIDE;
void onInitTheme(ui::InitThemeEvent& ev) OVERRIDE;
@ -104,7 +109,7 @@ private:
void stopAni();
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);
Tab* getTabByView(TabView* tabView);
int getMaxScrollX();