| [ Return to Bugs & Features | Roadmap 1.1 | SVN ⇄ GIT ]
STR #205
Application: | FLTK Library |
Status: | 1 - Closed w/Resolution |
Priority: | 1 - Request for Enhancement, e.g. asking for a feature |
Scope: | 3 - Applies to all machines and operating systems |
Subsystem: | Core Library |
Summary: | Fl_Scroll background ignores Fl::scheme("plastic") |
Version: | 1.1.4 |
Created By: | greg.ercolano |
Assigned To: | mike |
Fix Version: | 1.1.5rc2 |
Update Notification: | |
Trouble Report Files:
Trouble Report Comments:
|
#1 | greg.ercolano 22:33 Nov 10, 2003 |
| With Fl::scheme("plastic") in effect, Fl_Scroll still draws the solid battleship gray background, instead of the Mac-like subtle delineated background.
Enclosed patch for possible solution, which handles scrolling the background. Can probably be implemented with a faster drawing algorithm. | |
|
#2 | mike 07:49 Nov 11, 2003 |
| You can get the tiled background to show through (but not scrolled...) by using a frame boxtype...
If we do fix this in 1.1.x (working on 1.2.x right now :), we'll probably use the tile image instead of manually drawing lines... | |
|
#3 | greg.ercolano 14:35 Nov 11, 2003 |
| > You can get the tiled background to show through.. > by using a frame boxtype...
Don't think so.. maybe I'm doing something wrong; I'll attach a test program showing how that doesn't seem to work in a followup.
Even with scroll.box(FL_NO_BOX) it still draws flat gray rectangles.
I suppose if it didn't, scrolling would leave behind a trail of widget artifacts for the widgets being scrolled.
I suppose one would expect the window background to redraw during scrolling if the scroll had no box type, but I don't think it actually works that way, or scrolling would flicker.
For sure there are parts of the scroll area that are unconditionally drawn with a filled rectangle, eg. from Fl_Scroll.cxx:
---- // fill any area to right & bottom of widgets: if (R < X+W && B > Y) { fl_color(s->color()); fl_rectf(R,Y,X+W-R,B-Y); } ----
..this code doesn't check boxtypes or schemes, and draws flat areas instead of stripes w/plastic schemes.
This is why the patch replaces code like the above with the bgfill() function, which detects the scheme setting, and aligns the stripes according to the current scroll position.
I think I tried to use the tile approach used by Fl_Window to do the plastic scheme, but had a lot of trouble aligning the tiles to each other, ending up with tears in the pattern. Maybe there's a way to do it, and I just wasn't manipulating the tile algorithm correctly. At least with the line drawing approach, I seemed to be able to control alignment of the patterns.
| |
|
#4 | mike 21:13 Mar 10, 2004 |
| I think this is resolved in current CVS, but please let me know if this isn't so... | |
|
#5 | mike 16:25 Apr 09, 2004 |
| I just checked it; looks like it needs to be re-opened:
o I checked out cvs 1_1 on a redhat 9.0 system o Recompiled clean o Copied the foo.cxx into the test directory and built it (I renamed out tile.cxx, putting foo.cxx's code in its place, then 'make tile')
The background of the scroll window is still battleship gray. The background of the scroll should match the window's background; the plastic "louvered" look. | |
|
#6 | mike 17:55 Apr 09, 2004 |
| Try the attached patch; it draws the scheme_bg_ image, if present, for all "frame" box types and FL_NO_BOX, but only when the Fl_Scroll is the direct decendent of a Fl_Window.
For any other kind of usage, you'll want to make your own Fl_Scroll widget that has a background image. | |
|
#7 | greg.ercolano 19:23 Apr 09, 2004 |
| Applied str205.patch, and recompiled.
Yes, the louvers show through now.. but, as soon as you start scrolling around, it leaves garbage behind; see attached 'drit.gif'.
If you obscure the window then reveal it again, it redraws correctly.
I ran into this when creating the first patch, which is what the fl_scroll-patch.txt non-trivially addresses; it redraws the pattern, instead of doing the Screen To Screen (STS) region copies optimization.
The STS optimization is great, but won't work if the bg is a "pattern". If the scrolling step rate doesn't precisely match the step rate of the pattern, the pattern is smeared at the edges during the STS copy and the resulting scanline drit is then scrolled into the window.
This is why the patch I submitted redraws the pattern, to ensure the background aligns correctly.
I think it's an operational hazard that when plastic mode is enabled, scrolling can no longer use the STS optimization trick; it's what you live with for the app to look "pretty" instead of battleship gray.
Any 'plastic' programs that depend on large scrolling regions will look like 'battleship gray' programs if not addressed.
| |
|
#8 | greg.ercolano 19:43 Apr 09, 2004 |
| Wait, looking closely at the str205.patch, it /is/ trying to redraw the pattern during scrolling.
But it's not doing it right for some reason, causing the drit.
Trying to figure out the real cause.
| |
|
#9 | greg.ercolano 03:57 Apr 10, 2004 |
| I'm attaching "erco-04-09-2004.patch" which makes it draw correctly.
The problem was the Fl::scheme_bg_ louver pattern wasn't lining up with the scroller, causing the redraw() problems shown in drit.gif. It would appear the Fl_Tiled_Image isn't able to pan the pattern around, making it impossible to line it up with the scrolled region.
The attached patch is against the current 1.7.2.6.2.8 version of Fl_Scroll.cxx in cvs 1_1.
The patch solves the problem by using a small static function (plastic_draw()) to draw the tile pattern; the function is capable of 'panning' the tile pattern around to match the vertical scroll position.
Seems like a decent hack that solves the visual problem, until someone can figure out how to pan the Fl::scheme_bg_ pattern.
| |
|
#10 | mike 15:08 Apr 10, 2004 |
| The tiled background should *not* scroll with the contents; if you want that functionality, make a subclass that does its own background tile, as the current fix just makes sure that the window background shows through.
Adding a background image to 1.2cvs is a possibility, however not for 1.1.x. | |
|
#11 | greg.ercolano 17:19 Apr 10, 2004 |
| > The tiled background should *not* scroll with the contents;
I think you're missing it..
I agree it shouldn't pan, but it does because of how fl_scroll() is used to pan the screen. The new draw_clip() code you have is only used to redraw the tiny little rectangles of screen left behind after fl_scroll() pans the image.
The problem is this redraw code is not adjusting the pattern to match the region that was fl_scroll()ed, making it 'smear' the pattern.
To make the bg pattern stand still, one would have to NOT use fl_scroll(), and redraw the entire bg each time the scroller moves, then redraw all the children over that. This would cause flicker.
Here's the current behavior:
Before scroll up: After scroll up: __________________________ __________________________ |1 | |2 | |2 | |3 | |3 | |4 | |4 | |5 | |5 | |XXXXXXXXXXXXXXXXXXXXXXXXXX| -------------------------- --------------------------
fl_scroll() is taking care of the scroll up, which moves the children AND the bg pattern (there's no stopping that), revealing the XXX region. Then the new "draw_clip()" function is called to redraw /just/ the XXX region.
The problem is the tile pattern doesn't line up with the fl_scroll()ed pattern above it, leaving a garbage scanline at the intersection of the two regions, causing the smear as the user continues to scroll.
Hope this makes sense; without my patch, the bg slides around and leaves drit behind. My patch clears up the drit, but does not address the issue of the bg moving; I don't know anyone that has offered a solution to that; that's a tough one to do without getting 'flicker'.
The patched draw_clip() code is deceptive; the call to Fl::scheme_bg_->draw() is not doing what the programmer intended. See my elaborations in fltk.bugs. It's kinda hard to explain, and took me a while to figure out.
| |
|
#12 | mike 21:03 Apr 10, 2004 |
| I'm not too partial to the line drawing hack; try the attached patch instead (patch is relative to the first patch...)
(I added an "image()" method to Fl_Tiled_Image) | |
|
#13 | greg.ercolano 21:42 Apr 10, 2004 |
| Applied new patch.
Closer.
Everything to the right of the children looks right; the bg even stands still.
But the area of the screen between the children still smears, it's just hard to see with the example.
If you change the arrangement of the buttons, you can see it more clearly; see attached 'staircase.gif' and staircase.cxx. | |
|
#14 | mike 17:45 Apr 11, 2004 |
| Well, short of forcing a full redraw for this case, or always clearing the background and not doing the tile, I don't see a solution. Fl_Scroll was never meant to support "frame" box types... | |
|
#15 | greg.ercolano 03:29 Apr 12, 2004 |
| IMO the only course of action is to 1) accept that the only way to get flicker free scrolling is to live with the fact the bg moves with the children, and 2) make sure the small region redraws of the pattern synchronize with the scrolled bg.
Problem is, Fl_Tiled_Image seems to lock the pattern to physical screen positions, preventing #2. So the pattern's white lines alwyas draw at y positions 0, 4, 8, 12.. there seems no way to shift the pattern so the white lines draw at 1, 5, 9, 13.
It seems like the cx/cy values for Fl_Tiled_Image::draw() should do this, but they don't, hence the erco-04-09-2004 'Alan Cox' patch ;)
| |
|
#16 | mike 07:04 Apr 12, 2004 |
| Well, at this point I am not inclined to support a scrolling background - it doesn't look right against the non-moving background and isn't what Fl_Scroll was designed for.
IMHO, we have three choices:
1. Leave it as it is and note the redraw behavior in the docos. 2. Force a full redraw for all scrolling when plastic + frame is in use, and note this behavior in the docos so the user can use Fl_Double_Window to avoid flicker. 3. Put things back such that we clear the background to color() and don't try to do the background tile at all.
Which do you want? | |
|
#17 | greg.ercolano 12:58 Apr 12, 2004 |
| > 1. Leave it as it is and note the redraw behavior in the docos. > 2. Force a full redraw for all scrolling when plastic + frame is > in use, and note this behavior in the docos so the user can > use Fl_Double_Window to avoid flicker. > 3. Put things back such that we clear the background to color() > and don't try to do the background tile at all.
If restricted to those three, I'd say:
#2 with caveat: If window==Fl_Double_Window, full redraw. If it's not, fall back to #3. Document the behavior, citing this STR.
That way if someone uses Fl_Double_Window with a 'frame' or 'nobox', they'll get 100% correct behavior.
The smearing problem with the current implemention of #1 will affect most scrolling apps, I think. I compiled my production code with #1, and it just looks wrong: http://seriss.com/people/erco/fltk/bugs/submit-renderman-smear.gif
I think the combo of #2 (if parent is a double window) and #3 (if non-double) will at least give behavior that has no artifacts 100% of the time.
| |
|
#18 | mike 15:47 May 15, 2004 |
| OK, I've implemented #2; doing #2 + #3 was a lot of extra work and I didn't feel it was necessary. | |
|
#19 | mike 15:47 May 15, 2004 |
| Fixed in CVS - the anonymous CVS repository will be updated at midnight PST. | |
[ Return to Bugs & Features ]
|
| |