Replace ui::jregion with gfx::Region class

This is an old TODO item, and it's the first step to finally
get rid of JRect and struct jrect.
This commit is contained in:
David Capello 2013-01-13 22:39:44 -03:00
parent 6332b1a6e5
commit eacd0c7642
32 changed files with 357 additions and 3263 deletions

View File

@ -53,7 +53,6 @@
* About Signals/Slots: Add some field in slots to avoid disconnecting
them from dead signals.
* Replace JRect & jrect with gfx::Rect.
* Create gfx::Region to replace JRegion & jregion.
* editors_ -> MultiEditors class widget
* convert all widgets to classes:
* match UI library design with Vaca library.

View File

@ -32,7 +32,6 @@
#include "raster/stock.h"
#include "ui/manager.h"
#include "ui/rect.h"
#include "ui/region.h"
#include "ui/view.h"
#include "ui/widget.h"
#include "undo_transaction.h"
@ -256,28 +255,21 @@ void FilterManagerImpl::applyToTarget()
void FilterManagerImpl::flush()
{
if (m_row >= 0) {
JRegion reg1, reg2;
struct jrect rect;
gfx::Rect rect;
Editor* editor = current_editor;
reg1 = jregion_new(NULL, 0);
editor->editorToScreen(m_x+m_offset_x,
m_y+m_offset_y+m_row-1,
&rect.x1, &rect.y1);
rect.x2 = rect.x1 + (m_w << editor->getZoom());
rect.y2 = rect.y1 + (1 << editor->getZoom());
&rect.x, &rect.y);
rect.w = (m_w << editor->getZoom());
rect.h = (1 << editor->getZoom());
reg2 = jregion_new(&rect, 1);
jregion_union(reg1, reg1, reg2);
jregion_free(reg2);
reg2 = jwidget_get_drawable_region(editor, JI_GDR_CUTTOPWINDOWS);
jregion_intersect(reg1, reg1, reg2);
jregion_free(reg2);
gfx::Region reg1(rect);
gfx::Region reg2;
editor->getDrawableRegion(reg2, Widget::kCutTopWindows);
reg1.createIntersection(reg1, reg2);
editor->invalidateRegion(reg1);
jregion_free(reg1);
}
}

View File

@ -1383,10 +1383,10 @@ void AnimationEditor::setScroll(int x, int y, bool use_refresh_region)
int old_scroll_y = 0;
int max_scroll_x;
int max_scroll_y;
JRegion region = NULL;
Region region;
if (use_refresh_region) {
region = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
getDrawableRegion(region, kCutTopWindows);
old_scroll_x = m_scroll_x;
old_scroll_y = m_scroll_y;
}
@ -1404,51 +1404,36 @@ void AnimationEditor::setScroll(int x, int y, bool use_refresh_region)
int new_scroll_y = m_scroll_y;
int dx = old_scroll_x - new_scroll_x;
int dy = old_scroll_y - new_scroll_y;
JRegion reg1 = jregion_new(NULL, 0);
JRegion reg2 = jregion_new(NULL, 0);
JRect rect2 = jrect_new(0, 0, 0, 0);
Rect rect2;
Region reg1;
jmouse_hide();
// Scroll layers.
jrect_replace(rect2,
this->rc->x1,
this->rc->y1 + HDRSIZE,
this->rc->x1 + m_separator_x,
this->rc->y2);
jregion_reset(reg2, rect2);
jregion_copy(reg1, region);
jregion_intersect(reg1, reg1, reg2);
this->scrollRegion(reg1, 0, dy);
rect2 = Rect(this->rc->x1,
this->rc->y1 + HDRSIZE,
m_separator_x,
this->rc->y2 - (this->rc->y1 + HDRSIZE));
reg1.createIntersection(region, Region(rect2));
scrollRegion(reg1, 0, dy);
// Scroll header-frame.
jrect_replace(rect2,
this->rc->x1 + m_separator_x + m_separator_w,
this->rc->y1,
this->rc->x2,
this->rc->y1 + HDRSIZE);
jregion_reset(reg2, rect2);
jregion_copy(reg1, region);
jregion_intersect(reg1, reg1, reg2);
this->scrollRegion(reg1, dx, 0);
rect2 = Rect(this->rc->x1 + m_separator_x + m_separator_w,
this->rc->y1,
this->rc->x2 - (this->rc->x1 + m_separator_x + m_separator_w),
HDRSIZE);
reg1.createIntersection(region, Region(rect2));
scrollRegion(reg1, dx, 0);
// Scroll cels.
jrect_replace(rect2,
this->rc->x1 + m_separator_x + m_separator_w,
this->rc->y1 + HDRSIZE,
this->rc->x2,
this->rc->y2);
jregion_reset(reg2, rect2);
jregion_copy(reg1, region);
jregion_intersect(reg1, reg1, reg2);
this->scrollRegion(reg1, dx, dy);
rect2 = Rect(this->rc->x1 + m_separator_x + m_separator_w,
this->rc->y1 + HDRSIZE,
this->rc->x2 - (this->rc->x1 + m_separator_x + m_separator_w),
this->rc->y2 - (this->rc->y1 + HDRSIZE));
reg1.createIntersection(region, Region(rect2));
scrollRegion(reg1, dx, dy);
jmouse_show();
jregion_free(region);
jregion_free(reg1);
jregion_free(reg2);
jrect_free(rect2);
}
}

View File

