1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Programming the Be Operating System-Chapter 6: Controls and Messages ppt

49 385 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Controls and Messages
Trường học Be Operating System University
Chuyên ngành Computer Science
Thể loại Tài liệu
Năm xuất bản 2023
Thành phố San Francisco
Định dạng
Số trang 49
Dung lượng 511,79 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

When you create a control such as a button object fromthe BButton class, define a unique message type that becomes associated withthat one control.. In thischapter, you’ll read about the

Trang 1

Chapter 5, Drawing, described the color control and the BColorControl class

used to create such controls This chapter discusses other control types and theclasses used to create each Also discussed is the BControl class, the class fromwhich all other control classes are derived

When the user clicks on a control, the system responds by sending a message tothe window that holds the control This message indicates exactly which controlhas been clicked The message is received by the window’s MessageReceived()hook function, where it is handled Since the BWindow version ofMessageReceived() won’t know how to go about responding to messages thatoriginate from your controls, you’ll override this routine Your application thengains control of how such messages are handled, and can include any code neces-sary to carry out the task you want the control to perform This chapter includesexamples that demonstrate how to create controls and how to overrideMessageReceived() such that the function handles mouse clicks on controls ofany of the standard types

Introduction to Controls

When a BWindow object receives a message, it either handles the message itself orlets one of its views handle it To handle a message, the window invokes aBWindow hook function For example, a B_ZOOM message delivered to a window

Trang 2

results in that window invoking the BWindow hook function Zoom() to shrink orenlarge the window To allocate the handling of a message to one of its views, thewindow passes the message to the affected view, and the view then invokes theappropriate BView hook function For example, a B_MOUSE_DOWN message results

in the affected view invoking the BView hook function MouseDown()

Besides being the recipient of system messages, a window is also capable ofreceiving application-defined messages This lets you implement controls in yourapplication’s windows When you create a control (such as a button object fromthe BButton class), define a unique message type that becomes associated withthat one control Also, add the control to a window When the user operates thecontrol (typically by clicking on it, as for a button), the system passes the applica-tion-defined message to the window How the window handles the message isdetermined by the code you include in the BWindow member functionMessageReceived()

Control Types

You can include a number of different types of controls in your windows Eachcontrol is created from a class derived from the abstract class BControl TheBControl class provides the basic features common to all controls, and theBControl-derived classes add capabilities unique to each control type In thischapter, you’ll read about the following control types:

Button

The BButton class is used to create a standard button, sometimes referred to

as a push button Clicking on a button results in some immediate action ing place

tak-Picture button

The BPictureButton class is used to create a button that can have any size,shape, and look to it While picture buttons can have an infinite variety oflooks, they act in the same manner as a push button—a mouse click results in

an action taking place

Checkbox

The BCheckBox class creates a checkbox A checkbox has two states: on andoff Clicking a checkbox always toggles the control to its opposite state orvalue Clicking on a checkbox usually doesn’t immediately impact the pro-gram Instead, a program typically waits until some other action takes place(such as the click of a certain push button) before gathering the current state

of the checkbox At that time, some program setting or feature is adjustedbased on the value in the checkbox

Trang 3

Introduction to Controls 179

Radio button

The BRadioButton class is used to create a radio button Like a checkbox, aradio button has two states: on and off Unlike a checkbox, a radio button isnever found alone Radio buttons are grouped together in a set that is used tocontrol an option or feature of a program Clicking on a radio button turns offwhatever radio button was on at the time of the mouse click, and turns on thenewly clicked radio button Use a checkbox in a yes or no or true or false sit-uation Use radio buttons for a condition that offers multiple choices that aremutually exclusive (since only one button can be on at any given time)

Text field

The BTextControl class is used to create a text field A text field is a controlconsisting of a static string on the left and an editable text area on the right.The static text acts as a label that provides the user with information aboutwhat is to be typed in the editable text area of the control Typing text in theeditable text area of a control can have an immediate effect on the program,but it’s more common practice to wait until some other action takes place (like

a click on a push button) before the program reads the user-entered text

