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


+ 5
- 5
FL/Fl_Dial.H View File

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


+ 7
- 5
FL/Fl_Widget.H View File

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



+ 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) {
// 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);


+ 10
- 10
src/Fl_Group.cxx View File

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



+ 3
- 3
src/Fl_Overlay_Window.cxx View File

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




+ 1
- 1
src/Fl_Pack.cxx View File

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


+ 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() {
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*) {


+ 2
- 2
src/Fl_Scrollbar.cxx View File

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


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


+ 3
- 0
src/Fl_x.cxx View File

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


Loading…
Cancel
Save