@ -577,7 +577,7 @@ Cursor* SkinTheme::getCursor(CursorType type)
}
}
void SkinTheme::init_widget(Widget* widget)
void SkinTheme::initWidget(Widget* widget)
{
#define BORDER(n) \
widget->border_width.l = (n); \
@ -781,12 +781,12 @@ void SkinTheme::init_widget(Widget* widget)
}
}
JRegion SkinTheme::get_window_mask(Widget* widget)
void SkinTheme::getWindowMask(Widget* widget, Region& region)
{
return jregion_new(widget->rc, 1);
region = widget->getBounds();
}
void SkinTheme::map_decorative_widget(Widget* widget)
void SkinTheme::mapDecorativeWidget(Widget* widget)
{
if (widget->getId() == kThemeCloseButtonId) {
Widget* window = widget->getParent();

View File

@ -119,9 +119,9 @@ public:
void reload_fonts();
ui::Cursor* getCursor(ui::CursorType type);
void init_widget(ui::Widget* widget);
ui::JRegion get_window_mask(ui::Widget* widget);
void map_decorative_widget(ui::Widget* widget);
void initWidget(ui::Widget* widget);
void getWindowMask(ui::Widget* widget, gfx::Region& region);
void mapDecorativeWidget(ui::Widget* widget);
void paintDesktop(ui::PaintEvent& ev);
void paintBox(ui::PaintEvent& ev);

View File

@ -36,7 +36,6 @@ add_library(ui-lib
preferred_size_event.cpp
property.cpp
rect.cpp
region.cpp
scroll_bar.cpp
separator.cpp
slider.cpp

View File

@ -32,7 +32,6 @@
namespace ui {
struct jrect;
struct jregion;
// Alignment.
#define JI_HORIZONTAL 0x0001
@ -134,14 +133,9 @@ namespace ui {
JM_REGISTERED_MESSAGES
};
// Flags for jwidget_get_drawable_region.
#define JI_GDR_CUTTOPWINDOWS 1 // Cut areas where are windows on top.
#define JI_GDR_USECHILDAREA 2 // Use areas where are children.
typedef unsigned int JID;
typedef struct jrect* JRect;
typedef struct jregion* JRegion;
class GuiSystem {
public:

View File

@ -14,7 +14,6 @@
#include "ui/font.h"
#include "ui/intern.h"
#include "ui/rect.h"
#include "ui/region.h"
#include "ui/system.h"
#include "ui/widget.h"
@ -154,33 +153,33 @@ void jdraw_text(BITMAP* bmp, FONT* font, const char *s, int x, int y,
}
}
void ji_move_region(JRegion region, int dx, int dy)
void ji_move_region(const Region& region, int dx, int dy)
{
int c, nrects = JI_REGION_NUM_RECTS(region);
JRect rc;
size_t nrects = region.size();
// Blit directly screen to screen.
if (is_linear_bitmap(ji_screen) && nrects == 1) {
rc = JI_REGION_RECTS(region);
blit(ji_screen, ji_screen,
rc->x1, rc->y1,
rc->x1+dx, rc->y1+dy, jrect_w(rc), jrect_h(rc));
Rect rc = region[0];
blit(ji_screen, ji_screen, rc.x, rc.y, rc.x+dx, rc.y+dy, rc.w, rc.h);
}
// Blit saving areas and copy them.
else if (nrects > 1) {
std::vector<BITMAP*> images(nrects);
Region::const_iterator it, begin=region.begin(), end=region.end();
BITMAP* bmp;
int c;
for (c=0, rc=JI_REGION_RECTS(region); c<nrects; ++c, ++rc) {
bmp = create_bitmap(jrect_w(rc), jrect_h(rc));
blit(ji_screen, bmp,
rc->x1, rc->y1, 0, 0, bmp->w, bmp->h);
for (c=0, it=begin; it != end; ++it, ++c) {
const Rect& rc = *it;
bmp = create_bitmap(rc.w, rc.h);
blit(ji_screen, bmp, rc.x, rc.y, 0, 0, bmp->w, bmp->h);
images[c] = bmp;
}
for (c=0, rc=JI_REGION_RECTS(region); c<nrects; ++c, ++rc) {
for (c=0, it=begin; it != end; ++it, ++c) {
const Rect& rc = *it;
bmp = images[c];
blit(bmp, ji_screen, 0, 0, rc->x1+dx, rc->y1+dy, bmp->w, bmp->h);
blit(bmp, ji_screen, 0, 0, rc.x+dx, rc.y+dy, bmp->w, bmp->h);
destroy_bitmap(bmp);
}
}

View File

@ -8,6 +8,7 @@
#define UI_DRAW_H_INCLUDED
#include "gfx/rect.h"
#include "gfx/region.h"
#include "ui/base.h"
#include "ui/color.h"
@ -34,7 +35,7 @@ namespace ui {
void jdraw_inverted_sprite(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void ji_move_region(JRegion region, int dx, int dy);
void ji_move_region(const gfx::Region& region, int dx, int dy);
} // namespace ui

View File

@ -44,7 +44,6 @@
#include "ui/preferred_size_event.h"
#include "ui/property.h"
#include "ui/rect.h"
#include "ui/region.h"
#include "ui/save_layout_event.h"
#include "ui/scroll_bar.h"
#include "ui/separator.h"

View File

@ -824,15 +824,13 @@ void Manager::_openWindow(Window* window)
void Manager::_closeWindow(Window* window, bool redraw_background)
{
Message* msg;
JRegion reg1;
gfx::Region reg1;
if (!hasChild(window))
return;
if (redraw_background)
reg1 = jwidget_get_region(window);
else
reg1 = NULL;
window->getRegion(reg1);
// Close all windows to this desktop
if (window->is_desktop()) {
@ -841,9 +839,9 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
if (child == window)
break;
else {
JRegion reg2 = jwidget_get_region(window);
jregion_union(reg1, reg1, reg2);
jregion_free(reg2);
gfx::Region reg2;
window->getRegion(reg2);
reg1.createUnion(reg1, reg2);
_closeWindow(child, false);
}
@ -872,10 +870,7 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
removeChild(window);
// Redraw background.
if (reg1) {
invalidateRegion(reg1);
jregion_free(reg1);
}
invalidateRegion(reg1);
// Maybe the window is in the "new_windows" list.
WidgetsList::iterator it =
@ -1115,14 +1110,11 @@ void Manager::pumpQueue()
}
}
void Manager::invalidateDisplayRegion(const JRegion region)
void Manager::invalidateDisplayRegion(const gfx::Region& region)
{
JRegion reg1 = jregion_new(NULL, 0);
JRegion reg2 = jregion_new(this->rc, 0);
JRegion reg3;
// TODO intersect with jwidget_get_drawable_region()???
jregion_intersect(reg1, region, reg2);
// TODO intersect with getDrawableRegion()???
gfx::Region reg1;
reg1.createIntersection(region, gfx::Region(getBounds()));
// Redraw windows from top to background.
bool withDesktop = false;
@ -1139,19 +1131,15 @@ void Manager::invalidateDisplayRegion(const JRegion region)
}
// Clip this window area for the next window.
reg3 = jwidget_get_region(window);
jregion_copy(reg2, reg1);
jregion_subtract(reg1, reg2, reg3);
jregion_free(reg3);
gfx::Region reg3;
window->getRegion(reg3);
reg1.createSubtraction(reg1, reg3);
}
// Invalidate areas outside windows (only when there are not a
// desktop window).
if (!withDesktop)
Widget::invalidateRegion(reg1);
jregion_free(reg1);
jregion_free(reg2);
}
LayoutIO* Manager::getLayoutIO()

View File

@ -64,7 +64,7 @@ namespace ui {
void removeMessageFilter(int message, Widget* widget);
void removeMessageFilterFor(Widget* widget);
void invalidateDisplayRegion(const JRegion region);
void invalidateDisplayRegion(const gfx::Region& region);
LayoutIO* getLayoutIO();

View File

@ -679,11 +679,8 @@ void MenuBox::set_position(JRect rect)
{
jrect_copy(this->rc, rect);
if (Menu* menu = getMenu()) {
JRect cpos = jwidget_get_child_rect(this);
jwidget_set_rect(menu, cpos);
jrect_free(cpos);
}
if (Menu* menu = getMenu())
menu->setBounds(getChildrenBounds());
}
bool MenuItem::onProcessMessage(Message* msg)

View File

@ -74,12 +74,6 @@ namespace ui {
struct jrect rect; /* set position */
};
struct MessageDrawRgn
{
MessageAny any;
JRegion region; /* region to redraw */
};
struct MessageUser
{
MessageAny any;
@ -96,7 +90,6 @@ namespace ui {
MessageMouse mouse;
MessageTimer timer;
MessageSetPos setpos;
MessageDrawRgn drawrgn;
MessageUser user;
};

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,6 @@ PopupWindow::PopupWindow(const char* text, bool close_on_buttonpressed)
: Window(false, text)
{
m_close_on_buttonpressed = close_on_buttonpressed;
m_hot_region = NULL;
m_filtering = false;
set_sizeable(false);
@ -40,25 +39,17 @@ PopupWindow::PopupWindow(const char* text, bool close_on_buttonpressed)
PopupWindow::~PopupWindow()
{
stopFilteringMessages();
if (m_hot_region != NULL)
jregion_free(m_hot_region);
}
/**
* @param region The new hot-region. This pointer is holded by the @a widget.
* So you cannot destroy it after calling this routine.
*/
void PopupWindow::setHotRegion(JRegion region)
void PopupWindow::setHotRegion(const gfx::Region& region)
{
ASSERT(region != NULL);
if (m_hot_region != NULL)
jregion_free(m_hot_region);
startFilteringMessages();
m_hot_region = region;
m_hotRegion = region;
}
void PopupWindow::makeFloating()
@ -82,7 +73,7 @@ bool PopupWindow::onProcessMessage(Message* msg)
break;
case JM_MOUSELEAVE:
if (m_hot_region == NULL && !is_moveable())
if (m_hotRegion.isEmpty() && !is_moveable())
closeWindow(NULL);
break;
@ -119,13 +110,11 @@ bool PopupWindow::onProcessMessage(Message* msg)
case JM_MOTION:
if (!is_moveable() &&
m_hot_region != NULL &&
!m_hotRegion.isEmpty() &&
getManager()->getCapture() == NULL) {
struct jrect box;
// If the mouse is outside the hot-region we have to close the
// window.
if (!jregion_point_in(m_hot_region, msg->mouse.x, msg->mouse.y, &box))
if (!m_hotRegion.contains(Point(msg->mouse.x, msg->mouse.y)))
closeWindow(NULL);
}
break;

View File

@ -18,7 +18,7 @@ namespace ui {
PopupWindow(const char* text, bool close_on_buttonpressed);
~PopupWindow();
void setHotRegion(JRegion region);
void setHotRegion(const gfx::Region& region);
void makeFloating();
void makeFixed();
@ -34,7 +34,7 @@ namespace ui {
void stopFilteringMessages();
bool m_close_on_buttonpressed;
JRegion m_hot_region;
gfx::Region m_hotRegion;
bool m_filtering;
};

View File

@ -1,115 +0,0 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is distributed under a BSD-like license, please
// read LICENSE.txt for more information.
#include "config.h"
#include <allegro.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "base/memory.h"
#include "ui/base.h"
#include "ui/rect.h"
#include "ui/region.h"
namespace ui {
#define xalloc base_malloc
#define xfree base_free
#define xrealloc base_realloc
#define Bool bool
#define BoxRec struct jrect
#define RegDataRec struct jregion_data
#define RegionRec struct jregion
#define BoxPtr JRect
#define RegDataPtr RegDataRec *
#define RegionPtr JRegion
#define NullBox ((JRect)NULL)
#define REGION_NIL(reg) JI_REGION_NIL(reg)
#define REGION_NAR(reg) JI_REGION_NAR(reg)
#define REGION_NUM_RECTS(reg) JI_REGION_NUM_RECTS(reg)
#define REGION_SIZE(reg) JI_REGION_SIZE(reg)
#define REGION_RECTS(reg) JI_REGION_RECTS(reg)
#define REGION_BOXPTR(reg) JI_REGION_RECTPTR(reg)
#define REGION_BOX(reg,i) JI_REGION_RECT(reg,i)
#define REGION_TOP(reg) JI_REGION_TOP(reg)
#define REGION_END(reg) JI_REGION_END(reg)
#define REGION_SZOF(n) JI_REGION_SZOF(n)
#define rgnOUT JI_RGNOUT
#define rgnIN JI_RGNIN
#define rgnPART JI_RGNPART
struct ji_point { int x, y; };
#define DDXPointRec struct ji_point
#define DDXPointPtr DDXPointRec *
#if !defined(MAXSHORT) || !defined(MINSHORT) || \
!defined(MAXINT) || !defined(MININT)
/*
* Some implementations #define these through <math.h>, so preclude
* #include'ing it later.
*/
#include <math.h>
#endif
#undef MAXSHORT
#define MAXSHORT SHRT_MAX
#undef MINSHORT
#define MINSHORT SHRT_MIN
#undef MAXINT
#define MAXINT INT_MAX
#undef MININT
#define MININT INT_MIN
// min/max macros
#ifndef min
#define min MIN
#endif
#ifndef max
#define max MAX
#endif
#define miBrokenData ji_broken_data
#define miBrokenRegion ji_broken_region
#define miRegionCreate jregion_new
#define miRegionInit jregion_init
#define miRegionDestroy jregion_free
#define miRegionUninit jregion_uninit
#define miRegionCopy jregion_copy
#define miIntersect jregion_intersect
#define miUnion jregion_union
#define miRegionAppend jregion_append
#define miRegionValidate jregion_validate
/* JRegion jrects_to_region(int nrects, JRect *prect, int ctype); */
#define miSubtract jregion_subtract
#define miInverse jregion_inverse
#define miRectIn jregion_rect_in
#define miTranslateRegion jregion_translate
#define miRegionReset jregion_reset
#define miRegionBreak jregion_break
#define miPointInRegion jregion_point_in
#define miRegionEqual jregion_equal
#define miRegionNotEmpty jregion_notempty
#define miRegionEmpty jregion_empty
#define miRegionExtents jregion_extents
#undef assert
#define assert ASSERT
#include "miregion.cpp"
} // namespace ui

View File

@ -1,78 +0,0 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is distributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef UI_REGION_H_INCLUDED
#define UI_REGION_H_INCLUDED
#include "ui/rect.h"
namespace ui {
#define JI_REGION_NIL(reg) ((reg)->data && !(reg)->data->numRects)
/* not a region */
#define JI_REGION_NAR(reg) ((reg)->data == &ji_broken_data)
#define JI_REGION_NUM_RECTS(reg) ((reg)->data ? (reg)->data->numRects : 1)
#define JI_REGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0)
#define JI_REGION_RECTS(reg) ((reg)->data ? (JRect)((reg)->data + 1) \
: &(reg)->extents)
#define JI_REGION_RECTPTR(reg) ((JRect)((reg)->data + 1))
#define JI_REGION_RECT(reg,i) (&JI_REGION_RECTPTR(reg)[i])
#define JI_REGION_TOP(reg) JI_REGION_RECT(reg, (reg)->data->numRects)
#define JI_REGION_END(reg) JI_REGION_RECT(reg, (reg)->data->numRects - 1)
#define JI_REGION_SZOF(n) (sizeof(struct jregion_data) + ((n) * sizeof(struct jrect)))
/* return values from jregion_rect_in */
#define JI_RGNOUT 0
#define JI_RGNIN 1
#define JI_RGNPART 2
struct jregion_data
{
int size;
int numRects;
/* struct jrect rects[size]; */
};
struct jregion
{
struct jrect extents;
struct jregion_data *data;
};
extern struct jregion_data ji_broken_data;
extern struct jregion ji_broken_region;
JRegion jregion_new(JRect rect, int size);
void jregion_init(JRegion reg, JRect rect, int size);
void jregion_free(JRegion reg);
void jregion_uninit(JRegion reg);
bool jregion_copy(JRegion dst, JRegion src);
bool jregion_intersect(JRegion newrgn, JRegion reg1, JRegion reg2);
bool jregion_union(JRegion newrgn, JRegion reg1, JRegion reg2);
bool jregion_append(JRegion dstrgn, JRegion rgn);
bool jregion_validate(JRegion badreg, bool *overlap);
/* JRegion jrects_to_region(int nrects, JRect *prect, int ctype); */
bool jregion_subtract(JRegion regD, JRegion regM, JRegion regS);
bool jregion_inverse(JRegion newReg, JRegion reg1, JRect invRect);
int jregion_rect_in(JRegion region, JRect rect);
void jregion_translate(JRegion reg, int x, int y);
void jregion_reset(JRegion reg, JRect box);
bool jregion_break(JRegion reg);
bool jregion_point_in(JRegion reg, int x, int y, JRect box);
bool jregion_equal(JRegion reg1, JRegion reg2);
bool jregion_notempty(JRegion reg);
void jregion_empty(JRegion reg);
JRect jregion_extents(JRegion reg);
} // namespace ui
#endif

View File

@ -17,7 +17,6 @@
#include "ui/overlay.h"
#include "ui/overlay_manager.h"
#include "ui/rect.h"
#include "ui/region.h"
#include "ui/theme.h"
#include "ui/widget.h"
@ -33,7 +32,6 @@ namespace ui {
/* Global output bitmap. */
BITMAP* ji_screen = NULL;
JRegion ji_dirty_region = NULL;
int ji_screen_w = 0;
int ji_screen_h = 0;

View File

@ -13,6 +13,10 @@
struct BITMAP;
struct FONT;
namespace gfx {
class Region;
}
namespace ui {
class ButtonBase;
@ -37,9 +41,9 @@ namespace ui {
void regenerate();
virtual Cursor* getCursor(CursorType type) = 0;
virtual void init_widget(Widget* widget) = 0;
virtual ui::JRegion get_window_mask(ui::Widget* widget) = 0;
virtual void map_decorative_widget(ui::Widget* widget) = 0;
virtual void initWidget(Widget* widget) = 0;
virtual void getWindowMask(ui::Widget* widget, gfx::Region& region) = 0;
virtual void mapDecorativeWidget(ui::Widget* widget) = 0;
virtual void paintDesktop(PaintEvent& ev) = 0;
virtual void paintBox(PaintEvent& ev) = 0;

View File

@ -153,7 +153,6 @@ TipWindow::TipWindow(const char *text, bool close_on_buttonpressed)
: Window(false, text)
{
m_close_on_buttonpressed = close_on_buttonpressed;
m_hot_region = NULL;
m_filtering = false;
m_arrowAlign = 0;
@ -175,29 +174,18 @@ TipWindow::~TipWindow()
getManager()->removeMessageFilter(JM_BUTTONPRESSED, this);
getManager()->removeMessageFilter(JM_KEYPRESSED, this);
}
if (m_hot_region != NULL) {
jregion_free(m_hot_region);
}
}
/**
* @param region The new hot-region. This pointer is holded by the @a widget.
* So you can't destroy it after calling this routine.
*/
void TipWindow::set_hotregion(JRegion region)
void TipWindow::setHotRegion(const Region& region)
{
ASSERT(region != NULL);
if (m_hot_region != NULL)
jregion_free(m_hot_region);
if (!m_filtering) {
m_filtering = true;
getManager()->addMessageFilter(JM_MOTION, this);
getManager()->addMessageFilter(JM_BUTTONPRESSED, this);
getManager()->addMessageFilter(JM_KEYPRESSED, this);
}
m_hot_region = region;
m_hotRegion = region;
}
int TipWindow::getArrowAlign() const
@ -224,8 +212,8 @@ bool TipWindow::onProcessMessage(Message* msg)
break;
case JM_MOUSELEAVE:
if (m_hot_region == NULL)
this->closeWindow(NULL);
if (m_hotRegion.isEmpty())
closeWindow(NULL);
break;
case JM_KEYPRESSED:
@ -250,14 +238,11 @@ bool TipWindow::onProcessMessage(Message* msg)
break;
case JM_MOTION:
if (m_hot_region != NULL &&
if (!m_hotRegion.isEmpty() &&
getManager()->getCapture() == NULL) {
struct jrect box;
/* if the mouse is outside the hot-region we have to close the window */
if (!jregion_point_in(m_hot_region,
msg->mouse.x, msg->mouse.y, &box)) {
this->closeWindow(NULL);
// If the mouse is outside the hot-region we have to close the window
if (!m_hotRegion.contains(Point(msg->mouse.x, msg->mouse.y))) {
closeWindow(NULL);
}
}
break;

View File

@ -57,7 +57,7 @@ namespace ui {
TipWindow(const char *text, bool close_on_buttonpressed = false);
~TipWindow();
void set_hotregion(JRegion region);
void setHotRegion(const gfx::Region& region);
int getArrowAlign() const;
void setArrowAlign(int arrowAlign);
@ -70,7 +70,7 @@ namespace ui {
private:
bool m_close_on_buttonpressed;
JRegion m_hot_region;
gfx::Region m_hotRegion;
bool m_filtering;
int m_arrowAlign;
};

View File

@ -11,7 +11,6 @@
#include "ui/message.h"
#include "ui/preferred_size_event.h"
#include "ui/rect.h"
#include "ui/region.h"
#include "ui/system.h"
#include "ui/theme.h"
#include "ui/view.h"
@ -250,9 +249,9 @@ bool View::onProcessMessage(Message* msg)
// TODO This is theme specific stuff
// Redraw the borders each time the focus enters or leaves the view.
{
JRegion region = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
Region region;
getDrawableRegion(region, kCutTopWindows);
invalidateRegion(region);
jregion_free(region);
}
break;
}

View File

@ -63,8 +63,6 @@ Widget::Widget(int type)
this->m_font = this->m_theme ? this->m_theme->default_font: NULL;
this->m_bgColor = ui::ColorNone;
this->m_update_region = jregion_new(NULL, 0);
this->theme_data[0] = NULL;
this->theme_data[1] = NULL;
this->theme_data[2] = NULL;
@ -98,10 +96,6 @@ Widget::~Widget()
while (!m_children.empty())
delete m_children.front();
/* destroy the update region */
if (m_update_region)
jregion_free(m_update_region);
/* destroy widget position */
if (this->rc)
jrect_free(this->rc);
@ -576,6 +570,14 @@ Rect Widget::getClientBounds() const
return Rect(0, 0, jrect_w(rc), jrect_h(rc));
}
Rect Widget::getChildrenBounds() const
{
return Rect(rc->x1+border_width.l,
rc->y1+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)
{
jrect jrc = { rc.x, rc.y, rc.x+rc.w, rc.y+rc.h };
@ -595,6 +597,108 @@ void Widget::setBorder(const Border& br)
border_width.b = br.bottom();
}
void Widget::getRegion(gfx::Region& region)
{
if (this->type == JI_WINDOW)
getTheme()->getWindowMask(this, region);
else
region = getBounds();
}
void Widget::getDrawableRegion(gfx::Region& region, DrawableRegionFlags flags)
{
Widget* window, *manager, *view;
getRegion(region);
// Cut the top windows areas
if (flags & kCutTopWindows) {
window = getRoot();
manager = window ? window->getManager(): NULL;
while (manager) {
const WidgetsList& windows_list = manager->getChildren();
WidgetsList::const_reverse_iterator it =
std::find(windows_list.rbegin(), windows_list.rend(), window);
if (!windows_list.empty() &&
window != windows_list.front() &&
it != windows_list.rend()) {
// Subtract the rectangles
for (++it; it != windows_list.rend(); ++it) {
Region reg1;
(*it)->getRegion(reg1);
region.createSubtraction(region, reg1);
}
}
window = manager->getRoot();
manager = window ? window->getManager(): NULL;
}
}
// Clip the areas where are children
if (!(flags & kUseChildArea) && !getChildren().empty()) {
Region reg1;
Region reg2(getChildrenBounds());
UI_FOREACH_WIDGET(getChildren(), it) {
Widget* child = *it;
if (child->isVisible()) {
Region reg3;
child->getRegion(reg3);
if (child->flags & JI_DECORATIVE) {
reg1 = getBounds();
reg1.createIntersection(reg1, reg3);
}
else {
reg1.createIntersection(reg2, reg3);
}
region.createSubtraction(region, reg1);
}
}
}
// Intersect with the parent area
if (!(this->flags & JI_DECORATIVE)) {
Widget* parent = getParent();
while (parent) {
region.createIntersection(region,
Region(parent->getChildrenBounds()));
parent = parent->getParent();
}
}
else {
Widget* parent = getParent();
if (parent) {
region.createIntersection(region,
Region(parent->getBounds()));
}
}
// Limit to the manager area
window = getRoot();
manager = (window ? window->getManager(): NULL);
while (manager) {
view = View::getView(manager);
Rect cpos;
if (view) {
cpos = static_cast<View*>(view)->getViewportBounds();
}
else
cpos = manager->getChildrenBounds();
region.createIntersection(region, Region(cpos));
window = manager->getRoot();
manager = (window ? window->getManager(): NULL);
}
}
/* gets the position of the widget */
JRect jwidget_get_rect(Widget* widget)
{
@ -614,141 +718,6 @@ JRect jwidget_get_child_rect(Widget* widget)
widget->rc->y2 - widget->border_width.b);
}
JRegion jwidget_get_region(Widget* widget)
{
JRegion region;
ASSERT_VALID_WIDGET(widget);
if (widget->type == JI_WINDOW)
region = widget->getTheme()->get_window_mask(widget);
else
region = jregion_new(widget->rc, 1);
return region;
}
/* gets the region to be able to draw in */
JRegion jwidget_get_drawable_region(Widget* widget, int flags)
{
Widget* window, *manager, *view;
JRegion region, reg1, reg2, reg3;
JRect cpos;
ASSERT_VALID_WIDGET(widget);
region = jwidget_get_region(widget);
// Cut the top windows areas
if (flags & JI_GDR_CUTTOPWINDOWS) {
window = widget->getRoot();
manager = window ? window->getManager(): NULL;
while (manager) {
const WidgetsList& windows_list = manager->getChildren();
WidgetsList::const_reverse_iterator it =
std::find(windows_list.rbegin(), windows_list.rend(), window);
if (!windows_list.empty() &&
window != windows_list.front() &&
it != windows_list.rend()) {
// Subtract the rectangles
for (++it; it != windows_list.rend(); ++it) {
reg1 = jwidget_get_region(*it);
jregion_subtract(region, region, reg1);
jregion_free(reg1);
}
}
window = manager->getRoot();
manager = window ? window->getManager(): NULL;
}
}
// Clip the areas where are children
if (!(flags & JI_GDR_USECHILDAREA) && !widget->getChildren().empty()) {
cpos = jwidget_get_child_rect(widget);
reg1 = jregion_new(NULL, 0);
reg2 = jregion_new(cpos, 1);
UI_FOREACH_WIDGET(widget->getChildren(), it) {
Widget* child = *it;
if (child->isVisible()) {
reg3 = jwidget_get_region(child);
if (child->flags & JI_DECORATIVE) {
jregion_reset(reg1, widget->rc);
jregion_intersect(reg1, reg1, reg3);
}
else {
jregion_intersect(reg1, reg2, reg3);
}
jregion_subtract(region, region, reg1);
jregion_free(reg3);
}
}
jregion_free(reg1);
jregion_free(reg2);
jrect_free(cpos);
}
// Intersect with the parent area
if (!(widget->flags & JI_DECORATIVE)) {
Widget* parent = widget->getParent();
reg1 = jregion_new(NULL, 0);
while (parent) {
cpos = jwidget_get_child_rect(parent);
jregion_reset(reg1, cpos);
jregion_intersect(region, region, reg1);
jrect_free(cpos);
parent = parent->getParent();
}
jregion_free(reg1);
}
else {
Widget* parent = widget->getParent();
if (parent) {
cpos = jwidget_get_rect(parent);
reg1 = jregion_new(cpos, 1);
jregion_intersect(region, region, reg1);
jregion_free(reg1);
jrect_free(cpos);
}
}
// Limit to the manager area
window = widget->getRoot();
manager = window ? window->getManager(): NULL;
while (manager) {
view = View::getView(manager);
if (view) {
Rect vp = static_cast<View*>(view)->getViewportBounds();
cpos = jrect_new(vp.x, vp.y, vp.x+vp.w, vp.y+vp.h);
}
else
cpos = jwidget_get_child_rect(manager);
/* if (!manager->parent) */
/* cpos = jwidget_get_rect(manager); */
/* else */
/* cpos = jwidget_get_child_rect(manager->parent); */
reg1 = jregion_new(cpos, 1);
jregion_intersect(region, region, reg1);
jregion_free(reg1);
jrect_free(cpos);
window = manager->getRoot();
manager = window ? window->getManager(): NULL;
}
/* return the region */
return region;
}
int jwidget_get_text_length(const Widget* widget)
{
#if 1
@ -934,9 +903,7 @@ void jwidget_set_max_size(Widget* widget, int w, int h)
void Widget::flushRedraw()
{
std::queue<Widget*> processing;
int c, nrects;
Message* msg;
JRect rc;
if (this->flags & JI_DIRTY) {
this->flags ^= JI_DIRTY;
@ -961,31 +928,35 @@ void Widget::flushRedraw()
}
}
nrects = JI_REGION_NUM_RECTS(widget->m_update_region);
if (nrects > 0) {
/* get areas to draw */
JRegion region = jwidget_get_drawable_region(widget, JI_GDR_CUTTOPWINDOWS);
jregion_intersect(widget->m_update_region,
widget->m_update_region, region);
jregion_free(region);
if (!widget->m_updateRegion.isEmpty()) {
// Intersect m_updateRegion with drawable area.
{
Region region;
widget->getDrawableRegion(region, kCutTopWindows);
widget->m_updateRegion.createIntersection(widget->m_updateRegion, region);
}
nrects = JI_REGION_NUM_RECTS(widget->m_update_region);
size_t c, nrects = widget->m_updateRegion.size();
Region::const_iterator it = widget->m_updateRegion.begin();
/* draw the widget */
for (c=0, rc=JI_REGION_RECTS(widget->m_update_region);
c<nrects;
c++, rc++) {
/* create the draw message */
// Draw the widget
for (c=0; c<nrects; c++, ++it) {
const Rect& rc = *it;
// Create the draw message
msg = jmessage_new(JM_DRAW);
msg->draw.count = nrects-1 - c;
msg->draw.rect = *rc;
msg->draw.rect.x1 = rc.x;
msg->draw.rect.y1 = rc.y;
msg->draw.rect.x2 = rc.x2();
msg->draw.rect.y2 = rc.y2();
jmessage_add_dest(msg, widget);
/* enqueue the draw message */
// Enqueue the draw message
getManager()->enqueueMessage(msg);
}
jregion_empty(widget->m_update_region);
widget->m_updateRegion.clear();
}
}
}
@ -1003,10 +974,8 @@ void Widget::setDoubleBuffered(bool doubleBuffered)
void Widget::invalidate()
{
if (isVisible()) {
JRegion reg1 = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
jregion_copy(this->m_update_region, reg1);
jregion_free(reg1);
m_updateRegion.clear();
getDrawableRegion(m_updateRegion, kCutTopWindows);
mark_dirty_flag(this);
@ -1017,53 +986,37 @@ void Widget::invalidate()
void Widget::invalidateRect(const gfx::Rect& rect)
{
if (isVisible()) {
JRect tmp = jrect_new(rect.x, rect.y, rect.x+rect.w, rect.y+rect.h);
invalidateRect(tmp);
jrect_free(tmp);
}
if (isVisible())
invalidateRegion(Region(rect));
}
void Widget::invalidateRect(const JRect rect)
{
if (isVisible()) {
JRegion reg1 = jregion_new(rect, 1);
invalidateRegion(reg1);
jregion_free(reg1);
}
}
void Widget::invalidateRegion(const JRegion region)
void Widget::invalidateRegion(const Region& region)
{
onInvalidateRegion(region);
}
void Widget::scrollRegion(JRegion region, int dx, int dy)
void Widget::scrollRegion(const Region& region, int dx, int dy)
{
if (dx != 0 || dy != 0) {
JRegion reg2 = jregion_new(NULL, 0);
jregion_copy(reg2, region);
jregion_translate(reg2, dx, dy);
jregion_intersect(reg2, reg2, region);
jregion_translate(reg2, -dx, -dy);
Region reg2 = region;
reg2.offset(dx, dy);
reg2.createIntersection(reg2, region);
reg2.offset(-dx, -dy);
// Move screen pixels
jmouse_hide();
ji_move_region(reg2, dx, dy);
jmouse_show();
jregion_translate(reg2, dx, dy);
reg2.offset(dx, dy);
jregion_union(this->m_update_region, this->m_update_region, region);
jregion_subtract(this->m_update_region, this->m_update_region, reg2);
m_updateRegion.createUnion(m_updateRegion, region);
m_updateRegion.createSubtraction(m_updateRegion, reg2);
mark_dirty_flag(this);
// Generate the JM_DRAW messages for the widget's m_update_region
this->flushRedraw();
jregion_free(reg2);
// Generate the JM_DRAW messages for the widget's m_updateRegion
flushRedraw();
}
}
@ -1362,31 +1315,28 @@ bool Widget::onProcessMessage(Message* msg)
// EVENTS
// ===============================================================
void Widget::onInvalidateRegion(const JRegion region)
void Widget::onInvalidateRegion(const Region& region)
{
if (isVisible() &&
jregion_rect_in(region, this->rc) != JI_RGNOUT) {
JRegion reg1 = jregion_new(NULL, 0);
JRegion reg2 = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
jregion_union(reg1, this->m_update_region, region);
jregion_intersect(this->m_update_region, reg1, reg2);
jregion_free(reg2);
jregion_subtract(reg1, region, this->m_update_region);
if (isVisible() && region.contains(getBounds()) != Region::Out) {
Region reg1;
reg1.createUnion(m_updateRegion, region);
{
Region reg2;
getDrawableRegion(reg2, kCutTopWindows);
m_updateRegion.createIntersection(reg1, reg2);
}
reg1.createSubtraction(region, m_updateRegion);
mark_dirty_flag(this);
UI_FOREACH_WIDGET(getChildren(), it)
(*it)->invalidateRegion(reg1);
jregion_free(reg1);
}
}
void Widget::onPreferredSize(PreferredSizeEvent& ev)
{
ev.setPreferredSize(Size(this->min_w, this->min_h));
ev.setPreferredSize(Size(min_w, min_h));
}
void Widget::onLoadLayout(LoadLayoutEvent& ev)
@ -1412,7 +1362,7 @@ void Widget::onBroadcastMouseMessage(WidgetsList& targets)
void Widget::onInitTheme(InitThemeEvent& ev)
{
if (m_theme) {
m_theme->init_widget(this);
m_theme->initWidget(this);
if (!(flags & JI_INITIALIZED))
flags |= JI_INITIALIZED;

View File

@ -11,6 +11,7 @@
#include "gfx/border.h"
#include "gfx/rect.h"
#include "gfx/region.h"
#include "gfx/size.h"
#include "ui/base.h"
#include "ui/color.h"
@ -42,8 +43,6 @@ namespace ui {
JRect jwidget_get_rect(Widget* widget);
JRect jwidget_get_child_rect(Widget* widget);
JRegion jwidget_get_region(Widget* widget);
JRegion jwidget_get_drawable_region(Widget* widget, int flags);
int jwidget_get_text_length(const Widget* widget);
int jwidget_get_text_height(const Widget* widget);
void jwidget_get_texticon_info(Widget* widget,
@ -242,11 +241,21 @@ namespace ui {
gfx::Rect getBounds() const;
gfx::Rect getClientBounds() const;
gfx::Rect getChildrenBounds() const;
void setBounds(const gfx::Rect& rc);
gfx::Border getBorder() const;
void setBorder(const gfx::Border& border);
// Flags for getDrawableRegion()
enum DrawableRegionFlags {
kCutTopWindows = 1, // Cut areas where are windows on top.
kUseChildArea = 2, // Use areas where are children.
};
void getRegion(gfx::Region& region);
void getDrawableRegion(gfx::Region& region, DrawableRegionFlags flags);
// ===============================================================
// REFRESH ISSUES
// ===============================================================
@ -256,12 +265,11 @@ namespace ui {
void invalidate();
void invalidateRect(const gfx::Rect& rect);
void invalidateRect(const JRect rect);
void invalidateRegion(const JRegion region);
void invalidateRegion(const gfx::Region& region);
void flushRedraw();
void scrollRegion(JRegion region, int dx, int dy);
void scrollRegion(const gfx::Region& region, int dx, int dy);
// ===============================================================
// GUI MANAGER
@ -312,7 +320,7 @@ namespace ui {
// EVENTS
// ===============================================================
virtual void onInvalidateRegion(const JRegion region);
virtual void onInvalidateRegion(const gfx::Region& region);
virtual void onPreferredSize(PreferredSizeEvent& ev);
virtual void onLoadLayout(LoadLayoutEvent& ev);
virtual void onSaveLayout(SaveLayoutEvent& ev);
@ -332,7 +340,7 @@ namespace ui {
std::string m_text; // Widget text
struct FONT *m_font; // Text font type
ui::Color m_bgColor; // Background color
JRegion m_update_region; // Region to be redrawed.
gfx::Region m_updateRegion;; // Region to be redrawed.
WidgetsList m_children; // Sub-widgets
Widget* m_parent; // Who is the parent?
gfx::Size* m_preferredSize;

View File

@ -460,10 +460,8 @@ void Window::onPreferredSize(PreferredSizeEvent& ev)
Widget* manager = getManager();
if (m_is_desktop) {
JRect cpos = jwidget_get_child_rect(manager);
ev.setPreferredSize(jrect_w(cpos),
jrect_h(cpos));
jrect_free(cpos);
Rect cpos = manager->getChildrenBounds();
ev.setPreferredSize(cpos.w, cpos.h);
}
else {
Size maxSize(0, 0);
@ -515,21 +513,19 @@ void Window::onSetText()
void Window::window_set_position(JRect rect)
{
/* copy the new position rectangle */
// Copy the new position rectangle
jrect_copy(this->rc, rect);
JRect cpos = jwidget_get_child_rect(this);
Rect cpos = getChildrenBounds();
/* set all the children to the same "child_pos" */
UI_FOREACH_WIDGET(getChildren(), it) {
Widget* child = *it;
if (child->isDecorative())
child->getTheme()->map_decorative_widget(child);
child->getTheme()->mapDecorativeWidget(child);
else
jwidget_set_rect(child, cpos);
child->setBounds(cpos);
}
jrect_free(cpos);
}
void Window::limit_size(int *w, int *h)
@ -540,13 +536,13 @@ void Window::limit_size(int *w, int *h)
void Window::move_window(JRect rect, bool use_blit)
{
#define FLAGS JI_GDR_CUTTOPWINDOWS | JI_GDR_USECHILDAREA
#define FLAGS (DrawableRegionFlags)(kCutTopWindows | kUseChildArea)
Manager* manager = getManager();
JRegion old_drawable_region;
JRegion new_drawable_region;
JRegion manager_refresh_region;
JRegion window_refresh_region;
Region old_drawable_region;
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;
@ -564,70 +560,59 @@ void Window::move_window(JRect rect, bool use_blit)
jmessage_add_dest(msg, this);
manager->enqueueMessage(msg);
/* get the region & the drawable region of the window */
old_drawable_region = jwidget_get_drawable_region(this, FLAGS);
// Get the region & the drawable region of the window
getDrawableRegion(old_drawable_region, FLAGS);
/* if the size of the window changes... */
// If the size of the window changes...
if (jrect_w(old_pos) != jrect_w(rect) ||
jrect_h(old_pos) != jrect_h(rect)) {
/* we have to change the whole positions sending JM_SETPOS
messages... */
// We have to change the whole positions sending JM_SETPOS
// messages...
window_set_position(rect);
}
else {
/* we can just displace all the widgets
by a delta (new_position - old_position)... */
// We can just displace all the widgets by a delta (new_position -
// old_position)...
displace_widgets(this,
rect->x1 - old_pos->x1,
rect->y1 - old_pos->y1);
}
/* get the new drawable region of the window (it's new because we
moved the window to "rect") */
new_drawable_region = jwidget_get_drawable_region(this, FLAGS);
// Get the new drawable region of the window (it's new because we
// moved the window to "rect")
getDrawableRegion(new_drawable_region, FLAGS);
/* create a new region to refresh the manager later */
manager_refresh_region = jregion_new(NULL, 0);
// First of all, we have to refresh the manager in the old window's
// drawable region, but we have to substract the new window's
// drawable region.
manager_refresh_region.createSubtraction(old_drawable_region,
new_drawable_region);
/* create a new region to refresh the window later */
window_refresh_region = jregion_new(NULL, 0);
// In second place, we have to setup the window's refresh region...
/* first of all, we have to refresh the manager in the old window's
drawable region... */
jregion_copy(manager_refresh_region, old_drawable_region);
/* ...but we have to substract the new window's drawable region (and
that is all for the manager's refresh region) */
jregion_subtract(manager_refresh_region, manager_refresh_region,
new_drawable_region);
/* now we have to setup the window's refresh region... */
/* if "use_blit" isn't activated, we have to redraw the whole window
(sending JM_DRAW messages) in the new drawable region */
// If "use_blit" isn't activated, we have to redraw the whole window
// (sending JM_DRAW messages) in the new drawable region
if (!use_blit) {
jregion_copy(window_refresh_region, new_drawable_region);
window_refresh_region = new_drawable_region;
}
/* if "use_blit" is activated, we can move the old drawable to the
new position (to redraw as little as possible) */
// If "use_blit" is activated, we can move the old drawable to the
// new position (to redraw as little as possible)
else {
JRegion reg1 = jregion_new(NULL, 0);
JRegion moveable_region = jregion_new(NULL, 0);
Region reg1;
Region moveable_region;
/* add a region to draw areas which were outside of the screen */
jregion_copy(reg1, new_drawable_region);
jregion_translate(reg1,
old_pos->x1 - this->rc->x1,
old_pos->y1 - this->rc->y1);
jregion_intersect(moveable_region, old_drawable_region, reg1);
// 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);
moveable_region.createIntersection(old_drawable_region, reg1);
jregion_subtract(reg1, reg1, moveable_region);
jregion_translate(reg1,
this->rc->x1 - old_pos->x1,
this->rc->y1 - old_pos->y1);
jregion_union(window_refresh_region, window_refresh_region, reg1);
reg1.createSubtraction(reg1, moveable_region);
reg1.offset(this->rc->x1 - old_pos->x1,
this->rc->y1 - old_pos->y1);
window_refresh_region.createUnion(window_refresh_region, reg1);
/* move the window's graphics */
// 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);
@ -637,18 +622,11 @@ void Window::move_window(JRect rect, bool use_blit)
this->rc->y1 - old_pos->y1);
set_clip_rect(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1);
jmouse_show();
jregion_free(reg1);
jregion_free(moveable_region);
}
manager->invalidateDisplayRegion(manager_refresh_region);
invalidateRegion(window_refresh_region);
jregion_free(old_drawable_region);
jregion_free(new_drawable_region);
jregion_free(manager_refresh_region);
jregion_free(window_refresh_region);
jrect_free(old_pos);
jrect_free(man_pos);
}

View File

@ -254,17 +254,11 @@ void ColorButton::openSelectorDialog()
m_window->getManager()->dispatchMessages();
m_window->layout();
/* setup the hot-region */
{
JRect rc = jrect_new(MIN(this->rc->x1, m_window->rc->x1)-8,
MIN(this->rc->y1, m_window->rc->y1)-8,
MAX(this->rc->x2, m_window->rc->x2)+8,
MAX(this->rc->y2, m_window->rc->y2)+8);
JRegion rgn = jregion_new(rc, 1);
jrect_free(rc);
static_cast<PopupWindow*>(m_window)->setHotRegion(rgn);
}
// Setup the hot-region
gfx::Rect rc = getBounds().createUnion(m_window->getBounds());
rc.enlarge(8);
gfx::Region rgn(rc);
static_cast<PopupWindow*>(m_window)->setHotRegion(rgn);
}
void ColorButton::closeSelectorDialog()

View File

@ -32,7 +32,6 @@
#include "tools/tool.h"
#include "ui/base.h"
#include "ui/rect.h"
#include "ui/region.h"
#include "ui/system.h"
#include "ui/widget.h"
#include "ui_context.h"
@ -85,8 +84,8 @@ static int saved_pixel_n;
// These clipping regions are shared between all editors, so we cannot
// make assumptions about their old state
static JRegion clipping_region = NULL;
static JRegion old_clipping_region = NULL;
static gfx::Region clipping_region;
static gfx::Region old_clipping_region;
static void generate_cursor_boundaries();
@ -98,8 +97,6 @@ static void savepixel(BITMAP *bmp, int x, int y, int color);
static void drawpixel(BITMAP *bmp, int x, int y, int color);
static void cleanpixel(BITMAP *bmp, int x, int y, int color);
static int point_inside_region(int x, int y, JRegion region);
static int get_pen_color(Sprite *sprite);
//////////////////////////////////////////////////////////////////////
@ -240,8 +237,8 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
ASSERT(m_cursor_thick == 0);
ASSERT(m_sprite != NULL);
/* get drawable region */
clipping_region = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
// Get drawable region
getDrawableRegion(clipping_region, kCutTopWindows);
/* get cursor color */
cursor_negative = is_cursor_mask();
@ -335,9 +332,7 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
m_cursor_editor_x = x;
m_cursor_editor_y = y;
/* save the clipping-region to know where to clean the pixels */
if (old_clipping_region)
jregion_free(old_clipping_region);
// Save the clipping-region to know where to clean the pixels
old_clipping_region = clipping_region;
}
@ -404,7 +399,7 @@ void Editor::editor_clean_cursor(bool refresh)
ASSERT(m_cursor_thick != 0);
ASSERT(m_sprite != NULL);
clipping_region = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
getDrawableRegion(clipping_region, kCutTopWindows);
x = m_cursor_editor_x;
y = m_cursor_editor_y;
@ -438,12 +433,8 @@ void Editor::editor_clean_cursor(bool refresh)
m_cursor_thick = 0;
jregion_free(clipping_region);
if (old_clipping_region)
jregion_free(old_clipping_region);
clipping_region = NULL;
old_clipping_region = NULL;
clipping_region.clear();
old_clipping_region.clear();
}
/**
@ -634,13 +625,13 @@ static void editor_cursor_bounds(Editor *editor, int x, int y, int color, void (
static void savepixel(BITMAP *bmp, int x, int y, int color)
{
if (saved_pixel_n < MAX_SAVED && point_inside_region(x, y, clipping_region))
if (saved_pixel_n < MAX_SAVED && clipping_region.contains(gfx::Point(x, y)))
saved_pixel[saved_pixel_n++] = getpixel(bmp, x, y);
}
static void drawpixel(BITMAP *bmp, int x, int y, int color)
{
if (saved_pixel_n < MAX_SAVED && point_inside_region(x, y, clipping_region)) {
if (saved_pixel_n < MAX_SAVED && clipping_region.contains(gfx::Point(x, y))) {
if (cursor_negative) {
int r, g, b, c = saved_pixel[saved_pixel_n++];
@ -659,20 +650,14 @@ static void drawpixel(BITMAP *bmp, int x, int y, int color)
static void cleanpixel(BITMAP *bmp, int x, int y, int color)
{
if (saved_pixel_n < MAX_SAVED) {
if (point_inside_region(x, y, clipping_region))
if (clipping_region.contains(gfx::Point(x, y)))
putpixel(bmp, x, y, saved_pixel[saved_pixel_n++]);
else if (old_clipping_region &&
point_inside_region(x, y, old_clipping_region))
else if (!old_clipping_region.isEmpty() &&
old_clipping_region.contains(gfx::Point(x, y)))
saved_pixel_n++;
}
}
static int point_inside_region(int x, int y, JRegion region)
{
struct jrect box;
return jregion_point_in(region, x, y, &box);
}
static int get_pen_color(Sprite *sprite)
{
app::Color c = UIContext::instance()->getSettings()->getFgColor();

View File

@ -300,14 +300,14 @@ void Editor::setEditorScroll(int x, int y, int use_refresh_region)
{
View* view = View::getView(this);
Point oldScroll;
JRegion region = NULL;
Region region;
int thick = m_cursor_thick;
if (thick)
editor_clean_cursor();
if (use_refresh_region) {
region = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
getDrawableRegion(region, kCutTopWindows);
oldScroll = view->getViewScroll();
}
@ -327,11 +327,9 @@ void Editor::setEditorScroll(int x, int y, int use_refresh_region)
if (use_refresh_region) {
// Move screen with blits
this->scrollRegion(region,
oldScroll.x - newScroll.x,
oldScroll.y - newScroll.y);
jregion_free(region);
scrollRegion(region,
oldScroll.x - newScroll.x,
oldScroll.y - newScroll.y);
}
if (thick)
@ -495,22 +493,20 @@ void Editor::drawSprite(int x1, int y1, int x2, int y2)
void Editor::drawSpriteSafe(int x1, int y1, int x2, int y2)
{
JRegion region = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
int c, nrects = JI_REGION_NUM_RECTS(region);
int cx1, cy1, cx2, cy2;
JRect rc;
Region region;
getDrawableRegion(region, kCutTopWindows);
int cx1, cy1, cx2, cy2;
get_clip_rect(ji_screen, &cx1, &cy1, &cx2, &cy2);
for (c=0, rc=JI_REGION_RECTS(region);
c<nrects;
c++, rc++) {
add_clip_rect(ji_screen, rc->x1, rc->y1, rc->x2-1, rc->y2-1);
for (Region::const_iterator it=region.begin(), end=region.end();
it != end; ++it) {
const Rect& rc = *it;
add_clip_rect(ji_screen, rc.x, rc.y, rc.x2()-1, rc.y2()-1);
drawSprite(x1, y1, x2, y2);
set_clip_rect(ji_screen, cx1, cy1, cx2, cy2);
}
jregion_free(region);
}
/**
@ -582,9 +578,8 @@ void Editor::drawMaskSafe()
m_document->getBoundariesSegments()) {
int thick = m_cursor_thick;
JRegion region = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
int c, nrects = JI_REGION_NUM_RECTS(region);
JRect rc;
Region region;
getDrawableRegion(region, kCutTopWindows);
acquire_bitmap(ji_screen);
@ -593,14 +588,13 @@ void Editor::drawMaskSafe()
else
jmouse_hide();
for (c=0, rc=JI_REGION_RECTS(region);
c<nrects;
c++, rc++) {
set_clip_rect(ji_screen, rc->x1, rc->y1, rc->x2-1, rc->y2-1);
for (Region::const_iterator it=region.begin(), end=region.end();
it != end; ++it) {
const Rect& rc = *it;
set_clip_rect(ji_screen, rc.x, rc.y, rc.x2()-1, rc.y2()-1);
drawMask();
}
set_clip_rect(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1);
jregion_free(region);
// Draw the cursor
if (thick)

View File

@ -53,11 +53,9 @@ void PopupWindowPin::onPinClick(Event& ev)
makeFloating();
}
else {
JRect rc = jrect_new(this->rc->x1-8, this->rc->y1-8, this->rc->x2+8, this->rc->y2+8);
JRegion rgn = jregion_new(rc, 1);
jrect_free(rc);
setHotRegion(rgn);
gfx::Rect rc = getBounds();
rc.enlarge(8);
setHotRegion(gfx::Region(rc));
makeFixed();
}
}

View File

@ -400,9 +400,7 @@ void ToolBar::openPopupWindow(int group_index, ToolGroup* tool_group)
// Redraw the overlapped area and save it to use it in the ToolStrip::onProcessMessage(JM_DRAW)
{
JRect rcTemp = jrect_new(rc.x, rc.y, rc.x+rc.w, rc.y+rc.h);
getManager()->invalidateRect(rcTemp);
jrect_free(rcTemp);
getManager()->invalidateRect(rc);
// Flush JM_DRAW messages and send them
getManager()->flushRedraw();
@ -413,11 +411,9 @@ void ToolBar::openPopupWindow(int group_index, ToolGroup* tool_group)
}
// Set hotregion of popup window
{
jrect rc2 = { rc.x, rc.y, this->rc->x2, rc.y+rc.h };
JRegion hotregion = jregion_new(&rc2, 1);
m_popupWindow->setHotRegion(hotregion);
}
Region rgn(rc);
rgn.createUnion(rgn, Region(getBounds()));
m_popupWindow->setHotRegion(rgn);
m_popupWindow->set_autoremap(false);
m_popupWindow->setBounds(rc);