Color control

The BColorControl class, shown in Chapter 5, creates color controls A colorcontrol displays the 256 system colors, each in a small square The user canchoose a color by clicking on it A program can, at any time, check to seewhich color the user has currently selected, and perform some action based

on that choice Often the selected color is used in the next, or all subsequent,drawing operation the program performs

Figure 6-1 shows four of the six types of controls available to you In the upperleft of the figure is a button The control in the upper right is a text field Thelower left of the figure shows a checkbox in both its on and off states, while thelower right of the figure shows a radio button in both its states A picture buttoncan have any size and look you want, so it’s not shown All the buttons are associ-ated with labels that appear on or next to the controls themselves

The sixth control type, the color control based on the BColorControl class, isn’tshown either—it was described in detail in Chapter 5 and will only be mentioned

in passing in this chapter

A control can be in an enabled statewhere the user can interact with itor adisabled state A disabled control will appear dim, and clicking on the control willhave no effect Figure 6-2 shows a button control in both its enabled state (left-most in the figure) and its disabled state (rightmost in the figure) Also shown iswhat an enabled button looks like when it is selected using the Tab key (middle

in the figure) A user can press the Tab key to cycle through controls, making eachone in turn the current control As shown in Figure 6-2, a button’s label will be

Trang 4

underlined when it’s current Once current, other key presses (typically the Returnand Enter key) affect that control.

Creating a Control

A control is created from one of six Interface Kit classes—each of which is ered in detail in this chapter Let us start by examining the BControl class fromwhich they are derived

cov-The BControl class

The BControl class is an abstract class derived from the BView and BInvokerclasses Control objects are created from BControl-derived classes, so all controlsare types of views

It’s possible to create controls that aren’t based on the BControl

class In fact, the Be API does that for the BListView and

BMenuItem classes These are exceptions, though You’ll do best by

basing each of your application’s controls on one of the six

BControl-derived classes Doing so means your controls will

behave as expected by the user.

BControlis an abstract class, so your project will create BControl-derived classobjects rather than BControl objects However, because the constructor of eachBControl-derived class invokes the BControl constructor, a study of theBControl constructor is a worthwhile endeavor Here’s the prototype:

