@@ -930,7 +930,8 @@ enum Fl_Damage { | |||||
FL_DAMAGE_OVERLAY = 0x08, /**< The overlay planes need to be redrawn. */ | FL_DAMAGE_OVERLAY = 0x08, /**< The overlay planes need to be redrawn. */ | ||||
FL_DAMAGE_USER1 = 0x10, /**< First user-defined damage bit. */ | FL_DAMAGE_USER1 = 0x10, /**< First user-defined damage bit. */ | ||||
FL_DAMAGE_USER2 = 0x20, /**< Second 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... | // FLTK 1.0.x compatibility definitions... | ||||
@@ -66,11 +66,11 @@ public: | |||||
Fl_Dial_Base::type( n ); | 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_style ( int n ) { Fl_Dial::_default_style = n; } | ||||
static void default_image ( Fl_Image *i ) { Fl_Dial::_default_image = i; } | 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; | typedef unsigned long fl_uintptr_t; | ||||
#endif | #endif | ||||
typedef unsigned short fl_damage_t; | |||||
class Fl_Widget; | class Fl_Widget; | ||||
class Fl_Window; | class Fl_Window; | ||||
class Fl_Group; | class Fl_Group; | ||||
@@ -118,7 +120,7 @@ class FL_EXPORT Fl_Widget { | |||||
Fl_Color color_; | Fl_Color color_; | ||||
Fl_Color color2_; | Fl_Color color2_; | ||||
uchar type_; | uchar type_; | ||||
uchar damage_; | |||||
fl_damage_t short damage_; | |||||
uchar box_; | uchar box_; | ||||
uchar when_; | uchar when_; | ||||
@@ -885,7 +887,7 @@ public: | |||||
\return a bitmap of flags describing the kind of damage to the widget | \return a bitmap of flags describing the kind of damage to the widget | ||||
\see damage(uchar), clear_damage(uchar) | \see damage(uchar), clear_damage(uchar) | ||||
*/ | */ | ||||
uchar damage() const {return damage_;} | |||||
fl_damage_t damage() const {return damage_;} | |||||
/** Clears or sets the damage flags. | /** Clears or sets the damage flags. | ||||
Damage flags are cleared when parts of the widget drawing is repaired. | 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) | \param[in] c new bitmask of damage flags (default: 0) | ||||
\see damage(uchar), damage() | \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. | /** Sets the damage bits for the widget. | ||||
Setting damage bits will schedule the widget for the next redraw. | Setting damage bits will schedule the widget for the next redraw. | ||||
\param[in] c bitmask of flags to set | \param[in] c bitmask of flags to set | ||||
\see damage(), clear_damage(uchar) | \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. | /** Sets the damage bits for an area inside the widget. | ||||
Setting damage bits will schedule the widget for the next redraw. | 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 | \param[in] x, y, w, h size of damaged area | ||||
\see damage(), clear_damage(uchar) | \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; | 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) { | if (type() < FL_WINDOW) { | ||||
// damage only the rectangle covered by a child widget: | // damage only the rectangle covered by a child widget: | ||||
damage(fl, x(), y(), w(), h()); | 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; | Fl_Widget* wi = this; | ||||
// mark all parent widgets between this and window with FL_DAMAGE_CHILD: | // 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->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... */ | /* 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; | fl = FL_DAMAGE_CHILD; | ||||
if ( ! hit_opaque_widget ) | |||||
fl |= FL_DAMAGE_BACKGROUND; | |||||
/* at this point 'wi' is the window */ | /* at this point 'wi' is the window */ | ||||
Fl_X* i = Fl_X::i((Fl_Window*)wi); | Fl_X* i = Fl_X::i((Fl_Window*)wi); | ||||
@@ -725,25 +725,25 @@ void Fl_Group::draw_children() { | |||||
h() - Fl::box_dh(box())); | 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 ) { | // if ( damage() & FL_DAMAGE_ALL ) { | ||||
for (int i=children_; i--;) { | for (int i=children_; i--;) { | ||||
Fl_Widget& o = **a++; | Fl_Widget& o = **a++; | ||||
draw_child(o); | draw_child(o); | ||||
draw_outside_label(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(); | if (clip_children()) fl_pop_clip(); | ||||
} | } | ||||
void Fl_Group::draw() { | 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_box(); | ||||
draw_label(); | draw_label(); | ||||
// } | |||||
} | |||||
draw_children(); | draw_children(); | ||||
} | } | ||||
@@ -771,10 +771,10 @@ void Fl_Group::update_child(Fl_Widget& widget) const { | |||||
*/ | */ | ||||
void Fl_Group::draw_child(Fl_Widget& widget) const { | void Fl_Group::draw_child(Fl_Widget& widget) const { | ||||
if (widget.visible() && widget.type() < FL_WINDOW && | 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 | #endif | ||||
int erase_overlay = (damage()&FL_DAMAGE_OVERLAY); | 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_Double_Window::flush(erase_overlay); | ||||
Fl_X* myi = Fl_X::i(this); | Fl_X* myi = Fl_X::i(this); | ||||
draw_overlay(); | draw_overlay(); | ||||
@@ -76,8 +76,8 @@ int Fl_Overlay_Window::can_do_overlay() {return 0;} | |||||
calling show(). | calling show(). | ||||
*/ | */ | ||||
void Fl_Overlay_Window::redraw_overlay() { | 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 rw, rh; | ||||
int current_position = horizontal() ? tx : ty; | int current_position = horizontal() ? tx : ty; | ||||
int maximum_position = current_position; | int maximum_position = current_position; | ||||
uchar d = damage(); | |||||
fl_damage_t d = damage(); | |||||
Fl_Widget*const* a = array(); | Fl_Widget*const* a = array(); | ||||
if (horizontal()) { | if (horizontal()) { | ||||
rw = -spacing_; | rw = -spacing_; | ||||
@@ -242,16 +242,17 @@ void Fl_Scroll::bbox(int& X, int& Y, int& W, int& H) { | |||||
} | } | ||||
void Fl_Scroll::draw() { | void Fl_Scroll::draw() { | ||||
box( FL_FLAT_BOX ); | |||||
fix_scrollbar_order(); | fix_scrollbar_order(); | ||||
int X,Y,W,H; bbox(X,Y,W,H); | 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_box(box(),x(),y(),w(),h(),color()); | ||||
draw_clip(this, X, Y, W, H); | draw_clip(this, X, Y, W, H); | ||||
} else { | } else { | ||||
if (d & FL_DAMAGE_SCROLL) { | |||||
if ( d & FL_DAMAGE_SCROLL) { | |||||
// scroll the contents: | // scroll the contents: | ||||
fl_scroll(X, Y, W, H, oldx-xposition_, oldy-yposition_, draw_clip, this); | 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 (T > Y) draw_clip(this, X, Y, W, T - Y); | ||||
if (B < (Y + H)) draw_clip(this, X, B, W, Y + H - B); | 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_push_clip(X, Y, W, H); | ||||
Fl_Widget*const* a = array(); | Fl_Widget*const* a = array(); | ||||
for (int i=children()-2; i--;) update_child(**a++); | 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; | if (o == &hscrollbar || o == &scrollbar) continue; | ||||
o->position(o->x()+dx, o->y()+dy); | 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*) { | void Fl_Scroll::hscrollbar_cb(Fl_Widget* o, void*) { | ||||
@@ -118,7 +118,7 @@ int Fl_Scrollbar::handle(int event) { | |||||
case FL_LEAVE: | case FL_LEAVE: | ||||
return 1; | return 1; | ||||
case FL_RELEASE: | case FL_RELEASE: | ||||
damage(FL_DAMAGE_ALL); | |||||
redraw(); | |||||
if (pushed_) { | if (pushed_) { | ||||
Fl::remove_timeout(timeout_cb, this); | Fl::remove_timeout(timeout_cb, this); | ||||
pushed_ = 0; | pushed_ = 0; | ||||
@@ -132,7 +132,7 @@ int Fl_Scrollbar::handle(int event) { | |||||
handle_push(); | handle_push(); | ||||
Fl::add_timeout(INITIALREPEAT, timeout_cb, this); | Fl::add_timeout(INITIALREPEAT, timeout_cb, this); | ||||
increment_cb(); | increment_cb(); | ||||
damage(FL_DAMAGE_ALL); | |||||
redraw(); | |||||
return 1; | return 1; | ||||
} | } | ||||
return Fl_Slider::handle(event, X,Y,W,H); | 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 draw the box with x=0 and y=0 instead of x() and y() | ||||
// - we don't draw a label | // - 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_box(box(),0,0,w(),h(),color()); // draw box with x/y = 0 | ||||
// } | |||||
} | |||||
draw_children(); | draw_children(); | ||||
if (fl_gc && !parent() && resizable() && (!size_range_set || minh!=maxh || minw!=maxw)) { | 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_window = i->xid; | ||||
fl_gc = gc; | fl_gc = gc; | ||||
#ifdef FLTK_HAVE_CAIRO | #ifdef FLTK_HAVE_CAIRO | ||||
if ( i->cairo_surface_invalid && i->cc ) | if ( i->cairo_surface_invalid && i->cc ) | ||||
{ | { | ||||
cairo_destroy( i->cc ); i->cc = 0; | 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->cs = Fl::cairo_create_surface( i->xid, w(), h() ); | ||||
i->cc = cairo_create( i->cs ); | i->cc = cairo_create( i->cs ); | ||||
} | } | ||||
Fl::cairo_make_current( i->cs, i->cc ); | Fl::cairo_make_current( i->cs, i->cc ); | ||||
#endif | #endif | ||||
current_ = this; | current_ = this; | ||||