The IUP documentation specifies a GUI element called Separator.
However it’s missing from the Available Classes list that pops up when you click Add Child / Add Brother in the Layout Dialog (the IUP GUI layout editor).
Not only that, when you try to include Separator manually in a LED file (as SEPARATOR() inside VBOX() or HBOX()) and then load it in the Layout Dialog and show it (or “map” it), you get the following error message:
IupMap failed.
Subsequently, only the GUI elements that precede Separator are displayed. Why?
Part of the answer could be that “it shows a line between two menu items” (per documentation) whereas I have attempted to use it outside menu on dialog’s canvas (inside VBOX()). It can’t be a complete truth though because I have seen Separator being used outside menu in GetParam dialog (screenshot there). And even if it were, it still doesn’t explain why Separator is missing from Available Classes in the Layout Dialog.
IupSeparator is for menus only. That list is displayed to insert a new element inside the dialog.
The separator in IupGetParam is a IupLabel with the SEPARATOR attribute.
In the meanwhile, I have found a functional replacement to Separator and it’s apparently Label with attribute SEPARATOR set to HORIZONTAL/VERTICAL/YES.
Example (LED):
FakeSeparatorDlg = DIALOG[TITLE = "IUP fake separator demo"](
VBOX[MARGIN = 5x5,GAP = 5](
LABEL[TITLE = "Label Text 1"](""),
LABEL[SEPARATOR = HORIZONTAL](""),
LABEL[TITLE = "Label Text 2"]("")
)
)
Attribute EXPAND = HORIZONTALFREE will be added automatically.
Demo sample.c also includes an unexplained attribute NAME = SAMP_SEP.
The downside is lack of a visible title but I will simply use Frame instead of Label when I need that.
Further reading
IUP documentation: IupLabel
thread “divider line” on a mailing list named Iup-users
“sample” (C/LED/Lua), as well as a compiled demo iuptest(.exe) that includes it (download, unzip, launch and choose “sample”)
Related
I want users entering data across multiple tabs to be able to see at a glance whether and where they have validation errors / fields not populated. I can indicate errors for the selected form in the form body, but for unselected tabs I want to use red color and/or a red icon in the tab to indicate if it is failing validation.
I see various posts explaining how to use a custom renderer or effect to set tab text color for all tabs or selected/unselected tabs (e.g. here, here, here modifying the framework itself and here). However, the posts I've seen do not show a way to change the color of a SPECIFIC tab. In this case I want to either change the color or add/remove an error icon that would show beside the Title in the tab header based on the validation results for the page accessed via the tab. Is that possible?
Update:
I also found this - seemed more promising because it does seem to change tabs based on their positions or title rather than just on whether they were selected or not, but it seems to be dependent on using bottom tabs, which I'm not doing.
I also have found this, and element.Children[i] does get me the ContentPage from which I can determine what color I want the tab's test to be, and it's possible that the tab variable that's returned by activity.ActionBar.GetTabAt(i) somehow gives me access to update the tab's text color, but I'm not seeing any method or property that seems promising - basically I still don't see how to get access to the UITabBarItem so I can call SetTitleAndAttributes on it to set its text color. (Also, if I declare the tab variable by its type of Android.App.ActionBar.Tab instead of using var, I get a note saying that type has been deprecated. It seems upon investigation that the whole ActionBar class has been deprecated. But how can that be when it still exists as a property of Android.App.Activity, which is not deprecated?)
Many thanks for your assistance!
I've tried nearly anything, The "Type Into" activity won't print plain text into the text box let alone a held variable. The textbox element in question is the update work items comment box in the acme-test website from the Level 3 RPA developer course. I am able to type into the box manually and the robot is able to find it (the cursor moves to the centre of the text box and the program continues). I've tried quite a lot, including using a click activity and then sending the string as hotkeys.
Most probably the issue is related to your selectors. Since you are on level 3 RPA developer course I assume you are using Reframework for the task and I believe because of comprehensive error handling capabilities of this template your application just continuous with the next item instead of crashing when it can't find the element.
To solve the selector issues I usually do the following:
Use partial selectors instead of full selectors
Use wildcards for dynamic parts of your selectors (* for replacing any number of characters, ? for replacing exactly 1 character)
You can also store the page you are working on in a Uipath.Core.Browser type variable to eliminate the need of reselecting browser.
Also keep in mind that if you have used basic recorder functionality of UI path it generates full selectors.
I'm new to the Xcode User Interface testing framework. I can successfully manipulate the screen elements, but cannot work out how to produce a meaningful assertion about what text is visible in a scrolling view.
The test I would like to write would go as follows: launch the app, type lots of text into a text view (enough that the first line scrolls out of view), assert that the first line of text is not visible, scroll the view back up to the top, then assert that the first line is now visible. Note that the purpose of this test is to ensure my app has wired things up correctly, not to test Apple's code.
XCUIApplication allows me to type into my NSTextView instance, and also allows me to scroll the associated NSScrollView. But how do I assert whether the first line of text is currently visible? The value attribute on XCUIElement provides the entire text content of the view, whether or not it is currently displayed.
The accessibilityRange(forLine:) and accessibilityString(for:) methods on NSTextView would be ideal, but I can't see how to access them as the UI test only has access to an XCUIElement, not the underlying NSTextView.
Have I missed something, or is there a better way to approach this?
If you set the accessibility identifier in the storyboard or in code for the text view you can get the text view via (assuming you gave it the id "textview1" and the window it's in has the default accessibility identifier of "Window"):
let textview1TextView = app.windows["Window"].textViews["textview1"]
but that won't actually get you what you need.
Instead, set the accessibility identifier of the scrollview and get that:
let scrollview = app.windows["Window"].scrollViews["scrollview1"]
Then use that to get the scrollbars (you should only have one in this case; you can use scrollbars.count to check.
let scrollbars = scrollview.scrollBars
print("scrollbars count: \(scrollbars.count)")
Then you can use the value attribute of the scrollbar to get it's value:
(you're converting a XCUIElemenTypeQueryProvider into an XCUIElement so you can get it's value):
let val = scrollbars.element.value
it will be 0 at the top and a floating point value when scrolled (one line of text in my test code showed a value of {{0.02409638554216868}}.
Documentation that will help you explore further:
XCUIElementTypeQueryProvider
XCUIElementAttributes
Note that you can put a breakpoint in the middle of your test, run it and then use the debugger console to examine things:
(lldb) po scrollbars.element.value
t = 749.66s Find the ScrollBar ▿ Optional<Any>
- some : 0
(lldb) po scrollbars.element.value
t = 758.17s Find the ScrollBar ▿ Optional<Any>
- some : 0.05421686746987952
and while in the debugger you can even interact with your app's window to scroll it manually (which is what I did between typing in those two po calls), or perhaps add text and so on.
OK OP now noted that they're interested in the specific text showing or not rather than the first line in view or not (which is what I previously answered above).
Here's a bit of a hack, but I think it'll work:
Use XCUICoordinate's click(forDuration:, thenDragTo:) method to select the first line of text (use the view frame to calculate coordinates) and then use the typeKey( modifierFlags:) to invoke the edit menu "copy" command. Then use NSPasteboard methods to get the pasteboard contents and check the text.
Here's a quick test I did to validate the approach (selecting the first line of text using XCUICoordinate as noted above is left as an exercise for the reader):
NSPasteboard.general.clearContents()
// stopped at break point on next line and I manually selected the text of the first line of text in my test app and then hit continue in the debugger
textview1TextView.typeKey("c", modifierFlags:.command)
print( NSPasteboard.general.pasteboardItems?.first?.string(forType: NSPasteboard.PasteboardType.string) ?? "none" );
-> "the text of the first line" was printed to the console.
Note that you can scroll the selection off screen so you have to not scroll after doing the select or you won't be getting the answer you want.
I am working on a GUI using qtruby. I have a ListWidget that I am filling with ListWidgetItems. So far these have just contained the text that I wanted to display and everything worked fine. I wanted these items to also hold some hidden data to use when they are clicked on. I used ListWidgetItem.setData() to set the data and I can get the data from it when it is clicked just fine. However once I add the data the text being displayed is now shifted over to the right about 4 spaces. When I click on it a little dotted box appears around the text but not the space that was added. It looks like it is a space for an icon but I have not set any icon and I don't want one. How do I get rid of this extra space so that items containing data are lined up with everything?
The code is very straight forward:
item = Qt::ListWidgetItem.new( #grain_strings[index] )
item.setFont( #font )
# TODO this is causing the text to be indented, removing it removes the indent
item.setData( 1, Qt::Variant.from_value( grain.type ) )
#item_list.insertItem( #end_of_grains+1, item )
The first argument to setData is the role number and for some reason you chose to set it to 1. The documentation says: "The data to be rendered as a decoration in the form of an icon. (QColor, QIcon or QPixmap)". So you are telling Qt to display an icon but you are not giving it a valid icon object.
Try setting the role to Qt::UserRole, which is "The first role that can be used for application-specific purposes." I am not sure how to access that constant from Ruby. If it is not provided by the qtruby gem, you could use 0x100 I suppose.
We have an in house button control, and quite frankly it sucks. I'd like to replace it but I don't want to go onto every form in our project and delete/add a new control. It seems to me that if I design a new button that has all the same properties as the old one then I ought to be able to give it the same name as the old one and just replace all the reference lines in the vbp files to point to the new control.
Has anyone tried this (better yet have you heard of a tool that will do it for you) and if so what 'gotchas' should I be on the look out for?
Thanks!
The *.vbp files are one place you'll need to change. There are also references to the used control libraries in the files containing GUIs -- that's form (*.frm), control (*.ctl), and property page (*.pag) files. These files are in a plain text format and you can see the references at the top. They look like this:
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "mscomctl.ocx"
Those refs will need to be added or updated in all relevant files if the new control is a compiled OCX. If it's in the same project I don't think it needs any reference there, and if it's in a different project in the same project group I'm not sure. Save a test form with the new control to see.
Note that you don't have to keep the same control class name. Inside the *.frm/ctl/pag files, instances of individual controls on them are represented by a simple format like this:
Begin VB.CommandButton Command2
Caption = "Cancel"
Height = 375
Left = 2460
TabIndex = 1
Top = 2400
Width = 1455
End
The syntax of the first line there is "Begin LibraryOrProjectName.ClassName NameOfThisInstance". So, provided the offending control's name is distinctive it should be easy to search & replace references to it both in the BASIC source and in the GUI layouts. You might want a plain text editor that can perform search and replace across multiple files (Notepad++ is one).
Some control properties are stored like this:
Picture = "frmMain.frx":292F
These correspond to the *.frx, *.ctx, and *.pgx files, which contain binary data for the values of certain control properties. I don't think these files should need altering or cause any problems. They don't appear to contain control names.
Use a full compile (Ctrl+F5) to be sure no problems linger in parts of the source afterward.
Never tried it. Good luck.
There is only one tip to be added to the accepted answer.
If you need to replace any generic VB control with 3rd party or custom ActiveX control you must replace the:
BeginProperty Font
with
BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}
Omiting to do so results with run-time error 713 when trying to edit/open the form.
If there is no BeginProperty statement in the block then control uses default font and this replacement is not needed.
An additional scenario to look for is if the classes in the OCX are referenced directly in code.
In other words, if the control class was ABCButton then you need to look for ABCButton in all .BAS and .CLS files as well, and make appropriate changes.