haiku-website/static/legacy-docs/bebook/TheInterfaceKit_Responding....

394 lines
44 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The Be Book - System Overview - The Interface Kit</title><link rel="stylesheet" href="be_book.css" type="text/css" media="all" /><link rel="shortcut icon" type="image/vnd.microsoft.icon" href="./images/favicon.ico" /><!--[if IE]>
<link rel="stylesheet" type="text/css" href="be_book_ie.css" />
<![endif]--><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="Access, BeOS, BeBook, API" /><link rel="start" href="index.html" title="The Be Book" /><link rel="up" href="TheInterfaceKit_Overview.html" title="The Interface Kit" /><link rel="prev" href="TheInterfaceKit_Drawing.html" title="Drawing" /><link rel="next" href="TheInterfaceKit_The_Coordinate_Space.html" title="The Coordinate Space" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="TheInterfaceKit_Drawing.html" title="Drawing"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="TheInterfaceKit_Overview.html" title="The Interface Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="TheInterfaceKit_The_Coordinate_Space.html" title="The Coordinate Space"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="headerTR"><div id="navigpeople"><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div><div class="navigboxed" id="navigindex"><a accesskey="i" href="ClassIndex.html" title="Index">I</a></div><div class="navigboxed" id="naviglang" title="English">en</div></div><div id="headerTC">The Be Book - System Overview - The Interface Kit</div></div><div id="headerB">Prev: <a href="TheInterfaceKit_Drawing.html">Drawing</a>  Up: <a href="TheInterfaceKit_Overview.html">The Interface Kit</a>  Next: <a href="TheInterfaceKit_The_Coordinate_Space.html">The Coordinate Space</a></div><hr /></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Responding"></a>Responding to the User</h2></div></div></div><p>
When the user fiddles with the mouse or keyboard, the Application Server
figures out which window the event is intended for, and then forms an
interface message that it sends to the <a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a>
object. The <a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a>
receives the message in its
<a class="link" href="BWindow.html#BWindow_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a>
function and invokes an interface hook function declared by
<a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a> or
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>. If your application
wants to respond to an event it simply implements the appropriate hook
function. For example, if you want to watch for mouse down events within
a view, you implement
<a class="link" href="BView.html#BView_MouseDown" title="MouseDown()"><code class="methodname">MouseDown()</code></a> in your
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> subclass.
</p><p>
You can also find out what's going on with the keyboard and mouse through
the (global)
<a class="link" href="TheInputServer_Functions.html#get_key_info" title="get_key_info()"><code class="function">get_key_info()</code></a>
function and the
<a class="link" href="BView.html#BView_GetMouse" title="GetMouse()"><code class="methodname">BView::GetMouse()</code></a> function.
You typically use these functions within the implementation of an
interface hook function to get more information about the keyboard or
mouse.
</p><p>
You shouldn't call
<a class="link" href="TheInputServer_Functions.html#get_key_info" title="get_key_info()"><code class="function">get_key_info()</code></a> or
<a class="link" href="BView.html#BView_GetMouse" title="GetMouse()"><code class="methodname">BView::GetMouse()</code></a> in a loop to
track the keyboard or mouse unless you really know what you're doing
(some game developers may need to poll). To track the keyboard, you
implement <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>'s
<a class="link" href="BView.html#BView_KeyDown" title="KeyDown()"><code class="methodname">KeyDown()</code></a> and
<a class="link" href="BView.html#BView_KeyUp" title="KeyUp()"><code class="methodname">KeyUp()</code></a>
functions. To track the mouse, implement
<a class="link" href="BView.html#BView_MouseDown" title="MouseDown()"><code class="methodname">MouseDown()</code></a>,
<a class="link" href="BView.html#BView_MouseMoved" title="MouseMoved()"><code class="methodname">MouseMoved()</code></a>, and
<a class="link" href="BView.html#BView_MouseUp" title="MouseUp()"><code class="methodname">MouseUp()</code></a>.
</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Responding_InterfaceMessages"></a>Interface Messages</h3></div></div></div><p>
The interface messages are reasonably self-explanatory. See the notes
below and the documentation of the individual hook functions for more
information.
</p><div class="informaltable"><table border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Message</th><th>Hook function</th></tr></thead><tbody><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_ZOOM" title="B_ZOOM">B_ZOOM</a></code></td><td><a class="link" href="BWindow.html#BWindow_Zoom" title="Zoom()"><code class="methodname">BWindow::Zoom()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_MINIMIZE" title="B_MINIMIZE">B_MINIMIZE</a></code></td><td><a class="link" href="BWindow.html#BWindow_Minimize"><code class="methodname">BWindow::Minimize()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_KEY_DOWN" title="B_KEY_DOWN, B_KEY_UP, B_UNMAPPED_KEY_DOWN, B_UNMAPPED_KEY_UP">B_KEY_DOWN</a></code></td><td><a class="link" href="BView.html#BView_KeyDown" title="KeyDown()"><code class="methodname">BView::KeyDown()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_KEY_UP">B_KEY_UP</a></code></td><td><a class="link" href="BView.html#BView_KeyUp" title="KeyUp()"><code class="methodname">BView::KeyUp()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_MOUSE_DOWN" title="B_MOUSE_DOWN">B_MOUSE_DOWN</a></code></td><td><a class="link" href="BView.html#BView_MouseDown" title="MouseDown()"><code class="methodname">BView::MouseDown()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_MOUSE_UP" title="B_MOUSE_UP">B_MOUSE_UP</a></code></td><td><a class="link" href="BView.html#BView_MouseUp" title="MouseUp()"><code class="methodname">BView::MouseUp()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_MOUSE_MOVED" title="B_MOUSE_MOVED">B_MOUSE_MOVED</a></code></td><td><a class="link" href="BView.html#BView_MouseMoved" title="MouseMoved()"><code class="methodname">BView::MouseMoved()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_VIEW_MOVED" title="B_VIEW_MOVED">B_VIEW_MOVED</a></code></td><td><a class="link" href="BView.html#BView_FrameMoved" title="FrameMoved()"><code class="methodname">BView::FrameMoved()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_VIEW_RESIZED" title="B_VIEW_RESIZED">B_VIEW_RESIZED</a></code></td><td><a class="link" href="BView.html#BView_FrameResized" title="FrameResized()"><code class="methodname">BView::FrameResized()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_VALUE_CHANGED" title="B_VALUE_CHANGED">B_VALUE_CHANGED</a></code></td><td><a class="link" href="BScrollBar.html#BScrollBar_ValueChanged" title="ValueChanged()"><code class="methodname">BScrollBar::ValueChanged()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_WINDOW_ACTIVATED" title="B_WINDOW_ACTIVATED">B_WINDOW_ACTIVATED</a></code></td><td><a class="link" href="BWindow.html#BWindow_WindowActivated" title="WindowActivated()"><code class="methodname">BWindow::WindowActivated()</code></a>
<a class="link" href="BView.html#BView_WindowActivated" title="WindowActivated()"><code class="methodname">BView::WindowActivated()</code></a></td></tr><tr><td><a class="link" href="TheApplicationKit_MessageConstants.html#B_QUIT_REQUESTED" title="B_QUIT_REQUESTED"><code class="constant">B_QUIT_REQUESTED</code></a></td><td><a class="link" href="BLooper.html#BLooper_QuitRequested" title="QuitRequested()"><code class="methodname">BLooper::QuitRequested()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_WINDOW_MOVED" title="B_WINDOW_MOVED">B_WINDOW_MOVED</a></code></td><td><a class="link" href="BWindow.html#BWindow_FrameMoved" title="FrameMoved(), FrameResized()"><code class="methodname">BWindow::FrameMoved()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_WINDOW_RESIZED" title="B_WINDOW_RESIZED">B_WINDOW_RESIZED</a></code></td><td><a class="link" href="BWindow.html#BWindow_FrameResized"><code class="methodname">BWindow::FrameResized()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_SCREEN_CHANGED" title="B_SCREEN_CHANGED">B_SCREEN_CHANGED</a></code></td><td><a class="link" href="BWindow.html#BWindow_ScreenChanged" title="ScreenChanged()"><code class="methodname">BWindow::ScreenChanged()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_WORKSPACE_ACTIVATED" title="B_WORKSPACE_ACTIVATED">B_WORKSPACE_ACTIVATED</a></code></td><td><a class="link" href="BWindow.html#BWindow_WorkspaceActivated" title="WorkspaceActivated()"><code class="methodname">BWindow::WorkspaceActivated()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheInterfaceKit_MessageConstants.html#B_WORKSPACES_CHANGED" title="B_WORKSPACES_CHANGED">B_WORKSPACES_CHANGED</a></code></td><td><a class="link" href="BWindow.html#BWindow_WorkspacesChanged" title="WorkspacesChanged()"><code class="methodname">BWindow::WorkspacesChanged()</code></a></td></tr><tr><td><code class="constant"><a class="link" href="TheApplicationKit_MessageConstants.html#B_PULSE" title="B_PULSE">B_PULSE</a></code></td><td><a class="link" href="BView.html#BView_Pulse" title="Pulse()"><code class="methodname">BView::Pulse()</code></a></td></tr></tbody></table></div><p>
Notes:
</p><ul class="itemizedlist"><li><p>
<code class="constant">B_ZOOM</code> is usually caused by the user operating the zoom button in the
window's title tab.
</p></li><li><p>
<code class="constant">B_MINIMIZE</code> tells the window to hide/show itself. This message is
usually caused by the user double-clicking the window's tab (to hide),
and clicking the window token in the application's window list (in the
<span class="application">DeskBar</span>).
</p></li><li><p>
<code class="constant">B_KEY_DOWN</code> and <code class="constant">B_KEY_UP</code> report that the user pressed and then release
a character key. When the key is held down, repeated <code class="constant">B_KEY_DOWN</code>
messages are sent. If a key is mapped to a string of characters, a
<code class="constant">B_KEY_DOWN</code>/<code class="constant">B_KEY_UP</code> pair is generated for each character. Pressing a
modifier keys on its own doesn't generate key messages.
</p></li><li><p>
<code class="constant">B_MOUSE_DOWN</code>, <code class="constant">B_MOUSE_MOVED</code>,
and <code class="constant">B_MOUSE_UP</code> are delivered (as hook
functions) to the <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>
that the mouse is over at the time, regardless
of where it started. For example, if the user drags the mouse through
your view, you'll get a series of <code class="constant">B_MOUSE_MOVED</code> messages without
getting a <code class="constant">B_MOUSE_UP</code> or a <code class="constant">B_MOUSE_DOWN</code>. The
<a class="link" href="BView.html#BView_MouseMoved" title="MouseMoved()"><code class="methodname">BView::MouseMoved()</code></a>
function has a code that tells you whether the mouse is just entering,
inside, or exiting your view. You can tell your
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> to track the
mouse even when it's outside your view through
<a class="link" href="BView.html#BView_SetMouseEventMask"><code class="methodname">BView::SetMouseEventMask()</code></a>.
</p></li><li><p>
A <code class="constant">B_VALUE_CHANGED</code> message reports that the Application Server changed
a value associated with a <a class="link" href="BScrollBar.html" title="BScrollBar"><code class="classname">BScrollBar</code></a> objects.
</p></li><li><p>
<code class="constant">B_WORKSPACE_ACTIVATED</code> reports that the active workspace (the one
displayed on-screen) has changed. The message is only sent to windows
that live in one of the affected workspaces.
</p></li><li><p>
<code class="constant">B_WORKSPACES_CHANGED</code> notifies the window that the set of workspaces
in which it can be displayed has changed.
</p></li><li><p>
A <a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a> reinterprets a
<a class="link" href="TheApplicationKit_MessageConstants.html#B_QUIT_REQUESTED" title="B_QUIT_REQUESTED"><code class="constant">B_QUIT_REQUESTED</code></a>
message, originally defined
for the <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>
class in the Application Kit, to mean a user request to
close the window. However, it doesn't redeclare the
<a class="link" href="BLooper.html#BLooper_QuitRequested" title="QuitRequested()"><code class="methodname">QuitRequested()</code></a>
hook function that it inherits from <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>.
</p></li></ul><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Tracking_The_Keyboard"></a>Tracking the Keyboard</h4></div></div></div><p>
The view that's responsible for handling keyboard events is called as the
focus view. The focus view is the view within the active window that's
displaying the current selection, or the control that's marked to show
that it can be operated from the keyboard. Only one view in the window
can be in focus at a time.
</p><p>
You promote a view to focus by calling
<a class="link" href="BView.html#BView_MakeFocus" title="MakeFocus()"><code class="methodname">BView::MakeFocus()</code></a>, and you ask
for the current focus through
<a class="link" href="BWindow.html#BWindow_CurrentFocus" title="CurrentFocus()"><code class="methodname">BWindow::CurrentFocus()</code></a>.
</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Focus_View_Commands"></a>Focus View Commands</h4></div></div></div><p>
The table below maps a keyboard action to the hook function it invokes or
the message it sends. In each of these cases, the function or message is
sent to the current focus view (which may change between a key down and a
key up)
</p><div class="informaltable"><table border="1"><colgroup><col /><col /></colgroup><thead><tr><th>User action</th><th>Function or message</th></tr></thead><tbody><tr><td>Press a character key</td><td><a class="link" href="BView.html#BView_KeyDown" title="KeyDown()"><code class="methodname">BView::KeyDown()</code></a></td></tr><tr><td>Release a character key</td><td><a class="link" href="BView.html#BView_KeyUp" title="KeyUp()"><code class="methodname">BView::KeyUp()</code></a></td></tr><tr><td><span class="keycap">Command</span>+<span class="keycap">a</span></td><td><code class="constant">B_SELECT_ALL</code></td></tr><tr><td><span class="keycap">Command</span>+<span class="keycap">x</span></td><td><code class="constant">B_CUT</code></td></tr><tr><td><span class="keycap">Command</span>+<span class="keycap">c</span></td><td><code class="constant">B_COPY</code></td></tr><tr><td><span class="keycap">Command</span>+<span class="keycap">v</span></td><td><code class="constant">B_PASTE</code></td></tr></tbody></table></div><p>
The focus view needn't respond to all of these functions and commands,
but a <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>
that doesn't respond to any of them should never promote itself to focus.
</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Other_Keyboard_Commands"></a>Other Keyboard Commands</h4></div></div></div><p>
There are four other built-in keyboard commands:
</p><div class="informaltable"><table border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>User action</th><th>Message or Action</th><th>Target</th></tr></thead><tbody><tr><td><span class="keycap">Command</span>+<span class="keycap">w</span></td><td><a class="link" href="TheApplicationKit_MessageConstants.html#B_QUIT_REQUESTED" title="B_QUIT_REQUESTED"><code class="constant">B_QUIT_REQUESTED</code></a></td><td>The active window.</td></tr><tr><td><span class="keycap">Command</span>+<span class="keycap">q</span></td><td><a class="link" href="TheApplicationKit_MessageConstants.html#B_QUIT_REQUESTED" title="B_QUIT_REQUESTED"><code class="constant">B_QUIT_REQUESTED</code></a></td><td>The active app.</td></tr><tr><td><span class="keycap">Option</span>+<span class="keycap">Tab</span></td><td>Changes focus to the next navigable view.</td><td>The active window.</td></tr><tr><td><span class="keycap">Enter</span></td><td>Activates the default button.</td><td>The active window.</td></tr></tbody></table></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Kinds_Of_Keyboard_Messages"></a>Kinds of Keyboard Messages</h4></div></div></div><p>
<code class="constant">B_KEY_UP</code> events are always assigned to the view that's in focus when the
user releases the key—even if the previous <code class="constant">B_KEY_DOWN</code> message
performed a shortcut, forced keyboard navigation, or was assigned to the
default button.
</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Message_Protocols"></a>Message Protocols</h4></div></div></div><p>
The event messages that the Application Server sends to a
<a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a> usually
have more information in them than is passed to the corresponding hook
function. For example, while a <code class="constant">B_MOUSE_DOWN</code> message knows where, when,
and which mouse button was pressed (among other things), only the "where"
information is passed to the
<a class="link" href="BView.html#BView_MouseDown" title="MouseDown()"><code class="methodname">MouseDown()</code></a> function.
</p><p>
You can retrieve the message that initiated a hook function from within
the hook function itself by calling
<a class="link" href="BLooper.html#BLooper_CurrentMessage" title="CurrentMessage(), DetachCurrentMessage()"><code class="methodname">BLooper::CurrentMessage()</code></a> function:
</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyView</code>::<code class="methodname">MouseDown</code>(<code class="classname">BPoint</code> <code class="parameter">where</code>)
{
<span class="type">BMessage *</span><code class="varname">msg</code> = <code class="methodname">Window</code>()-&gt;<code class="methodname">CurrentMessage</code>();
...</pre></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_The_User_Interface"></a>The User Interface</h3></div></div></div><p>
The Interface Kit provides interface mechanisms that your classes can
participate in, if they coordinate with kit-defined code. Two such
mechanisms are described below—keyboard navigation and the
drag-and-drop delivery of messages.
</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_KeyboardNavigation"></a>Keyboard Navigation</h4></div></div></div><p>
Keyboard navigation is a mechanism for allowing users to manipulate
views—especially buttons, check boxes, and other control
devices—from the keyboard. It gives users the ability to:
</p><ul class="itemizedlist"><li><p>
Move the focus of keyboard actions from view to view within a window
by pressing the <span class="keycap">Tab</span> key.
</p></li><li><p>
Operate the view that's currently in focus by pressing <span class="keycap">spacebar</span> and
<span class="keycap">Enter</span> (to invoke it) or the arrow keys (to move around inside it).
</p></li></ul><p>
The first ability—navigation between views—is implemented by
the Interface Kit. The second—navigation within a view—is up
to individual applications (although the
<a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a> class helps a little),
as are most view-specific aspects of the user interface. The only trick,
and it's not a difficult one, is to make the two kinds of navigation work
together.
</p><p>
To participate in the navigation mechanism, a class derived from
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>
needs to coordinate three aspects of its code—setting navigation
flags, drawing an indication that the
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> is in focus, and responding
to keyboard events. The following sections discuss each of these elements.
</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Setting_Navigation_Flags"></a>Setting Navigation Flags</h4></div></div></div><p>
The <code class="constant">B_NAVIGABLE</code> flag marks a
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>
as an eligible target for keyboard navigation. It's one flag in a mask that the
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> constructor sets,
along with other view attributes. For example:
</p><pre class="programlisting example cpp"><code class="classname">MyView</code>::<code class="methodname">MyView</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">const char *</span><code class="parameter">name</code>,
<span class="type">uint32</span> <code class="parameter">resizingMode</code>, <span class="type">uint32</span> <code class="parameter">flags</code>)
: <code class="classname">BView</code>(<code class="parameter">frame</code>, <code class="parameter">name</code>, <code class="parameter">resizingMode</code>, <code class="parameter">flags</code>|<code class="constant">B_NAVIGIBLE</code>|<code class="constant">B_WILL_DRAW</code>)
{
. . .
}</pre><p>
When the user presses the <span class="keycap">Tab</span> key, the focus moves from one <code class="constant">B_NAVIGIBLE</code>
target to the next, working first down and then across the view
hierarchy. That is, if a <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>
has both <code class="constant">B_NAVIGIBLE</code> children and
<code class="constant">B_NAVIGIBLE</code> siblings, the children will be targeted before the siblings.
</p><p>
The flag should be removed from the mask when the view is disabled or
cannot become the focus view for any reason, and included again when it's
re-enabled. The mask can be altered with the
<a class="link" href="BView.html#BView_SetFlags" title="SetFlags() , Flags()"><code class="methodname">SetFlags()</code></a> function:
</p><pre class="programlisting example cpp">if ( <span class="comment">/* cannot become the focus view */</span> )
<code class="methodname">SetFlags</code>(<code class="methodname">Flags()</code> &amp; ~<code class="constant">B_NAVIGIBLE</code>);
else
<code class="methodname">SetFlags</code>(<code class="methodname">Flags()</code> | <code class="constant">B_NAVIGIBLE</code>);</pre><p>
Most navigible <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>s
are control devices and derive from the <a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a>
class. All <a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a>
are navigible by default and <a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a> has a
<a class="link" href="BControl.html#BControl_SetEnabled" title="SetEnabled(), IsEnabled()"><code class="methodname">SetEnabled()</code></a>
function that turns the <code class="constant">B_NAVIGIBLE</code> flag on and off, so this
work is already done for objects that inherit from
<a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a>.
</p><p>
You may also want to set a view's <code class="constant">B_NAVIGIBLE_JUMP</code> flag to permit larger
jumps between navigible views.
<span class="keycap">Control</span>+<span class="keycap">Tab</span> moves the focus from one group
of views to another, where the groups are (hopefully) obvious to the user
from their arrangement in the window.
</p><p>
<code class="constant">B_NAVIGIBLE_JUMP</code> marks positions in the view hierarchy for these larger
jumps. When the user presses
<span class="keycap">Control</span>+<span class="keycap">Tab</span>, focus jumps to the next
<code class="constant">B_NAVIGIBLE_JUMP</code> view. If a <code class="constant">B_NAVIGABLE_JUMP</code>
view isn't also <code class="constant">B_NAVIGABLE</code>,
focus moves to the next available <code class="constant">B_NAVIGABLE</code> view. For example, if a
<code class="constant">B_NAVIGABLE_JUMP</code> parent view is not navigible itself but has navigible
children, <span class="keycap">Control</span>+<span class="keycap">Tab</span>
focusses on the first <code class="constant">B_NAVIGABLE</code> child.
</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Drawing_The_Focus_Indicator"></a>Drawing the Focus Indicator</h4></div></div></div><p>
When the user navigates to a view, the
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> needs to draw some sort of
visual indication that it's the current focus for keyboard actions.
Be-defined views underline text (for example, a button label) when the
view is in focus, or draw a rectangular outline of the view. The
underline and outline are drawn in the color returned by
<a class="link" href="TheInterfaceKit_Functions.html#keyboard_navigation_color" title="keyboard_navigation_color()"><code class="function">keyboard_navigation_color()</code></a>.
Using this color lends consistency to the user interface.
</p><p>
A <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> learns that the focus has
changed when its <a class="link" href="BView.html#BView_MakeFocus" title="MakeFocus()"><code class="methodname">MakeFocus()</code></a>
hook function is called. It's up to
<a class="link" href="BView.html#BView_MakeFocus" title="MakeFocus()"><code class="methodname">MakeFocus()</code></a>
to ensure that the focus indicator is drawn or erased, depending on the
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>'s
new status. It's usually simplest for
<a class="link" href="BView.html#BView_MakeFocus" title="MakeFocus()"><code class="methodname">MakeFocus()</code></a> to call
<a class="link" href="BView.html#BView_Draw" title="Draw()"><code class="methodname">Draw()</code></a> and have it do the work.
For example:
</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyView</code>::<code class="methodname">MakeFocus</code>(<span class="type">bool</span> <code class="parameter">focused</code>)
{
if ( <code class="parameter">focused</code> != <code class="methodname">IsFocus</code>() ) {
<code class="classname">baseClass</code>::<code class="methodname">MakeFocus</code>(<code class="parameter">focused</code>);
<code class="methodname">Draw</code>(<code class="methodname">Bounds</code>());
<code class="methodname">Flush</code>();
. . .
}
}</pre><p>
The <a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a> class has a
<a class="link" href="BControl.html#BControl_MakeFocus" title="MakeFocus()"><code class="methodname">MakeFocus()</code></a>
function that calls
<a class="link" href="BView.html#BView_Draw" title="Draw()"><code class="methodname">Draw()</code></a>,
so if your class derives from
<a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a>,
all you need to do is implement
<a class="link" href="BView.html#BView_Draw" title="Draw()"><code class="methodname">Draw()</code></a>.
<a class="link" href="BView.html#BView_Draw" title="Draw()"><code class="methodname">Draw()</code></a>
can call
<a class="link" href="BView.html#BView_IsFocus" title="IsFocus()"><code class="methodname">IsFocus()</code></a> to test the
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>'s
current status. Here's a rough example:
</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyView</code>::<code class="methodname">Draw</code>(<code class="classname">BRect</code> <code class="parameter">updateRect</code>)
{
<span class="type">rgb_color</span> <code class="varname">navigationColor</code> = <code class="function">keyboard_navigation_color</code>();
<code class="classname">BRect</code> <code class="varname">r</code> = <code class="methodname">Bounds</code>()
<code class="parameter">r</code>.<code class="methodname">InsetBy</code>(2.0, 2.0)
. . .
<span class="type">rgb_color</span> <code class="varname">c</code> = <code class="methodname">HighColor</code>();
if ( <code class="methodname">IsFocus</code>() ) {
<span class="comment">/* draw the indicator */</span>
<code class="methodname">SetHighColor</code>(<code class="varname">navigationColor</code>);
<code class="methodname">StrokeRect</code>(<code class="varname">r</code>);
<code class="methodname">SetHighColor</code>(<code class="varname">c</code>);
}
else {
<span class="comment">/* erase the indicator */</span>
<code class="methodname">SetHighColor</code>(<code class="methodname">ViewColor</code>());
<code class="methodname">StrokeRect</code>(<code class="varname">r</code>);
<code class="methodname">SetHighColor</code>(<code class="varname">c</code>);
}
. . .
}</pre></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Handling_Keyboard_Actions"></a>Handling Keyboard Actions</h4></div></div></div><p>
Finally, your <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> may need to override
<a class="link" href="BView.html#BView_KeyDown" title="KeyDown()"><code class="methodname">KeyDown()</code></a> to handle the
keystrokes that are used to operate the view (for view-internal
navigation). Always incorporate the inherited version of
<a class="link" href="BView.html#BView_KeyDown" title="KeyDown()"><code class="methodname">KeyDown()</code></a> so
that it can take care of navigation between views. For example:
</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyView</code>::<code class="methodname">KeyDown</code>(<span class="type">const char *</span><code class="parameter">bytes</code>, <span class="type">int32</span> <code class="parameter">numBytes</code>)
{
switch ( <code class="parameter">bytes</code>[0] ) {
case <code class="constant">B_ENTER</code>:
case <code class="constant">B_SPACE</code>:
<span class="comment">/* take action */</span>
break;
case <code class="constant">B_UP_ARROW</code>:
case <code class="constant">B_DOWN_ARROW</code>:
case <code class="constant">B_RIGHT_ARROW</code>:
case <code class="constant">B_LEFT_ARROW</code>:
<span class="comment">/* move within the view */</span>
break;
default:
<span class="emphasis"><em><code class="classname">baseClass</code></em></span>::<code class="methodname">KeyDown</code>(<code class="parameter">bytes</code>, <code class="parameter">numBytes</code>);
break;
}
}</pre><p>
Again, the <a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a> class implements a
<a class="link" href="BControl.html#BControl_KeyDown" title="KeyDown()"><code class="methodname">KeyDown()</code></a> function that invokes
the control device when the user presses the space bar or <span class="keycap">Enter</span> key. If
your class derives from <a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a>
and it doesn't have to do any other view-internal navigation, the
<a class="link" href="BControl.html" title="BControl"><code class="classname">BControl</code></a>
function may be adequate for your needs.
</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheInterfaceKit_Listening_Drag_And_Drop"></a>Drag and Drop</h4></div></div></div><p>
The <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>
class supports a drag-and-drop user interface. The user can
transfer a parcel of information from one place to another by dragging an
image from a source view and dropping it on a destination
view—perhaps a view in a different window in a different
application.
</p><p>
A source <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> initiates dragging
by calling <a class="link" href="BView.html#BView_DragMessage" title="DragMessage()"><code class="methodname">DragMessage()</code></a>
from within its
<a class="link" href="BView.html#BView_MouseDown" title="MouseDown()"><code class="methodname">MouseDown()</code></a>
function. The <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> bundles all information relevant to
the dragging session into a <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> object and passes it to
<a class="link" href="BView.html#BView_DragMessage" title="DragMessage()"><code class="methodname">DragMessage()</code></a>.
It also passes an image or a rectangle to represent the
data package on-screen. For example:
</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyView</code>::<code class="methodname">MouseDown</code>(<code class="classname">BPoint</code> <code class="parameter">point</code>)
{
. . .
if ( <code class="varname">aRect</code>.<code class="methodname">Contains</code>(<code class="parameter">point</code>) ) {
<code class="classname">BMessage</code> <code class="varname">message</code>(<code class="constant">SOME_WORDS_OF_ENCOURAGEMENT</code>);
<code class="varname">message</code>.<code class="methodname">AddString</code>("words", <code class="varname">theEncouragingWords</code>);
<code class="methodname">DragMessage</code>(&amp;<code class="varname">message</code>, <code class="varname">aRect</code>);
}
. . .
}</pre><p>
The Application Server then takes charge of the
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> object and
animates the image as the user drags it on-screen. As the image moves
across the screen, the views it passes over are informed with
<a class="link" href="BView.html#BView_MouseMoved" title="MouseMoved()"><code class="methodname">MouseMoved()</code></a>
function calls. These notifications give views a chance to
show the user whether or not they're willing to accept the message being
dragged. When the user releases the mouse button, dropping the dragged
message, the message is delivered to the
<a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a> and targeted to the
destination
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>.
</p><p>
A <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>
is notified that a message has arrived by a
<a class="link" href="BView.html#BView_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
function call. This is the same function that announces the arrival of
other messages. By calling
<a class="link" href="BMessage.html#BMessage_WasDropped" title="WasDropped(), DropPoint()"><code class="methodname">WasDropped()</code></a>, you can ask the message whether
it was dropped on the view or delivered in some other way. If it was
dropped, you can find out where by calling
<a class="link" href="BMessage.html#BMessage_DropPoint"><code class="methodname">DropPoint()</code></a>. For example:
</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">AnotherView</code>::<code class="methodname">MessageReceived</code>(<span class="type">BMessage *</span><code class="parameter">message</code>)
{
switch ( <code class="varname">message</code>-&gt;<code class="varname">what</code> ) {
. . .
case <code class="constant">SOME_WORDS_OF_ENCOURAGEMENT</code>:
{
<span class="type">char *</span><code class="varname">words</code>;
if ( <code class="varname">message</code>-&gt;<code class="methodname">FindString</code>("words", &amp;words) != <code class="constant">B_OK</code> )
return;
if ( <code class="varname">message</code>-&gt;<code class="methodname">WasDropped</code>() ) {
<code class="classname">BPoint</code> <code class="varname">where</code> = <code class="methodname">DropPoint</code>();
<code class="methodname">ConvertFromScreen</code>(&amp;<code class="varname">where</code>);
<code class="methodname">PleaseInsertTheseWords</code>(<code class="varname">words</code>, <code class="varname">where</code>);
}
break;
}
. . .
default:
<span class="emphasis"><em><code class="classname">baseClass</code></em></span>::<code class="methodname">MessageReceived</code>(<code class="parameter">message</code>);
}
}</pre><p>
Aside from creating a <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
object and passing it to
<a class="link" href="BView.html#BView_DragMessage" title="DragMessage()"><code class="methodname">DragMessage()</code></a>,
or implementing
<a class="link" href="BView.html#BView_MouseMoved" title="MouseMoved()"><code class="methodname">MouseMoved()</code></a> and
<a class="link" href="BView.html#BView_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a> functions to handle any
messages that come its way, there's nothing an application needs to do to
support a drag-and-drop user interface. The bulk of the work is done by
the Application Server and Interface Kit.
</p></div></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="TheInterfaceKit_Drawing.html">Drawing</a>  Up: <a href="TheInterfaceKit_Overview.html">The Interface Kit</a>  Next: <a href="TheInterfaceKit_The_Coordinate_Space.html">The Coordinate Space</a> </div><div id="footerB"><div id="footerBL"><a href="TheInterfaceKit_Drawing.html" title="Drawing"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="TheInterfaceKit_Overview.html" title="The Interface Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="TheInterfaceKit_The_Coordinate_Space.html" title="The Coordinate Space"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="footerBR"><div><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div></div><div id="footerBC"><a href="http://www.access-company.com/home.html" title="ACCESS Co."><img alt="Access Company" src="./images/access_logo.png" /></a></div></div></div><div id="licenseFooter"><div id="licenseFooterBL"><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/" title="Creative Commons License"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by-nc-nd/3.0/88x31.png" /></a></div><div id="licenseFooterBR"><a href="./LegalNotice.html">Legal Notice</a></div><div id="licenseFooterBC"><span id="licenseText">This work is licensed under a
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative
Commons Attribution-Non commercial-No Derivative Works 3.0 License</a>.</span></div></div></body></html>