You can use the view port within a scrolled window to add scroll-bars that determine which part of the child should be shown.By themselves, view ports do not make a widget scrollable.. G
Trang 1if (!isset(self::$instance)) {
$class = CLASS ;
self::$instance = new $class;
}return self::$instance;
}}
?>
Summary
Trees and lists by themselves are relatively simple objects for modeling, rather than complexdata structures A tree or list can take a collection of data and make it easy to navigate andaccess individual elements The organized nature of these models allows them to be used in
a myriad of ways when combined with GtkTreeView and its associated objects The tion and abstraction of responsibility of these classes make for a very powerful tool set thatcan provide almost endless flexibility when it comes to how a model should be displayed andaccessed
specializa-Now that you have seen how to work with large collections of data, you’ll want to knowhow to display all of that data in a small space Chapter 10 discusses how to make a section of
an application scroll so that the user can access data that cannot fit in the space given for a tool
No longer will the sections of the application be restricted by the size of a container or the user’sscreen An endless amount of space will be made available for any piece of the application thatneeds it by providing scrollbars for both the horizontal and vertical axes
Trang 2C H A P T E R 1 0
■ ■ ■
Scrolling
At this point, the Crisscott PIMS application has several tools that may contain large amounts
of data Unfortunately, none of them currently provides a graceful way to handle this data when
it exceeds the boundaries of the tool For instance, if the data contained within the product tree
exceeds the space provided by the tree, rows and characters just get pushed out of the visible
area Other tools may stretch to accommodate the oversized data While this approach doesn’t
hide data from the user, it can interfere with the layout of the rest of the application, which may
be more damaging than hiding values A better solution enables a tool to extend its data beyond
its visible borders, but remain accessible to the users This is the role of scrolling widgets
GtkScrolledWindowand GtkViewPort are widgets specifically designed to make data ble even though it has outgrown its available space within the application These two widgets
accessi-provide a means to access data in another widget that is not currently within the widget’s
visi-ble area Additionally, you can customize scrolling for a particular widget
Throughout this chapter, we will examine ways to use scrolling to make better use of thespace available in the PIMS application
Scrolled Windows
Some widgets have been designed with scrolling in mind These widgets, including GtkTreeView
and GtkTextView, will likely display large amounts of data For example, a tree or list could show
many rows from a database A GtkTextView widget may display a lengthy press release or report
In order to make either of those documents fit on one screen, the font would have to be very
small, likely rendering the document unreadable Instead of asking developers to squeeze datainto a restricted space, the designers of these widgets have given them native scrolling support
Native scrolling support means that the widgets can accept scrollbars and will allow thescrollbars to control which part of the widget is shown in the visible area GtkScrolledWindow
provides the scrollbars that these widgets need
GtkScrolledWindowis a bin container, a descendant of GtkBin The scrollbars that it providesmake it easier for users to access different parts of the child widget
For instance, consider Figure 10-1, which depicts the product tree without scrollbars It isimpossible to see all the rows of the tree at once, and there is nothing to indicate to the user
that the contents of the view are scrollable
Trang 3C H A P T E R 1 0■ S C R O L L I N G
220
Figure 10-1. A GtkTreeView without scrollbars
Figure 10-2. A GtkTreeView with scrollbars
On the other hand, Figure 10-2 displays the product tree after it has been added to
a GtkScrolledWindow While this doesn’t make it possible to see all the rows at once (actually,the scrollbars take up space, making even less information visible), it does make it clear thatthe contents of the window can be scrolled
Adding scrollbars to those widgets that have native scrollbar support is relatively easy.Listing 10-1 presents an excerpt from an updated version of the Crisscott_MainWindow class
In previous iterations of this class, the Crisscott_Tools_ProductTree instance was attacheddirectly to the table In this example, the instance is added to a GtkScrolledWindow, which isthen attached to the table
Listing 10-1. Adding Scrollbars to a GtkTreeView
Trang 4C H A P T E R 1 0■ S C R O L L I N G 221
// Create a scrolled window for the product tree
$scrolledWindow = new GtkScrolledWindow();
// Set the size of the scrolled window
product tree were sized to 150 pixels wide and then added to the scrolled window, the layout
of the application would be distorted
In the simplest scrolling use case, adding the child is all that needs to be done But, as youcan see in Listing 10-1, some customizations may be made
Setting the Scrollbar Policy
One of the most common customizations for a GtkScrolledWindow is setting the scrollbar policy.
The scrollbar policy determines when scrollbars will appear in the scrolled window The default
is to always show both the horizontal and vertical scrollbars, but this can be changed
Three policy rules can be applied to horizontal and vertical scrollbars individually:
• Gtk::POLICY_ALWAYS: The scrollbar should be shown, regardless of whether or not there
is enough information to scroll in the given direction
• Gtk::POLICY_AUTOMATIC: The scrolled window shows the scrollbar only when it is needed
• Gtk::POLICY_NEVER: The scrollbar will never be shown
You can set the policies for a scrolled window with set_policy The first argument thatset_policyexpects is the policy for the horizontal scrollbar, and the second argument is for
the vertical scrollbar The code in Listing 10-1 sets the policy for the horizontal scrollbar to
Gtk::POLICY_NEVER, while the vertical scrollbar is set to Gtk::POLICY_AUTOMATIC The horizontal
scrollbar is not needed because the cell renderer for the tree is told to ellipsize the cell text
Even if the policy were set to automatic, the scrollbar would never be shown because the child
widget will not expand horizontally
Not only is it possible to set whether the scrollbars appear in a GtkScrolledWindow, butyou can also control where they appear in relation to the child widget
Trang 5Figure 10-3. Different child placements in a GtkScrolledWindow
Controlling Child Placement
Technically speaking, the position of the scrollbars is not changeable, but the placement of thechild can be controlled You can position the child in one of four places relative to the scroll-bars: Gtk::CORNER_TOP_LEFT (the default), Gtk::CORNER_TOP_RIGHT, Gtk::CORNER_BOTTOM_LEFT,and Gtk::CORNER_BOTTOM_RIGHT Figure 10-3 shows the effect each of these placements has on
// Create and set up a window
$window = new GtkWindow();
$window->connect_simple('destroy', array('gtk', 'main_quit'));
// Add a table to the window
$table = new GtkTable(2, 2);
// Create four frames
$frame1 = new GtkFrame('TOP_LEFT');
Trang 6Figure 10-4. Different shadow types in a GtkScrolledWindow
C H A P T E R 1 0■ S C R O L L I N G 223
$frame2 = new GtkFrame('TOP_RIGHT');
$frame3 = new GtkFrame('BOTTOM_LEFT');
$frame4 = new GtkFrame('BOTTOM_RIGHT');
// Add the scrolled windows to the frames
In this example, four scrolled windows are created and added to four frames Each frame
is then attached to a table Each of the four frames is given a different placement by calling
set_placement Along with set_policy, set_placement gives a great degree of control over how
and where scrollbars appear in a scrolled window
Setting a Shadow
The final customization that you can make to a GtkScrolledWindow is to set a shadow around
the child widget Setting a shadow around a scrolled window’s child widget helps it to stand
out a little from the rest of the application
You can set the shadow by using set_shadow_type and passing a shadow type constant
These constants are the same as the constants used to set the border on a frame: Gtk::SHADOW_
IN, Gtk::SHADOW_OUT, Gtk::SHADOW_ETCHED_IN, and Gtk::SHADOW_ETCHED_OUT Figure 10-4 shows
what each of these shadow types looks like As you can see from the different windows, the
name of the shadow type refers to the position of the window, not the scrollbars
Trang 7GtkViewPortis a widget that has native scrollbar support, designed to hold other widgetsand make them scrollable GtkViewPort is a bin container that provides the tools needed toallow its child to be scrolled You can use the view port within a scrolled window to add scroll-bars that determine which part of the child should be shown.
By themselves, view ports do not make a widget scrollable GtkViewPort is simply a tainer that implements native scrollbar support, meaning that adding a widget to a view portdoesn’t accomplish much unless the view port is then added to GtkScrolledWindow
con-Creating and using a GtkViewPort is rather easy Listing 10-3 shows the code needed toadd a table to a view port
Listing 10-3. Adding Scrollbars Using a GtkViewPort
<?php
// Create and set up a window
$window = new GtkWindow();
$window->connect_simple('destroy', array('gtk', 'main_quit'));
// Add a table to the window
$table = new GtkTable(1, 1);
// Add some stuff to the table that will make it large
$label = new GtkLabel('This is a rather long label Hopefully '
'the table will scroll now.');
// Attach the label
$table->attach($label, 0, 1, 0, 1);
// Create the view port
$viewPort = new GtkViewPort();
// Create the scrolled window
$sWindow = new GtkScrolledWindow();
// Add the table to the view port
Trang 8■ Tip Adding scrolling capabilities to a widget doesn’t even have to be as complicated as Listing 10-3 The
steps of creating a view port and adding it to a scrolled window can be consolidated.GtkScrolledWindow
has a method named add_with_viewport This method takes a widget and creates a view port for it
auto-matically The widget is then added to the view port, and the view port is added to the scrolled window
Only two lines are required to add scrollbars to the table The first adds the table to the viewport, and the second adds the view port to a scrolled window The rest of the code in the exam-ple, aside from instantiating the view port and scrolled window, is set up for creating a table that
will need to scroll You determine if and where the scrollbars will appear in the view port in the
same way as you do for the tree view, as described in the previous section Figure 10-5 shows
the result of running this code
■ Note GtkViewPortautomatically adds a shadow to its child widget of type Gtk::SHADOW_IN
You can change this by calling set_shadow_typeon the view port You can also set a shadow for the
GtkScrolledWindowin which the view port resides This will cause a double border effect
Custom Scrolling
Everything in PHP-GTK is designed to give flexibility to the developer Scrolling is no
excep-tion You have total control over how a widget reacts when the user clicks a scrollbar In fact,
you don’t even need to use a scrolled window or a view port
When you use a scrolled window, the widget inside must listen to the scrolled window,but the way that a scrolled window controls a widget may be undesirable For instance, scroll-
ing the product tree in the previous examples moves the window by fractions of a row each
time the user clicks the scroll arrows Showing a fraction of a row isn’t very helpful to the user
It would be better if the widget scrolled by whole rows, so that the user sees the entire text of
Trang 9Creating the Scrollbar
GtkScrollbaris an abstract class that provides the basics for GtkHScrollbar and GtkVScrollbar.Scrollbars are only the visual component to scrolling They work in conjunction with
a GtkAdjustment The adjustment manages the value and bounds of the scrollbar, while thescrollbar provides the visual representation of the value and communicates with the user.Every scrollbar has an adjustment that keeps track of the value and makes sure that the valuestays within a certain range The adjustment should be passed to the scrollbar on construction Listing 10-4 shows how to create a vertical scrollbar Instantiating the scrollbar is the easypart It’s creating the adjustment that can be tricky
Listing 10-4. Creating a GtkVScrollbar
<?php
// Create an array consisting of the tree path
function createPathArray($model, $path, $iter, $pathArray)
{
$pathArray[0][] = $path;
return false;
}
// Create a reasonably sized window to display the view
$window = new GtkWindow();
$window->set_size_request(150, 150);
$window->connect_simple('destroy', array('gtk', 'main_quit'));
// First create a model and view
Trang 10C H A P T E R 1 0■ S C R O L L I N G 227
// Create the adjustment and add it to a scrollbar
$adj = new GtkAdjustment($value, $lower, $upper, $step, $page, $size);
$vScroll = new GtkVScrollbar($adj)
?>
An adjustment is nothing more than a collection of numbers that determine how thescrollbar will appear and function Listing 10-4 shows how these values are collected from
the product tree An adjustment requires six numbers:
• value: The value is simply set to 0 because the initial view should start at the beginning
The value of the adjustment is used to mark a tree path as selected Look at the call toforeachon the view’s model The callback builds an array of tree paths Because foreachworks in a depth-first manner, the array will be built with the first row shown as the firstelement and the last row shown as the last element Changing the scrollbar’s value to 5will scroll to the path defined by the array element with an index of 5
• lower: The lower bound is set to 0 because that is the lowest index in the array
• upper: The upper bound is set to the number of elements in the array
• step: The step size is the amount the value should change when the user clicks thearrows in the scrollbar This is set to 1
• page: The page increment is the amount the value should change when the user clicksthe empty space in the scrollbar This is set to 6 This means that the selected row will
be six rows up or down when the user pages the view
• size: The page size is set to 1 so that the scrollbar is allowed to move through the entire list With these settings, the custom scrollbar is now ready to control the tree view
Creating the Signal Handlers
To make the newly created scrollbar control the GtkTreeView, you need a few signal handlers
Listing 10-5 creates a signal handler for the scrollbar created in the previous listing This signal
handler connects the adjustment’s value-changed signal to the scrollView function
Listing 10-5. Creating the Signal Handler That Makes the View Scroll
<?php
// Function to scroll to and select a top level row
function scrollView($adj, $view, $pathArray)
{
// Create a path to a top level row
$path = $pathArray[$adj->get_value()];
// Set the cursor at that path
$view->set_cursor($path, $view->get_column(0), false);
// Grab focus so that the cell is selected
$view->grab_focus();
}
Trang 11C H A P T E R 1 0■ S C R O L L I N G
228
// Connect the scrollbar to the view so that it scrolls
$adj->connect('value_changed', 'scrollView', $view, $pathArray);
$adj->value_changed();
?>
By default, the callback is passed the adjustment whose value has been changed The call
to connect in this example also passes the view and the array of tree paths created earlier.When the value-changed signal is fired and the callback is called, the cursor of the view is set
to the path with the index equal to the adjustment’s value Notice also that the view is told tograb the keyboard focus This is because the row cannot be selected unless the view has thefocus After the signal handler is created, the value_changed method of the adjustment iscalled This method forces the adjustment to emit the value-changed signal whether or not itsvalue has actually changed Calling value_changed calls the callback method and selects thefirst row in the view
It is important not only that the scrollbar communicates with the target widget, but alsothat the target widget communicates with the scrollbar If the user selects a different row thanthe one selected by scrolling, the scrollbar’s value needs to be updated so that when the userwants to scroll again, the scrollbar picks up from where the user left off The scrollbar alsoneeds to know when a row has been added or removed Changing the model will requirechanging the adjustment bounds
Listing 10-6 creates the signal handler to make sure that the adjustment stays in sync withthe widget It listens for the changed signal from GtkTreeSelection The changed signal is emit-
ted whenever the selection of the view may have changed The changed signal can be emitted
even though nothing has changed in the view This isn’t that big of a deal in most cases, includingListing 10-6
Listing 10-6. Creating the Signal Handler That Keeps the Widget and Adjustment Synchronized
<?php
// Update the scrollbar based on the adjustment
function setScrollValue($selection, $adj, $pathArray)
// Connect the selection to the scrollbar
$view->get_selection()->connect('changed', 'setScrollValue', $adj, $pathArray);
?>
In Listing 10-6, the changed signal is connected to the setScrollValue Whenever the selectedrow might have changed, setScrollValue will be called and passed the selection, the adjust-ment, and the array of tree paths setScrollValue then looks for the selected path in the treepath array and sets the adjustment’s value to the array index This signal handler makes surethat the adjustment and target widget are always in sync if the user navigates using the viewinstead of the scrollbar
Trang 12C H A P T E R 1 0■ S C R O L L I N G 229
Finally, the adjustment must be modified every time the model is updated This calls forthree more signal handlers: one for when a row is added to the model, one for when a row is
removed from the model, and one for when the rows are reordered When each of these actions
occurs, the array of tree paths must be updated to accurately represent the model
Listing 10-7 begins by first defining a method to create the tree path array Next, threesignal handlers are created: one each for when rows are inserted, deleted, or reordered
Listing 10-7. Creating the Signal Handlers to Keep the Model and the Adjustment Synchronized
<?php
// Update the adjustment to keep in sync with the model
function updateArrayAdj($model, $array, $adjustment)
■ Tip The scrolling that has been implemented in the preceding examples requires the tree to be fully
expanded It would be a good idea when implementing this in a real-world application to scroll only to the
rows that are visible or to expand the hidden rows automatically
These signal handlers connect their respective signals to the createTreePathArray method
It is easier in this case to maintain one method that re-creates the array each time than it is to
create three methods that modify the array If the model becomes very large, this approach may
need to be reworked slightly, but for purposes of this example, it works just fine These three
signal handlers ensure that the model and the adjustment stay synchronized when the model
is modified
In summary, when setting up custom scrolling for a widget, you must take three steps:
1. Set up the adjustment to properly represent the target widget (Listing 10-5)
2. Create a signal handler to scroll the target widget when the adjustment’s value changes(Listing 10-6)
3. Create one or more signal handlers to make sure that the target widget and the ment stay synchronized (Listing 10-7)
Trang 13adjust-C H A P T E R 1 0■ S C R O L L I N G
230
It isn’t difficult to accomplish these three steps and override the built-in scrolling abilities
of many widgets or those added to a view port
The ability to control how a widget is scrolled is more powerful than it may first appear.Aside from controlling what data appears on the screen, implementing custom scrolling alsoallows the scrollbar to be separated from the target widget The scrollbar in the precedingexamples is not physically attached to the tree view It could be placed on the other side of theapplication And you don’t even need to use a GtkHScrollbar or GtkVScrollbar for this function-ality As long as the adjustment’s value can be modified, you could use anything as the scrollbar.For example, a GtkSpinButton could easily be set up to act as a type of scrollbar
Summary
This chapter was relatively short Scrolling in PHP-GTK 2 is typically easy to implement Thosewidgets that have native scrollbar support can be added to a GtkScrolledWindow Those thatdon’t can be added to a GtkViewPort These two widgets can satisfy most scrolling needs When a scrolled window or a view port just isn’t enough, you can customize scrolling for
a particular widget The three steps for creating custom scrollbars are to set up a GtkAdjustmentproperly, make the adjustment scroll the target widget, and keep the adjustment and thetarget widget synchronized
GtkScrolledWindowand GtkViewPort provide ease of use, while custom scrolling allows fornear limitless flexibility
In Chapter 11, we will add the final components to the main application window First, wewill add the menus that will provide interfaces for many of the applications features, such assaving data, transmitting the information to the Crisscott server, and quitting the application.Then we will move on to adding a toolbar The toolbar will make some of the actions easilyaccessible by providing clickable icons that will call certain signal handlers With these twofeatures in place, the usability of the application will be greatly enhanced
Trang 14C H A P T E R 1 1
■ ■ ■
Adding Menus and Toolbars
The final major pieces of the Crisscott PIMS user interface are the menus and toolbars Menus
and toolbars are widgets that provide a means for the user to initiate some action, such as
sav-ing a document, clossav-ing an application, or copysav-ing a block of text Menus and toolbars are
essentially different ways of representing a group of tasks Menus dynamically hide and show
a hierarchical grouping of actions; toolbars tend to be more static Regardless of whether an
action is represented in a menu or a toolbar, the idea is basically to allow the user to activate
a segment of the application code
In this chapter, you will learn how to create several types of menus and how to set up bars with various types of buttons First, let’s look at how to create menus, and then we will get
tool-into working with toolbars
Menus
Menus are widgets responsible for organizing user tasks Most GUI applications will have at
least File and Help menus
What makes a menu different from a toolbar is that a menu provides a hierarchical ture and can hide most of the actions when they are not needed This makes menus perfect fororganizing the user actions in an application, especially those actions that are not used very
struc-frequently Because menus hide the actions when not in use, they can pack a lot of functionality
into a relatively small space In fact, menus can even be set up to detach from the application or
seemingly appear out of nowhere
Let’s start with adding a rather simple menu to the Crisscott PIMS application This menuwill allow the users to close the application, save their work, and perform a few other tasks By
the end of this section, the menu will evolve into the menu shown in Figure 11-1
Trang 15C H A P T E R 1 1■ A D D I N G M E N U S A N D TO O L B A R S
232
Figure 11-1. A full-featured menu
Figure 11-2. A menu bar (GtkMenuBar)
Creating Menu Bars
The most familiar part of an application menu is the menu bar This is the persistent piece ofthe menu that doesn’t change Figure 11-2 shows a simple menu bar
GtkMenuBaris a specialized container that holds GtkMenuItem items A menu bar simplyorganizes the menu items GtkMenuBar is a child class of GtkMenuShell, which provides a fewmethods for adding menu items GtkMenuBar provides two methods for determining how thenewly added items will be shown
In Listing 11-1, three menu items are added to a menu bar:
• A Help menu item appended to (added to the end of ) the menu bar using the appendmethod
• A File menu item prepended to (added to the beginning of ) the menu bar using theprependmethod
• An Edit menu item added in the second position in the menu bar using the insertmethod
Listing 11-1. Adding Items to GtkMenuBar
<?php
// Create a menu bar
$menuBar = new GtkMenuBar();
Trang 16C H A P T E R 1 1■ A D D I N G M E N U S A N D TO O L B A R S 233
// Create a help menu item
$help = new GtkMenuItem('Help');
// Append it to the menu bar
$menuBar->append($help);
// Create a file menu item
$file = new GtkMenuItem('File');
// Prepend it to the menu bar
$menuBar->prepend($file);
// Create an edit menu item
$edit = new GtkMenuItem('Edit');
// Insert it into the menu bar
$menuBar->insert($edit, 1);
?>
As you can see, the append, prepend, and insert methods each take a GtkMenuItem and add
it to the menu bar
Adding Menus
GtkMenuis similar to GtkMenuBar in that it also extends GtkMenuShell A GtkMenu is a container
that can accept only GtkMenuItem widgets Whereas a GtkMenuBar is a static fixture, a GtkMenu is
not always visible GtkMenu is often used as a submenu for a menu item (more on menu items
in the next section)
Normally, when a menu item from a menu bar is activated, a GtkMenu widget drops down
If a menu item from a GtkMenu is activated, sometimes another GtkMenu pops up Think of your
favorite web browser Most web browsers have a menu bar at the top with items like File, Edit,
and Help When you click one of those items, a menu drops down with more options Depending
on which browser you use, you may have a View menu with a Zoom or Text Zoom option In the
Mozilla Firefox browser, the Text Zoom option pops up another menu with different zoom options
Both the drop-down and pop-up menus are examples of GtkMenu
You create a GtkMenu instance by using the new operator When a GtkMenu is created, it isautomatically placed inside a GtkWindow This window is not a top-level window, but rather
a pop-up window This means that when a menu is created, it should not be added to any other
container widgets Doing so will produce an error message (Refer to Chapter 5 if you need to
review the difference between a pop-up and top-level window.)
After a GtkMenu is created, menu items should be added You add items to a GtkMenu in thesame way that you add items to a GtkMenuBar—by using append, prepend, and insert GtkMenu
also has one additional method for adding menu items called attach
The attach method functions very similarly to that of GtkTable Using attach allows you
to create menus with multiple rows and columns Its first argument is the menu item to attach
The next four arguments are the same as those in GtkTable::attach They define the four rows
and columns to which to attach the menu item Listing 11-2 shows how to attach a menu item
Trang 17Listing 11-2. Creating a GtkMenu Widget and Attaching GtkMenuItem Items
<?php
// Create a menu bar
$menuBar = new GtkMenuBar();
// Create a help menu item
$help = new GtkMenuItem('Help');
// Append it to the menu bar
$menuBar->append($help);
// Create a file menu item
$file = new GtkMenuItem('File');
// Prepend it to the menu bar
$menuBar->prepend($file);
// Create a menu
$fileMenu = new GtkMenu();
// Create four menu items to be added to the file menu
$new = new GtkMenuItem('New');
$open = new GtkMenuItem('Open');
$save = new GtkMenuItem('Save');
$edit = new GtkMenuItem('Edit');
// Attach the four items to the menu
// Create an edit menu item
$edit = new GtkMenuItem('Edit');
// Insert it into the menu bar
$menuBar->insert($edit, 1);
// Create a window and add the menu
$window = new GtkWindow();
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
Trang 18Figure 11-3. GtkMenu with two columns of GtkMenuItem items
C H A P T E R 1 1■ A D D I N G M E N U S A N D TO O L B A R S 235
Creating Menu Items
The real power of menus is in GtkMenuItem Menu items are the selectable icons and text of the
menu GtkMenuItem widgets are the only valid children of GtkMenu and GtkMenuBar GtkMenuItem
is itself a container It is a descendant of GtkBin, which was first discussed in Chapter 3 This
means that it can take one child widget
Creating menu items is pretty simple Listing 11-3 creates a menu bar with three menuitems
Listing 11-3. Creating GtkMenuItem Items
<?php
// Create a menu bar
$menuBar = new GtkMenuBar();
// Create a file menu item
$file = new GtkMenuItem();
$file->add(new GtkLabel('File'));
// Prepend it to the menu bar
$menuBar->prepend($file);
// Create an edit menu item
$edit = new GtkMenuItem('Edit');
// Insert it into the menu bar
$menuBar->append($edit);
// Create a help menu item
$help = new GtkMenuItem('_Help');
// Append it to the menu bar
$menuBar->append($help);
// Create a window and add the menu
$window = new GtkWindow();
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
$window->add($menuBar);
$window->show_all();
Gtk::main();
?>
Trang 19C H A P T E R 1 1■ A D D I N G M E N U S A N D TO O L B A R S
236
The first menu item is created using the new operator with no arguments After it is created,
a GtkLabel with the text 'File' is added The second menu item is created by passing the menuitem’s label text, 'Edit', at the time of construction The third menu item is created in a simi-lar manner to the second The label is passed on construction, but it is also given a mnemonic.Recall from Chapter 7 that a mnemonic is a keyboard shortcut Therefore, the text passed forthe third menu item is '_Help' This means that pressing Alt+H will activate the Help menu
■ Tip By default, the label for aGtkMenuItemis left justified You can make the label right justified bypassing trueto set_right_justifiedfor that menu item
A menu item’s primary responsibility is to handle events from the user Menu items are used
to trigger events When a menu item is clicked, or activated, one of two things usually happens:either some programmatic action is initiated or a submenu appears Regardless of what themenu item is configured to do, its action is triggered by the activate signal The activate signal
is emitted when the menu item is clicked (or the activate method is called) If the menu itemconsists of a submenu, PHP-GTK will automatically create a signal handler that shows thesubmenu when the item is clicked If there is no submenu, you must create a signal handler tocall the method associated with the menu item
Adding Submenus
Take a look at Listing 11-4, which contains the initial code for the Crisscott PIMS application.First, the menu bar parent constructor is called Next, two menu items are added to the menubar Both items are created with mnemonics to make activating them a little easier At thisstage, activating the items would do nothing There are no signal handlers created and thereare no submenus Therefore, the next step is to create and add a submenu The submenu iscreated by using the new operator and adding a few menu items Then, set_submenu is called
on the File menu item Another submenu is created and added to the Help menu
Listing 11-4. Adding Submenus to GtkMenuItem
Trang 20C H A P T E R 1 1■ A D D I N G M E N U S A N D TO O L B A R S 237
// Add two menu items
$this->file = new GtkMenuItem('_File');
// Create the file menu and items
$fileMenu = new GtkMenu();
$new = new GtkMenuItem('New');
$open = new GtkMenuItem('Open');
$save = new GtkMenuItem('Save');
$quit = new GtkMenuItem('Quit');
// Add the four items to the file menu
$fileMenu->append($new);
$fileMenu->append($open);
$fileMenu->append($save);
$fileMenu->append($quit);
// Create the help menu and items
$helpMenu = new GtkMenu();
$help = new GtkMenuItem('Help');
$about = new GtkMenuItem('About');
// Add both items to the help menu
?>
Now when one of the menu bar’s menu items is activated, the attached submenu willdrop down Figure 11-4 shows the menu bar when the File menu has been activated