I'm making my own UI from scratch using OpenGL that is why I'm asking this and please don't make any discouragement as this is just a hobby project.
Currently, I'm stuck implementing how this scrollbars really work. In my current implementation, the content scrolls at the wrong step value as well as the thumb, meaning, I set the value manually like 1px step for each of them.
The structure of my scrollbar implementation is describe as follows:
I draw scrollbars i.e the main rectangle where the 3 button lies.
Those 3 buttons are, thumb, buttonBack and buttonNext.
All of them do the basic logic of scrollbars i.e when I click each one of them, they moved. But the whole part(scrollbar) don't know how to scroll contents
So what I did is: I make another object and I call it scrollarea
It has two scrollbars, vertical and horizontal scrollbar.
I made a function called scrollToX and scrollToY which
does what I named to them.
But the step values I set to them are
manually set up.
I try to google some scrollbar, scrollarea, scrollview or whatever you call to that scrollable rectangle thing, but all I see are implementation and I cannot find any guides how to build your own. I have no choice but to look at their implementation. I try my best to comprehend what they did but their implementation of how their whole UI structure is very different to mine, and I cannot find anything useful there.
So I ask again here if anybody can explain me well how to make a properly functional scrollbar.
Most specific things I'm really concerned of are:
How do I determine the thumb step value?
How do I determine the content step value?
All of these depend on your content -
Is it just an image ? If so, you only need to change the offset depending on the size of the image.
Is it a list of values like in Windows explorer ? Then you need to create a data structure first that contains all of it, and shows the content that fits within the window as it scrolls.
OpenGL does not fit into this discussion.
Related
I want to make a menu that will take an undetermined quantity of labels and spread them out horizontally so that 3 are visible on screen at once. When pressing left/right it will go to the next one, the one that is selected is always in the center of the screen horizontally with the other two on the left/right of the screen.
The problem is that I also want a smooth transition not just a replacement. They need to wrap endlessly.
Not sure where to begin, not finding examples on google.
The concept you are talking about was popularized by Apple under the name "Cover Flow".
There is a widget like that available under a permissive license here: https://code.google.com/p/pictureflow/
I take it you want something a bit simpler (only show three labels, less fancy 3D effect), but I assume this is a good starting point.
Another one is the PathView QML element:
http://qt-project.org/doc/qt-5/qml-qtquick-pathview.html#details
It is even closer to what you like to do, feature-wise. It is also available in Qt4 and there is a tutorial here: http://qt-project.org/doc/qt-4.8/declarative-modelviews-pathview.html
folks!
I use a listview (Icon mode) to display items which consist of an image and a label.
As you can see in the shots the row height is variable on y depending on the label length. The problem is that I want the complete labels to be drawn, but they are automatically shrinked into two lines:
The strange thing about it is that once you select an item the whole label will be shown:
This is also the case when deselecting the item, but when another item gets selected, only that one will be shown completely.
Is there a way (without drawing the text manually) to avoid truncation in my case?
If some code is needed to answer this question, don't hesitate to ask.
Greetings,
Satara
I'm guessing this was a design choice: make things look less cluttered. E.g. picture your desktop with all labels shown completely... will look messy in my case.
However, you can fix this by drawing the label yourself. Have a look into custom draw which is a service provided by the list control. The thing is that it's usually an all or nothing approach, so this will likely require you to draw everything yourself: border, image, label, etc. The other option is to get hacky: subclass the window and draw the labels again after Windows did in response to several messages (unfortunately Windows does not restrict the painting to WM_PAINT, an optimization that is a left-over from the old days...)
I am building an editor using C++/Qt which has a click-and-drag feel to it. The behavour is similar to schematic editors (Eagle, KiCAD, etc), Microsoft Visio, or other programs where you drag objects from a toolbar into a central editing area.
My problem is that when the user clicks inside the custom widget I want to be able to select the instance of the box-like object and manipulate it. There will also be lines connecting the boxes together. However, I can't decide on an efficient method for selecting those objects.
I have two main thoughts on how to do the programming for this: The first is that the widget which is drawing the entire editor would simply encapsulate every one of the instances of the box. The other is to have each instance of the box (which is in my Model) carry with it an instance of a QWidget which would handle rendering the box (which would be in my View...but it would end up being strongly attached to the model). As for the lines connecting them, since they don't have a square bounding boxes they will have to be rendered by the containing widget.
So here is the summary of how I see this being done:
The editor widget turns into a container which holds the widgets and the widgets process their own click events. The potential issues here are that I don't know how to make the custom widget turn into a layout which lets click-and-drag functionality.
The editor widget takes care of all the rendering and processes the mouse clicks (the easier way in that I don't have to worry about layout...its just selecting the instances efficiently that I don't know what would be best).
So, now that there is a bit of background, for the 2nd method I plan on having each box-like instance having a bounding rectangle and the lines being represented by 3-4 pixel wide bounding rectangle segments (they are at 90 degree angles). I could iterate through every single box and line, but that seems really inefficient.
The big question: Is there some sort of data structure I can hold rectangles in and link them to widgets (or anything else for that matter) and then give it two coordinates (such as mouse coordinates) and have it spit me out the bounding box or linked object that those coordinates are inside of?
It sounds like your real question is about finding a good way to implement your editor, not the specifics of rectangle intersection performance.
You may be interested in Qt's "Diagram Scene" example project, which demonstrates the QGraphicsScene API. It sounds like a good fit for the scenario you describe. (The full source for the example ships with Qt.)
The best part is that you still don't have to implement hit testing yourself, because the API already provides what you are looking for (e.g., QGraphicsScene::itemAt()).
It's worth noting that internally, QGraphicsScene uses a simple iterative method to perform hit tests. As others have pointed out, this isn't going to be a serious bottleneck unless your scenes have a lot of individual items.
I'm having all sorts of size problems with Qt. I am creating my own widgets and using different layouts (generally, I need my own to make them work properly without spending hours on the "powerful" default layouts... which don't lay things out as intended.)
Once I'm done with a widget and its layout though, it doesn't work right. The size is never getting set properly unless I call widget->resize(1, 1); which finally forces a "resize" and makes the widget look correct (i.e. recompute the geometry.) Even the updateGeometry() call has no effect.
This is a dreadful problem when the resize() needs to be called on the parent widget (yuck!) and from what I'm reading should not be necessary were the layouts properly programmed.
Is there a sample that works and is not several thousand of lines long, or does Qt require several thousand lines to make anything work perfectly, even the simplest widget?
What are the minimal functions to be called to make a widget & its layout work at once?
Thank you.
Alexis
P.S. I tried to implement the sizeHint(), minimumSize(), maximumSize(), others that I'm missing? I was hoping that would be enough. Obviously, I also implement the setGeometry() on the layout to resize the children appropriately.
--- addition 1
There is a sample image with a layout that clearly isn't available as is in Qt. The positioning, functions, and colors of the different keys is XML driven and works for any keyboard in the world.
(note, this sample doesn't show the Enter key displayed on two rows and wider below than at the top; more or less, not doable at all with the regular layouts; of course, it works with my version.)
--- clarification
I'm not too sure how to describe the problem better. I was thinking to write a test widget next to see how I can reproduce the problem and then post that and eventually fix it. 8-)
The default layout function that the internal Qt layouts make use of require a lot of coding. I would like to avoid having to copy/paste all of that because for maintenance, it makes it close to impossible.
--- today's findings
As I needed to tweak one of the widgets, I decided to add a VBoxLayout and make it work.
I actually found the problem... One of the widgets in my tree is a QScrollArea and that sizeHint() returns (-1, -1). Not exactly what I'd expect but... whatever you put inside that widget has better know how to compute its width and height or else... it fails.
Looking at the code closely, I could actually compute the width by using the widest width found. Once I used that, the widget would appear (and it actually resizes itself as things change in the list, kinda cool.)
This being said, my earlier comment about having a tree of widgets that auto-resize themselves stands. From the root up to the parents of the leaves in your tree, all of those widgets will need a valid layout. Once I added one in the top widget it resized itself and its children properly (well... in my case up to the QScrollArea, the rest required a bottom to top resizing. Funny how that works!)
--- ah! ha! moment (or: what you find reading the implementation code!)
Today I bumped in another problem which just needed the correct call... I just couldn't find anything worth it in the documentation.
All the objects have a layout now, but a certain parent would not resize properly. Plain simple.
I had a call to the parent as following:
// changes to the children are changing the geometry
parentWidget()->updateGeometry();
Yeah. The docs says that's what you have to do. Nothing happens at all with that call. No idea what it's supposed to do, I did not look at that function. It never did anything for me anyway.
So... I looked at the layout to try to understand how it would send the info up/down. I did not see much except for one interesting comment:
// will trigger resize
This is said of the SetFixedSize mode. To reach that function you need to make the layout for update. Ah! Yes... the layout, not the parent widget... let's try that instead:
parentWidget()->layout()->update();
And voila! It resizes correctly in all cases I have. Quite incredible that the widget updateGeometry() doesn't trigger the same effect...
Although it's possible to do what you want it sounds like the problems you are having are because you're using Qt in a way that it's not meant to be used. Why do you need separate widgets for each key represented on the keyboard?
I see two options, both of which are better in some way:
Use QGraphicsScene and QGraphicsView.
A single custom widget that uses custom drawing to display the keyboard (and likely uses hover for hints).
The first option is probably better. Your keys could then be represented by QGraphicsSimpleTextItem's or even a QGraphicsSvgItem. It also provides a number of standard layouts or you could choose to write your own layout. By default you can use the keyPressEvent or mouseReleaseEvent to respond to user interactions.
I'd highly recommend you take a look at the QGraphicsView examples to get an idea what you can do.
If you go the second route you'll need to record the different key locations so you can respond accordingly as the user moves the mouse around, clicks, etc.
This won't help you with your immediate issue but I wanted to show you a keyboard I made using standard layouts and buttons. It's not perfect and it still won't help you with an enter key that spans two rows but it's not bad. It's resizable too by resizing the window, although I'm not sure if that will be apparent from the images below as SO may be scaling them. (you can view the actual images by opening them in their own tab)
Anyway, this was done using only Qt Designer with no manual coding. It consists of a top level vertical layout with 5 horizontal layouts in it. The buttons are then inserted into one of the 5 horizontal layouts. The size of the keys can be controlled by setting the horizontal and vertical size policies to "ignored" for most of the buttons and then horizontal "minimum" for buttons that you want to be wider. Things can be tweaked by setting min and max size restrictions to buttons. When resized, the buttons will not maintain their relative proportions though, that would probably take some custom programming.
The styling in your example could be approximated pretty well using css style sheets and background images. Still not a minor effort but you should be able to get most of the way there without custom layouts and buttons.
I have an MFC application. When running it on Windows 7 I realized that when changing the display percentage to meduium - 125%, I have a TextControl which is cut off (end of sentence doesn't appear.)
How can I fix this?
I could enlarge the size of the control on the dialog, but I'd rather do that via the code.
My application is localized and I woudn't want to change all the dialogs on every language.
In general, the issue is that absolute coordinates are being used for some sizing rather than relative. The framework will initially lay things out correctly in large DPI, it's then up to you to keep things straight through resizes.
You can use a layout framework like this one: Ultimate Toolbox Layout Manager, or you can roll your own.
Here's a common pattern I use:
Define a struct that captures ID, size, location, and layout behavior (anchor top|left|right|bottom) of a control
In the document constructor initialize an array of structs with your desired layout behavior
In OnInitDialog, capture the initial control positions, e.g. for controls set to anchor top left you need to grab the initial distance from the top and left of the parent.
In OnSize, reposition and resize each control according to its layout behavior.
I'm not exactly sure if it helps in your case but the ResizableLib works pretty well for me. You can also skip creating a library and just use the files in your project.
There is a separate article for CResizableDialog which explains in a few easy steps how to implement this for existing dialogs.