394 lines
44 KiB
HTML
394 lines
44 KiB
HTML
<?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>()-><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> & ~<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>(&<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>-><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>-><code class="methodname">FindString</code>("words", &words) != <code class="constant">B_OK</code> )
|
||
return;
|
||
if ( <code class="varname">message</code>-><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>(&<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>
|