From feed81e124fe5fd07854e9ab2066beddb0ea8fc9 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Mon, 1 Dec 2025 22:58:13 +0100 Subject: Fix more box drawing stuff - using Fl::box_bg(box()) The biggest changes are in src/Fl_Scroll.cxx where most of the changes are caused only by formatting (alignment). The behavior is the same for all boxtypes that had been covered by the old switch/case code and should be improved for other FL_*_FRAME boxtypes that had been ignored. --- src/Fl.cxx | 104 +++++++++++++++++++++++----------------------- src/Fl_Anim_GIF_Image.cxx | 22 ++++++---- src/Fl_Scroll.cxx | 47 +++++++-------------- 3 files changed, 81 insertions(+), 92 deletions(-) (limited to 'src') diff --git a/src/Fl.cxx b/src/Fl.cxx index c470f95e3..8be33c92f 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1753,59 +1753,59 @@ void Fl_Widget::redraw() { } void Fl_Widget::redraw_label() { - if (window()) { - if (box() == FL_NO_BOX) { - // Widgets with the FL_NO_BOX boxtype need a parent to - // redraw, since it is responsible for redrawing the - // background... - int X = x() > 0 ? x() - 1 : 0; - int Y = y() > 0 ? y() - 1 : 0; - window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2); - } + if (!window()) + return; - if (align() && !(align() & FL_ALIGN_INSIDE) && window()->shown()) { - // If the label is not inside the widget, compute the location of - // the label and redraw the window within that bounding box... - int W = 0, H = 0; - label_.measure(W, H); - W += 5; // Add a little to the size of the label to cover overflow - H += 5; - - // FIXME: - // This assumes that measure() returns the correct outline, which it does - // not in all possible cases of alignment combined with image and symbols. - switch (align() & 0x0f) { - case FL_ALIGN_TOP_LEFT: - window()->damage(FL_DAMAGE_EXPOSE, x(), y()-H, W, H); break; - case FL_ALIGN_TOP: - window()->damage(FL_DAMAGE_EXPOSE, x()+(w()-W)/2, y()-H, W, H); break; - case FL_ALIGN_TOP_RIGHT: - window()->damage(FL_DAMAGE_EXPOSE, x()+w()-W, y()-H, W, H); break; - case FL_ALIGN_LEFT_TOP: - window()->damage(FL_DAMAGE_EXPOSE, x()-W, y(), W, H); break; - case FL_ALIGN_RIGHT_TOP: - window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y(), W, H); break; - case FL_ALIGN_LEFT: - window()->damage(FL_DAMAGE_EXPOSE, x()-W, y()+(h()-H)/2, W, H); break; - case FL_ALIGN_RIGHT: - window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y()+(h()-H)/2, W, H); break; - case FL_ALIGN_LEFT_BOTTOM: - window()->damage(FL_DAMAGE_EXPOSE, x()-W, y()+h()-H, W, H); break; - case FL_ALIGN_RIGHT_BOTTOM: - window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y()+h()-H, W, H); break; - case FL_ALIGN_BOTTOM_LEFT: - window()->damage(FL_DAMAGE_EXPOSE, x(), y()+h(), W, H); break; - case FL_ALIGN_BOTTOM: - window()->damage(FL_DAMAGE_EXPOSE, x()+(w()-W)/2, y()+h(), W, H); break; - case FL_ALIGN_BOTTOM_RIGHT: - window()->damage(FL_DAMAGE_EXPOSE, x()+w()-W, y()+h(), W, H); break; - default: - window()->damage(FL_DAMAGE_ALL); break; - } - } else { - // The label is inside the widget, so just redraw the widget itself... - damage(FL_DAMAGE_ALL); + // Widgets without a solid background need a parent to redraw, + // since it is responsible for redrawing the background... + if (!Fl::box_bg(box())) { + int X = x() > 0 ? x() - 1 : 0; + int Y = y() > 0 ? y() - 1 : 0; + window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2); + } + + if (align() && !(align() & FL_ALIGN_INSIDE) && window()->shown()) { + // If the label is not inside the widget, compute the location of + // the label and redraw the window within that bounding box... + int W = 0, H = 0; + label_.measure(W, H); + W += 5; // Add a little to the size of the label to cover overflow + H += 5; + + // FIXME: + // This assumes that measure() returns the correct outline, which it does + // not in all possible cases of alignment combined with image and symbols. + switch (align() & 0x0f) { + case FL_ALIGN_TOP_LEFT: + window()->damage(FL_DAMAGE_EXPOSE, x(), y()-H, W, H); break; + case FL_ALIGN_TOP: + window()->damage(FL_DAMAGE_EXPOSE, x()+(w()-W)/2, y()-H, W, H); break; + case FL_ALIGN_TOP_RIGHT: + window()->damage(FL_DAMAGE_EXPOSE, x()+w()-W, y()-H, W, H); break; + case FL_ALIGN_LEFT_TOP: + window()->damage(FL_DAMAGE_EXPOSE, x()-W, y(), W, H); break; + case FL_ALIGN_RIGHT_TOP: + window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y(), W, H); break; + case FL_ALIGN_LEFT: + window()->damage(FL_DAMAGE_EXPOSE, x()-W, y()+(h()-H)/2, W, H); break; + case FL_ALIGN_RIGHT: + window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y()+(h()-H)/2, W, H); break; + case FL_ALIGN_LEFT_BOTTOM: + window()->damage(FL_DAMAGE_EXPOSE, x()-W, y()+h()-H, W, H); break; + case FL_ALIGN_RIGHT_BOTTOM: + window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y()+h()-H, W, H); break; + case FL_ALIGN_BOTTOM_LEFT: + window()->damage(FL_DAMAGE_EXPOSE, x(), y()+h(), W, H); break; + case FL_ALIGN_BOTTOM: + window()->damage(FL_DAMAGE_EXPOSE, x()+(w()-W)/2, y()+h(), W, H); break; + case FL_ALIGN_BOTTOM_RIGHT: + window()->damage(FL_DAMAGE_EXPOSE, x()+w()-W, y()+h(), W, H); break; + default: + window()->damage(FL_DAMAGE_ALL); break; } + } else { + // The label is inside the widget, so just redraw the widget itself... + damage(FL_DAMAGE_ALL); } } @@ -2452,7 +2452,7 @@ FL_EXPORT Window fl_xid_(const Fl_Window *w) { to be effective for files dropped on the application icon at launch time. It can also be called at any point to change the function used to open dropped files. A call with a NULL argument, after a previous call, makes the app ignore files dropped later. - + Use of this function also requires the application bundle's \c Info.plist file to declare what file types are allowed to be dropped on the icon. File \c README.macOS.md describes how to do that in its section diff --git a/src/Fl_Anim_GIF_Image.cxx b/src/Fl_Anim_GIF_Image.cxx index cd04f9467..c70d15866 100644 --- a/src/Fl_Anim_GIF_Image.cxx +++ b/src/Fl_Anim_GIF_Image.cxx @@ -2,6 +2,7 @@ // Fl_Anim_GIF_Image class for the Fast Light Tool Kit (FLTK). // // Copyright 2016-2023 by Christian Grabner . +// Copyright 2024-2025 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -1195,21 +1196,24 @@ void Fl_Anim_GIF_Image::set_frame(int frame) { Fl_Widget* cv = canvas(); if (cv) { Fl_Group* parent = cv->parent(); - bool no_bg = (cv->box() == FL_NO_BOX); + bool no_bg = !Fl::box_bg(cv->box()); bool outside = (!(cv->align() & FL_ALIGN_INSIDE) && !((cv->align() & FL_ALIGN_POSITION_MASK)==FL_ALIGN_CENTER)); -// bool dispose = (fi_->frames[last_frame].dispose == FrameInfo::DISPOSE_BACKGROUND) -// || (fi_->frames[last_frame].dispose == FrameInfo::DISPOSE_PREVIOUS); + // bool dispose = (fi_->frames[last_frame].dispose == FrameInfo::DISPOSE_BACKGROUND) + // || (fi_->frames[last_frame].dispose == FrameInfo::DISPOSE_PREVIOUS); if (parent && (no_bg || outside)) parent->redraw(); else cv->redraw(); -// Note: the code below did not animate labels with a pixmap outside of the canvas -// canvas()->parent() && -// (frame_ == 0 || (last_frame >= 0 && (fi_->frames[last_frame].dispose == FrameInfo::DISPOSE_BACKGROUND || -// fi_->frames[last_frame].dispose == FrameInfo::DISPOSE_PREVIOUS))) && -// (canvas()->box() == FL_NO_BOX || (canvas()->align() && !(canvas()->align() & FL_ALIGN_INSIDE))) ? -// canvas()->parent()->redraw() : canvas()->redraw(); + // Note: the code below did not animate labels with a pixmap outside of the canvas. + // Todo: Replace 'canvas()->box() == FL_NO_BOX' with '!Fl::box_bg(canvas()->box())' + // if the code below is ever uncommented again. Maybe this would fix it? + // + // canvas()->parent() && + // (frame_ == 0 || (last_frame >= 0 && (fi_->frames[last_frame].dispose == FrameInfo::DISPOSE_BACKGROUND || + // fi_->frames[last_frame].dispose == FrameInfo::DISPOSE_PREVIOUS))) && + // (canvas()->box() == FL_NO_BOX || (canvas()->align() && !(canvas()->align() & FL_ALIGN_INSIDE))) ? + // canvas()->parent()->redraw() : canvas()->redraw(); } } diff --git a/src/Fl_Scroll.cxx b/src/Fl_Scroll.cxx index e90809d1f..f64dbb952 100644 --- a/src/Fl_Scroll.cxx +++ b/src/Fl_Scroll.cxx @@ -147,42 +147,27 @@ int Fl_Scroll::delete_child(int index) { } // Draw widget's background and children within a specific clip region -// So widget can just redraw damaged parts. +// so widget can just redraw damaged parts. // void Fl_Scroll::draw_clip(void* v,int X, int Y, int W, int H) { fl_push_clip(X,Y,W,H); - Fl_Scroll* s = (Fl_Scroll*)v; - // erase background as needed... - switch (s->box()) { - case FL_NO_BOX : - case FL_UP_FRAME : - case FL_DOWN_FRAME : - case FL_THIN_UP_FRAME : - case FL_THIN_DOWN_FRAME : - case FL_ENGRAVED_FRAME : - case FL_EMBOSSED_FRAME : - case FL_BORDER_FRAME : - case _FL_SHADOW_FRAME : - case _FL_ROUNDED_FRAME : - case _FL_OVAL_FRAME : - case _FL_PLASTIC_UP_FRAME : - case _FL_PLASTIC_DOWN_FRAME : - if (s->parent() == (Fl_Group *)s->window() && Fl::scheme_bg_) { - Fl::scheme_bg_->draw(X-(X%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w()), - Y-(Y%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()), - W+((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w(), - H+((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()); - break; - } + Fl_Scroll *s = (Fl_Scroll*)v; - default : - if (s->active_r()) - fl_color(s->color()); - else - fl_color(fl_inactive(s->color())); - fl_rectf(X,Y,W,H); - break; + // erase background as needed... + if (!Fl::box_bg(s->box()) && (s->parent() == (Fl_Group *)s->window() && Fl::scheme_bg_)) { + Fl::scheme_bg_->draw(X - (X%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w()), + Y - (Y%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()), + W + ((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w(), + H + ((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()); + } else { + if (s->active_r()) + fl_color(s->color()); + else + fl_color(fl_inactive(s->color())); + fl_rectf(X,Y,W,H); } + + // draw visible children Fl_Widget*const* a = s->array(); for (int i=s->children()-2; i--;) { Fl_Widget& o = **a++; -- cgit v1.2.3