594 lines
44 KiB
HTML
594 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>Be Newsletters - Volume 3: 1998</title><link rel="stylesheet" href="be_newsletter.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_newsletter_ie.css" />
|
||
<![endif]--><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="Be Newsletters" /><link rel="up" href="volume3.html" title="Volume 3: 1998" /><link rel="prev" href="Issue3-8.html" title="Issue 3-8, February 25, 1998" /><link rel="next" href="Issue3-10.html" title="Issue 3-10, March 11, 1998" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="Issue3-8.html" title="Issue 3-8, February 25, 1998"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="volume3.html" title="Volume 3: 1998"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="Issue3-10.html" title="Issue 3-10, March 11, 1998"><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="naviglang" title="English">en</div></div><div id="headerTC">Be Newsletters - Volume 3: 1998</div></div><div id="headerB">Prev: <a href="Issue3-8.html">Issue 3-8, February 25, 1998</a> Up: <a href="volume3.html">Volume 3: 1998</a> Next: <a href="Issue3-10.html">Issue 3-10, March 11, 1998</a></div><hr /></div><div class="article"><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="Issue3-9"></a>Issue 3-9, March 4, 1998</h2></div></div></div><div class="sect1"><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="Engineering3-9"></a>Be Engineering Insights: Fun with Tabs and Sliders</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Robert</span> <span class="surname">Chinn</span></span></div></div></div><p>
|
||
When you receive Release 3 of the BeOS, among other grander and more
|
||
important advances, you'll find that the Interface Kit now contains two
|
||
more classes, <code class="classname">BTabView</code> and
|
||
<code class="classname">BSlider</code>. Since they're new I'd like to
|
||
introduce them and discuss how to use them.
|
||
</p><p>
|
||
A tabview is a simple container object that allows you to separate and
|
||
present information in a clean, easily accessed fashion. Instead of using
|
||
a pop-up menu to toggle between pages of information, you can use a
|
||
tabview to provide an interface that presents topics and focused
|
||
information to the user.
|
||
</p><p>
|
||
<code class="classname">BTabView</code> is a simple and pretty much self-contained class that doesn't
|
||
require a lot of maintenance once it has been constructed. In its most
|
||
basic form there are only two things you need to do to use a <code class="classname">BTabView</code>:
|
||
construct it and add views to it.
|
||
</p><pre class="programlisting cpp">
|
||
<span class="type"><code class="classname">BTabView</code>*</span> <code class="varname">tab_container</code> = new <code class="classname">BTabView</code>( <code class="classname">BRect</code>(0,0,320,240),
|
||
"tab container",
|
||
<code class="constant">B_WIDTH_AS_USUAL</code>,
|
||
<code class="constant">B_FOLLOW_LEFT</code> | <code class="constant">B_FOLLOW_RIGHT</code>,
|
||
<code class="constant">B_WILL_DRAW</code> | <code class="constant">B_NAVIGABLE</code>);
|
||
</pre><p>
|
||
This constructs an empty tab container and shows no tabs. As with most
|
||
other simple <code class="classname">BView</code> derivatives, you pass in the
|
||
<code class="parameter">frame</code>, <code class="parameter">name</code>,
|
||
<code class="parameter">resizing_mode</code>, and view <code class="parameter">flags</code>.
|
||
The only other item in the constructor for a
|
||
tabview is the <code class="parameter">button_width</code> parameter, which configures the width of each
|
||
tab that the tabview presents. This parameter has three options, which
|
||
are identical to those used in a <code class="classname">BAlert</code>:
|
||
</p><pre class="screen">
|
||
<code class="constant">B_WIDTH_AS_USUAL</code> —sets the tab width to the
|
||
default of 100
|
||
<code class="constant">B_WIDTH_FROM_WIDEST</code>—bases all tab widths on the
|
||
longest tab name
|
||
<code class="constant">B_WIDTH_FROM_LABEL</code> —bases each tab width on
|
||
its related name
|
||
</pre><p>
|
||
To add a tab to the tabview you need to call the following:
|
||
</p><pre class="programlisting cpp">
|
||
<code class="varname">tab_container</code>-><code class="methodname">AddTab</code>(<code class="varname">tab_view_1</code>, <code class="constant">NULL</code>);
|
||
</pre><p>
|
||
where <code class="varname">tab_view_1</code> is a <code class="classname">BView</code> that contains the rest of the objects you
|
||
want to present in this "page." The name of the tab associated with the
|
||
page is the name of the view that you add in the <code class="methodname">AddTab()</code> call. Also, the
|
||
location of the view to be added, if set to 0,0, will be the left edge of
|
||
the tab, just below and inside the box drawn by the tabview.
|
||
</p><p>
|
||
The optional parameter to the <code class="methodname">AddTab()</code>
|
||
method, in this case <code class="constant">NULL</code>, is a <code class="classname">BTab</code>
|
||
pointer. The <code class="classname">BTab</code> class is a simple non-view class that simply draws to a
|
||
target view. Using this parameter you can override the default <code class="classname">BTab</code>
|
||
object and perform custom drawing for each individual tab.
|
||
</p><p>
|
||
As you make successive calls to <code class="methodname">AddTab()</code>,
|
||
</p><pre class="programlisting cpp">
|
||
<code class="varname">tab_container</code>-><code class="methodname">AddTab</code>( <code class="varname">tab_view_2</code> );
|
||
<code class="varname">tab_container</code>-><code class="methodname">AddTab</code>( <code class="varname">tab_view_3</code> );
|
||
<code class="varname">tab_container</code>-><code class="methodname">AddTab</code>( <code class="varname">tab_view_4</code> );
|
||
</pre><p>
|
||
more tabs are added to the tabview. When the user clicks on any of these
|
||
tabs, the view it is associated with is added to the tabview via
|
||
<code class="methodname">AddChild()</code>, and made visible, while the previous visible view is hidden as
|
||
a result of <code class="methodname">RemoveChild()</code>. That's all it takes to make a tabview functional
|
||
in an application.
|
||
</p><p>
|
||
The second class I'd like to introduce is <code class="classname">BSlider</code>.
|
||
Like <code class="classname">BTabView</code>, this is
|
||
also a simple class, based on <code class="classname">BControl</code>, that presents itself as a slider
|
||
control. As with any other <code class="classname">BControl</code>-based objects the construction is
|
||
quite simple:
|
||
</p><pre class="programlisting cpp">
|
||
<span class="type"><code class="classname">BSlider</code>*</span> <code class="varname">slider</code> = new <code class="classname">BSlider</code> ( <code class="classname">BRect</code> (0,0,100,10),
|
||
"slider",
|
||
"Some value:",
|
||
new <code class="classname">BMessage</code>('slde'),
|
||
0, 255,
|
||
<code class="constant">B_BLOCK_THUMB</code>);
|
||
</pre><p>
|
||
The first four parameters are the standard <code class="classname">BControl</code> parameters:
|
||
<code class="parameter">frame</code>,
|
||
<code class="parameter">name</code>, <code class="parameter">label</code>, and <code class="parameter">message</code>.
|
||
The message is sent when you move the slider
|
||
and release it. The fifth and sixth parameters are the <code class="parameter">minimum</code> and
|
||
<code class="parameter">maximum</code> values for the slider. The last parameter is the thumb style,
|
||
which can be set to one of two built-in thumbs, a rectangle (as used in
|
||
the Keyboard preferences) or a triangle (as used in the Fonts
|
||
preferences).
|
||
</p><p>
|
||
If you take a look at the <span class="application">VirtualMemory</span> preferences application you'll
|
||
notice that the bar color to the left of the thumb is different from the
|
||
color to the right. To accomplish this, simply do the following:
|
||
</p><pre class="programlisting cpp">
|
||
<span class="type">rgb_color</span> <code class="varname">color</code>;
|
||
<code class="varname">color</code>.<code class="varname">red</code> = <code class="varname">color</code>.<code class="varname">green</code> = 102;
|
||
<code class="varname">color</code>.<code class="varname">blue</code> = 152;
|
||
<code class="varname">color</code>.<code class="varname">alpha</code> = 255;
|
||
<code class="varname">slider</code>-><code class="methodname">UseFillColor</code>(<code class="constant">true</code>, &<code class="varname">color</code>);
|
||
</pre><p>
|
||
The callback method <code class="methodname">UpdateText()</code> provides live updating of information. In
|
||
this method you can call <code class="methodname">Value()</code> or
|
||
<code class="methodname">Position()</code> to obtain information relating
|
||
to the slider and return a string of text to present to the user; in its
|
||
default state it simply returns <code class="constant">NULL</code>.
|
||
</p><pre class="programlisting cpp">
|
||
<span class="type">char*</span>
|
||
<code class="classname">DemoSlider</code>::<code class="varname">UpdateText</code>()
|
||
{
|
||
<span class="type">char</span> <code class="varname">msg</code>[32];
|
||
|
||
<code class="function">sprintf</code>(<code class="varname">msg</code>, "The current value is: %i.", <code class="methodname">Value</code>());
|
||
return <code class="varname">msg</code>;
|
||
}
|
||
</pre><p>
|
||
The slider can have as many as four different labels or none. The
|
||
standard <code class="classname">BControl</code> label is drawn at the top
|
||
left; set via <code class="methodname">SetLimitLabels()</code>
|
||
(the minimum and maximum labels) in the bottom left and right; and the
|
||
string returned from <code class="methodname">UpdateText()</code> in the top right. If any of these labels
|
||
is set to <code class="constant">NULL</code>, it will not be drawn.
|
||
</p><p>
|
||
To recap, here is a bit of code that builds two sliders in a two-tab
|
||
tabview. The second slider is a custom slider to demonstrate use of the
|
||
<code class="methodname">UpdateText()</code> callback.
|
||
</p><pre class="programlisting cpp">
|
||
class <code class="classname">DemoSlider</code> : public <code class="classname">BSlider</code> {
|
||
public:
|
||
<code class="methodname">DemoSlider</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">char *</span><code class="parameter">label</code>, <span class="type"><code class="classname">BMessage</code> *</span><code class="parameter">msg</code>,
|
||
<span class="type">int32</span> <code class="parameter">min</code>, <span class="type">int32</span> <code class="parameter">max</code>, <span class="type">thumb_style</span> <code class="parameter">t</code>);
|
||
<code class="methodname">~DemoSlider</code>();
|
||
|
||
<span class="type">char*</span> <code class="methodname">UpdateText</code>() const;
|
||
|
||
private:
|
||
<span class="type">char*</span> <code class="varname">fStatus</code>;
|
||
};
|
||
|
||
<code class="classname">DemoSlider</code>::<code class="methodname">DemoSlider</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">char *</span><code class="parameter">label</code>,
|
||
<span class="type"><code class="classname">BMessage</code> *</span><code class="parameter">msg</code>, <span class="type">int32</span> <code class="parameter">min</code>, <span class="type">int32</span> <code class="parameter">max</code>, <span class="type">thumb_style</span> <code class="parameter">t</code>)
|
||
: <code class="classname">BSlider</code>(frame,"demo slider",label,msg, min, max, t)
|
||
{
|
||
<span class="comment">// allocate some space for the string to be returned in</span>
|
||
<span class="comment">// UpdateText. use malloc so that Pavel will yell at me</span>
|
||
<code class="varname">fStatus</code> = (<span class="type">char*</span>)<code class="function">malloc</code>(64);
|
||
}
|
||
|
||
<code class="classname">DemoSlider</code>::<code class="methodname">~DemoSlider</code>()
|
||
{
|
||
if (<code class="varname">fStatus</code>)
|
||
<code class="function">free</code>(<code class="varname">fStatus</code>);
|
||
}
|
||
|
||
<span class="comment">// When the slider's Draw method is called, this method</span>
|
||
<span class="comment">// will also be called. If its return value is non-NULL,</span>
|
||
<span class="comment">// then it will be drawn with the rest of the slider</span>
|
||
<span class="type">char*</span>
|
||
<code class="classname">DemoSlider</code>::<code class="methodname">UpdateText</code>() const
|
||
{
|
||
if (<code class="varname">fStatus</code> && <code class="methodname">Window</code>()-><code class="methodname">Lock</code>()) {
|
||
<code class="function">sprintf</code>(<code class="varname">fStatus</code>,"Current value is %i",<code class="methodname">Value</code>());
|
||
<code class="methodname">Window</code>()-><code class="methodname">Unlock</code>();
|
||
return <code class="varname">fStatus</code>;
|
||
} else
|
||
return <code class="constant">NULL</code>;
|
||
}
|
||
|
||
static <span class="type">void</span>
|
||
<code class="function">DoMe</code>()
|
||
{
|
||
<span class="comment">// construct a simple window</span>
|
||
<span class="type"><code class="classname">BWindow</code>*</span> <code class="varname">a_window</code> = new <code class="classname">BWindow</code>(<code class="classname">BRect</code>(25, 25, 345, 165),
|
||
"New Control Demo",
|
||
<code class="constant">B_TITLED_WINDOW</code>,
|
||
<code class="constant">B_NOT_ZOOMABLE</code> | <code class="constant">B_NOT_RESIZABLE</code>);
|
||
|
||
<span class="comment">// construct a tabview</span>
|
||
<span class="comment">// make the tab width based on the widest label</span>
|
||
<span class="type"><code class="classname">BTabView</code>*</span> <code class="varname">tab_container</code> = new <code class="classname">BTabView</code>(
|
||
<code class="classname">BRect</code>(0, 0, 320, 140), "tab container",
|
||
<code class="constant">B_WIDTH_FROM_WIDEST</code>);
|
||
<code class="varname">a_window</code>-><code class="methodname">AddChild</code>(<code class="varname">tab_container</code>);
|
||
|
||
<span class="comment">// do a quick calculation to determine the height of the</span>
|
||
<span class="comment">// content region of the tabview</span>
|
||
<span class="type">float</span> <code class="varname">contents_height</code> =
|
||
<code class="varname">tab_container</code>-><code class="methodname">Bounds</code>().<code class="methodname">Height</code>() -
|
||
<code class="varname">tab_container</code>-><code class="methodname">TabHeight</code>();
|
||
<code class="classname">BRect</code> <code class="varname">contents_rect</code>(0, 0, <code class="varname">tab_container</code>-><code class="methodname">Bounds</code>().<code class="methodname">Width</code>(),
|
||
<code class="varname">contents_height</code>);
|
||
<code class="classname">BRect</code> <code class="varname">slider_rect</code>(<code class="varname">contents_rect</code>);
|
||
<code class="varname">slider_rect</code>.<code class="methodname">InsetBy</code>(25,25);
|
||
|
||
<span class="comment">// construct a view to hold the first control</span>
|
||
<span class="comment">// the name of the tab associated with this view</span>
|
||
<span class="comment">// will be the name of this view</span>
|
||
<span class="type"><code class="classname">BView</code>*</span> <code class="varname">bg_1</code> = new <code class="classname">BView</code>(<code class="varname">contents_rect</code>,
|
||
"Slider with Block Thumb", <code class="constant">B_FOLLOW_NONE</code>, <code class="constant">B_WILL_DRAW</code>);
|
||
|
||
<span class="comment">// set the view to this control so that is blends in</span>
|
||
<span class="comment">// with the tabview</span>
|
||
<span class="comment">// set the alpha component so Hiroshi won't yell at you</span>
|
||
<code class="varname">bg_1</code>-><code class="methodname">SetViewColor</code>(216,216,216,255);
|
||
|
||
<span class="comment">// construct a slider with a block thumb</span>
|
||
<span class="comment">// the message that it will send will have a 'what' of 'blok'</span>
|
||
<span class="comment">// the minimum setting will be 0, the maximum will be 300</span>
|
||
<span class="type"><code class="classname">BSlider</code>*</span> <code class="varname">block_thumb_slider</code> = new <code class="classname">BSlider</code>(<code class="varname">slider_rect</code>,
|
||
"block thumb", "Slider Label", new <code class="classname">BMessage</code>('blok'), 0,
|
||
300, <code class="constant">B_BLOCK_THUMB</code>);
|
||
|
||
<span class="comment">// if this slider has the focus (set by tabbing to it),</span>
|
||
<span class="comment">// the left and right arrows will move it by 10</span>
|
||
<code class="varname">block_thumb_slider</code>-><code class="methodname">SetKeyIncrementValue</code>(10);
|
||
|
||
<span class="comment">// add some labels</span>
|
||
<code class="varname">block_thumb_slider</code>-><code class="methodname">SetLimitLabels</code>("minimum", "maximum");
|
||
|
||
<span class="comment">// add some hash marks</span>
|
||
<code class="varname">block_thumb_slider</code>-><code class="methodname">SetHashMarkCount</code>(5);
|
||
<code class="varname">block_thumb_slider</code>-><code class="methodname">SetHashMarks</code>(<code class="constant">B_HASH_MARKS_BOTH</code>);
|
||
<code class="varname">bg_1</code>-><code class="methodname">AddChild</code>(<code class="varname">block_thumb_slider</code>);
|
||
|
||
<span class="comment">// make this view (and control) a tab of the tabview</span>
|
||
<code class="varname">tab_container</code>-><code class="methodname">AddTab</code>(<code class="varname">bg_1</code>);
|
||
|
||
<span class="comment">// construct a second view</span>
|
||
<span class="type"><code class="classname">BView</code>*</span> <code class="varname">bg_2</code> = new <code class="classname">BView</code>(<code class="varname">contents_rect</code>,
|
||
"Slider with Triangle Thumb", <code class="constant">B_FOLLOW_NONE</code>, <code class="constant">B_WILL_DRAW</code>);
|
||
<code class="varname">bg_2</code>-><code class="methodname">SetViewColor</code>(216,216,216,255);
|
||
|
||
<span class="comment">// construct a custom slider with a triangle thumb</span>
|
||
<span class="comment">// when this slider is drawn, the text returned</span>
|
||
<span class="comment">// from UpdateText will be drawn in the</span>
|
||
<span class="comment">// upper right corner of the slider</span>
|
||
<span class="type"><code class="classname">DemoSlider</code>*</span> <code class="varname">triangle_thumb_slider</code> =
|
||
new <code class="classname">DemoSlider</code>(<code class="varname">slider_rect</code>,"", new <code class="classname">BMessage</code>('tri '), 1, 7,
|
||
<code class="constant">B_TRIANGLE_THUMB</code>);
|
||
<code class="varname">triangle_thumb_slider</code>-><code class="methodname">SetKeyIncrementValue</code>(1);
|
||
<code class="varname">triangle_thumb_slider</code>-><code class="methodname">SetLimitLabels</code>("one", "seven");
|
||
<code class="varname">triangle_thumb_slider</code>-><code class="methodname">SetHashMarkCount</code>(7);
|
||
<code class="varname">triangle_thumb_slider</code>-><code class="methodname">SetHashMarks</code>(<code class="constant">B_HASH_MARKS_BOTTOM</code>);
|
||
|
||
<span class="comment">// set the fill for left of thumb color</span>
|
||
<span class="type">rgb_color</span> <code class="varname">c</code>;
|
||
<code class="varname">c</code>.<code class="varname">green</code> = 102;
|
||
<code class="varname">c</code>.<code class="varname">red</code> = 102;
|
||
<code class="varname">c</code>.<code class="varname">blue</code> = 152;
|
||
<code class="varname">triangle_thumb_slider</code>-><code class="methodname">UseFillColor</code>(<code class="constant">true</code>,&<code class="varname">c</code>);
|
||
|
||
<code class="varname">bg_2</code>-><code class="methodname">AddChild</code>(<code class="varname">triangle_thumb_slider</code>);
|
||
|
||
<code class="varname">tab_container</code>-><code class="methodname">AddTab</code>(<code class="varname">bg_2</code>);
|
||
|
||
<span class="comment">// the list of tabs is 0 based, make the first tab active</span>
|
||
<code class="varname">tab_container</code>-><code class="methodname">Select</code>(0);
|
||
|
||
<span class="comment">// make the window visible</span>
|
||
<code class="varname">a_window</code>-><code class="methodname">Show</code>();
|
||
}
|
||
</pre><p>
|
||
Both <code class="classname">BSlider</code> and <code class="classname">BTabView</code> are fairly simple. The goal was to make them
|
||
not difficult to use or overbearing and complex objects. I hope that both
|
||
of these objects suffice and that programmers find them useful. An
|
||
example of the use of <code class="classname">BTabView</code> can be found in the Fonts preferences
|
||
application. Examples of <code class="classname">BSlider</code> can be found in Keyboard, Mouse, and
|
||
many other preference applications.
|
||
</p></div><hr class="pagebreak" /><div class="sect1"><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="Marketing3-9"></a>Making Money</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Dave</span> <span class="surname">Johnson</span></span></div></div></div><p>
|
||
Good news: The BeOS is beginning to be noticed in the PC press.
|
||
</p><p>
|
||
More good news: Most of the "media" companies I talk to tell me they
|
||
realize that media applications will eventually HAVE TO be on the BeOS to
|
||
be competitive, and sooner rather than later.
|
||
</p><p>
|
||
Every day it looks more and more like the BeOS will emerge as the OS of
|
||
choice for media development. If you're writing a media application and
|
||
you're reading this Newsletter, you are in the right place.
|
||
</p><p>
|
||
You're also in the right place to make money writing software that is not
|
||
media-oriented. One good bet right now is developer tools: the BeOS for
|
||
Intel offers you a fresh shot at the same developers you're trying to
|
||
sell to right now. Another wide-open area to consider is utilities of all
|
||
kinds.
|
||
</p><p>
|
||
Here are some tips on making money selling software for the BeOS:
|
||
</p><p>
|
||
Be offers BeOS software developers a unique opportunity to reach their
|
||
potential market through our BeWare listings. The web orientation of our
|
||
CDs and downloadable OS make it a safe bet that most BeOS users will
|
||
visit the BeWare site. This immediate visibility to the user base of an
|
||
OS is a new concept that gives BeOS software developers a terrific—and
|
||
inexpensive—head start at reaching a market.
|
||
</p><p>
|
||
Need proof that this concept works? BeWare had 36,000 hits last week and
|
||
18,791 files were downloaded. Keep in mind that's for the Power Mac BeOS
|
||
only, with the Mac at 2.6% market share.
|
||
</p><p>
|
||
So get something up on BeWare! Make sure that your BeWare listings are up
|
||
to date, informative, benefit-oriented, and that they SELL your products.
|
||
If you're not up on BeWare yet, you're missing out.
|
||
</p><p>
|
||
There's another reason to get your product up on BeWare: publishers are
|
||
entering the BeOS market and they're looking for products and
|
||
programmers. What better way to reach them than via BeWare? Read my
|
||
article "How to Finish a Product,"
|
||
http://www.be.com/aboutbe/benewsletter/Issue98.html#Developer. Stop
|
||
adding features and ship what you have to BeWare! (You can always put the
|
||
rest in version 2.)
|
||
</p><p>
|
||
At your end of the sales process, do you have a web site ready? Your own
|
||
web site is your primary BeOS sales tool after BeWare! The BeWare site
|
||
will send many software-hungry customers your way, so you should have
|
||
your web site ready to accommodate them. Is the entry page of your web
|
||
site clear, informative, and sales oriented? Does your web site direct
|
||
the customer to product information? Do you have clear, benefit-oriented
|
||
descriptions of your products? Benefits, benefits, benefits—stress
|
||
benefits. Repeat your message, repeatedly.
|
||
</p><p>
|
||
Do you have order forms? Do you accept credit cards? Do you quickly send
|
||
the software to customers who order it? Do you sell through BeDepot? If
|
||
you do, get the customers interested in your product and send them where
|
||
they can place the order right now. Getting the order should be an
|
||
immediate part of the process. The excitement you generate for your
|
||
product will fade, so it's important to provide the ordering opportunity
|
||
immediately.
|
||
</p><p>
|
||
If you're not sales-oriented, take heart. This isn't a huckster approach
|
||
to ripping off the customer. Look at it as an opportunity to place your
|
||
fine product in the hands of more and more people.
|
||
</p><p>
|
||
Acquiring a sales orientation is difficult for many of us. I came by mine
|
||
the hard way in a past life running a software company. After years of
|
||
struggling, we tried actually selling something to customers using direct
|
||
mail, and learned that it works. It changed the culture of the company.
|
||
Gosh, offering products to customers in a sales-oriented way actually
|
||
works!
|
||
</p><p>
|
||
It's surprising how many smaller software companies don't understand
|
||
that. I know how hard it was for me, coming from primarily an engineering
|
||
background, to become sales-oriented. It seemed pushy, obnoxious, and
|
||
aggressive but it turned out that it works. (Now I'm pushy, obnoxious,
|
||
and aggressive, and I work...)
|
||
</p><p>
|
||
So before you get revolted at the thought of selling your product,
|
||
remember that those sales types wouldn't be doing what they do if it
|
||
didn't work. As much as you hate the thought, it might be a good idea to
|
||
infect your offices with one of those sales types—checkered sport
|
||
jacket, slick hair, suspenders, and all the rest—because if your
|
||
background is engineering, the world of sales may be another planet to
|
||
you, but it's very necessary to making money.
|
||
</p><p>
|
||
But wait, there's more! Accept this free gift as a token of my
|
||
appreciation for reading this article! Check out the web sites of
|
||
companies that are sales-oriented, and blatantly steal ideas from them.
|
||
Two that come to mind are Intuit
|
||
(<a class="ulink" href="http://www.intuit.com/">http://www.intuit.com/</a>) and Berkeley
|
||
Systems (http://www.berksys.com/).
|
||
</p><p>
|
||
Here's a very important tip: Make the press aware of your products. My
|
||
next article will discuss getting press for your products. The very best
|
||
way to get people interested in your software is by getting press
|
||
attention, so start thinking about it now and we'll compare notes.
|
||
Getting press for your BeOS products helps us get the Be ball rolling,
|
||
and that helps you, too.
|
||
</p></div><hr class="pagebreak" /><div class="sect1"><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="DevWorkshop3-9"></a>Developers' Workshop: Welcome to x86</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Doug</span> <span class="surname">Wright</span></span></div></div></div><p>
|
||
This week we'd like to present a laundry list of issues you should be
|
||
aware of when moving to the brave new world of x86 development.
|
||
</p><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id670014"></a>Endianness</h3></div></div></div><p>
|
||
Incompatibilities between the x86 and PowerPC releases stem primarily
|
||
from the opposing endianness of the processors. This topic has been
|
||
covered exhaustively in previous Newsletter articles. For specifics,
|
||
reread:
|
||
</p><p>
|
||
"<a class="link" href="">Swapping Bytes, Part III</a>"<br />
|
||
By Peter Potrebic - Issue 3-#8
|
||
</p><p>
|
||
"<a class="link" href="">YABSA—Yet Another Byte-swapping Article</a>"<br />
|
||
By Bradley Taylor - Issue 2-#45
|
||
</p><p>
|
||
"<a class="link" href="">Will Your DATA Look Like ATAD?</a>"<br />
|
||
By Bradley Taylor - Issue 2-#9
|
||
</p><p>
|
||
The new header <code class="filename">support/ByteOrder.h</code> contains a slew of handy-dandy
|
||
functions and macros to help you sex, resex, and neuter your data.
|
||
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id670079"></a>Filesystem and Resource File Incompatibility</h3></div></div></div><p>
|
||
Although we successfully eliminated many of the endian problems
|
||
encountered in porting the BeOS to x86, there are still a few that will
|
||
linger at least through Release 3.
|
||
</p><p>
|
||
The internal BFS structures are endian opposite on the different
|
||
platforms: big-endian on PowerPC and little-endian on x86. We currently
|
||
do not have any tools that allow a BeOS machine to read a disk in the
|
||
opposite endian format. This does not mean there is no way to transfer
|
||
information across platforms; ftp still works as advertised, and, when
|
||
combined with zip, will even correctly transfer the filesystem attributes.
|
||
</p><p>
|
||
The BFS endian issues have to do with BFS's internal structures for
|
||
storing data, not the data itself. If your data is endian-independent, it
|
||
will be usable on both platforms without changes. Otherwise, you may have
|
||
problems if you don't check the endianness of the data before using it.
|
||
</p><p>
|
||
The majority of the persistent data formats in the BeOS are endian-
|
||
independent; in particular, both filesystem attributes and flattened
|
||
<code class="classname">BMessage</code>s are endian-agnostic. The resource file format is a notable
|
||
exception to this rule. You cannot use PowerPC resource files while
|
||
building a x86 application (and vice versa)—you need new x86 resources.
|
||
</p><p>
|
||
Release 3 ships with several tools to help translate resources, but their
|
||
abilities are limited: They convert only a few resource types, and are
|
||
unable to translate many of the data types found in a resource file.
|
||
Custom resource formats, of course, need to be translated manually. In
|
||
most cases, it's easier to create separate PowerPC and Intel resource
|
||
files from scratch and use the appropriate one as needed.
|
||
</p><p>
|
||
We are working on solutions to both of these problems, but at this time
|
||
we can't say exactly when they will be available.
|
||
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id670141"></a>Compiling</h3></div></div></div><p>
|
||
The biggest change to compiling is in the creation of shared libraries
|
||
(and consequently add-ons). In the PowerPC world, symbols are exported
|
||
from a shared library through the use of the <code class="code">#pragma export on</code> and
|
||
<code class="code">#pragma export off</code> pair. Additionally, you don't have to do anything
|
||
special to import symbols.
|
||
</p><p>
|
||
The x86 release understands different semantics for importing and
|
||
exporting symbols. It is still necessary to explicitly export a symbol
|
||
from a library, but you also must explicitly import the symbol into your
|
||
applications. Importing symbols from add-ons doesn't change; the symbol
|
||
is still resolved with <code class="function">find_image_symbol()</code>. However, if you are linking
|
||
against a shared library, you need to import the symbols.
|
||
</p><p>
|
||
The Intel release uses the traditional x86 methods for importing and
|
||
exporting symbols:
|
||
</p><pre class="programlisting c">
|
||
__declspec(dllexport) type name for exporting
|
||
__declspec(dllimport) type name for importing
|
||
</pre><p>
|
||
In both cases, type specifies what is being exported, and name specifies
|
||
its name. The new header file
|
||
<code class="filename">BeBuild.h</code> selectively exports or imports
|
||
the system classes and global functions, depending on whether the
|
||
libraries are being built or linked against.
|
||
</p><p>
|
||
We recommend following a similar pattern in your own header files, rather
|
||
than having separate header files for importing and exporting. Please see
|
||
the "Moving from PR2 to Release 3: Development Layout" section of the
|
||
Release 3 Release Notes for a more detailed look at this issue.
|
||
</p><p>
|
||
A related note: The Metrowerks x86 compiler allows the use of <code class="code">#pragma
|
||
export</code> and <code class="code">#pragma import</code> to export and import symbols on the x86.
|
||
However, we strongly recommend use of the more traditional (if ugly)
|
||
<code class="code">__declspec()</code> system, as it is more likely to be supported by future
|
||
compilers.
|
||
</p><p>
|
||
Finally, with the recent codification of the ANSI C++ spec, Metrowerks
|
||
has removed the inherited keyword from their compilers. This is a good
|
||
thing. If you use this keyword in your code, we strongly urge you to
|
||
replace it with a specific call to the appropriate parent member.
|
||
Meanwhile, you can use the compiler switch -pragma "def_inherited on" to
|
||
accept the old method. This switch will not be supported indefinitely, so
|
||
it's best to take the time and replace those calls to inherited.
|
||
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id670242"></a>Linking</h3></div></div></div><p>
|
||
Linking with shared libraries is a bit different on the x86. Instead of
|
||
linking with the library itself, you now link with a special
|
||
<code class="filename">.LIB</code> file (a
|
||
"linkable library"). For example, you now link with the linkable library
|
||
<code class="filename">libbe.so.LIB</code>, instead of the shared library
|
||
<code class="filename">libbe.so</code>. The system-linkable
|
||
libraries may be found in <code class="filename">/boot/develop/lib/x86</code>. On the PowerPC, nothing
|
||
changes: You still link with the shared library itself.
|
||
</p><p>
|
||
On a similar note, if you are linking against either the kernel (for
|
||
drivers) or the current application (for add-ons), you must link against
|
||
either <code class="filename">_KERNEL_.LIB</code> or
|
||
<code class="filename">_APP_.LIB</code>, as appropriate.
|
||
<code class="filename">_KERNEL_.LIB</code> may be
|
||
found in the same directory as the other system linkable libraries, while
|
||
<code class="filename">_APP_.LIB</code> must be culled from the appropriate application. The compiler
|
||
automatically generates a <code class="filename">.LIB</code> file for an x86 image—be it an
|
||
application, a static library, or a dynamic library—if any symbols are
|
||
exported (via <code class="code">__declspec(export)</code>).
|
||
</p><p>
|
||
There are a few new objects in
|
||
<code class="filename">/boot/develop/lib/x86</code>, notably
|
||
<code class="filename">glue-noinit.a</code>, <code class="filename">init_term_dyn.o</code>,
|
||
and <code class="filename">start_dyn.o</code>. All programs need these
|
||
objects. Normally, you shouldn't notice them since they're pulled in
|
||
automatically by the linker. However, if you run into problems with
|
||
unresolved symbols, try explicitly linking these files into your object.
|
||
The same drill applies to the PowerPC release as well.
|
||
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id670337"></a>Stephen Makes Life Easier</h3></div></div></div><p>
|
||
In an effort to make things easier for our developers, I've developed a
|
||
fairly basic, but usable, cross-platform makefile. The current
|
||
incarnation can be found at
|
||
ftp://ftp.be.com/pub/samples/intro/obsolete/Makefile. This is a generic
|
||
makefile that allows a developer to specify whether an application or
|
||
static or shared library is being created; what files, libraries, and
|
||
resources are needed to create it; and what its final name will be. This
|
||
makefile will continue to be upgraded as time allows, and as needed.
|
||
</p><p>
|
||
If you are an experienced makefile builder, and you have suggestions on
|
||
how to improve it, I'd like to hear from you. If you are unfamiliar with
|
||
makefiles in general (as I was when I started this), take a look. They
|
||
really aren't that terrible to deal with. Send all reports directly to
|
||
Developer Support via the online form in the Registered Developer Area.
|
||
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id670358"></a>The BeDC</h3></div></div></div><p>
|
||
Finally, please realize that the Newsletter format doesn't permit an
|
||
exhaustive look at all the issues arising from the x86 port of the BeOS.
|
||
For a more thorough presentation, be sure to attend the BeDC, where two
|
||
sessions will be devoted to the x86 port: Approaching a Cross Platform
|
||
OS; and in the extended track, Working with Intel. Bring your comments,
|
||
questions, and concerns to these sessions, and we'll try to get you the
|
||
answers you need.
|
||
</p></div></div><hr class="pagebreak" /><div class="sect1"><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="Gassee3-9"></a>The Newton Experience</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Jean-Louis</span> <span class="surname">Gassée</span></span></div></div></div><p>
|
||
The Newton is no more. This is a little sad for the few people at Be who
|
||
once worked on that project in an earlier life, people such as Bob
|
||
Herold, Peter Potrebic, Steve Sakoman and yours truly. But we live on and
|
||
we are grateful for a few lessons which found their way into our work
|
||
here at Be.
|
||
</p><p>
|
||
The Newton story started late Spring of 1987. After successfully
|
||
directing the engineering efforts resulting in the Mac Plus, the Mac SE
|
||
and the Mac II (the Open Mac), Steve Sakoman sat in my office in the De
|
||
Anza III building in Cupertino and calmly told me he was going to leave
|
||
Apple.
|
||
</p><p>
|
||
To do what? To start a company that would build a new portable computer.
|
||
The size of a notebook, you'd write on the screen with a stylus and the
|
||
computer would recognize your handwriting. I asked Steve if he would hire
|
||
me as a CEO for his venture, he said yes, and we started looking for
|
||
money.
|
||
</p><p>
|
||
I'll cut a convoluted story to the known next milestone, we stayed at
|
||
Apple, Steve started what became known as the Newton project in a
|
||
building on Bubb Road. We liked the Newton concept very much, we saw the
|
||
Newton as "scalable": the idea of a computing device capable of
|
||
recognizing handwriting could be implemented, in theory, on a product as
|
||
small as a checkbook, or as large as a drafting table or even a networked
|
||
whiteboard.
|
||
</p><p>
|
||
Furthermore, the Newton concept did not threaten to cannibalize desktop
|
||
sales. As a result, we could develop a complete hardware and software
|
||
architecture and, if the market graft "took"—that is, if we succeeded
|
||
in attracting enough developers and customers—we could mutate a
|
||
version of the new platform into a more classical desktop product.
|
||
</p><p>
|
||
The latter thought was directed at our concern over the limitations of
|
||
the Macintosh architecture and the perceived need to, first, develop a
|
||
replacement in case it would age prematurely and, second, to do so
|
||
without wrecking the existing desktop business, without, in other words,
|
||
"osborning" the Mac.
|
||
</p><p>
|
||
We liked the Newton so much that when John Sculley gave me the benevolent
|
||
physical and financial kick to get in business on my own, I offered to
|
||
lead an effort to "claris" the Newton into an independent subsidiary.
|
||
Benevolently again, the offer was turned down. Still, for several years,
|
||
as we kept our work at Be under wraps, many were convinced we were
|
||
developing some PDA, as the term gained currency after the Go/Eo, Winpad,
|
||
Zoomer and finally Newton were announced.
|
||
</p><p>
|
||
We started collecting the benefits of the Newton's lessons early. One of
|
||
several reasons we didn't start a PDA company was we had grown
|
||
disenchanted with handwriting recognition. We had started to suspect
|
||
recognition would never reach "transparency." By this I mean the kind of
|
||
performance that never stands between you and your goal, your task. Most
|
||
of the time, error correction on a hard disk or a CD is transparent, it
|
||
takes place but stays out of the way. At Be, we decided our project would
|
||
only integrate known technologies, there were enough other kinds of risk
|
||
in it already.
|
||
</p><p>
|
||
The other lesson we learned, we hope, was setting expectations. The
|
||
Newton was announced with the greatest of fanfares, with proclamations of
|
||
trillion dollar turn-of-the-century markets. Imagine for a moment a
|
||
different kind of announcement: This is from our advance technology
|
||
division, this is only for the hardiest of explorers, this is not yet a
|
||
product for the mainstream.
|
||
</p><p>
|
||
Instead of becoming the butt of Doonesbury cartoons, not necessarily bad
|
||
publicity, the Newton could have iterated towards a nice PDA with the
|
||
support of the early adopter community. In other words, the Surgeon
|
||
General warnings and pocket protectors we associated with our product
|
||
come from our concern to represent our product as we think it is, good
|
||
genes, but not an adult yet, not ready for the mainstream.
|
||
</p><p>
|
||
We hope you'll join us at our Developer Conference in two weeks to check
|
||
on the young OS's progress.
|
||
</p></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="Issue3-8.html">Issue 3-8, February 25, 1998</a> Up: <a href="volume3.html">Volume 3: 1998</a> Next: <a href="Issue3-10.html">Issue 3-10, March 11, 1998</a> </div><div id="footerB"><div id="footerBL"><a href="Issue3-8.html" title="Issue 3-8, February 25, 1998"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="volume3.html" title="Volume 3: 1998"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="Issue3-10.html" title="Issue 3-10, March 11, 1998"><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>
|