How can I position QDockWidgets as the screen shot shows using code? - user-interface

I want a Qt window to come up with the following arrangement of dock widgets on the right.
alt text http://img72.imageshack.us/img72/6180/docksonside.png
Qt allows you to provide an argument to the addDockWidget method of QMainWindow to specify the position (top, bottom, left or right) but apparently not how two QDockWidgets placed on the same side will be arranged.
Here is the code that adds the dock widgets. this uses PyQt4 but it should be the same for Qt with C++
self.memUseGraph = mem_use_widget(self)
self.memUseDock = QDockWidget("Memory Usage")
self.memUseDock.setObjectName("Memory Usage")
self.memUseDock.setWidget(self.memUseGraph)
self.addDockWidget(Qt.DockWidgetArea(Qt.RightDockWidgetArea),self.memUseDock)
self.diskUsageGraph = disk_usage_widget(self)
self.diskUsageDock = QDockWidget("Disk Usage")
self.diskUsageDock.setObjectName("Disk Usage")
self.diskUsageDock.setWidget(self.diskUsageGraph)
self.addDockWidget(Qt.DockWidgetArea(Qt.RightDockWidgetArea),self.diskUsageDock)
When this code is used to add both of them to the right side, one is above the other, not like the screen shot I made. The way I made that shot was to drag them there with the mouse after starting the program, but I need it to start that way.

You can use QMainWindow::splitDockWidget .
From the docs:
Splits the space covered by the first dock widget into two parts, moves the first dock widget into the first part, and moves the second dock widget into the second part.
The orientation specifies how the space is divided: A Qt::Horizontal split places the second dock widget to the right of the first; a Qt::Vertical split places the second dock widget below the first.
You have to set QMainWindow::dockNestingEnabled to true first (but I guess you already did that).

I never tried it but I think you can set the orientation of the dock widget when adding it to the main window:
void QMainWindow::addDockWidget ( Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation )

Related

How to attach a band to the right side of CReBar control

On my frame window I have a CReBar control with non-movable bands on several lines. On the last line there are two bands, which currently aligned to the left, the second immediately after the first.
+--------+-------+------------------------------------+
|11111111|2222222|
+--------+-------+------------------------------------+
But my product management wants me to attach the second band to the right side of the line, with empty space in the middle.
+--------+------------------------------------+-------+
|11111111| |2222222|
+--------+------------------------------------+-------+
I cannot find anywhere how to do that. I would be grateful for any help.
Edit:
The actual code uses the Xtreme GUI library, but its structure is pretty standard:
// ... Create toolbars
// Add toolbars to ReBar.
if (m_wndReBar.Create(this) &&
m_wndReBar.AddToolBar(pNavigateTB, RBBS_BREAK | RBBS_NOGRIPPER) &&
m_wndReBar.AddBar(&m_wndAddressBar, NULL, NULL, RBBS_NOGRIPPER) &&
m_wndReBar.AddToolBar(pMainToolBar, RBBS_BREAK | RBBS_NOGRIPPER) &&
m_wndReBar.AddToolBar(pViewsHelpTB, RBBS_NOGRIPPER))
{
...
}
Here m_wndReBar is a CReBar-derived class, and toolbars are Xtreme wrappers of the common Toolbar control. They use the regular MFC flags, and I didn't find an option to align toolbar to the right.
There is no style or parameter of a toolbar, which forces it to align to the right. However, it is possible to expand the previous toolbar in a way that it will push the subsequent toolbar to the rightmost position.
Let, as in the first figure above, two consecutive toolbars are on the same line in the CReBar, and the first toolbar has index I. Than the command
m_ReBar.SendMessage(RB_MAXIMIZEBAND, I, 0);
will move the second toolbar to the right, as in the second figure. This rightmost position will be kept during the window resizing, but adding a new toolbar to the rebar can break it.

How to grab the scrolling amount in one window?

