QScrollBar Snap to value - qt

I'm wanting to implement a scroll bar that snaps to particular values (like windows can snap to the edge of a screen). The idea is that as I drag the scrollbar down it snaps the bar to values as it approaches them.
My scenario is displaying 3 chapters of text. I would like to be able to snap to the beginning or end of a chapter. Of course, to go to the start of the first chapter the scrollbar one can just scroll to the top and likewise with the end of the third chapter. So I'd like to draw two lines on the scrollbar to represent the start of the second and third chapters and then have the top and bottom of the scrollbar snap to those lines. So I'm really actually wanting to use this within a QTextBrowser but I can control a QTextBrowser with a QSnapScrollBar I just don't really know where to start.
Any help would be greatly appreciated.

You could roll your own custom scrollbar class that inherits from QScrollBar or perhaps QAbstractSlider and override the valueChanged(int) signal. Some basic pseudocode:
if currentValue is within 5 of snapvalue1:
set scrollbar value to snapvalue1
elsif currentValue is within 5 of snapvalue2:
set scrollbar value to snapvalue2
...
update/redraw widget
Though I have a feeling that this might seem jerky to the end user.
You could also investigate the pageStep property (which controls how far it will scroll when using the Page Up/Down keys), maybe that could be used to serve your purposes

Related

GWT - PopupPanel, change layout when flipped

I'm creating a context menu for certain elements using a PopupPanel; the menu itself is going to be fairly large and complex. What I'm looking to do is to have a list of buttons, plus an image and some text, related to the element clicked.
My problem is that I'd like the buttons to always display directly under the clicked element, because that's convenient for the user; the issue is that when PopupPanel is near the edges of the screen, it automatically changes position to be fully visible, not aligning its left side to the element as usual. I like this behavior, but it moves the position of the buttons away.
So what I'd like to happen is: normally the buttons are on the left of the panel, the other stuff is to the right. When the panel is close to the right of the screen, I'd like the buttons to instead be on the right (and thus under the clicked element) and the other stuff on the left.
Is there a clever way to do this, either in GWT or better yet, using only CSS? PopupPanel itself doesn't seem to tell you when it's going to get flipped, sadly. The only solution I currently have is to manually check the position and width of the popup before showing it and adjust accordingly, but I'm hoping there's a better solution.
Here is what I suggest (based on my own implementation of a similar use case):
Have the position callback implementation accept references (in constructor) on:
PopupPanel element
element on which user right cliked
the content you put in the PopupPanel
Replicate (I know this not DRY but implementation is package private) the code from default position callback
When opening to the right invoke a method that changes the layout of your content (CSS based or otherwise)
I hope it helps. If you find something better let me know.

Qt overlay(drop-up) box

I am creating a Qt application where I need to display contents in an overlay box(Please refer to the attached image). The box needs to slide up from behind the bottom dock when a button is pressed and slide down by toggling the button. I tried with a QWidget but couldn't achieve what I wanted. Also I don't know how to list the elements in the overlay box. The elements are dynamic or changing.
The widgets stacking order is defined by their order in the QObject hierarchy tree. The first element is the bottom, and every next is on top of the previous. Children are on top of their parents, in widgets confined within their bounds, in QML free.
If you want that sliding element to appear on top of everything else, just put its parent on top of everything else.
After all it is on top of the bottom control bar, which is on top of the playlist, so you have it all worked out for you.
The same applies if you decide to do the wiser thing and use QML instead of QWidget. Animation and states are much easier there. Not to mention more specific designs.

Flex: preventing tree's vertical scroll bar overlapping view