BControl(BRect frame,

Figure 6-1 Examples of button, text field, checkbox, and radio button controls

Figure 6-2 A button control that’s (from left to right) enabled, current, and disabled

Trang 5

param-in Chapter 4, Wparam-indows, Views, and Messages, so here I’ll offer only a brief recap of

their purposes The frame parameter is a rectangle that defines the boundaries ofthe view The name parameter establishes a name by which the view can be iden-tified at any time The resizingMode parameter is a mask that defines the behav-ior of the view should the size of the view’s parent view change The flagsparameter is a mask consisting of one or more Be-defined constants that deter-mine the kinds of notifications (such as update) the view is to be aware of

The remaining two BControl constructor parameters are specific to the control.The label parameter is a string that defines the text associated with it Forinstance, for a button control, the label holds the words that appear on the but-ton The message parameter is a BMessage object that provides a means for thesystem to recognize the control as a unique entity When the control is selected bythe user, it is this message that the system will send to the window that holds thecontrol

Your project won’t create BControl objects, so a sample call to the BControlconstructor isn’t useful here Instead, let’s look at the simplest type of BControl-derived object: the BButton

The BButton class

Creating a new push button involves creating a new BButton object TheBButton constructor parameters are an exact match of those used by theBControl constructor:

BButton(BRect frame,

const char *name,

const char *label,

BMessage *message,

uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,

uint32 flags = B_WILL_DRAW | B_NAVIGABLE)

The BButton constructor invokes the BControl constructor, passing all of itsarguments to that routine The BControl constructor uses the label argument toinitialize the button’s label, and uses the message argument to assign a uniquemessage to the button The BControl constructor then invokes the BView con-structor, passing along the remaining four arguments it received from the BButtonconstructor The BView constructor then sets up the button as a view After the

Trang 6

BControl and BView constructors have executed, the BButton constructor ries on with its creation of a button object by implementing button-specific tasks.This is, in essence, how the constructor for each of the BControl-derived classesworks.

car-Creating a button

A button is created by defining the arguments that are passed to the BButton structor and then invoking that constructor using new To become functional, thebutton must then be added to a window That’s what’s taking place in this snippet:

con-#define BUTTON_OK_MSG 'btmg'

BRect buttonRect(20.0, 20.0, 120.0, 50.0);

const char* buttonName = "OKButton";

const char* buttonLabel = "OK";

BButton *buttonOK;

buttonOK = new BButton(buttonRect, buttonName,

buttonLabel, new BMessage(BUTTON_OK_MSG));

aView->AddChild(buttonOK);

In the above code, the BRect variable buttonRect defines the size and location

of the button This push button will be 100 pixels wide by 30 pixels high ThebuttonNamestring gives the button the name “OKButton.” This is the name used

to locate and access the button by view name using the BView member functionFindView() The name that actually appears on the button itself, “OK,” is defined

by the buttonLabel string The message associated with the new button control

is a new BMessage object of type BUTTON_OK_MSG I’ll explain the BMessage class

in a minute Here it suffices to say that, as shown above, creating a new messagecan be as easy as defining a four-character string and passing this constant to theBMessage constructor

The BButton constructor prototype lists six parameters, yet the above invocation

of that constructor passes only four arguments The fifth and sixth parameters,resizingMode and flags, offer default values that are used when these argu-ments are omitted The default resizingMode value (B_FOLLOW_LEFT |B_FOLLOW_TOP) creates a button that will remain a fixed distance from the left andtop edges of the control’s parent view should the parent view be resized Thedefault flags value (B_WILL_DRAW | B_NAVIGABLE) specifies that the controlneeds to be redrawn if altered, and that it can become the focus view in response

to keyboard actions

Adding a control to a window means adding the control to a view In the abovesnippet, it’s assumed that a view (perhaps an object of the application-definedBView-derived MyDrawView class) has already been created

Trang 7

Introduction to Controls 183

Enabling and disabling a control

When a control is created, it is initially enabled—the user can click on the control

to select it If you want a control to be disabled, invoke the control’sSetEnabled() member function The following line of code disables thebuttonOK button control that was created in the previous snippet:

buttonOK->SetEnabled(false);

SetEnabled() can be invoked on a control at any time, but if the control is tostart out disabled, call SetEnabled() before displaying the window the controlappears in To again enable a control, call SetEnabled() with an argument oftrue

This chapter’s CheckBoxNow project demonstrates the enabling and disabling of abutton The technique in that example can be used on any type of control

Turning a control on and off

Checkboxes and radio buttons are two-state controls—they can be on or off.When a control of either of these two types is created, it is initially off If you wantthe control on (to check a checkbox or fill in a radio button), invoke theBControl member function SetValue() Passing SetValue() the Be-definedconstant B_CONTROL_ON sets the control to on Turning a control on and off inresponse to a user action in the control is the responsibility of the system—notyour program So after creating a control and setting it to the state you want, youwill seldom need to call SetValue() If you want your program to “manually”turn a control off (as opposed to doing so in response to a user action), have thecontrol invoke its SetValue() function with an argument of B_CONTROL_OFF

A button is a one-state device, so turning a button on or off doesn’t make sense.Instead, this snippet turns on a two-state control—a checkbox:

requirePasswordCheckBox->SetValue(B_CONTROL_ON)

Creating checkboxes hasn’t been covered yet, so you’ll want to look at the Box example project later in this chapter to see the complete code for creating andturning on a checkbox

Check-Technically, a button is also a two-state control When it is not being

clicked, it’s off When the control is being clicked (and before the

user releases the mouse button), it’s on This point is merely an

aside, though, as it’s unlikely that your program will ever need to

check the state of a button in the way it will check the state of a

checkbox or radio button.

Trang 8

To check the current state of a control, invoke the BControl member functionValue() This routine returns an int32 value that is either B_CONTROL_ON (which

is defined to be 1) or B_CONTROL_OFF (which is defined to be 0) This snippetobtains the current state of a checkbox, then compares the value of the state to theBe-defined constant B_CONTROL_ON:

int32 controlState;

controlState = requirePasswordCheckBox->Value();

if (controlState == B_CONTROL_ON)

// password required, display password text field

Changing a control’s label

Both checkboxes and radio buttons have a label that appears to the right of thecontrol A text field has a label to the left of the control The control’s label is setwhen the control is created, but it can be changed on the fly

The BControl member function SetLabel() accepts a single argument: the textthat is to be used in place of the control’s existing label In this next snippet, abutton’s label is initially set to read “Click,” but is changed to the string “ClickAgain” at some point in the program’s execution:

BRect buttonRect(20.0, 20.0, 120.0, 50.0);

const char *buttonName = "ClickButton";

const char *buttonLabel = "Click";

BButton *buttonClick;

buttonOK = new BButton(buttonRect, buttonName,

buttonLabel, new BMessage(BUTTON_CLICK_MSG));

Trang 9

Introduction to Controls 185

window That message will be your program’s prompt to perform whatever action

is appropriate

Messages and the BMessage class

When the Application Server delivers a system message to an applicationwindow, that message arrives in the form of a BMessage object Your code deter-mines how to handle a system message simply by overriding a BView hook func-tion (such as MouseDown()) Because the routing of a message from the Applica-tion Server to a window and then possibly to a view’s hook function isautomatically handled for you, the fact that the message is a BMessage object maynot have been important (or even known) to you A control also makes use of aBMessageobject However, in the case of a control, you need to know a little bitabout working with BMessage objects

The BMessage class defines a message object as a container that holds tion Referring to the BMessage class description in the Application Kit chapter ofthe Be Book, you’ll find that this information consists of a name, some number ofbytes of data, and a type code You’ll be pleased to find out that when using aBMessagein conjunction with a control, a thorough knowledge of these details ofthe BMessage class isn’t generally necessary (complex applications aside) Instead,all you need to know of this class is how to create a BMessage object The snip-pet a few pages back that created a BButton object illustrated how that’s done:

informa-#define BUTTON_OK_MSG 'btmg'

// variable declarations here

buttonOK = new BButton(buttonRect, buttonName,

buttonLabel, new BMessage(BUTTON_OK_MSG));

The only information you need to create a BMessage object is a four-character eral, as in the above definition of BUTTON_OK_MSG as ‘btmg’ This value, whichwill serve as the what field of the message, is actually a uint32 So you candefine the constant as an unsigned 32-bit integer, though most programmers find iteasier to remember a literal than the unsigned numeric equivalent This value thenbecomes the argument to the BMessage constructor in the BButton constructor.This newly created message object won’t hold any other information

lit-The BMessage class defines a single public data member named what lit-The whatdata member holds the four-character string that distinguishes the message from allother message types—including system messages—the application will use In theprevious snippet, the constant btmg becomes the what data member of theBMessage object created when invoking the BButton constructor

Trang 10

When the program refers to a system message by its Be-defined constant, such asB_QUIT_REQUESTED or B_KEY_DOWN, what’s really of interest is the what datamember of the system message The value of each Be-defined message constant is

a four-character string composed of a combination of only uppercase charactersand, optionally, one or more underscore characters Here’s how Be defines a few

of the system message constants:

“MSG” for “message.” The value of each constant may hint at the message type(for instance, ‘plSD’ for “play sound”), but aside from avoiding all uppercase char-acters, the value is somewhat arbitrary These two examples illustrate the conven-tion I use:

#define BUTTON_PLAY_SOUND_MSG 'plSD'

#define CALCULATE_VALUES 'calc'

Messages and the MessageReceived() member function

The BWindow class is derived from the BLooper class, so a window is a type oflooper—an object that runs a message loop that receives messages from the Appli-cation Server The BLooper class is derived from the BHandler class, so a win-dow is also a handler—an object that can handle messages that are dispatchedfrom a message loop A window can both receive messages and handle them.For the most part, system messages are handled automatically; for instance, when

a B_ZOOM message is received, the operating system zooms the window But youcannot completely entrust the handling of an application-defined message to thesystem

Trang 11

Introduction to Controls 187

When a user selects a control, the Application Server delivers a message objectwith the appropriate what data member value to the affected BWindow object.You’ve just seen a snippet that created a BButton associated with a BMessageobject That BMessage had a what data member of ‘btmg’ If the user clicked onthe button that results from this object, the Application Server would deliver such

a message to the affected BWindow It’s up to the window to include code thatwatches for, and responds to, this type of message The BWindow class memberfunction MessageReceived() is used for this purpose

When an application-defined message reaches a window, it looks for aMessageReceived() function This routine receives the message, examines themessage’s what data member, and responds depending on its value TheBHandler class defines such a MessageReceived() function The BHandler-derived class BWindow inherits this function and overrides it The BWindow ver-sion includes a call to the base class BHandler version, thus augmenting whatBHandler offers If the BWindow version of MessageReceived() can’t handle amessage, it passes it up to the BHandler version of this routine Figure 6-3 showshow a message that can’t be handled by one version of MessageReceived() getspassed up to the next version of this function

Here is how the MessageReceived() looks in BWindow:

void BWindow::MessageReceived(BMessage* message)

BWindow-derived version

MessageReceived() BWindow version

MessageReceived() BHandler version

message

message

Trang 12

void MyHelloWindow::MessageReceived(BMessage* message)

void MyHelloWindow::MessageReceived(BMessage* message)

The particular code that appears under the control’s case label depends entirely

on what action you want to occur in response to the control being clicked Forsimplicity, assume that we want a click on the OK button to do nothing more thansound a beep The completed version of MessageReceived() looks like this:

Trang 13

oper-Creating a Button

The BButton constructor has six parameters, each of which was described in the

“The BButton class” section of this chapter:

BButton(BRect frame,

const char *name,

const char *label,

BMessage *message,

uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,

uint32 flags = B_WILL_DRAW | B_NAVIGABLE)

The BButton constructor calls the BControl constructor, which in turn calls theBView constructor Together, these routines set up and initialize a BButton object.After attaching the button to a window, the height of the button may automati-cally be adjusted to accommodate the height of the text of the button’s label andthe border of the button If the values of the frame rectangle coordinates result in

a button that isn’t high enough, the BButton constructor will increase the buttonheight by increasing the value of the frame rectangle’s bottom value The exactheight of the button depends on the font in which the button label is displayed.For the example button creation code, assume that a window is keeping track ofBViewand BButton objects in data members named fView and fButton, respec-tively, and that the button’s message type is defined by the constant BUTTON_MSG:

#define BUTTON_MSG 'bttn'

class MyWindow : public BWindow {

Trang 14

fButton = new BButton(buttonRect, "MyButton",

"Click Me", new BMessage(BUTTON_MSG));

fView->AddChild(fButton);

Making a Button the Default Button

One button in a window can be made the default button—a button that the usercan select either by clicking or by pressing the Enter key If a button is the defaultbutton, it is given a wider border so that the user recognizes it as such a button

To make a button the default button, call the BButton member functionMakeDefault():

fButton->MakeDefault(true);

If the window that holds the new default button already had a default button, theold default button automatically loses its default status and becomes a “normal”button The system handles this task to ensure that a window has only one defaultbutton

While granting one button default status may be a user-friendly gesture, it mightalso not make sense in many cases Thus, a window isn’t required to have adefault button

Button Example Project

The TwoButtons project demonstrates how to create a window that holds two tons Looking at Figure 6-4, you can guess that a click on the leftmost button(which is the default button) results in the playing of the system sound a singletime, while a click on the other button produces the beep twice

but-Preparing the window class for the buttons

A few additions to the code in the MyHelloWindow.h file are in order First, a pair

of constants are defined to be used later when the buttons are created The choice

of constant names and values is unimportant, provided that the names don’t beginwith “B_” and that the constant values don’t consist of all uppercase characters

Trang 15

Buttons 191

#define BUTTON_BEEP_1_MSG 'bep1'

#define BUTTON_BEEP_2_MSG 'bep2'

To keep track of the window’s two buttons, a pair of data members of typeBButtonare added to the already present data member of type MyDrawView Andnow that the window will be receiving and responding to application-definedmessages, the BWindow-inherited member function MessageReceived() needs tooverridden:

class MyHelloWindow : public BWindow {

public:

MyHelloWindow(BRect frame);

virtual bool QuitRequested();

virtual void MessageReceived(BMessage* message);

Creating the buttons

The buttons are created and added to the window in the MyHelloWindow structor Before doing that, the constructor declares several variables that will beused in the pair of calls to the BButton constructor and assigns them values:

con-BRect buttonBeep1Rect(20.0, 60.0, 110.0, 90.0);

BRect buttonBeep2Rect(130.0, 60.0, 220.0, 90.0);

const char *buttonBeep1Name = "Beep1";

const char *buttonBeep2Name = "Beep2";

const char *buttonBeep1Label = "Beep One";

const char *buttonBeep2Label = "Beep Two";

In the past, you’ve seen that I normally declare a variable within the routine thatuses it, just before its use Here I’ve declared the six variables that are used asBButton constructor arguments outside of the MyHelloWindow constructor—butthey could just as well have been declared within the MyHelloWindow construc-tor I opted to do things this way to get in the habit of grouping all of a window’s

Figure 6-4 The window that results from running the TwoButtons program

Trang 16

layout-defining code together Grouping all the button boundary rectangles,names, and labels together makes it easier to lay out the buttons in relation to oneanother and to supply them with logical, related names and labels This technique

is especially helpful when a window holds several controls

The buttons will be added to the fMyView view Recall that this view is of theBView-derived application-defined class MyDrawView and occupies the entire con-tent area of a MyHelloWindow In the MyHelloWindow constructor, the view iscreated first, and then the buttons are created and added to the view:

Handling button clicks

MessageReceived() always has a similar format The Application Server passesthis function a message as an argument The message data member what holdsthe message type, so that data member should be examined in a switch state-ment, with the result compared to any application-defined message types the win-dow is capable of handling A window of type MyHelloWindow can handle aBUTTON_BEEP_1_MSGand a BUTTON_BEEP_2_MSG If a different type of message isencountered, it gets passed on to the BWindow version of MessageReceived():

void MyHelloWindow::MessageReceived(BMessage* message)

Trang 17

The BPictureButton class is used to create a picture button Associated with oneBPictureButtonobject are two BPicture objects One of the pictures acts as thebutton when the button is in its normal state (that is, when the user isn’t clicking

on it) The other picture acts as the button when the user clicks on the button.You’ll supply a BPictureButton object with the two pictures, and the system will

be responsible for switching back and forth between the pictures in response tothe user’s actions

Creating a Picture Button

A picture button is created by the BPictureButton constructor As is the case forother controls, this constructor invokes the BControl constructor, which in turninvokes the BView constructor:

uint32 behavior = B_ONE_STATE_BUTTON,

uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE)

The BPictureButton constructor has eight parameters, five of which you’realready familiar with The frame, name, resizingMode, and flags parametersget passed to the BView constructor and are used in setting up the picture button

as a view The message parameter is used by the BControl constructor to assign

a message type to the picture button The remaining three parameters, off, on,and behavior, are specific to the creation of a picture button

Trang 18

The off and on parameters are BPicture objects that define the two pictures to

be used to display the button In Chapter 5, you saw how to create a BPictureobject using the BPicture member functions BeginPicture() andEndPicture() Here I create a picture composed of a white circle within a blackcircle:

For more compelling graphic images, you can use bitmaps for

but-ton pictures Once a bitmap exists, all that needs to appear between

the BeginPicture() and EndPicture() calls is a call to the BView

member function DrawBitMap() Chapter 10, Files, discusses

bit-maps.

Picture buttons are actually more versatile than described in this section Here thepicture button is treated as a one-state device—just as a standard push button is.The BPictureButton class can also be used, however, to create a picture buttonthat is a two-state control Setting the behavior parameter to the constant B_TWO_STATE_BUTTON tells the BPictureButton constructor to create a picture buttonthat, when clicked on, toggles between the two pictures represented by theBPictureparameters off and on Clicking on such a picture button displays onepicture Clicking on the button again displays the second picture The displayedpicture indicates to the user the current state of the button To see a good real-world use of a two-state picture button, run the BeIDE Then choose Find fromthe Edit menu In the lower-left area of the Find window you’ll find a button thathas a picture of a small file icon on it Click on the button and it will now have apicture of two small file icons on it This button is used to toggle between twosearch options: search only the currently open, active file, and search all filespresent in the Find window list Figure 6-5 shows both of this button’s two states

Trang 19

Picture Buttons 195

Picture Button Example Project

The PictureButton project creates a program that displays a window that holds asingle picture button Figure 6-6 shows this one window under two different con-ditions The leftmost window in the figure shows the button in its normal state.The rightmost window shows that when the button is clicked it gets slightlysmaller and its center is filled in

The picture button can include other pictures, which will be used if

the program lets the button be disabled Now that you know the

basics of working with the BPictureButton class, the details of

enhancing your picture buttons will be a quick read in the

BPictureButton section of the Interface Kit chapter of the Be

Book.

Figure 6-5 The Find window of the BeIDE provides an example of a picture button

Figure 6-6 The window that results from running the PictureButton program

The two states of the same

picture button

Trang 20

Preparing the window class for the picture button

This chapter’s TwoButtons example project (presented in the “Buttons” section)provided a plan for adding a control, and support of that control, to a window

Here’s how the window class header file (the MyHelloWindow.h file for this

project) is set up for a new control:

• Define a constant to be used to represent an application-defined message type

• Override MessageReceived() in the window class declaration

• Add a control data member in the window class declaration

Here’s how the MyHelloWindow class is affected by the addition of a picture ton to a window of this class type:

but-#define PICTURE_BEEP_MSG 'bep1'

class MyHelloWindow : public BWindow {

public:

MyHelloWindow(BRect frame);

virtual bool QuitRequested();

virtual void MessageReceived(BMessage* message);

private:

MyDrawView *fMyView;

BPictureButton *fPicButtonBeep;

};

I’ve defined the PICTURE_BEEP_MSG constant to have a value of

' bep1 ' Looking back at the TwoButtons example project, you’ll see

that this is the same value I gave to that project’s BUTTON_BEEP_1_

MSG constant If both controls were present in the same application,

I’d give one of these two constants a different value so that the

MessageReceived() function could distinguish between a click on

the Beep One push button and a click on the picture button.

Creating the picture button

The process of creating a control can also be expressed in a number of steps All

of the following affect the window source code file (the MyHelloWindow.cpp file

in this particular example):

• Declare and assign values to the variables to be used in the control’s structor

con-• Create the control using new and the control’s constructor

• Attach the control to the window by adding it to one of the window’s views

Trang 21

Show();

}

The two BPicture objects are defined using a few of the basic drawing niques covered in Chapter 5 As you read the following, refer back to the picturebutton in its off state (normal, or unclicked) and on state (being clicked) inFigure 6-5

tech-The off picture fills in a rectangle with the B_SOLID_LOW pattern (solid white) toerase the on picture that might currently be displayed (if the user has just clicked

Trang 22

the picture button, the on picture will be serving as the picture button) Then arectangle is outlined to serve as the off button.

The on picture erases the off picture (should it be currently drawn to the window

as the picture button) by drawing a white (B_SOLID_LOW) rectangle outline withthe boundaries of the off picture rectangle That rectangle is then inset two pixels

in each direction and a new rectangle is framed in black (B_SOLID_HIGH) Therectangle is then inset two more pixels, and this new area is filled with black

Handling a picture button click

To handle a click on the picture button, MessageReceived() now looks for amessage of type PICTURE_BEEP_MSG Should that message reach the window, thecomputer sounds the system beep one time:

void MyHelloWindow::MessageReceived(BMessage* message)

Whether a click results in a checkbox being turned on (checked) or off(unchecked), a message is sent to the window that holds the checkbox While aprogram can immediately respond to a click on a checkbox, it is more typical forthe program to wait until some other action takes place before responding Forinstance, the setting of some program feature could be done via a checkbox.Clicking the checkbox wouldn’t, however, immediately change the setting Instead,when the user dismisses the window the checkbox resides in, the value of thecheckbox can be queried and the setting of the program feature could be per-formed at that time

Trang 23

Checkboxes 199

Creating a Checkbox

The BCheckBox constructor has six parameters:

BCheckBox(BRect frame,

const char *name,

const char *label,

BMessage *message,

uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,

uint32 flags = B_WILL_DRAW | B_NAVIGABLE)

The BCheckBox parameters match those used in the BButton constructor—if youknow how to create a button, you know how to create a checkbox Adding to thesimilarities is that after you attach the checkbox to a window, the control’s heightwill be automatically adjusted to accommodate the height of the text of the con-trol’s label If the values of the frame rectangle coordinates don’t produce arectangle with a height sufficient to display the checkbox label, the BCheckBoxconstructor will increase the checkbox boundary rectangle height by increasing thevalue of the frame rectangle’s bottom value The exact height of the checkboxdepends on the font in which the control’s label is displayed

As for other control types, you’ll define a message constant that is to be pairedwith the control For instance:

fCheckBox = new BCheckBox(checkBoxRect,"MyCheckbox"

"Check Me", new BMessage(CHECKBOX_MSG));

fMyView->AddChild(fCheckBox);

Checkbox (Action Now) Example Project

Clicking a checkbox may have an immediate effect on some aspect of the gram, or it may not have an impact on the program until the user confirms thecheckbox selection—usually by a click on a button The former use of a check-

Trang 24

pro-box is demonstrated in the example project described here: CheckBoxNow For anexample of the other usage, a checkbox that has an effect after another action istaken, look over the next example, the CheckBoxLater project.

The use of a checkbox to initiate an immediate action is often in practice whensome area of the window the checkbox resides in is to be altered For instance, ifsome controls in a window are to be rendered unusable in certain conditions, acheckbox can be used to disable (and then later enable) these controls This ishow the checkbox in the CheckBoxNow example works The CheckBoxNowproject creates a program with a window that holds two controls: a button and acheckbox When the program launches, both controls are enabled, and the check-box is unchecked—as shown in the top window in Figure 6-7 As expected, click-ing on the Beep One button produces a single system beep Clicking on thecheckbox disables beeping by disabling the button The bottom window inFigure 6-7 shows how the program’s one window looks after clicking the DisableBeeping checkbox

Preparing the Window class for the checkbox

The MyHelloWindow.h file prepares for the window’s support of a button and a

checkbox by defining a constant for each control’s message:

#define BUTTON_BEEP_1_MSG 'bep1'

#define CHECKBOX_SET_BEEP_MSG 'stbp'

The MyHelloWindow class now holds three data members:

class MyHelloWindow : public BWindow {

public:

MyHelloWindow(BRect frame);

virtual bool QuitRequested();

virtual void MessageReceived(BMessage* message);

private:

Figure 6-7 The windows that result from running the CheckBoxNow program

Ngày đăng: 26/01/2014, 07:20

TỪ KHÓA LIÊN QUAN

w