@@ -930,7 +930,8 @@ enum Fl_Damage { | |||
FL_DAMAGE_OVERLAY = 0x08, /**< The overlay planes need to be redrawn. */ | |||
FL_DAMAGE_USER1 = 0x10, /**< First user-defined damage bit. */ | |||
FL_DAMAGE_USER2 = 0x20, /**< Second user-defined damage bit. */ | |||
FL_DAMAGE_ALL = 0x80 /**< Everything needs to be redrawn. */ | |||
FL_DAMAGE_ALL = 0x80, /**< Everything needs to be redrawn. */ | |||
FL_DAMAGE_BACKGROUND = 1 << 9 | |||
}; | |||
// FLTK 1.0.x compatibility definitions... | |||
@@ -66,11 +66,11 @@ public: | |||
Fl_Dial_Base::type( n ); | |||
} | |||
virtual void value_damage ( void ) | |||
{ | |||
if ( window() ) | |||
window()->damage( FL_DAMAGE_ALL, x(), y(), w(), h() ); | |||
} | |||
/* virtual void value_damage ( void ) */ | |||
/* { */ | |||
/* if ( window() ) */ | |||
/* window()->damage( FL_DAMAGE_ALL, x(), y(), w(), h() ); */ | |||
/* } */ | |||
static void default_style ( int n ) { Fl_Dial::_default_style = n; } | |||
static void default_image ( Fl_Image *i ) { Fl_Dial::_default_image = i; } | |||
@@ -49,6 +49,8 @@ typedef long fl_intptr_t; | |||
typedef unsigned long fl_uintptr_t; | |||
#endif | |||
typedef unsigned short fl_damage_t; | |||
class Fl_Widget; | |||
class Fl_Window; | |||
class Fl_Group; | |||
@@ -118,7 +120,7 @@ class FL_EXPORT Fl_Widget { | |||
Fl_Color color_; | |||
Fl_Color color2_; | |||
uchar type_; | |||
uchar damage_; | |||
fl_damage_t short damage_; | |||
uchar box_; | |||
uchar when_; | |||
@@ -885,7 +887,7 @@ public: | |||
\return a bitmap of flags describing the kind of damage to the widget | |||
\see damage(uchar), clear_damage(uchar) | |||
*/ | |||
uchar damage() const {return damage_;} | |||
fl_damage_t damage() const {return damage_;} | |||
/** Clears or sets the damage flags. | |||
Damage flags are cleared when parts of the widget drawing is repaired. | |||
@@ -899,14 +901,14 @@ public: | |||
\param[in] c new bitmask of damage flags (default: 0) | |||
\see damage(uchar), damage() | |||
*/ | |||
void clear_damage(uchar c = 0) {damage_ = c;} | |||
void clear_damage(fl_damage_t c = 0) {damage_ = c;} | |||
/** Sets the damage bits for the widget. | |||
Setting damage bits will schedule the widget for the next redraw. | |||
\param[in] c bitmask of flags to set | |||
\see damage(), clear_damage(uchar) | |||
*/ | |||
void damage(uchar c); | |||
void damage(fl_damage_t c); | |||
/** Sets the damage bits for an area inside the widget. | |||
Setting damage bits will schedule the widget for the next redraw. | |||
@@ -914,7 +916,7 @@ public: | |||
\param[in] x, y, w, h size of damaged area | |||
\see damage(), clear_damage(uchar) | |||
*/ | |||
void damage(uchar c, int x, int y, int w, int h); | |||
void damage(fl_damage_t c, int x, int y, int w, int h); | |||
void draw_label(int, int, int, int, Fl_Align) const; | |||
@@ -1646,7 +1646,7 @@ void Fl_Widget::redraw_label() { | |||
} | |||
} | |||
void Fl_Widget::damage(uchar fl) { | |||
void Fl_Widget::damage(fl_damage_t fl) { | |||
if (type() < FL_WINDOW) { | |||
// damage only the rectangle covered by a child widget: | |||
damage(fl, x(), y(), w(), h()); | |||
@@ -1668,19 +1668,37 @@ void Fl_Widget::damage(uchar fl) { | |||
} | |||
} | |||
void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) { | |||
void Fl_Widget::damage(fl_damage_t fl, int X, int Y, int W, int H) { | |||
Fl_Widget* wi = this; | |||
// mark all parent widgets between this and window with FL_DAMAGE_CHILD: | |||
while (wi->type() < FL_WINDOW) { | |||
/* mark as exposed all parent widgets between this one and the window, stopping at the first widget to have FL_FLAT_BOX (and therefore be completely opaque! | |||
FIXME: check the color for an alpha less than 1! */ | |||
bool hit_opaque_widget = false; | |||
while (wi->type() < FL_WINDOW ) | |||
{ | |||
wi->damage_ |= fl; | |||
wi = wi->parent(); | |||
if (!wi) return; | |||
if ( wi->box() == FL_FLAT_BOX ) | |||
{ | |||
hit_opaque_widget = true; | |||
} | |||
if ( ! ( wi = wi->parent() ) ) | |||
return; | |||
/* we use FL_DAMAGE_EXPOSE now because of alpha blending and FL_NO_BOX and frames... */ | |||
fl = FL_DAMAGE_EXPOSE; | |||
// fl = FL_DAMAGE_EXPOSE; | |||
fl = hit_opaque_widget ? FL_DAMAGE_CHILD : FL_DAMAGE_ALL; | |||
} | |||
fl = FL_DAMAGE_CHILD; | |||
if ( ! hit_opaque_widget ) | |||
fl |= FL_DAMAGE_BACKGROUND; | |||
/* at this point 'wi' is the window */ | |||
Fl_X* i = Fl_X::i((Fl_Window*)wi); | |||
@@ -725,25 +725,25 @@ void Fl_Group::draw_children() { | |||
h() - Fl::box_dh(box())); | |||
} | |||
// if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: | |||
if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: | |||
// if ( damage() & FL_DAMAGE_ALL ) { | |||
for (int i=children_; i--;) { | |||
Fl_Widget& o = **a++; | |||
draw_child(o); | |||
draw_outside_label(o); | |||
} | |||
/* } else { // only redraw the children that need it: */ | |||
/* for (int i=children_; i--;) update_child(**a++); */ | |||
/* } */ | |||
} else { // only redraw the children that need it: | |||
for (int i=children_; i--;) update_child(**a++); | |||
} | |||
if (clip_children()) fl_pop_clip(); | |||
} | |||
void Fl_Group::draw() { | |||
// if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: | |||
if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: | |||
draw_box(); | |||
draw_label(); | |||
// } | |||
} | |||
draw_children(); | |||
} | |||
@@ -771,10 +771,10 @@ void Fl_Group::update_child(Fl_Widget& widget) const { | |||
*/ | |||
void Fl_Group::draw_child(Fl_Widget& widget) const { | |||
if (widget.visible() && widget.type() < FL_WINDOW && | |||
fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) { | |||
widget.clear_damage(FL_DAMAGE_ALL); | |||
widget.draw(); | |||
widget.clear_damage(); | |||
fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) { | |||
widget.clear_damage(FL_DAMAGE_ALL); | |||
widget.draw(); | |||
widget.clear_damage(); | |||
} | |||
} | |||
@@ -53,7 +53,7 @@ void Fl_Overlay_Window::flush() { | |||
} | |||
#endif | |||
int erase_overlay = (damage()&FL_DAMAGE_OVERLAY); | |||
clear_damage((uchar)(damage()&~FL_DAMAGE_OVERLAY)); | |||
clear_damage(damage()&~FL_DAMAGE_OVERLAY); | |||
Fl_Double_Window::flush(erase_overlay); | |||
Fl_X* myi = Fl_X::i(this); | |||
draw_overlay(); | |||
@@ -76,8 +76,8 @@ int Fl_Overlay_Window::can_do_overlay() {return 0;} | |||
calling show(). | |||
*/ | |||
void Fl_Overlay_Window::redraw_overlay() { | |||
clear_damage((uchar)(damage()|FL_DAMAGE_OVERLAY)); | |||
Fl::damage(FL_DAMAGE_CHILD); | |||
clear_damage(damage()|FL_DAMAGE_OVERLAY); | |||
Fl::damage(FL_DAMAGE_CHILD); | |||
} | |||
@@ -59,7 +59,7 @@ void Fl_Pack::draw() { | |||
int rw, rh; | |||
int current_position = horizontal() ? tx : ty; | |||
int maximum_position = current_position; | |||
uchar d = damage(); | |||
fl_damage_t d = damage(); | |||
Fl_Widget*const* a = array(); | |||
if (horizontal()) { | |||
rw = -spacing_; | |||
@@ -242,16 +242,17 @@ void Fl_Scroll::bbox(int& X, int& Y, int& W, int& H) { | |||
} | |||
void Fl_Scroll::draw() { | |||
box( FL_FLAT_BOX ); | |||
fix_scrollbar_order(); | |||
int X,Y,W,H; bbox(X,Y,W,H); | |||
uchar d = damage(); | |||
fl_damage_t d = damage(); | |||
if (d & FL_DAMAGE_ALL) { // full redraw | |||
if ( d & FL_DAMAGE_ALL ) { // full redraw | |||
draw_box(box(),x(),y(),w(),h(),color()); | |||
draw_clip(this, X, Y, W, H); | |||
} else { | |||
if (d & FL_DAMAGE_SCROLL) { | |||
if ( d & FL_DAMAGE_SCROLL) { | |||
// scroll the contents: | |||
fl_scroll(X, Y, W, H, oldx-xposition_, oldy-yposition_, draw_clip, this); | |||
@@ -273,7 +274,7 @@ void Fl_Scroll::draw() { | |||
if (T > Y) draw_clip(this, X, Y, W, T - Y); | |||
if (B < (Y + H)) draw_clip(this, X, B, W, Y + H - B); | |||
} | |||
if (d & FL_DAMAGE_CHILD) { // draw damaged children | |||
if ( d & FL_DAMAGE_CHILD) { // draw damaged children | |||
fl_push_clip(X, Y, W, H); | |||
Fl_Widget*const* a = array(); | |||
for (int i=children()-2; i--;) update_child(**a++); | |||
@@ -370,8 +371,9 @@ void Fl_Scroll::scroll_to(int X, int Y) { | |||
if (o == &hscrollbar || o == &scrollbar) continue; | |||
o->position(o->x()+dx, o->y()+dy); | |||
} | |||
if (parent() == (Fl_Group *)window() && Fl::scheme_bg_) damage(FL_DAMAGE_ALL); | |||
else damage(FL_DAMAGE_SCROLL); | |||
/* if (parent() == (Fl_Group *)window() && Fl::scheme_bg_) damage(FL_DAMAGE_ALL); */ | |||
/* else */ | |||
damage(FL_DAMAGE_SCROLL); | |||
} | |||
void Fl_Scroll::hscrollbar_cb(Fl_Widget* o, void*) { | |||
@@ -118,7 +118,7 @@ int Fl_Scrollbar::handle(int event) { | |||
case FL_LEAVE: | |||
return 1; | |||
case FL_RELEASE: | |||
damage(FL_DAMAGE_ALL); | |||
redraw(); | |||
if (pushed_) { | |||
Fl::remove_timeout(timeout_cb, this); | |||
pushed_ = 0; | |||
@@ -132,7 +132,7 @@ int Fl_Scrollbar::handle(int event) { | |||
handle_push(); | |||
Fl::add_timeout(INITIALREPEAT, timeout_cb, this); | |||
increment_cb(); | |||
damage(FL_DAMAGE_ALL); | |||
redraw(); | |||
return 1; | |||
} | |||
return Fl_Slider::handle(event, X,Y,W,H); | |||
@@ -106,10 +106,10 @@ void Fl_Window::draw() { | |||
// - we draw the box with x=0 and y=0 instead of x() and y() | |||
// - we don't draw a label | |||
// if (damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing | |||
/* always draw the box because the children may be transparent */ | |||
if (damage() & FL_DAMAGE_BACKGROUND || damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing | |||
// /* always draw the box because the children may be transparent */ | |||
draw_box(box(),0,0,w(),h(),color()); // draw box with x/y = 0 | |||
// } | |||
} | |||
draw_children(); | |||
if (fl_gc && !parent() && resizable() && (!size_range_set || minh!=maxh || minw!=maxw)) { | |||
@@ -2044,6 +2044,7 @@ void Fl_Window::make_current() { | |||
fl_window = i->xid; | |||
fl_gc = gc; | |||
#ifdef FLTK_HAVE_CAIRO | |||
if ( i->cairo_surface_invalid && i->cc ) | |||
{ | |||
cairo_destroy( i->cc ); i->cc = 0; | |||
@@ -2055,6 +2056,8 @@ void Fl_Window::make_current() { | |||
i->cs = Fl::cairo_create_surface( i->xid, w(), h() ); | |||
i->cc = cairo_create( i->cs ); | |||
} | |||
Fl::cairo_make_current( i->cs, i->cc ); | |||
#endif | |||
current_ = this; | |||