I have an mx:Tree, but when the vertical scroll bar appears, it overlaps the content of the tree (odd that the horizontal bar does not). That might be acceptable for the text, but the stripe that I create using the item renderer, for certain items, seems to make it an anathema to the QA guys. How can I keep this from happening?
I have an idea for a workaround: I could make use the item renderer to stop the drawing a little bit short of the right side of the view (not that I can reliably get the width of a scroll bar) but I can't even figure out how wide the displayable part of a tree is--all the properties of a tree seem to be about its entire width, which includes the entire area coverable using the horizontal scroll bar. However, the blue stripe signifying a selected item doesn't seem to have that problem--it stops short of the scroll bar. In any case, when trying to find the displayable region, I don't know if I could handle the added complication of when the horizontal scroll bar is moved. Much better if someone could tell me how to put the veritcal bar outside the displayable tree area (or shrink the displayable area, of course). Thanks.
I'm using the Flex 3.5 SDK
I was able to find the solution when researching horizontal scrollbar issue on list and tree component. The blog to which it links eventually shows a kind of hacky solution (in the readers' comments) that shows how to make sure that none of the drawing is done beyond a certain boundary.

ASP.NET AJAX Toolkit ReorderList with more items than fit on the page

I have a ReorderList on my page and it works just great, but...
Now, I have almost 100 items that I'd like to be able to reorder and they flow off the page, even at 8pt. When dragging, the page does not scroll as I approach the bottom (or the top) so I have to drop my item, scroll down, then drag some more. When I drag and drop in Word, as I approach the bottom of the window, the window scrolls so I can move to where I want to drop.
Alternately, it would be fine with me to have the items show up in multiple columns - their width would allow at least 3 columns. But none of the CSS solutions I have found which allow a <ul> to have multiple columns seem to work as they require multiple <ul>s which I don't think I can do with the ReorderList control.
Any ideas?
Here is an idea: Check if the left mouse button is being hold down, and also check for the position of the pointer on the page. If the coordinates are down at the bottom of the page at a position that you think is down enough for the page to be scrolled, then you could use the window.scrollBy() Method, and stop it when the Mouse button is released. You could also set a bool value when a Reorder item is clicked and while the button is down, and set it to false when it is released, and again the same idea, check for the position of the pointer.
Sample window.scrollBy()
Good luck!

Making a Flex DataGrid scroll smoothly

I've noticed that the default behaviour for a DataGrid's vertical scroll bar is to scroll one row at a time. This is all well and good when the rows are all uniform and small (e.g. displaying a single line of text), but gets really ugly as soon as you have rows with variable heights.
I'm curious, is there a way to make DataGrid scrolling "smooth"? For instance, is there a way to have the DataGrid scroll by a set number of pixels, lines of text, etc. rather than scrolling one row at a time?
So far, the only solution I've managed to come up with is to place the DataGrid in a Canvas and have the Canvas do the scrolling instead of the DataGrid. The issue with this approach, though, is that as soon as the Canvas scrolls far enough, the DataGrid headers scroll off-screen. Ideally, I'd like to get the smooth-scrolling nature of the Canvas, but also keep the DataGrid headers visible. Is that possible?
The way that ItemRenderer's work in Flex 3 makes smooth scrolling difficult to achieve. Basically Flex recycles item renderers scrolled off of the top of the list as the display objects used for new data at the bottom of the list. Adobe's implementation of most list components in Flex 3 creates and adds these items as they come on to the screen rather than just off the screen, so they "pop in" and smooth scrolling isn't available. I'm not sure why they couldn't have done it in a similar manner for items +/- one position above or below the current scroll pane, but they didn't, and we're stuck with sticky scrolling by default.
Work-arounds do exist, though the one you've noted (dropping the datagrid into a canvas) negates the display-object saving intention of item renderers and incurs a performance cost. This will be fixed for most list-based Flex components in Flex 4, though it won't be fixed immediately for DataGrid. The DataGrid / AdvancedDataGrid component is maintained by a separate team based in India, last time I heard, and so it tends to be a bit behind the rest of the SDK.
I'd recommend trying something similar to this implementation of a smooth-scrolling list by Alex Harui. I'm not sure exactly how well it'd work for DataGrid or AdvancedDataGrid, but this is the most intuitive technique I can think of for making the list scroll correctly.
Try this... It's still based on Alex's code that was mentioned above. His should still be a great start for removing the snap-to-row behavior. Original source:
http://blogs.adobe.com/aharui/2008/03/smooth_scrolling_list.html
Alex's original some code for smooth vertical scrolling but that was not an issue I had with the DataGrid. It was smooth scrolling horizontally that I needed. I am using the DataGrid in an unorthodox manner for analyzing plain text reports output by our database (great way of providing visual feedback on a document). The code below allows content to go off screen and the user can scroll without that snap-to-column behavior.
You can adapt this to use the same math routines for vertical scrolling and then it will make scrolling possible and ignore the snap to row behavior. In particular switch the usage of the listContent.move method to move the contents vertically and use a inverse of the rounded pixel value you calculate from the vertical scroll bar (as opposed to my using the horizontal).
This method is bit simpler than Alex's method from the link above - a lot less code so try adapting and see how it works.
override protected function scrollHandler(event:Event):void
{
// Override the default scroll behavior to provide smooth horizontal scrolling and not the usual "snap-to-column" behavior
var scrEvt:ScrollEvent = event as ScrollEvent;
if(scrEvt.direction == ScrollEventDirection.HORIZONTAL) {
// Get individual components of a scroll bar for measuring and get a horizontal position to use
var scrDownArrow:DisplayObject = horizontalScrollBar.getChildAt(3);
var sctThumb:DisplayObject = horizontalScrollBar.getChildAt(2);
// I replaced maxHorizontalScrollPosition in Alex's code with "1300" to fix my exact application. In other situations you may finding using some property or different value is more appropriate. Don't rely on my choice.
var hPos:Number = Math.round((sctThumb.y - scrDownArrow.height) / (scrDownArrow.y - sctThumb.height - scrDownArrow.height) * 1300);
// Inverse the position to scroll the content to the left for large reports
listContent.move(hPos * -1, listContent.y);
}
// Go ahead and use the default handler for vertical scrolling
else {
super.scrollHandler(event);
}
}

Resources