In my last article, http://www.be.com/aboutbe/benewsletter/Issue104.html,
I presented you with three unrelated tips. I have three more tips, this
time, all pertaining to BTextView
.
A number of people have asked how to get BTextView
to reflow its text
dynamically when resized (take a look at BeMail or
Expander for an
example). Although there is no way to tell BTextView
to do this for you
automatically, it's easy to implement this feature in your own TextView-
derived class.
The basic idea is to resize the BTextView
's "text rect" whenever the
window's frame is resized. The text rect is BTextView
's own coordinate
system in which it draws its text. BTextView
wraps its text according to
the width of the text rect. (The text rect's height is dynamic—it is
always in sync with the total height of the text.) So, to reflow the text
whenever the view is resized, implement your own
FrameResized()
method:
voidMyTextView
::FrameResized
( floatwidth
, floatheight
) {BTextView
::FrameResized
(width
,height
); if (DoesWordWrap
()) { // this gets the new bounds of the viewBRect
textRect
=Bounds
(); // make sure we are in the view's coordinate systemtextRect
.OffsetTo
(B_ORIGIN
); // inset the text rect by 3 pixels so that the text doesn't // touch the frame of the view: this is the text recttextRect
.InsetBy
(3.0, 3.0); // tell TextView to reflow itselfSetTextRect
(textRect
); } }
In order for this to work properly, make sure your BTextView
class has the
B_FRAME_EVENTS
view flag set; otherwise, it will not be continuously
notified of frame resize events.
An easy way to spruce up your editor is to support some sort of syntax
styling feature. For example, BeMail displays
URLs embedded in e-mail
messages in blue, and everything else is in black. It's simple to
implement this feature using BTextView
's
text_run_array structure.
BTextView
delimits its style runs using a structure called
text_run. A text_run associates a specific offset within the
BTextView
's text buffer with a BFont
and a rgb_color. So, a
text_run like this
text_runtheRun
;theRun
.offset
= 10;theRun
.font
=be_fixed_font
;theRun
.color
.red
= 255;theRun
.color
.green
= 0;theRun
.color
.blue
= 0;theRun
.color
.alpha
= 255;
would tell BTextView
that, starting at offset 10, it should start
displaying its text in red be_fixed_font
.
A text_run_array is simply a variable-length array of text_runs. So, to continue with our URL example, every URL will have two text_runs delimiting it, one at the start of the URL to start a blue run, and one at the end of the URL to restore the text to black.
Assuming that the e-mail message has been parsed and you have the offsets of the URLs, you could use something like this:
// allocate some room for the text_run_array int32number_of_runs
=number_of_urls
* 2; text_run_array *theTRA
= (text_run_array *)malloc
(sizeof
(text_run_array) + (sizeof
(int32) * (number_of_runs
- 1))); // fill in the individual text_runstheTRA
->count
=number_of_runs
; for (int32i
= 0;i
<theTRA
->count
;i
+= 2) { // start the URL runtheTRA
->runs
[i
].offset
=url_start_offsets
[i
];theTRA
->runs
[i].font
=kURLFont
;theTRA
->runs
[i].color
=kURLColor
; // end the URL runtheTRA
->runs
[i + 1].offset
=url_end_offsets
[i
];theTRA
->runs
[i + 1].font
=kNormalFont
;theTRA
->runs
[i + 1].color
=kNormalColor
; }
When you're done constructing your text_run_array, simply pass it on to
BTextView
as part of a call to
SetText()
, Insert()
, or more explicitly,
SetRunArray()
. Note that the offsets are always relative to the point
where you set/insert the text, or to the starting offset that you pass
into SetRunArray()
.
Now that you've successfully parsed for and displayed a URL in blue, wouldn't it be nice if clicking on it did something?
Click-detection of a specific range of text in BTextView
is pretty simple.
You already know the offsets of the URLs, so in your MouseDown()
function, look at the offset of the click, and compare with the URL
offsets:
voidMyTextView
::MouseDown
(BPoint
where
) { // this tells you the text offset of the click int32clickOffset
=OffsetAt
(where
); // assume that FindURL() returns the URL of the click // or NULL if there wasn't a URL there const char *theURL
=FindURL
(clickOffset
); if (theURL
!=NULL
) // while we're at it, send the user's preferred // HTML handler a message to open the URLbe_roster
->Launch
("text/html", 1, &theURL
); else // don't forget to call the original implementation!BTextView
::MouseDown
(where
); }
My final tip is about BTextView
's text buffer's performance. In order
to reduce the number of calls to realloc()
,
BTextView
employs a "gapped"
text buffer. The buffer always allocates more memory than is currently
needed so that realloc()
doesn't have to be
called per KeyDown()
. The gap
is always after the insertion point, which means that it is often
somewhere in the middle of the buffer.
BTextView
's Text()
function returns a const char* to the buffer.
Consequently, it moves the gap to the end of the buffer, so that you may
index the pointer without any knowledge of the whereabouts and the size
of the gap. Therefore, calling Text()
often on a BTextView
(from within
InsertText()
, for example) is not desirable. If you need to peek at the
contents of the buffer, consider using ByteAt()
,
or GetText()
. Use Text()
sparingly, preferably only for rare events such as writing the text into
a file.
One of Scott Adams' best Dilbert strips pokes fun at the standard components of trade show booths: magic tricks, special effects, raffles, and booth babes. "For the best result, combine all four: Create the illusion that you're raffling off the booth babes." I'd add race cars to the list. It stuns me to see a company pay $50K for prime trade show real estate, plop down a Porsche Boxster that takes up half the space, and then cram the actual product into the remainder.
Be has done a number of trade shows over the past few years, mostly MacWorld and Fall Comdex, and recently in joint participation with Adamation at NAB. We take pains to avoid an affliction known as "Trade Show Fever"—the assumption that trade shows are a natural part of doing business.
The costs associated with these extravaganzas are incredible, not only in dollars but also in people resources. We've got a lot of work to do and when we're at a trade show, for the most part, we're not getting other work done. So you can expect to see us at PC Expo in June and Comdex in November. We'll consider a couple of other shows, but before we sign up we'll need to see extremely compelling reasons and clear paths to the goals we desire to achieve by participating.
From our experience, here are a few tips to help you plan for your own future trade show participation.
Alex's Law: Don't Suck. No explanation required. All suggestions that follow will help you not to suck.
Pre-stage Equipment: If it works at home and you bring all the same stuff, the odds of it working at the show are pretty good. With the exception of one large demo machine, we rented machines for NAB locally and brought hard disks. This led to hours of frustration as we swapped video cards and hard disks, recreated partitions, and coaxed uncooperative hardware into performing properly. There is a definite tradeoff of time versus money, but often at a trade show, your deadlines are your least flexible concern.
Bring an Extra System: I've never set up a trade show where every piece of hardware worked properly. We always bring an extra system along with us and pilfer parts to replace failed components.
People Are Responsible, Groups Are Not: Never assign any important trade show task (like pre-staging the equipment) to a group of people; there's a good chance it won't get done. Assign tasks to specific individuals who are responsible for completing them. If the task requires the help of others, that individual can delegate sub-tasks, keep track of overall progress, and deal with problems that arise as they happen.
Schedules Work: Set a booth schedule and stick to it. Make sure your booth staff understands that the schedule is rigid. Remember, though, that we are all human. Scheduling someone for 8 hours of demos is shortsighted. They may have still be standing at a demo station at the end of the day, but they won't be delivering demos that achieve the desired effect.
I've found that people can give the large demo (the demo we do on two large TV screens to attract people into the booth) effectively for two hours at a time before their delivery goes slack. Alternating through the main demo staff solves that problem. At the less demanding (although no less important) one-on-one demo stations, four hours seems to be the limit for effective delivery. After some food, a trip to the bathroom, and a short walk, you can be ready to deliver again.
The Demo: I wrote an article in Newsletter #87 (http://www.be.com/aboutbe/benewsletter/Issue87.html) about how to give a great demo. For a trade show, there are three basic demos you should be prepared to do:
The main demo.
The one-on-one demo.
The "I don't have time for a demo" demo.
The main demo is the most important part of your trade show presentation, apart from the spinning sign on top of the booth. This demo attracts people into your booth to learn more about your product. This demo should make the most of everything that's eye-catching about your product. You've got to literally stop people in their tracks and make them pay attention to you. Here's a tip for doing it: Any static image on a TV screen is boring; any moving image, no matter how boring it is, is not boring, and immediately attracts the eye.
This is generally how I begin to attract a crowd. I leave the system up with a few movies playing, along with some other visual candy. I also think it's important to let people know when the next demo will start so they can decide to stay (FontDemo cycling through fonts is a good "Next Demo at" tool).
Once you have a couple of people waiting, start your demo. People attract people, so you'll build a crowd during the performance. Yes, this is a performance, so it needs to be scripted in advance and taught to your main demo staff—with enough time to practice. As for length, unless your demo is capable of winning awards, you won't keep a crowd standing around for more than 10 minutes. Show the highlights and invite them into the booth for more in-depth one-on-one demos.
The one-on-one demo is more loosely organized and should be tailored to each individual depending upon their area of interest. We don't show a video developer support for printing to AppleTalk devices. One-on-one demo staff must be comfortable showing off most aspects of the product and able to customize their demo on the fly. If someone with no specific area of interest is looking for a one-on-one demo, use an extended version of the "I don't have time for a demo" demo.
The "I don't have time for a demo" demo is for people who want to see a demo but only have 30 seconds. Be prepared to show them the three most impressive aspects of your product. It matters less that they are the most important or useful features, than that they can make someone say, "Wow, show me more."
Finally, everyone in the booth should be able to give a demo. It never fails that, with everyone busy giving demos, someone will walk up to you, point to the one empty station, and ask for a demo.
Look good, be prepared, have fun. There are few things more immediately gratifying than giving good demo. Oh, if you're in Vegas for Comdex, only play the single decks and always SPLIT aces and 8's, never 10's, 5's, and 4's.
So you think you have an amazing idea for the BeOS? It's potent. Compelling. Promises jaw-dropping capabilities. You can't sleep anymore because you're dreaming about it and you're coding every red-eyed moment you're awake and you're drinking way too much coffee and every chance you get you call your best friend to dream and scheme. There's only one small problem: Where do you find the capital?
You could start with a venture capital seed fund. In venture parlance, a "seed" fund is a capital pool aimed at small, very early stage and high risk investments. Seed-stage companies are still in the process of technology and product development; they have little or no revenue; they are not yet engaged in marketing. This article will give you some suggestions on what to think about and cover in your seed-stage business plan. There are also a number of useful resources available on the Web and in better booksellers that will be helpful to you in creating a plan for your prospective investors.
The Eastern Technology Seed Investment Fund (ETSIF) is a C$25 million (Canadian) venture capital fund created to provide financing and management support for early stage technology projects in Eastern Canada (Ontario and the Atlantic Provinces). ETSIF is distinguished by its very early stage focus and its ability to bring both equity funding and management support to technology opportunities. Most of ETSIF's initial investments are made in opportunities which do not have revenue and which are likely to require a number of rounds of venture financing before becoming cash self-sufficient. ETSIF's initial commitment is generally in the range of C$100,000 to C$500,000 but investments outside this range will be considered.
We usually expect that our seed investment will be enough to get a company started towards its first "milestone" achievement. Seed stage generally is preparatory to a full-blown startup round of financing (which may be in the several millions of dollars). During seed stage several important objectives are tackled. First, the technology or application is brought to prototype or beta stage. Second, the company's management team is rounded out. Third, a comprehensive business plan is researched and written, suitable for the raising of second round financing. At the end of seed stage—typically an eight or ten month period, perhaps shorter—companies will be able to move towards the second round of financing.
At ETSIF we look for three essentials in any seed funding application: technology, people, and customers. The inability of an applicant to satisfy us on all of these points usually means we will not proceed further. What follows is intended to give you a sense of how we typically approach each of these three qualities, and what sorts of questions you should ask yourself in devising your plan.
First, the technology must be powerful, compelling, unique. It should generally either (a) give the user a power to do things that were previously not possible, or (b) allow the user to save significant time and money over their existing solution. Small increments will not do here. It is no use saying that your solution is 20% better than the software that is available today: Your real competition is the software that is under development today. What will your advantage be when you actually begin to sell your product? How long will it last? How deep and wide will the moat be around your technology?
The second factor is the quality of the people. At seed stage the fundamental focus is on the development team. We like to see a team comprised of people who have the training and experience necessary to extend and deepen the technology over time; who possess passion and vigor and commitment and integrity; who can lay the right architectural foundation; who can plan in detail and with wisdom; who can build with discipline; who know the value and place of development tools and best practices. Be sure to detail the backgrounds and individual responsibilities of your team's members. Identify any gaps in the group, and explain how you intend to fill them.
The last major criterion is a simple one, but too often overlooked: customers. Who in the real flesh-and-blood world will pay hard money for your product? How many of them are out there today? Next year? Don't spend too much time dwelling on "markets," at least to begin with. Who are your customers going to be? Who will beg to test your beta? Who will buy your product? Better yet, who will pester their boss to buy your product for them? Whose heart will pound the most? That's your customer. Working backwards from that will help you see your markets. And sometimes by going through this exercise you will discover all kinds of new markets. If you know your customers, understand their needs and wants and methods and fears and similarities and differences, then you will know your market. And your knowledge will be of a kind that is meaningful, deep, and practical.
Your seed plan should discuss, in reasonable detail, the three key elements of technology, people, and customers.
Explain the technology development plan. Discuss architecture, design, construction. We know the difficulties in scheduling complex projects reliably; that's why we look for developers who understand "best practices," and who have the iron discipline necessary to make excellent use of a few useful control and quality tools. Define the key work packages as far as you can. Sketch the real decision points and the rough schedule. Outline the people and equipment that you will need. Divide responsibility for development among your team. Explain the various practices (daily builds, version controls, reviews, etc.) that you will rely on to ensure that the development process is as controlled as possible. Talk about the risks that worry you the most, and how you plan to confront those risks.
If you can, make a basic budget. Here are some tips:
"Get the money on the screen," as they say in the movie business; don't fill out the budget with "lifestyle" salaries and hefty fringe benefits and perks.
If you choose to forecast financial statements, then think cash flow, not accounting profits.
As to style: Avoid business jargon as much as possible. Jargon clouds thinking and obscures meaning. It gives even original ideas a hackneyed, worn feel. Think clearly. Build your case in logical steps. Write crisply, decisively, on the things you truly understand. As Hemingway said: "...write when you know something; and not before; and not too damned much after."
Your business plan at the seed stage shouldn't be a book. Truly exciting ideas need only a few pages to sell themselves; the bad ones cannot be sold even with hundreds of pages. While every investor has different requirements and tastes, the following suggestions may also prove useful to you:
Forget mission statements. Your mission should be clear from your plan.
Never gloss over or omit any risks, shortcomings, or unpleasant truths.
Don't waste ink on pie charts, or on pretty graphs that show limitless year-over-year growth in profits. Instead, use operational diagrams of the sort that you would use inside a functioning development company: Gantt charts, organizational and architectural charts, clear tables, simple drawings, and so forth.
While with seed applicants we don't need or want a full-fledged marketing plan, we do appreciate being given the rundown on the existing product solutions that your customers are using, even if they are not direct competition to your technology.
Footnotes are helpful. Include a glossary of technical terms used. Directions to Web resources are also good. Append any particularly relevant background articles from magazines or journals.
Always check spelling and grammar and make sure you understand the specific requirements of your audience. Sloppiness hurts credibility.
Take the time to learn how investors think. Read the "Red Herring" http://www.redherring.com/ and "Upside" http://www.upside.com/ on a regular basis, or skim back issues. Spend time carefully reviewing the literature available on the investment funds you intend to apply to, so that you accurately grasp the criteria of each. Pick up a copy of Geoffrey Moore's Crossing the Chasm, (HarperBusiness, 1991). There are a number of good books available on the writing of business plans; one very good choice for technology startups is Gordon Bell's High Tech Ventures, (Addison Wesley, 1991).
The BeOS platform affords numerous possibilities to build fast-growing software companies. The great chance is to create software that couples your own powerful insights with the explosive muscle of the BeOS, for irresistible results.
We are interested in meeting Canadian BeOS developers who have truly exciting software ideas, but who lack the capital and management support to get properly underway. Canada is home to thousands of developers who have spectacular strengths in digital media and animation. If you are in Canada and want to discuss your own BeOS project, you are invited to contact Keith Bates by telephone (416-861-2282) or e-mail kbates@easternseed.com.
If you are thinking about applying to ETSIF, you should visit our site at http://www.easternseed.com/, which authoritatively describes current ETSIF criteria and guidelines, or request a copy of ETSIF's brochure.
For developers located in Western Canada, you can visit http://www.westernseed.com/ for information on the Western Technology Seed Investment Fund.
These tools perform attribute tricks, and are great for attribute debugging. Almost anything that can be done programmatically (through the BNode attribute functions) can be done from the command line with these tools. All four of these tools return 0 upon success, and non-zero otherwise (but with a caveat, as described in rmattr).
addattr
writes an attribute
(a name/value pair) into an existing file:
addattr
[-t type] attr value file1 [file2 ...]
"type" is one of:
string (the default; 'text' and 'ascii' are synonyms)
mime (for MIME types)
int (for int32)
llong (for int64)
float
double
If the attribute ("attr") already exists, it's replaced by the new value—even if the new attribute is a different type.
catattr
displays the value of a named attribute:
catattr
attr file1 [file2 ...]
Each attribute is displayed in the form
file : type : value
The possible "type" values here are:
string (all strings, including MIME types)
int32
int64
float
double
raw_data (all other types)
Notice that the types that are displayed by catattr
are slightly
different from those expected by addattr
. This endearing quirk may be
kicked into line someday.
The data for a raw_data type attributes is displayed in a hexdump (hd) style byte table.
Also, note that the "attr" argument isn't a wildcard; for example, you can't dump all the attributes in a file by commanding "catattr * file".
listattr
dumps the names, types, and sizes—but not the values --
of the attributes in a file:
listattr
file1 [file2 ...]
For each file, a three-column table ("Type", "Size", "Name") is
displayed. The values in the "Type" column are—surprise—different
from those used by addattr
and catattr
:
Text
MIME str
Int-32
Int-64
Float
Double
Unrecognized attribute types (constants) are printed in hex. The "Size" column gives the size of the attribute in bytes; "Name" is the name of the attribute.
Keep in mind that directories can have attributes themselves. listattr
. lists the attributes in the current directory. If you want to list
the attributes in all the files in a directory, call listattr *
.
rmattr
removes a named attribute from a file:
rmattr
attr file1 [file2 ...]
rmattr
's return value shouldn't be trusted. It (properly) returns non-
zero if the arguments are invalid, but it (improperly) returns 0 if
something goes wrong while removing an attribute.
copyattr
also plays with attributes, but it's a much more involved
program. It copies the attributes and, optionally, data from one file
to another:
copyattr
[options] from_file1 [from_file2 ...] to_file
In its simplest use, copyattr copies all the attributes (names, types, and values) from a source file (A) to a destination file (B): copyattr A B
Destination attributes are clobbered in the case of duplicate attribute names. When copying attributes only (i.e. not data), the destination file must already exist.
To select a particular attribute (or set of attributes) use the -n or -t options:
-n The name of the attribute to copy
-t The type of attributes to copy
You can only specify one name or one type. The recognized types are:
string
mimestr (for MIME types)
int64 (or "llong")
int32 (or "int")
int16
int8
boolean
float
The real power of copyattr
is as an attribute-aware replacement for
cp
. To tell copyattr
to copy data AND
attributes, you pass it the -d
option:
copyattr -d A B
When you're copying data as well as attributes, the destination file needn't exist.
To recursively copy an entire directory, add the -r (recursive) switch:
copyattr -d -r ADIR BDIR
To move a directory, use '-d -r' as above, and then throw in the -m (remove source) switch:
copyattr -d -r -m ADIR BDIR
Note that the copyattr command line switches can't be combined. You have to use '-d -r -m', not '-drm'.
As with the other attribute programs, copyattr returns 0 if successful and non-zero otherwise.
It's amazing what you find looking through archives on the Web. In this case, obscure mutterings written in another time and another language. Originally published on March 3rd, 1995 in the Parisian (and Leftist) newspaper Libération, some parts have aged well—while others now look decidedly bizarre.
Francophones can read the original at: http://www.liberation.com/chroniques/ga950303.html
A hundred dollars per year per computer—for now. Is this a new fund raising idea from the government, a toll on the information highway, or perhaps the PC equivalent of the TV license [the French pay a yearly license for the use of a TV—supposedly for the "free" state channels]? No, it's Microsoft's strategy, a very simple core idea hidden behind multiple products, campaigns and announcements.
From the purchase of DOS in 1980 from a small company in Seattle (before its adoption by IBM), to the announcement of Windows 95, Bill Gates has worked from the same plan: develop, cajole, and ferociously protect a worldwide installed base of 90 million PCs. Once control is established, tax the installed base in the form of new or revised software. Average "obligatory" expenditure: A hundred dollars a year.
Operating system. In French, "systéme d'exploitation"—"exploitation system". We are warned.
An exaggeration? Let's look at the facts. Today, Microsoft controls about 90% of the market for PC operating systems, more than 70% of office automation applications under Windows, and more than 80% on the Macintosh. As if this wasn't enough, the latest generation of its systems—Windows NT and, soon, Windows 95—will strengthen Microsoft's share of an entire spectrum of markets, from office computers to large systems. In the meantime, Gates will have spread himself to databases and programming languages. He'll have closed the 1.6 billion dollar acquisition of Quicken, the champion of the very American hobby of home accounting; and he'll have leveraged this investment through an agreement with Visa that will combine Quicken with their credit card services.
At home or at the office, Microsoft is the toll gate: Whether in entertainment or education, Microsoft's CD-ROMs dominate the market and Gates is hard at work developing multimedia products with his Hollywood connections. In the enterprise market, he wants to federate telephones, fax machines, and copiers.
And that's not the end of it as Bill Gates feverishly works on projects such as Microsoft Network, which targets CompuServe, Calvacom [a French service] and the Internet, or its Tiger standard intended for the domination of interactive TV, or Teledesic, the satellite telecommunication project set up with billionaire Craig McCaw, the king of cellular telephony in the US.
Never has a company incarnated the spectre of dominant position as fully as Microsoft does—not even IBM at the height of its antitrust troubles. Bill Gates denies all this with admirable chutzpah: think of the gigantic investments! the ferocious competition! the fragility of being on top!... Microsoft is merely a small ship on the threatening oceans of a competitive marketplace.
This doesn't amuse the industry brethren.
Jim Manzi, president of Lotus, would like to know how to compete in the office market against an opponent that develops both the operating system and the applications, a conjunction that gives Microsoft's word processor and spreadsheet a crushing advantage. Microsoft Office is designed from within to work with Windows while Lotus must content itself with Microsoft's technical documentation—and trust Microsoft's word.
Such striking success generates bitter accusations of Microsoft's misuse of their dominant position, of ethical as well as legal breaches.
The success of Microsoft owes much to Bill Gates' intelligence, his energy, and his ability to see and willingness to seize opportunities. These were many over the years, as his opponents, weakened by incompetence and internecine struggles, tremulously clung to the good old ways. Gates plays all positions well, his authority is unquestioned, he's been at the helm for twenty years and, if he wants, he'll be in charge for another twenty or more. In his defense of the Microsoft system, he claims that without the standard he created and ferociously evangelized, the industry wouldn't have enjoyed the rapid and "harmonious" growth leading to its incredible prosperity. So go the arguments of enlightened despots. But when they succeed too well and for too long, they overshoot the point of optimal service to the community and end up doing harm to their own ecological niche. For Microsoft, the question is posed in these political terms. The time has come to acknowledge that the industry can no longer render unto Microsoft.
Bill Gates has the means to elegantly transmutate his image from wealthy despot into benevolent visionary: All he has to do is put Windows in the public domain, provide the source code and documentation through the Internet. Entrepreneurs would be free to modify and improve upon the standard, customers would be free to pick the best product.
This might cost Bill Gates one or two billion dollars of the five or six of his personal fortune today. But that's a rather abstract price for a very real place in history. Freed from suspicion, Bill Gates would become a legend, and would be able to throw himself into the boundless enjoyment of competition in the applications market.
One can dream.
It's three years and an (almost) automatic translation program later. As with all reminiscence, the views expressed here don't necessarily represent those of the author (any more). But...
The hand-wringing over the Quicken and Teledesic deals was premature; but the Microsoft strategy and the poor little rich kid attitude is still with us. Recall their words when they entered the Internet market in 1996:
“What you're seeing here is competition, which is good and healthy. Now we have Netscape's Navigator and Sun's Javasoft as our new competitors.”
More importantly, the events of the last year have again proven that the palace isn't safe when there's discontent in the village. Is it too late for Louis '98 to open the gates to Versailles?