Motif/Lesstif Application Development
Motif provides a simple menu bar that is easy to build but makes some assumptions about menu behavior. For a more flexible widget with more involved menus, you will want to explore XmMenuBar. Note that the menu bar is created as a child of the form. The menu bar built on line 114 specifies a single menu as a cascade button (line 115). If you want multiple pull-down menus, you simply add more lines. The string is the name of the menu as it will appear in the menu bar, and the single letter is the meta keystroke that will cause the menu to pull down (in this case, alt-F or meta-F).
Once the menu bar is constructed, the actual pull-down menus can be created as children of the menu-bar widget. Line 133 specifies the parent widget and name for the “File” menu; the arguments indicate the initial item and the callback function invoked if the user selects a menu item. Each of the subsequent lines describes a single menu item and each item begins with its type. The Menus can contain more than just the traditional push buttons; for more information, refer to the Motif Programming Manual. The next argument is the string displayed for the menu item, followed by a hot key the user can press when the menu is displayed, then an accelerator key sequence the user can press to invoke the menu item without actually pulling down the menu. The last argument for the item is the display string for the accelerator keystroke—this will be displayed right-justified in the menu.
Horizontal lines (separators) can be placed in the menu by specifying XmSEPARATOR for the type (with no associated values) as in line 135. This is another case where columnizing your source is a very good idea. It is easy to leave out one of the items, resulting in catastrophic (or at least bizarre) behavior at runtime. If you don't want to specify one of the options, a place holder such as an empty string must be used.
Once all the pull-down menus are created, the menu bar must be managed (line 142), so that when the form gets managed, it will be free to display the menu bar. In this case (as with some of the specialty manager widgets), it is not necessary to manage the pull-down menus. Remember, they aren't actually displayed until the user does something to make them appear.
The next widget we instantiate is the file selection dialog. It will not actually appear until invoked by the user (by a menu selection or button press), but I chose to build it here since it is logically related to the file menu. Motif provides a number of very nice specialty dialog boxes; one of the most interesting is the File Selection Dialog, XmFileSelectionDialog. This widget is derived from XmSelectionBox, so when you are looking for some of the resources in the Motif Reference Manual, you may need to refer to both widgets.
At times, it may be more convenient to assign callbacks after creating a widget, either because you don't have all the information you need at the time, or the callbacks cannot be easily supplied to the create function as in our example. Another reason is the explicit call to XtAddCallback makes it obvious the assignment took place; in addition, you get the benefit of compile-time-type checking.
The stock file-selection dialog handles all heavy lifting for you, file name globing, directory navigation and even file name filtering. The default dialog also provides a few extra buttons I will not use. To avoid confusing the user, set their XmNSensitive resource to false (causing them to be grayed out) or remove them altogether. Motif provides a convenience function for all widgets derived from the Selection Box to get the widget ID of specific children widgets in the dialog (line 150), XmSelectionBoxGetChild. Once I have the widget ID, a call to XtUnmanageChild will prevent that particular widget from appearing when the rest of the dialog is displayed.
The code on lines 157 to 204 is concerned with adding the remaining components to the display. I will use these widgets to explain the way XmForm handles the layout of its children. Attachments describe a widget's relationship with other widgets within the form; it may take a while to get used to the way attachments work. Widgets appear in the form in the order they are created—important to keep in mind as you code. I will describe the most basic aspects of form attachments.
Each widget parented by a form has attachment resources for the top, bottom, left and right sides. I will cover how to use XmATTACH_FORM and XmATTACH_WIDGET and attachment offsets. Other attachment types include XmATTACH_NONE, XmATTACH_SELF, XmATTACH_POSITION and some based on form and widget opposing sides. On line 116, you see the top, left and right sides of the menu bar are attached to the form. This means each of the sides will “stick” to the respective sides of the form, stretching the widget as needed. The bottom attachment is left as XmATTACH_NONE, since I need to use the remaining portion of the form for other display elements. If the attachments were not specified, the size and position of the menu bar would default to a fairly unattractive box in the upper left corner of the form.
On line 158, I specify that the top of the label is attached to the menu bar widget and line 159 specifies this attachment will stay 10 pixels off the menu. The left side of the label is attached to the form and the right and bottom sides are left unattached. If attachments were specified and a border was visible for the label, you would see it stretch as the position of the other widgets changed during a resize operation.
Mistakes in attachments can hide a widget altogether or generate ugly screens; in some cases, the errors are bad enough to be printed on STDERR (e.g., circular dependencies). If you specify a widget attachment, you must also specify the widget to which the side should be attached. Since no compile-time checking is done on these things, you won't discover your omission until runtime.
I want the text field used to enter a file name to stretch horizontally; so once the Browse button is created, I add a final attachment to the text field (line 181). This is an excellent example of the strength of using XmForm for your layouts.
|Designing Electronics with Linux||May 22, 2013|
|Dynamic DNS—an Object Lesson in Problem Solving||May 21, 2013|
|Using Salt Stack and Vagrant for Drupal Development||May 20, 2013|
|Making Linux and Android Get Along (It's Not as Hard as It Sounds)||May 16, 2013|
|Drupal Is a Framework: Why Everyone Needs to Understand This||May 15, 2013|
|Home, My Backup Data Center||May 13, 2013|
- Designing Electronics with Linux
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- Build a Skype Server for Your Home Phone System
- Validate an E-Mail Address with PHP, the Right Way
- A Topic for Discussion - Open Source Feature-Richness?
- Why Python?
- Tech Tip: Really Simple HTTP Server with Python
1 hour 35 min ago
- Reply to comment | Linux Journal
1 hour 43 min ago
- Understanding the Linux Kernel
3 hours 58 min ago
6 hours 27 min ago
- Kernel Problem
16 hours 30 min ago
- BASH script to log IPs on public web server
20 hours 57 min ago
1 day 33 min ago
- Reply to comment | Linux Journal
1 day 1 hour ago
- All the articles you talked
1 day 3 hours ago
- All the articles you talked
1 day 3 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi
It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?