This is the first step to scroll two windows simulteneously, the second step is to find a way to apply that amount to the other program. But I really don't know where to start, all I see in from Google is about modifying the behavior of the scroll of the mouse, not the scrolling amount in one window. Advantages of using this instead of listening to the keys:
Scrolling will be seamless since the other program are scrolled in the background
Clicking on the scrollbar works
Different scrolling speeds don't affect the comparison
Moving lines in text editors won't scroll pages in PDF viewers
I can tell you what I would do, but it's not going to be fun...
Assuming the text is roughly evenly distributed (which it might not be between two languages like that, and two windows with different text sizes and widths, really consider this carefully before you do the work), then the goal is to force both scroll bars to be at the same percent relative to their whole. So what you need to do is write a function to determine what percent each scroll bar is at. I would screen capture both windows and crop out the important parts of the scroll bar like this:
Specifically the up and down buttons, the top of the scroll handle, the bottom of the scroll handle. Save them in their own files. Do it for both windows in case they draw their scroll bars a little differently.
Now the tricky part. Write a function that does the following: imagesearch for the top button within rightmost 25 pixels or of the specified window. Same for the bottom button. Same for the top of the handle. Same for the bottom of the handle. Use this to determine where your window is.
SetTitleMatchMode, 2 ; so it matches the end of the title
WinGetPos , X, Y, Width, Height, LibreOffice Writer ;exact substring of window name required
Use something like this to find the scroll bar parts.
CoordMode, Pixel , Screen ;so image search searches entire screen
barwidth = 25 ; make sure it's more than the bar is wide.
ImageSearch, TopButtonX, TopButtonY, X+Width-barwidth , Y, X+Width, Y+Height, TopButton.bmp ; no jpg, fuzzy edges make searches fail
Then do some math, something like:
TopButtonY := TopButtonY+TopButtonImageHeight ; because we only care about the position of the bottom of the button.
BottomHandleY := BottomHandleY+BottomHandleImageHeight ; because we only care about where the bottom of the handle is.
HandleHeight := TopHandleY - BottomHandleY ; how tall the scroll handle is
TotalHeight := TopButtonY - BottomButtonY - HandleHeight ;how tall the scroll field is
HandleOffset := TopHandleY - TopButtonY ;how far it is from the top
HandlePercent := HandleOffset / TotalHeight ; the part we care about. return this value
With a function like that, you can know how scrolled each window is. All that's left is to send the scroll commands. There's a few choices.
; ControlSend , Control, Keys, LibreOffice Writer
ControlSend , Control, {Pgdown}, LibreOffice Writer ; or {Pgup}
ControlSend , Control, {WheelUp}, LibreOffice Writer ; or {wheeldown}
ControlSend , Control, {Up}, LibreOffice Writer ; or {down}
If it lets you move the caret with up/down arrows while the window is inactive, that is probably the most precise option, even if it takes a bit longer. The fastest most precise way is to simulate a click drag also using control send. To use ControlSend you need to figure out which control you're working on. WindowSpy can help you with that.
So first: Find the scroll positions of both windows. Second determine which window is active. Third, nudge the inactive window in the correct direction. Repeat until they're within a certain tolerance range (otherwise it will bounce up and down endlessly).
I can't emphasize this enough, but please make sure that getting the scroll bars in approximately the same positions is sufficiently close before even attempting this. If it isn't, you will have wasted a lot of time fiddling with it. Keep in mind it will be less and less accurate the longer the text is.
If it is an option, I would definitely consider copying the contents of both windows into a program that gives you more access to the controls (or better one that is specialized for this purpose). If you had more access, you could use the paragraph breaks to line up the texts with far more precision.
If you really just want to see both texts side by side (and the paragraphs do line up), you could find a text editor that tells you information like this:
If autohotkey will let you read the text of that information, you can copy the PDF into autohotkey's memory (separated by line) and use autohotkey to show only the corresponding paragraph of the PDF as you move around in the editable document.
Hope something I said helps, good luck.

Windows API Functions in FORTRAN - What series of API's is needed to Simulate a Window MAXimise button action?

