I have implemented a Scroll box that dynamically adds TCharts dependent on the number of channels available on an input device. The charts repaint on a loop to show the value of the voltage through the channel, so that the display outputs effectively a "real-time" view of the voltages being applied to each channel.
Currently I have an Application.ProcessMessages function to prevent the application becoming unresponsive during a run, but I would like to be able to scroll through the box whilst the channels are being displayed, without disturbing the display, which currently pauses whilst the scroll bar is clicked.
Is this possible?
Yes, this is possible.
The charts repaint on a loop ...
Repaints driven by an own loop indeed ensures respiratory distres on the system, which exactly is the reason for the need of Application.ProcessMessages. Try not to use it. Instead, you should just ask the charts to repaint themselves with Invalidate when new data comes in, and let the system decide when it is convenient to do so.
Related
Developing Smart Devices in Genexus. I am using the Load Event to load some hundreds of records (returned by a 3rd party webService) into the Grid (some rows might have different layouts).
When the user hits the search button, a ProgressIndicator is immediately shown (during the procedure execution). When the procedure ends (data retrieved), the ProgressIndicator disappears but it may take an additional 4-5 seconds for the Grid to show the fresh data.
This causes the user to think that there was a problem with the search. Then, unexpectedly, the grid refreshes.
Is it possible to, somehow, show a ProgressIndication during the Load or Refresh Events?
Or do you have any suggestions to prevent this behavior?
The main issue is that Refresh and Load events are "server" events in SD architecture so you don't have access to the device's APIs or resources like the Progress Indicator.
We had the same requirement in iOS and what we did was using the GXRefresh event.
Event 'gxrefresh'
Composite
//Your code. Example: ProgressIndicator.Hide()
EndComposite
EndEvent
Gxrefresh is a Local event that is executed after the Refresh and Load. Is a hidden event that helped us accomplish this. (This is not an official event and it can be taken out in any version of GeneXus)
So the solution is:
Start a Progress Indicator on the ClientStart event of that Panel.
Hide the Progress Indicator on the 'gxrefresh' event of that panel.
Note: Remember that in order to use the gxrefresh event you will need to add a hidden button named 'gxrefresh'. You can hide that button as you will not need it in the UI (we put it Visible=false on the application bar).
If that solution for any reason is not possible (for example the gxrefresh event is deprecated or you are developing for Android) I can think of a second WA that is not elegant at all but should work.
Start the Progress Indicator in the Client Start Event of the panel
Put a hidden variable with control type SD Chronometer.
Set the timer for 6 seconds
Stop the Progress Indicator on the Tick event of the SD Chronometer and stop the Chronometer so the Tick event is not executed any more.
These are the two options I can think of.
Maybe there is an easier way but I haven't heard of it. A Grid.DidLoad event would be great for this scenario. For sure we will have this soon or some other solution for this problem.
Links:
SD Chronometer: http://wiki.genexus.com/commwiki/servlet/hwikibypageid?25058
SD Events: http://wiki.genexus.com/commwiki/servlet/hwikibypageid?17042
Server Side Events: http://wiki.genexus.com/commwiki/servlet/hwikibypageid?24234
The way Delphi by default updates the selection with a timer can sometimes look funny if people scroll very fast (losing track), so I would like to disable that.
However, what I would like instead is that it would update selection immediately on the OnItemClick event. (i.e. I would like to force update the selection immediately before hen doing the rest of processing in the click event - that would be quite excellent.) However, after having tried quite a few things, this appears quite a bit more cumbersome to achieve than first expected.
I have tried force update selection, force animations, force updateselection etc. but none update the selection because of internal properties. Has anyone sucessfully done with without making changes to the listbox code directly?
So my problem is that I have a TJvDocServerForm with an image inside, now all functionality works when its pinned, however when its unpinned and I try to use the mousewheel to zoom, the form hides straight after the zoom operation.
The zoom works through a scrollboxmousewheel event that triggers a
timer.
The timer then redraws the larger/smaller image through my own
image class when movement on the mousewheel has stopped.
Through break points it appears the draw is causing the form to
hide.
I believe this has got something to do with the focus being lost, however resetting the focus back to he form directly after the draw does not stop the hide as it has already been told to hide.
Is there a way to somehow lock the form from hiding until after the image has been redrawn?
This functionality (the unpinning thing) is rarely used. This code is extremely complex, and changing it is not recommended unless you like causing regressions. How common is the combination of mouse wheel + unpinning? So rare, I'd let it go, if I were you. If you can live without the unpin feature at all, just change dock styles. Personally I hate the unpinned state and I use a dock style that doesn't even support it. The unpinned "zoom away" animation may be directly linked to the focus-loss. You could store that state, wait until the next time through the message loop and then trigger the animation, if you wanted to, but even I, who have done lots of work in JvDocking source code, would be hesitant to try it.
I'm developing an application for the XBox using XNA, with a custom made UI framework.
For this I developed a navigation system, the navigation system works as followed:
The system exists of pages, each page contains child UI elements, which all have
one or more PageTabs as I called them.
The pagetabs are objects, having 2 properties, X and Y.
(I know I could have used Point, but the pagetab class has some methods also)
Based on the current state of the system, I check for input, and I raise events on elements with the right pagetab.
So I have this array:
pages[]{
Start,
Exit,
Settings,
...}
Then, I use an enum for my state, like Start, and access the page navigatable elements like this:
pages[Start].Navigatables[]
This is an array containing all the pagetabs of the page. When you go down, Y gets increased, and vice versa. Same for X
This works great, it keeps the max & min Y&X values in mind, so something always get selected.
However, this system has one major flaw, it can only box input for 1 state.
But say I am for example on the start page,
so my state is Start, and I have a popup, with 2 buttons, pagetabs:
(1,1) & (2,1)
The system as it currently is designed, will look for ALL elements in the current state with the selected pagetab, but I need to make it so that if the popup is visible, only the popup accepts navigation, and everything else won't react to user input (gamepad).
I was thinking of adding an extra List to the PageTab class, which contains 'substates' on which the element may accept input, but there must be a better way, ain't there?
I hope I explained it good enough, if you need more info I'll be glad to provide it.
I'd suggest using some kind of flag in your system, so that when you have a pop-up active. it marks all other elements as disabled. then when you close the pop-up you re-enable the other elements. you can check this flag when passing input to the elements so that you only send it to enabled elements.
I went with the extra Z-index approach.
Using a different Z-index for some elements and catching this input works like a charm.
I also added a flag: IndependentNavigation, which makes sure some elements are Z-index-independent (so one could click somewhere different when a dropdown is opened for example)
Windows in my application are popping up off the edge of the screen, and this of course is a problem because some of the windows are modal and can't be dismissed (you don't even know they are there).
I'm using the TurboPower Orpheus component which remembers the location and size of each form, then restores it when the form is shown again. It saves the size and placement in an INI file.
What can I do to prevent windows from ever showing off the side of the screen?
It's common for this sort of thing to happen if you use multiple monitors and then disconnect one, such as when undocking a laptop. Or if you dock a laptop to a screen with a higher resolution. Or use remote desktop, etc..
The remedy is to override the "remember my position" behavior with a sanity check, to see if the left+width exceeds the width of the screen (Screen.Monitors array, actually - thanks guys), and vice-versa for the top+height.
Ideally, you "bump" by subtracting the difference, so you're butting up against the edge that the window wanted to straddle.
Also, see if there are updates to Orpheus that fix this. If not, you can get the source, make the correction (optional), and contribute it back to the project. It's OSS, as I recall.
You may want to give a look at their DefaultMonitor property and read the code from TCustomForm.SetWindowToMonitor to see how to deal with positioning relatively to Screen.Monitors.
Use DefaultMonitor to associate a form with a particular monitor in a multi-monitor application. The following table lists the possible values:
Value Meaning
dmDesktop No attempt is made to position the form on a specific monitor.
dmPrimary The form is positioned on the first monitor listed in the global screen object's Monitors property.
dmMainForm The form appears on the same monitor as the application's main form.
dmActiveForm The form appears on the same monitor as the currently active form.
Note: DefaultMonitor has no effect if the application does not have a main form.
To recall the previous position of a form, without having it suddenly in an area which is no longer available (due to a plugged off screen or changed resolution), you just call
TForm.MakeFullyVisible;
That's it. See the documentation.