I don't quite understand the difference between these two methods. In what situation would forceFocus() be better than setFocus()?
According to SWT: The Standard Widget Toolkit, Volume 1, forceFocus():
Forces the control to receive keyboard
events. Controls that do not normally
accept keyboard input will take focus
using this method. If focus cannot be
assigned for any reason, false is
returned.
also:
Generally speaking, forcing focus is
something that you never want to do.
For example, forcing focus to a label
is not very useful because labels
don't draw in a manner that indicates
they can accept input. Forcing focus
to a control that does not expect it
can confuse users because they have no
idea where their keystrokes are going.
Application programs should always use
setFocus() to assign focus.
Coming in way late on this one, but I just finished a prolonged head-beating-against-wall session on something related to this and thought I'd do a quick report:
If your control has children, the setFocus(myControl) will do a depth-first search down the child tree and set focus to the lowest first child. On the other hand, forceFocus(myControl) will just set focus to myControl and have done with it.
I had a situation with a modeless dialog with a GridLayout, where most of the grid cells were a set of Canvas subclassed objects that needed focus. (Yes, this is a bit odd, but I wanted to be able to hover over a cell and type stuff into it.) The last control in the grid was a "done" button, which I set as the default selection.
When the mouse left the canvas cells, I was doing a setFocus(myDialogShell), which instantly set focus to the first canvas element, preventing the "done" button from receiving the \r and disposing of the whole sordid business. On the other hand, forceFocus(myDialogShell) did the trick.
Related
I started writing test for a WPF application with FlaUI (UI Automation framework). Now I want to get the Visibility value of a couple of buttons.
These buttons are located on the same position in the WPF window. The first is a start button which will start a measurement. When clicked, the measurement button is replaced with a stop button. The visibility of these buttons are set in the code behind of the xaml and needs to be checked/verified.
With FlaUI I only get IsEnabled boolean and OffScreen boolean. But when using the Offscreen parameter, this boolean is not set or is set to the correct value for a couple of seconds but is changed again while the measurement is still running.
I also tried other ways, like looking for a clickable point of the not visible button. But those are not working.
Can this be done without extending the button class with an AutomationPeer and exposing a ValuePattern? I googled a bit but cannot find an (decent) answer. Hopefully someone can help.
I think an important part of your question is the word "replaced". Commonly a program draws one set of controls (in your case the start button) and later draws another set. Possible on top to hide the first, or possible by deleting them.
Commonly controls, including buttons, are drawn within other containing controls and so it may be that the button controls are not there at all, hence the visibility checks should be done on the parent or ancestor controls.
This Q&A seems related to the problem you are having and it may provide some more insight.
"Group Box", for lack of a better word: I want areas in my user form which are visually different from others, with a different background colour and a frame around them, such as is possible to create using Frame controls. However, I want none of the events of Frame controls and none of their interaction with other controls in the form.
More particular, I want to be able to tab through all text, list, combo and check boxes, regardless of their location in 'Group Boxes', in fact also regardless of the possible location of their 'Group Box' within another 'Group Box'. Most of my controls have On Enter, On Exit, On Change and On Key even procedures attached to them which may re-direct the focus to any control on the form. Doing so under the constant interference of Frame controls with their events and rules - many of them not working correctly, none of them properly explained anywhere - is a gargantuan task. The easy way would be to have the visual design capabilities only, without the "intelligence" which assumes control in a way not compatible with my own plans.
Perhaps the one feature of frames which makes them unfit for my purposes is that they act as forms within the form, meaning they appoint an ActiveControl when activated which they refuse to release when another control takes the focus outside their own frame. It is inconvenient to prevent a first control's On Enter procedure from running when any control in a frame receives the focus (different for first and subsequent times), but it's a much bigger task to deal with the selected control's On Exit event which won't fire until the form is closed, meaning it is missed when the control optically loses the focus and a nuisance when it technically does.
Is there a control that fits my needs in MS Word? Or can the Frame control be stripped of its events in some way? Could I place a Text Box, for example, in front of a Frame control without it also being "within" it?
For MS Word use a label with a background color.
For MS Access use the rectangle Object behind the controls.
First make the form background a grey color. Then add subforms(ms access) and rectangles to segment the controls.
The end effect is it looking like a paneled interface.
You can use a Frame control. Place the other controls first, then place the Frame control, and move it to the back. This should look visually identical to having the controls in the Frame.
I'm trying to set up a TEdit that will be used for research, so, it would be great to have a label displaying "current" / "count" over it, as observed by pressing CTRL + F in Google Chrome:
It seems that the TLabel control's always placed behind the TEdit control.
I also tried label1.BringToFront (Both at designtime and runtime), but it had no effect. Is there a way to place a label over an edit control?
TLabel inherits from TGraphicControl which cannot be shown on top of windowed controls, no matter how many times you try to use BringToFront it's just not going to happen.
However, you can use a container control such as a TPanel that can be used to contain your TEdit and TLabel controls, see this image as an example:
That is a quick and dirty way, it's simply a TPanel containing a TEdit and TLabel as child controls
The preferred way however is to create your own control which would give you full flexibility. Often trying to piece together multiple VCL controls to appear and function how you want is not usually ideal, and so by doing it the custom way gives you more freedom and possibilities.
Working with Accessibility
While VoiceOver reads the elements in the application in an order,Is there anyway to shift the focus between the elements?
I tried working with "nextResponder",but it is not working.
As of iOS 6, you can set the focus to a specific element with a UIAccessibilityLayoutChangedNotification, passing the element
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, firstBottom);
but if you're trying to completely change the “tab order” I don’t know of a way to do it.
This is a shot in the dark, but have you tried changing the accessibilityLabel or accessibilityHint in accordance when you want the order to change? If you can trick the VoiceOver to believe the text has changed, I would expect that it would change focus to it appropriately.
The timing would be the hard part, since it doesn't appear there are any delegate callbacks for when VoiceOver is crawling your view, so you may have to estimate the time to pass before trying to update the accessibility hint/value.
My last thought would be to mark the UIView that you want to bring attention to with the UIAccessibilityTraitUpdatesFrequently accessibility trait. That might be the closest you can get without tapping into hidden Apple libraries.
Check out this post for how to handle special ordering of elements for voice over. I just used this approach in the app I'm working on.
I tried UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, elementName); to change the focus on a different element. The behavior was that the focus got shifted to new element, but Voice Over would first announce the page title and then the accessible label value of the new element.
Customise Accessibility for a View:
You can customise the order(in which voice over should traverse the screen elements) by overriding accessibilityElements property of parent view in below manner.
self.accessibilityElements = [childView1, childView2, childView3]
With that voice over will follow the sequence like childView1 -> childView2 -> childView3.
Changing Accessibility focus to other element programatically:
At any time you can shift the focus to another element by using below code.
UIAccessibility.post(notification: .layoutChanged, argument: childView2)
With above code, voice over focus would be shifted to childView2 and then will follow the same sequence defined by accessibilityElements i.e. childView2 -> childView3 -> childView1... and so on
Customising Accessibility Order for Complex Views:
You can customise it further and If a view has multiple child views with further grand children views, then you can achieve accessibility order by defining accessibilityElements of main parent view by using accessibilityElements of all child views.
For example, for below view hierarchy, we have
View Controller Example
To define custom order of accessibility elements for such views, we can define in below manner.
var customElements = childView1.accessibilityElements
customElements.append(contentsOf: childView2.accessibilityElements)
customElements.append(contentsOf: childView3.accessibilityElements)
parentView.accessibilityElements = customElements
Does anyone have any examples or resources where i might find information on scrolling text which is too long to display in a button control? I'm thinking something along these lines.
Display as much text will fit within the current rect with a '...' at the end to signify overflow.
Pause for say 1 second then slowly scroll the text to the right edge displaying the right part of the string.
Display as much text will fit within the current rect with a '...' at the beginning to signify overflow.
Start the whole thing over in reverse.
Is there an easy way to do this using the "core" or built in "animation" frameworks on a certain mobile device?
[edit]
Iwanted to add some more details as i think people are more focused on wether or not what i'm trying to accomplish is appropriate. The button is for the answers on a trivia game. It does not perform any speciffic UI function but is for displaying the answer. Apple themselves is doing this in their iQuiz trivia game on the iPod Nano and i think its a pretty elegant solution to answers that are longer than the width of my button.
In case its the '...' that is the difficult part of this. Lets say i removed this requirement. Could i have the label for the button be full sized but clipped to the client rect of the button and use some animation methods to scroll it within the clipping rect? This would give me almost the same effect minus the ellipses.
Here's an idea: instead of ellipses (...), use a gradient on each side, so the extra text fades away into the background color. Then you could do this with three CALayers: one for the text and two for fade effect.
The fade masks would just be rectangles with a gradient that goes from transparent to the background color. They should be positioned above the text layer. The text would be drawn on the text layer, and then you just animate it sliding back and forth in the manner you describe. You can create a CGPath object describing the path and add it to a CAKeyframeAnimation object which you add to the text layer.
As for whether you think this is "easy" depends on how well you know Core Animation, but I think once you learn the API you'll find this isn't too bad and would be worth the trouble.
Without wishing to be obtuse, maybe you should rethink your problem. A button should have a clear and predictable function. It's not a place to store and display text. Perhaps you could have a description show on screen with a nice standard button below?
Update with source code example:
Here is some ready to use source code example (actually a full zipped Xcode project with image and nib files and some source code), not for the iPhone, not using Core Animation, just using a couple of simple NSImages and a NSImageView. It is just a cheap hack, it does not implement the full functionality you requested (sorry, but I don't feel like writing your source code for you :-P), horrible code layout (hey, I just hacked this together within a couple of minutes, so you can't expect any better ;-)) and it's just a demonstration how this can be done. It can be done with Core Animation, too, but this approach is simpler. Composing the button animation into a NSImageView is not as nice as subclassing a NSView and directly paint to its context, but it's much simpler (I just wanted to hack together the simplest solution possible). It will also not scroll back once it scrolled all the way to the right. Therefor you just need another method to scroll back and start another NSTimer that fires 2 seconds after you drew the dots to the left.
Just open the project in Xcode and hit run, that's all there is to do. Then have a look at the source code. It's really not that complicated (however, you may have to reformat it first, the layout sucks).
Update because of comment to my answer:
If you don't use Apple UI elements at all, I fail to see the problem. In that case your button is not even a button, it's just a clickable View (NSView if you use Cocoa). You can just sub-class NSView as MyAnswerView and overwrite the paint method to paint into the view whatever you wish. Multiline text, scrolling text, 3D text animated, it's completely up to your imagination.
Here's an example, showing how someone subclassed NSView to create a complete custom control that does not exist by default. The control looks like this:
See the funny thing in the upper left corner? That is a control. Here's how it works:
I hate to say that, as it is no answer to your question, but "Don't do that!". Apple has guidelines how to implement a user interface. While you are free to ignore them, Apple users are used to have UIs following these guidelines and not following them will create applications that Apple users find ugly and little appealing.
Here are Apple's Human Interface Guidelines
Let me quote from there
Push Button Contents and Labeling
A push button always contains text, it
does not contain an image. If you need
to display an icon or other image on a
button, use instead a bevel button,
described in “Bevel Buttons.”
The label on a push button should be a
verb or verb phrase that describes the
action it performs—Save, Close, Print,
Delete, Change Password, and so on. If
a push button acts on a single
setting, label the button as
specifically as possible; “Choose
Picture…,” for example, is more
helpful than “Choose…” Because buttons
initiate an immediate action, it
shouldn’t be necessary to use “now”
(Scan Now, for example) in the label.
Push button labels should have
title-style capitalization, as
described in “Capitalization of
Interface Element Labels and Text.” If
the push button immediately opens
another window, dialog, or application
to perform its action, you can use an
ellipsis in the label. For example,
Mail preferences displays a push
button that includes an ellipsis
because it opens .Mac system
preferences, as shown in Figure 15-8.
Buttons should contain a single verb or a verb phrase, not answers to trivia game! If you have between 2 and 5 answers, you should use Radio Buttons to have the user select the answer and an OK button to have the user accept the answer. For more than 5 answers, you should consider a Pop-up Selector instead according to guidelines, though I guess that would be rather ugly in this case.
You could consider using a table with just one column, one row per answer and each cell being multiline if the answer is very long and needs to break. So the user selects a table row by clicking on it, which highlights the table cell and then clicks on an OK button to finish. Alternatively, you can directly continue, as soon as the user selects any table cell (but that way you take the user any chance to correct an accidental click). On the other hand, tables with multiline cells are rather rare on MacOS X. The iPhone uses some, but usually with very little text (at most two lines).
Pretty sure you can't do that using the standard API, certainly not with UILineBreakMode. In addition, the style guide says that an ellipsis indicates that the button when pressed will ask you for more information -for example Open File... will ask for the name of a file. Your proposed use of ellipsis violates this guideline.
You'd need some custom logic to implement the behaviour you describe, but I don't think it's the way to go anyway.
This is not a very good UI practice, but if you still want to do it, your best bet is to do so via a clickable div styled to look like a button.
Set the width of the div to an explicit value, and its overflow to hidden, then use a script executing on an interval to adjust the scrollLeft property of this div.