first off, I'm very new to using API's so please bear with me I'm on a steep learning curve !
I'm creating an application using Silverfrost Fortran FTN95.
I've been trying to initiate the opening of an initial Window within the program which uses the whole screen
useable area (the so-called WORKAREA in API parlance) but am having a problem.
Having used GET_WINDOW_LOCATION# API function within my Fortran code to obtain the dimensions and origin of the max possible area for
the window (without taskbar), I've then defined the 'origin' of the window to be at -n,-n where the border is n pixels thick and I've
increased the window dimensions by (2xn) in each direction so that the other 2 borders will be off-screen at top or under the taskbar at the bottom edge).
Anyway, I'm having difficulty obtaining exactly the same as produced via clicking the 'MAXimise button' on a window.
While the window produced itself seems to occupy the whole area available, when it appears the CAption appears right on the upper edge of the
CAption ba(i.e. not centre justified vertically).
Also, the MINimise, MAXimise and CLOSE buttons in top rh corner of window do not fill the whole depth of the CAption bar (they're about half the depth and indeed appear to be cut-off).
If I subsequently click the window 'MAXimise button' after initial window creation then the CAption and buttons re-align themselves correctly.
This is all illustrated in this image here:-
http://s1164.photobucket.com/user/john_pbucket/media/SilverfrostForumsImageFiles/MAXWIN-Summary_zpscajfx3vx.png.html
Note - I first created the full window with borders within the available screen area (this is the first example shown) where the window Border (8pix wide) is visible
The subsequent attempt to create the window as per the MAXimise button places the window at origin (-8,-8) and I increase the window dimensions by 16 (2xborder width) in each direction in order to get the borders off-screen, but thy're still there.
So, What series of Windows API commands should I be using exactly to get the window to open in a correctly maximised state, and are there any 'subtleties' of alignment and/or spacings I should be aware of which may be causing this problem?
I guess the question boils down to 'what sequence of API commands does the window MAXIMISE button execute ?' but I can't find an answer anywhere.
Maybe there are also some subtleties I need to know about with regard to any windows dimensions parameters which could be creating the anomaly ?
Any help/guidance would be appreciated. Thanks

ZedGraph scrolling left truncates data

I am using a ZedGraphControl in a WindowsForms project in C#. The ZedGraphControl is V5.1.5.
The data in the control is static and I add it all before the form is shown. The X axis of the data consists of numbers indicating seconds offset from the beginning. in other words from 0 to some number of seconds.
I want to initially show the last 5 seconds, but provide a horizontal scrollbar so the user can scroll back and forth. I set the "graphPane.XAxis.Scale.Max = maxX;" where maxX is the largest X value in my data. I set the "graphPane.XAxis.Scale.Min = maxX - 5;".
The data starts off displaying the way I want it, but when the user scrolls the horizontal bar, bizzar behavior occurs.
As you drag the thumb of the scrollbar to the left, the beginning of the data shown in the grid moves to the lower values as expected, and the thumb of the scrollbar moves to the left, but the right edge of the thumb stays at the right of the scrollbar and you cannot move back to the right. It is as if the data to the right of the viewing range gets truncated as you scroll left.
I cannot find any reason for this nor any way to control it. Does anyone have any ideas about this behavior?
Ok, found it myself.
I found a fine article that describes scrolling:
Add a ScrollBar
In it the author specifically says "the scrolling will be wacky because the scrollable range has not been set".
I used the sample "Manually Setting the Scroll Range" and the part that I was missing is setting the zedGraphControl1.ScrollMinX and zedGraphControl1.ScrollMaxX properties. Once I defined these values everything started working as expected. I also found that in my case, the value of zedGraphControl1.IsAutoScrollRange had no effect, but I left it set to false to be consistent with the example. This would probably have an effect if the dataset is dynamic.

How can I get the screen position of the DockTile in OSX?

I need a window to 'point' to the icon that was clicked on in the dock, similar to the way the context menu has the little callout-arrow pointing to it. This means I need to get the screen location of the dock, or more accurately the DockTile. (Yes I could use the mouse coordinates, but that doesn't look as good as it 'moves'.)
Now my thought is to get the associated view (I already have that), then use view-to-screen coordinate conversions, but that's becoming problematic as the x/left and y/top values of the bounding rectangle always say zero. I know that's because there's a nested hierarchy of views as well. Problem is I've walked it and always end up hitting a road block.
So thoughts?
Mark
You can get the dock icon positions using the accessibility API, there's some excellent sample code and app from Apple here.

Resources