kungfoomasta
24-09-2007 05:56:53
So I have implemented scrolling, but there are some problems which will take some effort to fix. I tried browsing google some, but couldn't find much on how scrolling is implemented. I also tried looking at other GUI libraries, but I'm not sure where to look.
This is what I do currently. I have a ScrollPane widget that has event handlers that handle events fired by its parent. For example, the Panel Widget creates a ScrollPane. The scroll pane, on construction, creates 4 scroll bars, and sets up the event handlers. Note that the scroll bars, while created in the scroll pane constructor, are children of the ScrollPane's parent, in this case the Panel. When the parent creates children widgets, the ScrollPane gets notified. The ScrollPane adds the widget to a list of managed widgets, and also stores the original offset between the widget and its parent, the Panel. Whenever horizontal or vertical scrolling occurs, the ScrollPane's position changes. In addition, the Scroll Pane iterates through its managed widgets, and moves them vertically and horizontally, taking into account the original offset between widget and parent, and moves the widgets so that the offset is maintained, but according to the scroll pane's origin. I designed the ScrollPane object to not be too intrusive. Simply create it and it will hook into events and take care of everything behind the hood. It's a good idea, anyway..
Also at my disposal is the ability to perform clipping. I can set a Clipping rect for any quad, and the quad will only draw parts that are inside of this Rect. In this way, I can move widgets around, and they won't be drawn. For example, sliding buttons inside of a Window will scroll the buttons outside the window bounds, but the window is the clipping rect, so the buttons will not draw.
Current Problems:
- Removing managed widgets. I made a function that determines the ScrollPane's bounds, which should always oncompass all managed widgets. When a Widget is added to managed widgets, the pane could get larger. Likewise, when a widget is removed, it could get smaller. The problem is, it is difficult to derive the new scroll pane bounds, because the managed widgets are shifted around. For example, I create a Button at absolute x position -1. I create another button at absolute x position 2. I scroll down to the second button and click it, and it removes itself. The problem is, I have scrolled over to this button, which has moved the first button to -2. In general, the problem is that widget positions are not constant, and it's hard using them to derive scroll bounds, or where these widgets should be placed relative to scroll value, etc.
With some more work, I think I could solve this problem. Mouse events work normally. But I'm thinking to myself.. is there a better way to do this?
I would like to put into place some method that doesn't involve altering the widgets actual position. Since the Quad object is not part of the Widget class, I do have the ability to draw Quads in locations different from the actual widget location. Maybe this, combined with some form of translating mouse coordinates into "virtual" coordinates, would work? I haven't looked far enough into this to see if this is a good approach or not.
Any information, comments, or suggestions are welcome. If anybody has experience, or know where I can look, it would be most appreciated. Sorry for the long post.
This is what I do currently. I have a ScrollPane widget that has event handlers that handle events fired by its parent. For example, the Panel Widget creates a ScrollPane. The scroll pane, on construction, creates 4 scroll bars, and sets up the event handlers. Note that the scroll bars, while created in the scroll pane constructor, are children of the ScrollPane's parent, in this case the Panel. When the parent creates children widgets, the ScrollPane gets notified. The ScrollPane adds the widget to a list of managed widgets, and also stores the original offset between the widget and its parent, the Panel. Whenever horizontal or vertical scrolling occurs, the ScrollPane's position changes. In addition, the Scroll Pane iterates through its managed widgets, and moves them vertically and horizontally, taking into account the original offset between widget and parent, and moves the widgets so that the offset is maintained, but according to the scroll pane's origin. I designed the ScrollPane object to not be too intrusive. Simply create it and it will hook into events and take care of everything behind the hood. It's a good idea, anyway..
Also at my disposal is the ability to perform clipping. I can set a Clipping rect for any quad, and the quad will only draw parts that are inside of this Rect. In this way, I can move widgets around, and they won't be drawn. For example, sliding buttons inside of a Window will scroll the buttons outside the window bounds, but the window is the clipping rect, so the buttons will not draw.
Current Problems:
- Removing managed widgets. I made a function that determines the ScrollPane's bounds, which should always oncompass all managed widgets. When a Widget is added to managed widgets, the pane could get larger. Likewise, when a widget is removed, it could get smaller. The problem is, it is difficult to derive the new scroll pane bounds, because the managed widgets are shifted around. For example, I create a Button at absolute x position -1. I create another button at absolute x position 2. I scroll down to the second button and click it, and it removes itself. The problem is, I have scrolled over to this button, which has moved the first button to -2. In general, the problem is that widget positions are not constant, and it's hard using them to derive scroll bounds, or where these widgets should be placed relative to scroll value, etc.
With some more work, I think I could solve this problem. Mouse events work normally. But I'm thinking to myself.. is there a better way to do this?
I would like to put into place some method that doesn't involve altering the widgets actual position. Since the Quad object is not part of the Widget class, I do have the ability to draw Quads in locations different from the actual widget location. Maybe this, combined with some form of translating mouse coordinates into "virtual" coordinates, would work? I haven't looked far enough into this to see if this is a good approach or not.
Any information, comments, or suggestions are welcome. If anybody has experience, or know where I can look, it would be most appreciated. Sorry for the long post.