Browse Source

Rework damage system to work better with transparency and Fl_Scroll and window backdrops.

tags/v1.3.1000
Jonathan Moore Liles 13 years ago
parent
commit
118604d638
11 changed files with 68 additions and 42 deletions
  1. +2
    -1
      FL/Enumerations.H
  2. +5
    -5
      FL/Fl_Dial.H
  3. +7
    -5
      FL/Fl_Widget.H
  4. +24
    -6
      src/Fl.cxx
  5. +10
    -10
      src/Fl_Group.cxx
  6. +3
    -3
      src/Fl_Overlay_Window.cxx
  7. +1
    -1
      src/Fl_Pack.cxx
  8. +8
    -6
      src/Fl_Scroll.cxx
  9. +2
    -2
      src/Fl_Scrollbar.cxx
  10. +3
    -3
      src/Fl_Window.cxx
  11. +3
    -0
      src/Fl_x.cxx

+ 2
- 1
FL/Enumerations.H View File

@@ -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...


+ 5
- 5
FL/Fl_Dial.H View File

@@ -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; }


+ 7
- 5
FL/Fl_Widget.H View File

@@ -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;




+ 24
- 6
src/Fl.cxx View File

@@ -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);


+ 10
- 10
src/Fl_Group.cxx View File

@@ -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();
} }
} }




+ 3
- 3
src/Fl_Overlay_Window.cxx View File

@@ -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);
} }






+ 1
- 1
src/Fl_Pack.cxx View File

@@ -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_;


+ 8
- 6
src/Fl_Scroll.cxx View File

@@ -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*) {


+ 2
- 2
src/Fl_Scrollbar.cxx View File

@@ -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);


+ 3
- 3
src/Fl_Window.cxx View File

@@ -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)) {


+ 3
- 0
src/Fl_x.cxx View File

@@ -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;


Loading…
Cancel
Save