├── AwesomeSaver ├── AwesomeSaver.cpp ├── ReadMe ├── compile └── screensaver-dev.html ├── ButtonPress ├── App.cpp ├── App.h ├── MainWindow.cpp ├── MainWindow.h ├── ReadMe └── compile ├── EmptyWindow ├── App.cpp ├── App.h ├── MainWindow.cpp ├── MainWindow.h ├── ReadMe └── compile ├── FallLeaves ├── FLConfigView.cpp ├── FLConfigView.h ├── FLLeaf.cpp ├── FLLeaf.h ├── FallLeaves.cpp ├── FallLeaves.h ├── FallLeaves.pld ├── IconUtils.h ├── PackageRoot │ └── .PackageInfo └── compile ├── FileDialog ├── Main.cpp ├── ReadMe └── compile ├── HaikuAPISamples ├── HaikuFortune ├── App.cpp ├── App.h ├── FortuneFunctions.cpp ├── FortuneFunctions.h ├── HaikuFortune.rsrc ├── HaikuFortune16.png ├── HaikuFortune32.png ├── MainWindow.cpp ├── MainWindow.h ├── ReadMe └── compile ├── License ├── ListDirectory ├── App.cpp ├── ReadMe └── compile ├── ListItems ├── App.cpp ├── App.h ├── MainWindow.cpp ├── MainWindow.h ├── ReadMe └── compile ├── LoadResources ├── App.cpp ├── App.h ├── MainWindow.cpp ├── MainWindow.h ├── PictureView.cpp ├── PictureView.h ├── ReadMe ├── Resources.rsrc └── compile ├── MenuBar ├── App.cpp ├── App.h ├── MainWindow.cpp ├── MainWindow.h ├── ReadMe └── compile ├── README.md └── VerticalSlider ├── App.cpp ├── App.h ├── MainWindow.cpp ├── MainWindow.h ├── ReadMe └── compile /AwesomeSaver/AwesomeSaver.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // An awesome screensaver 3 | // 4 | #include 5 | #include 6 | 7 | 8 | class AwesomeSaver : public BScreenSaver 9 | { 10 | public: 11 | AwesomeSaver(BMessage* archive, image_id thisImage); 12 | void StartConfig(BView* configView); 13 | status_t StartSaver(BView* view, bool preview); 14 | void Draw(BView* view, int32 frame); 15 | private: 16 | // These variables are specific to AwesomeSaver 17 | int32 fX; 18 | int32 fY; 19 | int32 fChangeX; 20 | int32 fChangeY; 21 | }; 22 | 23 | 24 | AwesomeSaver::AwesomeSaver(BMessage* archive, image_id thisImage) 25 | : 26 | BScreenSaver(archive, thisImage), // Call the constructor for BScreenSaver 27 | fX(200), // Initialize variable 28 | fY(100), 29 | fChangeX(1), 30 | fChangeY(1) 31 | { 32 | // Empty 33 | } 34 | 35 | 36 | void 37 | AwesomeSaver::StartConfig(BView* configView) 38 | { 39 | // Show the name of the screensaver 40 | BRect rect(15, 15, 20, 20); 41 | BStringView* stringView = new BStringView(rect, "module", "AwesomeSaver"); 42 | stringView->SetFont(be_bold_font); 43 | stringView->ResizeToPreferred(); 44 | configView->AddChild(stringView); 45 | 46 | // Show some info about the screensaver 47 | rect.OffsetBy(0, stringView->Bounds().Height() + 4); 48 | stringView = new BStringView(rect, "info", "by Me!"); 49 | stringView->ResizeToPreferred(); 50 | configView->AddChild(stringView); 51 | } 52 | 53 | 54 | status_t 55 | AwesomeSaver::StartSaver(BView* view, bool preview) 56 | { 57 | if (preview) { 58 | fX = 20; 59 | fY = 10; 60 | } 61 | 62 | return B_OK; 63 | } 64 | 65 | 66 | const char* kText = "Haiku is AWESOME!"; 67 | 68 | 69 | void 70 | AwesomeSaver::Draw(BView* view, int32 frame) 71 | { 72 | if (frame == 0) { 73 | // Erase the screen 74 | view->SetLowColor(0, 0, 0); 75 | view->FillRect(view->Bounds(), B_SOLID_LOW); 76 | } 77 | 78 | // Erase the old text 79 | view->SetHighColor(0, 0, 0); // Black 80 | view->DrawString(kText, BPoint(fX, fY)); 81 | 82 | // Move the text 83 | fX += fChangeX; 84 | fY += fChangeY; 85 | 86 | // Bounce off the edge of the screen 87 | if (fX <= 0 || fX >= view->Bounds().right) 88 | fChangeX = -fChangeX; 89 | 90 | if (fY <= 0 || fY >= view->Bounds().bottom) 91 | fChangeY = -fChangeY; 92 | 93 | // Draw the text at its new location 94 | view->SetHighColor(249, 210, 42); // Haiku yellow 95 | view->DrawString(kText, BPoint(fX, fY)); 96 | } 97 | 98 | 99 | extern "C" _EXPORT BScreenSaver* 100 | instantiate_screen_saver(BMessage* msg, image_id id) 101 | { 102 | return new AwesomeSaver(msg, id); 103 | } 104 | -------------------------------------------------------------------------------- /AwesomeSaver/ReadMe: -------------------------------------------------------------------------------- 1 | Create a simple screensaver. 2 | 3 | Some of the code was taken from the "Haiku" screensaver. 4 | -------------------------------------------------------------------------------- /AwesomeSaver/compile: -------------------------------------------------------------------------------- 1 | gcc -o AwesomeSaver *.cpp -lbe -lscreensaver -nostart -Xlinker -soname=AwesomeSaver 2 | -------------------------------------------------------------------------------- /AwesomeSaver/screensaver-dev.html: -------------------------------------------------------------------------------- 1 |

Developing a Screensaver for Haiku

2 | 3 |

Basics

4 | 5 |

A screensaver in Haiku must be a subclass of BScreenSaver. The BScreenSaver class contains a collection of method hooks. The Haiku ScreenSaverRunner uses these hooks to configure, start, stop, and draw a screensaver. All you have to do to make a screensaver is overwrite the hooks.

6 | 7 |

Getting Started

8 | 9 |

Here is the definition of an example screensaver, called AwesomeSaver.

10 | 11 |
 12 | #include 
 13 | #include 
 14 | 
 15 | class AwesomeSaver : public BScreenSaver
 16 | {
 17 | public:
 18 | 					AwesomeSaver(BMessage* archive, image_id thisImage);
 19 | 	void			StartConfig(BView* configView);
 20 | 	status_t		StartSaver(BView* view, bool preview);
 21 | 	void			Draw(BView* view, int32 frame);
 22 | private:
 23 | 	// These variables are specific to AwesomeSaver
 24 | 	int32			fX;
 25 | 	int32			fY;
 26 | 	int32			fChangeX;
 27 | 	int32			fChangeY;
 28 | };
 29 | 
30 | 31 |

Filling In the Code

32 | 33 |

Constructor

34 | 35 |

Initialize your screensaver object in the constructor. If you added any variables to your class, initialize them here.

36 | 37 |
 38 | AwesomeSaver::AwesomeSaver(BMessage* archive, image_id thisImage)
 39 | 	:
 40 | 	BScreenSaver(archive, thisImage), // Call the constructor for BScreenSaver
 41 | 	fX(200), // Initialize variable
 42 | 	fY(100),
 43 | 	fChangeX(1),
 44 | 	fChangeY(1)
 45 | {
 46 | 	// Empty
 47 | }
 48 | 
49 | 50 |

StartConfig

51 | 52 |

This is called when the user selects your screensaver from the list of screensavers in the Screen Saver Preferences application. You're provided with a BView. You can use it to show some information about your screensaver or to provide the user with some options.

53 | 54 |
 55 | void
 56 | AwesomeSaver::StartConfig(BView* configView)
 57 | {
 58 | 	// Show the name of the screensaver
 59 | 	BRect rect(15, 15, 20, 20);
 60 | 	BStringView* stringView = new BStringView(rect, "module", "AwesomeSaver");
 61 | 	stringView->SetFont(be_bold_font);
 62 | 	stringView->ResizeToPreferred();
 63 | 	configView->AddChild(stringView);
 64 | 
 65 | 	// Show some info about the screensaver
 66 | 	rect.OffsetBy(0, stringView->Bounds().Height() + 4);
 67 | 	stringView = new BStringView(rect, "info", "by Me!");
 68 | 	stringView->ResizeToPreferred();
 69 | 	configView->AddChild(stringView);
 70 | }
 71 | 
72 | 73 |

StartSaver

74 | 75 |

This is called when your screensaver starts. If "preview" is true, it means your screensaver is running in the little preview window in the Screen Saver Preferences application. You can use this value to change how your screensaver behaves in the preview.

76 | 77 |
 78 | status_t
 79 | AwesomeSaver::StartSaver(BView* view, bool preview)
 80 | {
 81 | 	if (preview) {
 82 | 		fX = 20;
 83 | 		fY = 10;
 84 | 	}
 85 | 	
 86 | 	return B_OK;
 87 | }
 88 | 
89 | 90 |

Draw

91 | 92 |

This is the fun part. You're given a BView the size of the entire screen, and you can do whatever you want with it. "frame" is the current frame number. When the screensaver starts the frame is zero, and increases by one every time the Draw method is called.

93 | 94 |
 95 | const char* kText = "Haiku is AWESOME!";
 96 | 
 97 | void
 98 | AwesomeSaver::Draw(BView* view, int32 frame)
 99 | {
100 | 	if (frame == 0) {
101 | 		// Erase the screen
102 | 		view->SetLowColor(0, 0, 0);
103 | 		view->FillRect(view->Bounds(), B_SOLID_LOW);
104 | 	}
105 | 	
106 | 	// Erase the old text
107 | 	view->SetHighColor(0, 0, 0); // Black
108 | 	view->DrawString(kText, BPoint(fX, fY));
109 | 	
110 | 	// Move the text
111 | 	fX += fChangeX;
112 | 	fY += fChangeY;
113 | 	
114 | 	// Bounce off the edge of the screen
115 | 	if (fX <= 0 || fX >= view->Bounds().right)
116 | 		fChangeX = -fChangeX;
117 | 	
118 | 	if (fY <= 0 || fY >= view->Bounds().bottom)
119 | 		fChangeY = -fChangeY;
120 | 	
121 | 	// Draw the text at its new location
122 | 	view->SetHighColor(249, 210, 42); // Haiku yellow
123 | 	view->DrawString(kText, BPoint(fX, fY));
124 | }
125 | 
126 | 127 |

Instantiate

128 | 129 |

Lastly, you need to include a function that starts the screensaver.

130 | 131 |
132 | extern "C" _EXPORT BScreenSaver*
133 | instantiate_screen_saver(BMessage* msg, image_id id)
134 | {
135 | 	return new AwesomeSaver(msg, id);
136 | }
137 | 
138 | 139 |

Other

140 | 141 |

There are some other hooks you can use in your screensaver. To see the full list, see the ScreenSaver.h header file.

142 | 143 |

Drawing

144 | 145 |

You draw your screensaver onto the screen by manipulating the BView. A BView has many many methods. Here are some BView methods that you might find useful.

146 | 147 | 155 | 156 |

The BScreenSaver class (that your screensaver inherits) includes some useful functions too.

157 | 158 | 161 | 162 |

Random numbers are useful in a screensaver. Here is a simple function that returns a random number.

163 | 164 |

165 | int32
166 | rand_num(int32 low, int32 high)
167 | {
168 | 	static bool init = false;
169 | 	
170 | 	if (!init) {
171 | 		srand(system_time() % INT_MAX);	// Init the random number generator
172 | 		init = true;
173 | 	}
174 | 
175 | 	// Return a random number between high and low, inclusive
176 | 	return (rand() % (high - low + 1)) + low;
177 | }
178 | 
179 | 180 |

Double Buffering

181 | 182 |

Double buffering is a technique used to reduce flicker. If your screensaver changes a lot on the screen each frame, it might be good to use double buffering.

183 | 184 |

Double buffering involves drawing everything to a temporary area (a "buffer"), then drawing that temporary area to the screen.

185 | 186 |
187 | void
188 | Draw(BView* view, int32 frame)
189 | {
190 | 	// Setup double buffering
191 | 	BRect rect(0, 0, view->Frame().Width(), view->Frame().Height());
192 | 	backBitmap = new BBitmap(screenRect, B_RGBA32, true);
193 | 	backView = new BView(screenRect, NULL, 0, 0);
194 | 	backBitmap->AddChild(backView);
195 | 	backBitmap->Lock();
196 | 	
197 | 	//
198 | 	// Now you can draw anything you want to "backView"!
199 | 	//
200 | 	
201 | 	backBitmap->Unlock();
202 | 	view->DrawBitmap(backBitmap); // Draw the buffer to the screen
203 | }
204 | 
205 | 206 |

Compiling

207 | 208 |

Compiling a screensaver is done a little differently than a standard application. A screensaver isn't an application - it doesn't even have a "main" function. Instead, we compile it as a shared library.

209 | 210 |
211 | gcc -o AwesomeSaver *.cpp -lbe -lscreensaver -nostart -Xlinker -soname=AwesomeSaver
212 | 
213 | 214 | 222 | 223 |

When linking, be sure to include any libraries that you used in your code. For example, our example uses code from libbe.so and libscreensaver.so, so you include them with the -lbe and -lscreensaver arguments.

224 | 225 |

Running

226 | 227 |

Copy your new screensaver file to your personal screensaver area, in "~/config/add-ons/Screen Saver". To make testing a little speedier, simply make a link instead of copying it. That way, after you compile a new version of your screensaver, all you have to do is reload it.

228 | 229 |

Debugging

230 | 231 |

Don't worry about your screensaver crashing. If it does, the ScreenSaverRunner will notify you and give you the option of using the debugger to find out what went wrong. Use the "bt" (backtrace) debugger command to get a nice idea of where the problem is in your code.

232 | 233 |

Try to add and test code little by little. One of the nice things about making a screensaver is that it's easy to do things in pieces. You can fill in the method hooks one by one and make sure everything still works as you do.

234 | 235 |

Troubleshooting

236 | 237 |

I added a resource to my screensaver. Why can't I load it?

238 | 239 |

You can add resources to an application by using the "xres" command. This is a great way to add things like images to an application, but, unfortunately, it doesn't work with screensavers.

240 | 241 |

Screensavers are not actually applications. Instead, they are run by the ScreenSaverRunner application. When your screensaver tries to load a resource, it actually looks for it in the ScreenSaverRunner file. It will, of course, fail, because your resource is stored in your screensaver file, not the ScreenSaverRunner file.

242 | 243 |

As an alternative, you can create an image in Icon-O-Matic and export it as HVIF source code. You can copy the source code into your project and load it by using the BVectorIcon functions.

244 | 245 |
246 | BBitmap* bitmap = new BBitmap(BRect(0, 0, 100, 100), B_RGBA32);
247 | BIconUtils::GetVectorIcon(icon, sizeof(icon), bitmap);
248 | 
249 | -------------------------------------------------------------------------------- /ButtonPress/App.cpp: -------------------------------------------------------------------------------- 1 | #include "App.h" 2 | #include "MainWindow.h" 3 | 4 | 5 | App::App(void) 6 | : BApplication("application/x-vnd.dw-ButtonDemo") 7 | { 8 | MainWindow *mainwin = new MainWindow(); 9 | mainwin->Show(); 10 | } 11 | 12 | 13 | int 14 | main(void) 15 | { 16 | App *app = new App(); 17 | app->Run(); 18 | delete app; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ButtonPress/App.h: -------------------------------------------------------------------------------- 1 | #ifndef APP_H 2 | #define APP_H 3 | 4 | #include 5 | 6 | class App : public BApplication 7 | { 8 | public: 9 | App(void); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /ButtonPress/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | 3 | // Button.h adds the class definiton for the BButton control 4 | #include 5 | 6 | // The BString class is a phenomenally useful class which eliminates 7 | // almost all hassle associated with manipulating strings. 8 | #include 9 | 10 | // The BView class is the generic class used for creating controls and 11 | // drawing things inside a window. 12 | #include 13 | 14 | // This defines the identifier for the message that our button will send. The 15 | // letters inside the single quotes are translated into an integer. The value 16 | // for M_BUTTON_CLICKED is arbitrary, so as long as it's unique, it's not too 17 | // important what it is. 18 | enum 19 | { 20 | M_BUTTON_CLICKED = 'btcl' 21 | }; 22 | 23 | 24 | MainWindow::MainWindow(void) 25 | : BWindow(BRect(100,100,300,200),"ClickMe",B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | 26 | B_QUIT_ON_WINDOW_CLOSE), 27 | fCount(0) 28 | { 29 | // Create a button in pretty much the same way that we did the label in 30 | // the last lesson. The BRect() call inside the BButton constructor is a 31 | // quick shortcut that eliminates creating a variable. 32 | BButton *button = new BButton(BRect(10,10,11,11),"button","Click Me!", 33 | new BMessage(M_BUTTON_CLICKED)); 34 | 35 | // Like with last lesson's label, make the button choose how big it should be. 36 | button->ResizeToPreferred(); 37 | 38 | // Add our button to the window 39 | AddChild(button); 40 | } 41 | 42 | 43 | void 44 | MainWindow::MessageReceived(BMessage *msg) 45 | { 46 | // The way that BMessages are identified is by the public property 'what'. 47 | switch (msg->what) 48 | { 49 | // If the message was the one sent to the window by the button 50 | case M_BUTTON_CLICKED: 51 | { 52 | fCount++; 53 | 54 | BString labelString("Clicks: "); 55 | 56 | // This adds the value of fCount to the end of labelString. More on this later. 57 | labelString << fCount; 58 | 59 | // Set the window's title to the new string we've made 60 | SetTitle(labelString.String()); 61 | break; 62 | } 63 | default: 64 | { 65 | // If the message doesn't match one of the ones we explicitly define, it must 66 | // be some sort of system message, so we will call the version of MessageReceived() 67 | // created for BWindow so that it can handle them. THIS IS REQUIRED if you want 68 | // your window to act the way that you expect it to. 69 | BWindow::MessageReceived(msg); 70 | break; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /ButtonPress/MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | class MainWindow : public BWindow 7 | { 8 | public: 9 | MainWindow(void); 10 | 11 | // We are implementing the virtual BWindow method MessageReceived so 12 | // that we can do something with the message that the button sends. 13 | void MessageReceived(BMessage *msg); 14 | 15 | private: 16 | // This property will hold the number of 17 | // times the button has been clicked. 18 | int32 fCount; 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /ButtonPress/ReadMe: -------------------------------------------------------------------------------- 1 | From "Learning to Program with Haiku" by Jon Yoder (DarkWyrm) 2 | http://haiku-os.org/development/learning_to_program_with_haiku 3 | 4 | Create and show a window that has a button. 5 | The application counts the number of times the button is pressed. -------------------------------------------------------------------------------- /ButtonPress/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe -------------------------------------------------------------------------------- /EmptyWindow/App.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "App.h" 4 | #include "MainWindow.h" 5 | 6 | 7 | App::App() 8 | : 9 | BApplication("application/x-vnd.demo-app") 10 | { 11 | // The only thing that happens when you start this application is 12 | // a window is created. 13 | BWindow *mainwin = new MainWindow(); 14 | 15 | // Now that it has been created, show it! 16 | mainwin->Show(); 17 | } 18 | 19 | 20 | // Start the application. 21 | int main() 22 | { 23 | // Setup the application. 24 | // This includes setting up the user interface. 25 | new App(); 26 | 27 | // Run the application. 28 | // This includes all of the application logic. 29 | be_app->Run(); 30 | 31 | delete be_app; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /EmptyWindow/App.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | // Represents the running application. 5 | // Can be accessed anytime with the "be_app" variable. 6 | class App : public BApplication 7 | { 8 | public: 9 | 10 | App(); 11 | }; 12 | -------------------------------------------------------------------------------- /EmptyWindow/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include // To use the variable "be_app" 2 | 3 | #include "MainWindow.h" 4 | 5 | 6 | MainWindow::MainWindow() 7 | : 8 | BWindow(BRect(), "Main Window", B_TITLED_WINDOW, 9 | B_QUIT_ON_WINDOW_CLOSE) 10 | { 11 | MoveTo(100, 100); 12 | ResizeTo(200, 200); 13 | } 14 | 15 | 16 | // This method is called when the "close" button is pressed 17 | // on the application title bar. 18 | bool MainWindow::QuitRequested() 19 | { 20 | // Tell the application to quit 21 | be_app->PostMessage(B_QUIT_REQUESTED); 22 | 23 | return true; 24 | } 25 | -------------------------------------------------------------------------------- /EmptyWindow/MainWindow.h: -------------------------------------------------------------------------------- 1 | #include // To use "BWindow" 2 | 3 | 4 | // Represents the window on the screen. 5 | // You can't see it until you use the "Show" method. 6 | class MainWindow : public BWindow 7 | { 8 | public: 9 | 10 | MainWindow(); 11 | 12 | virtual bool QuitRequested(); // Override the BWindow method 13 | }; 14 | -------------------------------------------------------------------------------- /EmptyWindow/ReadMe: -------------------------------------------------------------------------------- 1 | Create and show an empty window. 2 | Press the "close" button to close the window. -------------------------------------------------------------------------------- /EmptyWindow/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe -------------------------------------------------------------------------------- /FallLeaves/FLConfigView.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 David Couzelis. All rights reserved. 3 | * Distributed under the terms of the MIT License. 4 | */ 5 | 6 | 7 | #include 8 | #include 9 | 10 | #include "FallLeaves.h" 11 | #include "FLConfigView.h" 12 | 13 | 14 | // For language translations 15 | #undef B_TRANSLATION_CONTEXT 16 | #define B_TRANSLATION_CONTEXT "FallLeaves" 17 | 18 | 19 | enum { 20 | MSG_SET_AMOUNT = 'amnt', 21 | MSG_SET_SPEED = 'sped' 22 | }; 23 | 24 | 25 | FLConfigView::FLConfigView(BRect frame, FallLeaves* saver, 26 | int32 amount, int32 speed) 27 | : 28 | BView(frame, B_EMPTY_STRING, B_FOLLOW_ALL_SIDES, B_WILL_DRAW), 29 | fSaver(saver), 30 | fAmountSlider(NULL), 31 | fSpeedSlider(NULL) 32 | { 33 | SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 34 | 35 | // Screensaver name 36 | BRect rect(10, 10, 20, 20); 37 | BStringView* stringView = new BStringView(rect, B_EMPTY_STRING, 38 | B_TRANSLATE("Fall Leaves")); 39 | stringView->SetFont(be_bold_font); 40 | stringView->ResizeToPreferred(); 41 | AddChild(stringView); 42 | 43 | // Developer name 44 | rect.OffsetBy(0, stringView->Bounds().Height() + 4); 45 | stringView = new BStringView(rect, B_EMPTY_STRING, 46 | B_TRANSLATE("by David Couzelis")); 47 | stringView->ResizeToPreferred(); 48 | AddChild(stringView); 49 | 50 | BRect bounds = Bounds(); 51 | bounds.InsetBy(10, 10); 52 | BRect frame(0, 0, bounds.Width(), 20); 53 | 54 | // Speed setting slider 55 | fSpeedSlider = new BSlider(frame, B_EMPTY_STRING, 56 | B_TRANSLATE("Speed:"), new BMessage(MSG_SET_SPEED), 57 | kMinSpeed, kMaxSpeed, B_BLOCK_THUMB, 58 | B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM); 59 | fSpeedSlider->SetValue(speed); 60 | fSpeedSlider->ResizeToPreferred(); 61 | bounds.bottom -= fSpeedSlider->Bounds().Height() * 1.5; 62 | fSpeedSlider->MoveTo(bounds.LeftBottom()); 63 | AddChild(fSpeedSlider); 64 | 65 | // Amount setting slider 66 | fAmountSlider = new BSlider(frame, B_EMPTY_STRING, 67 | B_TRANSLATE("Amount:"), new BMessage(MSG_SET_AMOUNT), 68 | kMinAmount, kMaxAmount, B_BLOCK_THUMB, 69 | B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM); 70 | fAmountSlider->SetValue(amount); 71 | fAmountSlider->ResizeToPreferred(); 72 | bounds.bottom -= fAmountSlider->Bounds().Height() * 1.5; 73 | fAmountSlider->MoveTo(bounds.LeftBottom()); 74 | AddChild(fAmountSlider); 75 | }; 76 | 77 | 78 | void 79 | FLConfigView::AttachedToWindow() 80 | { 81 | fAmountSlider->SetTarget(this); 82 | fSpeedSlider->SetTarget(this); 83 | } 84 | 85 | 86 | void 87 | FLConfigView::MessageReceived(BMessage* message) 88 | { 89 | switch (message->what) { 90 | case MSG_SET_AMOUNT: 91 | fSaver->SetAmount(fAmountSlider->Value()); 92 | break; 93 | case MSG_SET_SPEED: 94 | fSaver->SetSpeed(fSpeedSlider->Value()); 95 | break; 96 | default: 97 | BHandler::MessageReceived(message); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /FallLeaves/FLConfigView.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 David Couzelis. All rights reserved. 3 | * Distributed under the terms of the MIT License. 4 | */ 5 | #ifndef _FLCONFIGVIEW_H_ 6 | #define _FLCONFIGVIEW_H_ 7 | 8 | 9 | #include 10 | #include 11 | 12 | 13 | typedef class FallLeaves; 14 | 15 | 16 | class FLConfigView : public BView 17 | { 18 | public: 19 | FLConfigView(BRect frame, FallLeaves* saver, 20 | int32 amount, int32 speed); 21 | 22 | void AttachedToWindow(); 23 | void MessageReceived(BMessage* message); 24 | private: 25 | FallLeaves* fSaver; 26 | 27 | BSlider* fAmountSlider; 28 | BSlider* fSpeedSlider; 29 | }; 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /FallLeaves/FLLeaf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 David Couzelis. All rights reserved. 3 | * Distributed under the terms of the MIT License. 4 | */ 5 | 6 | 7 | #include "FLLeaf.h" 8 | 9 | 10 | Leaf::Leaf(BBitmap* bitmap) 11 | : 12 | fBitmap(bitmap), 13 | fPos(BPoint()), 14 | fZ(0), 15 | fSpeed(0), 16 | fFudge(0), 17 | fBoundary(BRect()), 18 | fDead(false) 19 | { 20 | // Empty 21 | } 22 | 23 | 24 | void 25 | Leaf::Update(int32 ticksPerSecond) 26 | { 27 | if (fDead) 28 | return; 29 | 30 | fFudge += fSpeed; 31 | 32 | while (fFudge >= ticksPerSecond) { 33 | fPos.y++; 34 | fFudge -= ticksPerSecond; 35 | } 36 | 37 | // If the leaf is out of boundary... 38 | if (fPos.x < fBoundary.left || fPos.x > fBoundary.right 39 | || fPos.y < fBoundary.top || fPos.y > fBoundary.bottom) { 40 | fDead = true; // ...then it's dead 41 | } 42 | } 43 | 44 | 45 | void 46 | Leaf::Draw(BView* view) 47 | { 48 | if (fDead) 49 | return; 50 | 51 | view->DrawBitmap(fBitmap, fPos); 52 | } 53 | -------------------------------------------------------------------------------- /FallLeaves/FLLeaf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 David Couzelis. All rights reserved. 3 | * Distributed under the terms of the MIT License. 4 | */ 5 | #ifndef _FLLEAF_H_ 6 | #define _FLLEAF_H_ 7 | 8 | 9 | #include 10 | #include 11 | 12 | 13 | class Leaf 14 | { 15 | public: 16 | Leaf(BBitmap* bitmap); 17 | ~Leaf() { delete fBitmap; }; 18 | 19 | void Update(int32 ticksPerSecond); 20 | void Draw(BView* view); 21 | 22 | void SetPos(BPoint pos) { fPos = pos; }; 23 | BPoint Pos() { return fPos; }; 24 | 25 | void SetZ(int32 z) { fZ = z; }; 26 | int32 Z() const { return fZ; }; 27 | // The Z axis controls how far "in" 28 | // to the screen the leaf is 29 | 30 | void SetSpeed(int32 speed) { fSpeed = speed; }; 31 | 32 | int32 Width() { return fBitmap->Bounds().IntegerWidth(); }; 33 | int32 Height() { return fBitmap->Bounds().IntegerHeight(); }; 34 | 35 | bool IsDead() { return fDead; }; 36 | void SetBoundary(BRect boundary) { fBoundary = boundary; }; 37 | // A leaf is dead if it moves outside the boundary 38 | 39 | private: 40 | BBitmap *fBitmap; 41 | 42 | BPoint fPos; 43 | // The position on the screen 44 | int32 fZ; 45 | 46 | int32 fSpeed; 47 | // In pixels per second 48 | int32 fFudge; 49 | 50 | BRect fBoundary; 51 | bool fDead; 52 | }; 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /FallLeaves/FallLeaves.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 David Couzelis. All rights reserved. 3 | * Distributed under the terms of the MIT License. 4 | * 5 | * Authors: 6 | * David Couzelis, drcouzelis@gmail.com 7 | * 8 | * Inspired by and partially copied from: 9 | * The "Icons" screensaver, by Vincent Duvert. 10 | * The "Leaves" screensaver, by Deyan Genovski, Geoffry Song. 11 | * 12 | *Leaf images by Stephan Aßmus. 13 | */ 14 | 15 | 16 | #include 17 | 18 | #include "IconUtils.h" // TEMP local, soon to be made a public Haiku API 19 | 20 | #include "FallLeaves.h" 21 | #include "FLConfigView.h" 22 | #include "FLLeaf.h" 23 | 24 | 25 | #define RAND_NUM(low, high) ((rand() % ((high) - (low) + 1) + (low))) 26 | 27 | #define TICKS_PER_SECOND 100 28 | #define MICROSECS_IN_SEC 1000000 29 | 30 | 31 | const char* kArchiveAmountStr = "FallLeaves amount"; 32 | const char* kArchiveSpeedStr = "FallLeaves speed"; 33 | 34 | 35 | FallLeaves::FallLeaves(BMessage* archive, image_id thisImage) 36 | : 37 | BScreenSaver(archive, thisImage), 38 | fLeaves(NULL), 39 | fSize(0), 40 | fAmount(kDefaultAmount), 41 | fSpeed(kDefaultSpeed), 42 | fBackBitmap(NULL), 43 | fBackView(NULL) 44 | { 45 | for (int32 i = 0; i < 101; i++) 46 | fZUsed[i] = false; 47 | 48 | if (archive) { 49 | if (archive->FindInt32(kArchiveAmountStr, &fAmount) != B_OK) 50 | fAmount = kDefaultAmount; 51 | if (archive->FindInt32(kArchiveSpeedStr, &fSpeed) != B_OK) 52 | fSpeed = kDefaultSpeed; 53 | } 54 | } 55 | 56 | 57 | FallLeaves::~FallLeaves() 58 | { 59 | for (int32 i = 0; ; i++) { 60 | Leaf* leaf = fLeaves->ItemAt(i); 61 | if (leaf == NULL) 62 | break; 63 | delete leaf; 64 | } 65 | 66 | delete fLeaves; 67 | 68 | fBackBitmap->RemoveChild(fBackView); 69 | 70 | delete fBackView; 71 | delete fBackBitmap; 72 | } 73 | 74 | 75 | void 76 | FallLeaves::StartConfig(BView* configView) 77 | { 78 | FLConfigView* flConfigView = new FLConfigView(configView->Bounds(), this, 79 | fAmount, fSpeed); 80 | 81 | configView->AddChild(flConfigView); 82 | } 83 | 84 | 85 | /* A small helper function to sort leaves. 86 | Sort the leaves in order of their Z axis, 87 | from large to small. 88 | */ 89 | int 90 | cmpz(const Leaf* leaf1, const Leaf* leaf2) 91 | { 92 | if (leaf1->Z() < leaf2->Z()) 93 | return 1; 94 | 95 | if (leaf1->Z() > leaf2->Z()) 96 | return -1; 97 | 98 | return 0; 99 | } 100 | 101 | 102 | status_t 103 | FallLeaves::StartSaver(BView* view, bool preview) 104 | { 105 | BRect screenRect = view->Bounds(); 106 | 107 | // Initialize the screen buffer 108 | fBackBitmap = new BBitmap(screenRect, B_RGBA32, true); 109 | fBackView = new BView(screenRect, NULL, 0, 0); 110 | 111 | fBackBitmap->AddChild(fBackView); 112 | 113 | if (fBackBitmap->Lock()) { 114 | fBackView->FillRect(fBackView->Bounds()); 115 | fBackView->SetDrawingMode(B_OP_OVER); // Leaf transparency 116 | fBackBitmap->Unlock(); 117 | } 118 | 119 | // Set the rate the screensaver to be updated 100 times per second 120 | // The argument here is in microseconds 121 | SetTickSize(MICROSECS_IN_SEC / TICKS_PER_SECOND); 122 | 123 | // Initialize the random number generator 124 | srand(system_time() % INT_MAX); 125 | 126 | // The max size of a leaf will be about 20% the 127 | // height of the screen 128 | fSize = (view->Bounds().IntegerHeight() * 2) / 10; 129 | 130 | fLeaves = new BObjectList(); 131 | 132 | // Create some leaves 133 | for (int32 i = 0; i < fAmount; i++) 134 | fLeaves->AddItem(_CreateLeaf(view, true)); 135 | 136 | // Sort the leaves by Z axis 137 | fLeaves->SortItems(cmpz); 138 | 139 | return B_OK; 140 | } 141 | 142 | 143 | status_t 144 | FallLeaves::SaveState(BMessage* into) const 145 | { 146 | if (into) { 147 | into->AddInt32(kArchiveAmountStr, fAmount); 148 | into->AddInt32(kArchiveSpeedStr, fSpeed); 149 | return B_OK; 150 | } 151 | 152 | return B_BAD_VALUE; 153 | } 154 | 155 | 156 | void 157 | FallLeaves::Draw(BView* view, int32 frame) 158 | { 159 | if (fBackBitmap->Lock()) { 160 | 161 | // Clear the offscreen buffer 162 | fBackView->FillRect(fBackView->Bounds()); 163 | 164 | // Update and draw the leaves 165 | for (int32 i = fLeaves->CountItems() - 1; ; i--) { 166 | Leaf* leaf = fLeaves->ItemAt(i); 167 | if (leaf == NULL) 168 | break; 169 | leaf->Update(TICKS_PER_SECOND); 170 | leaf->Draw(fBackView); 171 | 172 | // If the leaf is dead, remove it 173 | if (leaf->IsDead()) { 174 | fZUsed[leaf->Z()] = false; 175 | fLeaves->RemoveItem(leaf); 176 | delete leaf; 177 | } 178 | } 179 | 180 | fBackBitmap->Unlock(); 181 | } 182 | 183 | bool sort = false; 184 | 185 | // Add some new leaves if necessary 186 | // to replace any dead ones 187 | while (fLeaves->CountItems() < fAmount) { 188 | fLeaves->AddItem(_CreateLeaf(view, false)); 189 | sort = true; 190 | } 191 | 192 | // Keep the leaves sorted by Z axis 193 | if (sort) 194 | fLeaves->SortItems(cmpz); 195 | 196 | view->DrawBitmap(fBackBitmap); 197 | } 198 | 199 | 200 | void 201 | FallLeaves::SetAmount(int32 amount) 202 | { 203 | fAmount = amount; 204 | } 205 | 206 | 207 | void 208 | FallLeaves::SetSpeed(int32 speed) 209 | { 210 | fSpeed = speed; 211 | } 212 | 213 | 214 | /* 215 | Create a leaf. 216 | If the "above" parameter is true, it will create the leaf in 217 | a random location above the screen. If it's false, the leaf 218 | will be created just above the screen, ready to come it. 219 | */ 220 | Leaf* 221 | FallLeaves::_CreateLeaf(BView* view, bool above) 222 | { 223 | // The Z axis (how far away the leaf is) 224 | // determines the size and speed 225 | int32 z = RAND_NUM(40, 100); 226 | 227 | // Use this array to ensure unique Z values. 228 | while (fZUsed[z]) { 229 | z++; 230 | if (z > 100) 231 | z = 40; 232 | } 233 | fZUsed[z] = true; 234 | 235 | // The lower the Z axis number, the smaller the leaf 236 | int32 size = (fSize * z) / 100; 237 | 238 | // Create the leaf 239 | Leaf* leaf = new Leaf(_RandomBitmap(size)); 240 | 241 | leaf->SetZ(z); 242 | 243 | // The lower the Z axis number, the slower the leaf 244 | int32 maxSpeedFromScreenSize = view->Bounds().IntegerHeight(); 245 | int32 maxSpeed = (maxSpeedFromScreenSize * fSpeed) / kMaxSpeed; 246 | int32 speed = (maxSpeed * z) / 100; 247 | leaf->SetSpeed(speed); 248 | 249 | BRect boundary(-(size / 2), -view->Bounds().Height(), 250 | view->Bounds().Width() - (size / 2), view->Bounds().Height()); 251 | leaf->SetBoundary(boundary); 252 | 253 | // Set it to a random position 254 | BPoint pos; 255 | pos.x = RAND_NUM((int32)boundary.left, boundary.IntegerWidth()); 256 | pos.y = -size; 257 | 258 | if (above) 259 | pos.y = -(RAND_NUM(size, boundary.IntegerHeight())); 260 | 261 | leaf->SetPos(pos); 262 | 263 | return leaf; 264 | } 265 | 266 | 267 | // Leaf 1 - Orange 1 268 | const unsigned char kLeaf1[] = { 269 | 0x6e, 0x63, 0x69, 0x66, 0x08, 0x05, 0x00, 0x02, 0x00, 0x12, 0x02, 0x00, 270 | 0x00, 0x00, 0x3d, 0x40, 0x00, 0xbd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4b, 271 | 0x20, 0x00, 0x4a, 0x10, 0x00, 0x00, 0x01, 0x66, 0xff, 0x01, 0x85, 0x02, 272 | 0x00, 0x06, 0x02, 0x3b, 0x9f, 0xd5, 0xbb, 0x5f, 0x70, 0x3e, 0xb9, 0x98, 273 | 0x3e, 0xed, 0x9f, 0x45, 0xbf, 0xbf, 0x47, 0x19, 0x8c, 0x00, 0xc5, 0x84, 274 | 0x30, 0xff, 0xdd, 0x7a, 0x29, 0x02, 0x00, 0x06, 0x02, 0x3b, 0x9f, 0xd5, 275 | 0xbb, 0x5f, 0x70, 0x3e, 0xb9, 0x98, 0x3e, 0xed, 0x9f, 0x45, 0x8f, 0xbf, 276 | 0x46, 0xf9, 0x8c, 0x00, 0xff, 0xd7, 0x60, 0xff, 0xed, 0x9d, 0x46, 0x02, 277 | 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 278 | 0x3c, 0x7f, 0xb1, 0x4a, 0xd6, 0x23, 0x45, 0xf4, 0x80, 0x00, 0xda, 0x4c, 279 | 0x05, 0xfe, 0xff, 0xb6, 0x43, 0x02, 0x01, 0x06, 0x02, 0x38, 0xa0, 0x81, 280 | 0x3c, 0xe4, 0x69, 0xc0, 0x05, 0xf5, 0x3b, 0xac, 0xe9, 0x4a, 0x36, 0x3c, 281 | 0x4a, 0x20, 0x00, 0x00, 0xfd, 0xb3, 0x3d, 0xff, 0xda, 0x4c, 0x05, 0x02, 282 | 0x01, 0x06, 0x02, 0xbd, 0x28, 0x86, 0x3d, 0x5c, 0x6c, 0xbc, 0x93, 0x89, 283 | 0xbc, 0x6b, 0xc1, 0x4a, 0x2c, 0xa1, 0x4a, 0x72, 0x01, 0x00, 0xfd, 0xd1, 284 | 0x5b, 0xff, 0xda, 0x4c, 0x05, 0x02, 0x00, 0x06, 0x02, 0x34, 0xb4, 0xd1, 285 | 0x37, 0x3c, 0x1e, 0xbc, 0x49, 0x56, 0x39, 0xd3, 0x68, 0x48, 0xda, 0x03, 286 | 0x4a, 0xe2, 0x5a, 0x00, 0xff, 0xd7, 0x5f, 0xff, 0xa4, 0x37, 0x0b, 0x07, 287 | 0x06, 0x0d, 0xae, 0xff, 0xcf, 0x02, 0x24, 0x5a, 0x29, 0x5a, 0x29, 0x5a, 288 | 0x2f, 0x56, 0x34, 0x51, 0x3e, 0x5c, 0x41, 0x54, 0x40, 0x5b, 0x49, 0x58, 289 | 0x5a, 0x54, 0x57, 0x57, 0x5a, 0x4c, 0x4d, 0x4b, 0x4d, 0x4b, 0x55, 0x4a, 290 | 0x60, 0x3f, 0x5f, 0x43, 0x60, 0x3a, 0x52, 0x3a, 0x52, 0x3a, 0x58, 0x36, 291 | 0x5a, 0x2b, 0x5c, 0x2f, 0xc9, 0x69, 0xb6, 0xe2, 0x54, 0x25, 0x4e, 0x25, 292 | 0x4e, 0x28, 0x50, 0x2e, 0x50, 0x06, 0x0a, 0xee, 0xbe, 0x0b, 0x33, 0x4c, 293 | 0x3e, 0x43, 0x39, 0x48, 0xc1, 0xf5, 0xbd, 0xf0, 0x4d, 0x31, 0xbf, 0xe8, 294 | 0xc0, 0x75, 0x47, 0x3b, 0x48, 0x43, 0x52, 0x40, 0xbf, 0x63, 0xc1, 0x06, 295 | 0x47, 0x44, 0xbe, 0x4d, 0xc2, 0x30, 0xbd, 0x68, 0xc3, 0x0a, 0xbe, 0x25, 296 | 0xc2, 0x56, 0x40, 0x4c, 0x4a, 0x4f, 0xbc, 0xf9, 0xc3, 0x8b, 0xc0, 0x32, 297 | 0xc4, 0xfa, 0xbc, 0x3d, 0xc4, 0x39, 0x35, 0x4d, 0x06, 0x0f, 0xee, 0xbb, 298 | 0xfb, 0x2e, 0xba, 0xb8, 0xc4, 0xbb, 0xbc, 0x44, 0x49, 0xbb, 0x84, 0xc4, 299 | 0x01, 0x33, 0x46, 0x2e, 0x40, 0xbc, 0xca, 0xc2, 0xde, 0x35, 0x46, 0xbd, 300 | 0x85, 0xc2, 0x35, 0xbe, 0xd6, 0xc0, 0xfd, 0xbd, 0xae, 0xc2, 0x1d, 0x3d, 301 | 0x3b, 0x3a, 0x33, 0xbf, 0x80, 0xc0, 0x59, 0x3f, 0x3c, 0xc1, 0xe4, 0xbd, 302 | 0xf5, 0xc5, 0x14, 0xb9, 0xf9, 0xc0, 0x0e, 0xc0, 0xa8, 0x47, 0x3c, 0xc3, 303 | 0x16, 0xc1, 0x25, 0x52, 0x40, 0xbf, 0x89, 0xc1, 0x39, 0xc2, 0xb0, 0xc1, 304 | 0x8b, 0xbe, 0x73, 0xc2, 0x63, 0xbd, 0x8e, 0xc3, 0x3d, 0xbe, 0x4b, 0xc2, 305 | 0x89, 0xbf, 0xe6, 0xc4, 0xbb, 0x4a, 0x4f, 0x3a, 0x4a, 0xc0, 0x6f, 0xc5, 306 | 0x5d, 0xbc, 0xa0, 0xc4, 0x6a, 0x35, 0x4f, 0x06, 0x04, 0xae, 0x4e, 0x3a, 307 | 0x52, 0x26, 0x58, 0x2e, 0xc3, 0x89, 0xb5, 0xfd, 0x43, 0x35, 0x3f, 0x42, 308 | 0x06, 0x08, 0xef, 0xba, 0x26, 0x36, 0x30, 0x35, 0x25, 0x3f, 0x2c, 0x48, 309 | 0x2c, 0x48, 0x28, 0x48, 0x25, 0x4b, 0x33, 0x4c, 0x29, 0x4d, 0x33, 0x4c, 310 | 0x3f, 0x42, 0x43, 0x35, 0x38, 0x2a, 0x41, 0x2d, 0x31, 0x32, 0x35, 0x3e, 311 | 0x06, 0x08, 0xfb, 0xae, 0x35, 0x4d, 0x35, 0x4d, 0x35, 0x56, 0x3b, 0x59, 312 | 0x3e, 0x51, 0x3f, 0x54, 0x3e, 0x51, 0x55, 0x52, 0x4b, 0x57, 0x56, 0x4c, 313 | 0x48, 0x49, 0x5c, 0x3b, 0x59, 0x46, 0x5b, 0x37, 0x4e, 0x3a, 0x3f, 0x42, 314 | 0x06, 0x04, 0xeb, 0x33, 0x4c, 0x33, 0x4c, 0x2d, 0x51, 0x23, 0x55, 0x27, 315 | 0x56, 0x35, 0x4d, 0x30, 0x51, 0x35, 0x4d, 0x07, 0x0a, 0x00, 0x04, 0x03, 316 | 0x04, 0x05, 0x06, 0x10, 0x01, 0x17, 0x84, 0x00, 0x04, 0x0a, 0x05, 0x01, 317 | 0x04, 0x00, 0x0a, 0x06, 0x01, 0x05, 0x00, 0x0a, 0x04, 0x01, 0x03, 0x00, 318 | 0x0a, 0x02, 0x01, 0x02, 0x00, 0x0a, 0x07, 0x01, 0x06, 0x00, 0x0a, 0x03, 319 | 0x01, 0x01, 0x08, 0x15, 0xff 320 | }; 321 | 322 | // Leaf 2 - Orange 2 323 | const unsigned char kLeaf2[] = { 324 | 0x6e, 0x63, 0x69, 0x66, 0x09, 0x05, 0x00, 0x02, 0x00, 0x12, 0x02, 0x00, 325 | 0x00, 0x00, 0x3d, 0x40, 0x00, 0xbd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4a, 326 | 0xe0, 0x00, 0x4a, 0x10, 0x00, 0x00, 0x01, 0x66, 0xff, 0x01, 0x85, 0x02, 327 | 0x00, 0x06, 0x02, 0xbb, 0x54, 0x89, 0xbb, 0xa9, 0xdc, 0x3d, 0x61, 0x95, 328 | 0xbd, 0x12, 0xd5, 0x47, 0x21, 0xcd, 0x4b, 0x2e, 0xe5, 0x00, 0xff, 0xab, 329 | 0x3e, 0xff, 0xdd, 0x7a, 0x29, 0x02, 0x00, 0x06, 0x02, 0xba, 0x3f, 0xb3, 330 | 0x3b, 0x68, 0x5f, 0xbc, 0xea, 0x1e, 0xbb, 0xd8, 0xc4, 0x4a, 0x9e, 0xae, 331 | 0x4a, 0x75, 0x8e, 0x00, 0xff, 0xc1, 0x4b, 0xff, 0xff, 0xd7, 0x5f, 0x02, 332 | 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 333 | 0x3c, 0x7f, 0xb1, 0x4a, 0x96, 0x23, 0x45, 0xf4, 0x80, 0x00, 0xda, 0x4c, 334 | 0x05, 0xfe, 0xff, 0xb6, 0x43, 0x02, 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 335 | 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 0x3c, 0x7f, 0xb1, 0x4a, 0x96, 0x23, 336 | 0x45, 0xf4, 0x80, 0x00, 0xf7, 0x70, 0x2e, 0xff, 0xff, 0xd6, 0x59, 0x02, 337 | 0x01, 0x06, 0x02, 0x38, 0xa0, 0x81, 0x3c, 0xe4, 0x69, 0xc0, 0x05, 0xf5, 338 | 0x3b, 0xac, 0xe9, 0x49, 0xec, 0x78, 0x4a, 0x20, 0x00, 0x00, 0xfd, 0xb3, 339 | 0x3d, 0xff, 0xda, 0x4c, 0x05, 0x02, 0x01, 0x06, 0x02, 0xbd, 0x28, 0x86, 340 | 0x3d, 0x5c, 0x6c, 0xbc, 0x93, 0x89, 0xbc, 0x6b, 0xc1, 0x4a, 0x0c, 0xa1, 341 | 0x4a, 0x82, 0x01, 0x00, 0xff, 0xd6, 0x59, 0xff, 0xf7, 0x70, 0x2e, 0x02, 342 | 0x00, 0x06, 0x02, 0x35, 0x9e, 0x73, 0x37, 0x00, 0xe5, 0xbc, 0x1f, 0x7a, 343 | 0x3a, 0x8e, 0xd7, 0x48, 0x5d, 0xc8, 0x4a, 0xdf, 0x90, 0x00, 0xff, 0xd7, 344 | 0x5f, 0xff, 0xa4, 0x37, 0x0b, 0x08, 0x06, 0x0e, 0xee, 0xeb, 0xbb, 0x0b, 345 | 0x22, 0x5a, 0x28, 0x5a, 0x28, 0x5a, 0x2e, 0x55, 0x31, 0x51, 0x3d, 0x58, 346 | 0x39, 0x58, 0x3d, 0x58, 0x3d, 0x53, 0x3d, 0x53, 0x48, 0x58, 0x54, 0x52, 347 | 0x53, 0x4f, 0x60, 0x48, 0x5b, 0x4e, 0x60, 0x41, 0x4f, 0x3f, 0x4f, 0x3f, 348 | 0x57, 0x3a, 0x58, 0x30, 0x54, 0x2a, 0x53, 0x2e, 0x51, 0x2b, 0x4e, 0x2b, 349 | 0x23, 0x4d, 0x23, 0x4d, 0x26, 0x4f, 0x2d, 0x4f, 0x06, 0x0a, 0xee, 0xbe, 350 | 0x0b, 0x2f, 0x4c, 0x38, 0x44, 0xba, 0x74, 0xc3, 0x37, 0x41, 0x3c, 0x4c, 351 | 0x29, 0xbd, 0x1e, 0xc1, 0xa7, 0x42, 0x3c, 0x42, 0x45, 0x4d, 0x45, 0xbc, 352 | 0x99, 0xc2, 0x38, 0x43, 0x46, 0xbc, 0x99, 0xc2, 0x38, 0xbb, 0xd0, 0xc3, 353 | 0x0a, 0xbb, 0xd0, 0xc3, 0x0a, 0x3c, 0x4c, 0x46, 0x4f, 0xbb, 0x61, 0xc3, 354 | 0x8b, 0xbe, 0x9a, 0xc4, 0xfa, 0xba, 0xa5, 0xc4, 0x39, 0x31, 0x4d, 0x06, 355 | 0x0f, 0xee, 0xbb, 0xfb, 0x2e, 0xb9, 0x20, 0xc4, 0xbb, 0xba, 0xac, 0x49, 356 | 0xb9, 0xec, 0xc4, 0x01, 0x2f, 0x46, 0x2c, 0x42, 0xbb, 0x32, 0xc2, 0xde, 357 | 0x31, 0x46, 0xbb, 0x32, 0xc2, 0xde, 0xbc, 0x0c, 0xc2, 0x2f, 0xbc, 0x0c, 358 | 0xc2, 0x2f, 0x35, 0x40, 0x2d, 0x34, 0x38, 0x45, 0xbb, 0x9d, 0xbf, 0x8d, 359 | 0x3e, 0x3e, 0x48, 0x31, 0xbd, 0x44, 0xc1, 0xda, 0x40, 0x40, 0xc0, 0x4c, 360 | 0xc2, 0x57, 0x53, 0x44, 0xbc, 0xbf, 0xc2, 0x6b, 0x40, 0x49, 0xbc, 0xbf, 361 | 0xc2, 0x6b, 0x37, 0x49, 0x37, 0x49, 0xbe, 0x81, 0xc4, 0xd3, 0x3f, 0x4e, 362 | 0x36, 0x4a, 0x3a, 0x4d, 0xbb, 0x08, 0xc4, 0x6a, 0x31, 0x4f, 0x06, 0x05, 363 | 0xae, 0x02, 0x4e, 0x26, 0x42, 0x2a, 0x46, 0x2b, 0x3b, 0x2e, 0x38, 0x36, 364 | 0x3b, 0x42, 0x46, 0x34, 0x06, 0x05, 0xae, 0x02, 0x49, 0x3e, 0x52, 0x2f, 365 | 0xc6, 0xab, 0xbb, 0x90, 0xc5, 0xc8, 0xb8, 0x7c, 0x4e, 0x26, 0x46, 0x34, 366 | 0x3b, 0x42, 0x06, 0x0a, 0xeb, 0xaa, 0x0b, 0x22, 0x36, 0x22, 0x36, 0x21, 367 | 0x3f, 0x28, 0x48, 0x24, 0x49, 0x2f, 0x4c, 0x27, 0x4d, 0x2f, 0x4c, 0x3b, 368 | 0x42, 0x38, 0x36, 0x30, 0x2a, 0x2c, 0x2c, 0x28, 0x29, 0x28, 0x29, 0x24, 369 | 0x2d, 0x26, 0x36, 0x06, 0x0a, 0xeb, 0x6e, 0x0a, 0x31, 0x4d, 0x31, 0x4d, 370 | 0x31, 0x54, 0x39, 0x56, 0x3a, 0x51, 0x50, 0x4f, 0x49, 0x55, 0x50, 0x4f, 371 | 0x4e, 0x4c, 0x5a, 0x44, 0x55, 0x4b, 0x5a, 0x44, 0x56, 0x42, 0x40, 0x49, 372 | 0x3e, 0x3b, 0x42, 0x06, 0x04, 0xeb, 0x2f, 0x4c, 0x2f, 0x4c, 0x29, 0x52, 373 | 0x22, 0x57, 0x26, 0x58, 0x31, 0x4d, 0x2c, 0x53, 0x31, 0x4d, 0x08, 0x0a, 374 | 0x00, 0x05, 0x03, 0x05, 0x06, 0x07, 0x04, 0x10, 0x01, 0x17, 0x84, 0x02, 375 | 0x04, 0x0a, 0x06, 0x01, 0x05, 0x00, 0x0a, 0x07, 0x01, 0x06, 0x00, 0x0a, 376 | 0x04, 0x01, 0x03, 0x00, 0x0a, 0x05, 0x01, 0x04, 0x00, 0x0a, 0x02, 0x01, 377 | 0x02, 0x00, 0x0a, 0x08, 0x01, 0x07, 0x00, 0x0a, 0x03, 0x01, 0x01, 0x08, 378 | 0x15, 0xff 379 | }; 380 | 381 | // Leaf 3 - Green 1 382 | const unsigned char kLeaf3[] = { 383 | 0x6e, 0x63, 0x69, 0x66, 0x08, 0x05, 0x00, 0x02, 0x00, 0x12, 0x02, 0x00, 384 | 0x00, 0x00, 0x3d, 0x40, 0x00, 0xbd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4b, 385 | 0x20, 0x00, 0x4a, 0x10, 0x00, 0x00, 0x01, 0x66, 0xff, 0x01, 0x85, 0x02, 386 | 0x00, 0x06, 0x02, 0x3b, 0x9f, 0xd5, 0xbb, 0x5f, 0x70, 0x3e, 0xb9, 0x98, 387 | 0x3e, 0xed, 0x9f, 0x45, 0xbf, 0xbf, 0x47, 0x19, 0x8c, 0x00, 0xc5, 0xc3, 388 | 0x30, 0xff, 0xdd, 0xc5, 0x27, 0x02, 0x00, 0x06, 0x02, 0x3b, 0x9f, 0xd5, 389 | 0xbb, 0x5f, 0x70, 0x3e, 0xb9, 0x98, 0x3e, 0xed, 0x9f, 0x45, 0x8f, 0xbf, 390 | 0x46, 0xf9, 0x8c, 0x00, 0xe3, 0xff, 0x5f, 0xff, 0xed, 0xe2, 0x46, 0x02, 391 | 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 392 | 0x3c, 0x7f, 0xb1, 0x4a, 0xd6, 0x23, 0x45, 0xf4, 0x80, 0x00, 0xda, 0xa5, 393 | 0x05, 0xfe, 0xf8, 0xff, 0x43, 0x02, 0x01, 0x06, 0x02, 0x38, 0xa0, 0x81, 394 | 0x3c, 0xe4, 0x69, 0xc0, 0x05, 0xf5, 0x3b, 0xac, 0xe9, 0x4a, 0x36, 0x3c, 395 | 0x4a, 0x20, 0x00, 0x00, 0xf7, 0xfd, 0x3d, 0xff, 0xda, 0xa5, 0x05, 0x02, 396 | 0x01, 0x06, 0x02, 0xbd, 0x28, 0x86, 0x3d, 0x5c, 0x6c, 0xbc, 0x93, 0x89, 397 | 0xbc, 0x6b, 0xc1, 0x4a, 0x2c, 0xa1, 0x4a, 0x72, 0x01, 0x00, 0xe5, 0xfd, 398 | 0x5b, 0xff, 0xda, 0xa5, 0x05, 0x02, 0x00, 0x06, 0x02, 0x34, 0xb4, 0xd1, 399 | 0x37, 0x3c, 0x1e, 0xbc, 0x49, 0x56, 0x39, 0xd3, 0x68, 0x48, 0xda, 0x03, 400 | 0x4a, 0xe2, 0x5a, 0x00, 0xe3, 0xff, 0x5f, 0xff, 0xa4, 0x78, 0x0a, 0x07, 401 | 0x06, 0x0d, 0xae, 0xff, 0xcf, 0x02, 0x24, 0x5a, 0x29, 0x5a, 0x29, 0x5a, 402 | 0x2f, 0x56, 0x34, 0x51, 0x3e, 0x5c, 0x41, 0x54, 0x40, 0x5b, 0x49, 0x58, 403 | 0x5a, 0x54, 0x57, 0x57, 0x5a, 0x4c, 0x4d, 0x4b, 0x4d, 0x4b, 0x55, 0x4a, 404 | 0x60, 0x3f, 0x5f, 0x43, 0x60, 0x3a, 0x52, 0x3a, 0x52, 0x3a, 0x58, 0x36, 405 | 0x5a, 0x2b, 0x5c, 0x2f, 0xc9, 0x69, 0xb6, 0xe2, 0x54, 0x25, 0x4e, 0x25, 406 | 0x4e, 0x28, 0x50, 0x2e, 0x50, 0x06, 0x0a, 0xee, 0xbe, 0x0b, 0x33, 0x4c, 407 | 0x3e, 0x43, 0x39, 0x48, 0xc1, 0xf5, 0xbd, 0xf0, 0x4d, 0x31, 0xbf, 0xe8, 408 | 0xc0, 0x75, 0x47, 0x3b, 0x48, 0x43, 0x52, 0x40, 0xbf, 0x63, 0xc1, 0x06, 409 | 0x47, 0x44, 0xbe, 0x4d, 0xc2, 0x30, 0xbd, 0x68, 0xc3, 0x0a, 0xbe, 0x25, 410 | 0xc2, 0x56, 0x40, 0x4c, 0x4a, 0x4f, 0xbc, 0xf9, 0xc3, 0x8b, 0xc0, 0x32, 411 | 0xc4, 0xfa, 0xbc, 0x3d, 0xc4, 0x39, 0x35, 0x4d, 0x06, 0x0f, 0xee, 0xbb, 412 | 0xfb, 0x2e, 0xba, 0xb8, 0xc4, 0xbb, 0xbc, 0x44, 0x49, 0xbb, 0x84, 0xc4, 413 | 0x01, 0x33, 0x46, 0x2e, 0x40, 0xbc, 0xca, 0xc2, 0xde, 0x35, 0x46, 0xbd, 414 | 0x85, 0xc2, 0x35, 0xbe, 0xd6, 0xc0, 0xfd, 0xbd, 0xae, 0xc2, 0x1d, 0x3d, 415 | 0x3b, 0x3a, 0x33, 0xbf, 0x80, 0xc0, 0x59, 0x3f, 0x3c, 0xc1, 0xe4, 0xbd, 416 | 0xf5, 0xc5, 0x14, 0xb9, 0xf9, 0xc0, 0x0e, 0xc0, 0xa8, 0x47, 0x3c, 0xc3, 417 | 0x16, 0xc1, 0x25, 0x52, 0x40, 0xbf, 0x89, 0xc1, 0x39, 0xc2, 0xb0, 0xc1, 418 | 0x8b, 0xbe, 0x73, 0xc2, 0x63, 0xbd, 0x8e, 0xc3, 0x3d, 0xbe, 0x4b, 0xc2, 419 | 0x89, 0xbf, 0xe6, 0xc4, 0xbb, 0x4a, 0x4f, 0x3a, 0x4a, 0xc0, 0x6f, 0xc5, 420 | 0x5d, 0xbc, 0xa0, 0xc4, 0x6a, 0x35, 0x4f, 0x06, 0x04, 0xae, 0x4e, 0x3a, 421 | 0x52, 0x26, 0x58, 0x2e, 0xc3, 0x89, 0xb5, 0xfd, 0x43, 0x35, 0x3f, 0x42, 422 | 0x06, 0x08, 0xef, 0xba, 0x26, 0x36, 0x30, 0x35, 0x25, 0x3f, 0x2c, 0x48, 423 | 0x2c, 0x48, 0x28, 0x48, 0x25, 0x4b, 0x33, 0x4c, 0x29, 0x4d, 0x33, 0x4c, 424 | 0x3f, 0x42, 0x43, 0x35, 0x38, 0x2a, 0x41, 0x2d, 0x31, 0x32, 0x35, 0x3e, 425 | 0x06, 0x08, 0xfb, 0xae, 0x35, 0x4d, 0x35, 0x4d, 0x35, 0x56, 0x3b, 0x59, 426 | 0x3e, 0x51, 0x3f, 0x54, 0x3e, 0x51, 0x55, 0x52, 0x4b, 0x57, 0x56, 0x4c, 427 | 0x48, 0x49, 0x5c, 0x3b, 0x59, 0x46, 0x5b, 0x37, 0x4e, 0x3a, 0x3f, 0x42, 428 | 0x06, 0x04, 0xeb, 0x33, 0x4c, 0x33, 0x4c, 0x2d, 0x51, 0x23, 0x55, 0x27, 429 | 0x56, 0x35, 0x4d, 0x30, 0x51, 0x35, 0x4d, 0x07, 0x0a, 0x00, 0x04, 0x03, 430 | 0x04, 0x05, 0x06, 0x10, 0x01, 0x17, 0x84, 0x00, 0x04, 0x0a, 0x05, 0x01, 431 | 0x04, 0x00, 0x0a, 0x06, 0x01, 0x05, 0x00, 0x0a, 0x04, 0x01, 0x03, 0x00, 432 | 0x0a, 0x02, 0x01, 0x02, 0x00, 0x0a, 0x07, 0x01, 0x06, 0x00, 0x0a, 0x03, 433 | 0x01, 0x01, 0x08, 0x15, 0xff 434 | }; 435 | 436 | // Leaf 4 - Green 2 437 | const unsigned char kLeaf4[] = { 438 | 0x6e, 0x63, 0x69, 0x66, 0x09, 0x05, 0x00, 0x02, 0x00, 0x12, 0x02, 0x00, 439 | 0x00, 0x00, 0x3d, 0x40, 0x00, 0xbd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4a, 440 | 0xe0, 0x00, 0x4a, 0x10, 0x00, 0x00, 0x01, 0x66, 0xff, 0x01, 0x85, 0x02, 441 | 0x00, 0x06, 0x02, 0xbb, 0x54, 0x89, 0xbb, 0xa9, 0xdc, 0x3d, 0x61, 0x95, 442 | 0xbd, 0x12, 0xd5, 0x47, 0x21, 0xcd, 0x4b, 0x2e, 0xe5, 0x00, 0xff, 0xfc, 443 | 0x3c, 0xff, 0xdd, 0xc5, 0x27, 0x02, 0x00, 0x06, 0x02, 0xba, 0x3f, 0xb3, 444 | 0x3b, 0x68, 0x5f, 0xbc, 0xea, 0x1e, 0xbb, 0xd8, 0xc4, 0x4a, 0x9e, 0xae, 445 | 0x4a, 0x75, 0x8e, 0x00, 0xf2, 0xff, 0x4b, 0xff, 0xe7, 0xff, 0x5f, 0x02, 446 | 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 447 | 0x3c, 0x7f, 0xb1, 0x4a, 0x96, 0x23, 0x45, 0xf4, 0x80, 0x00, 0xda, 0xa5, 448 | 0x05, 0xfe, 0xf8, 0xff, 0x43, 0x02, 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 449 | 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 0x3c, 0x7f, 0xb1, 0x4a, 0x96, 0x23, 450 | 0x45, 0xf4, 0x80, 0x00, 0xf7, 0xc5, 0x2e, 0xff, 0xe3, 0xff, 0x59, 0x02, 451 | 0x01, 0x06, 0x02, 0x38, 0xa0, 0x81, 0x3c, 0xe4, 0x69, 0xc0, 0x05, 0xf5, 452 | 0x3b, 0xac, 0xe9, 0x49, 0xec, 0x78, 0x4a, 0x20, 0x00, 0x00, 0xf7, 0xfd, 453 | 0x3d, 0xff, 0xda, 0xa5, 0x05, 0x02, 0x01, 0x06, 0x02, 0xbd, 0x28, 0x86, 454 | 0x3d, 0x5c, 0x6c, 0xbc, 0x93, 0x89, 0xbc, 0x6b, 0xc1, 0x4a, 0x0c, 0xa1, 455 | 0x4a, 0x82, 0x01, 0x00, 0xe3, 0xff, 0x59, 0xff, 0xf7, 0xc5, 0x2e, 0x02, 456 | 0x00, 0x06, 0x02, 0x35, 0x9e, 0x73, 0x37, 0x00, 0xe5, 0xbc, 0x1f, 0x7a, 457 | 0x3a, 0x8e, 0xd7, 0x48, 0x5d, 0xc8, 0x4a, 0xdf, 0x90, 0x00, 0xe3, 0xff, 458 | 0x5f, 0xff, 0xa4, 0x78, 0x0a, 0x08, 0x06, 0x0e, 0xee, 0xeb, 0xbb, 0x0b, 459 | 0x22, 0x5a, 0x28, 0x5a, 0x28, 0x5a, 0x2e, 0x55, 0x31, 0x51, 0x3d, 0x58, 460 | 0x39, 0x58, 0x3d, 0x58, 0x3d, 0x53, 0x3d, 0x53, 0x48, 0x58, 0x54, 0x52, 461 | 0x53, 0x4f, 0x60, 0x48, 0x5b, 0x4e, 0x60, 0x41, 0x4f, 0x3f, 0x4f, 0x3f, 462 | 0x57, 0x3a, 0x58, 0x30, 0x54, 0x2a, 0x53, 0x2e, 0x51, 0x2b, 0x4e, 0x2b, 463 | 0x23, 0x4d, 0x23, 0x4d, 0x26, 0x4f, 0x2d, 0x4f, 0x06, 0x0a, 0xee, 0xbe, 464 | 0x0b, 0x2f, 0x4c, 0x38, 0x44, 0xba, 0x74, 0xc3, 0x37, 0x41, 0x3c, 0x4c, 465 | 0x29, 0xbd, 0x1e, 0xc1, 0xa7, 0x42, 0x3c, 0x42, 0x45, 0x4d, 0x45, 0xbc, 466 | 0x99, 0xc2, 0x38, 0x43, 0x46, 0xbc, 0x99, 0xc2, 0x38, 0xbb, 0xd0, 0xc3, 467 | 0x0a, 0xbb, 0xd0, 0xc3, 0x0a, 0x3c, 0x4c, 0x46, 0x4f, 0xbb, 0x61, 0xc3, 468 | 0x8b, 0xbe, 0x9a, 0xc4, 0xfa, 0xba, 0xa5, 0xc4, 0x39, 0x31, 0x4d, 0x06, 469 | 0x0f, 0xee, 0xbb, 0xfb, 0x2e, 0xb9, 0x20, 0xc4, 0xbb, 0xba, 0xac, 0x49, 470 | 0xb9, 0xec, 0xc4, 0x01, 0x2f, 0x46, 0x2c, 0x42, 0xbb, 0x32, 0xc2, 0xde, 471 | 0x31, 0x46, 0xbb, 0x32, 0xc2, 0xde, 0xbc, 0x0c, 0xc2, 0x2f, 0xbc, 0x0c, 472 | 0xc2, 0x2f, 0x35, 0x40, 0x2d, 0x34, 0x38, 0x45, 0xbb, 0x9d, 0xbf, 0x8d, 473 | 0x3e, 0x3e, 0x48, 0x31, 0xbd, 0x44, 0xc1, 0xda, 0x40, 0x40, 0xc0, 0x4c, 474 | 0xc2, 0x57, 0x53, 0x44, 0xbc, 0xbf, 0xc2, 0x6b, 0x40, 0x49, 0xbc, 0xbf, 475 | 0xc2, 0x6b, 0x37, 0x49, 0x37, 0x49, 0xbe, 0x81, 0xc4, 0xd3, 0x3f, 0x4e, 476 | 0x36, 0x4a, 0x3a, 0x4d, 0xbb, 0x08, 0xc4, 0x6a, 0x31, 0x4f, 0x06, 0x05, 477 | 0xae, 0x02, 0x4e, 0x26, 0x42, 0x2a, 0x46, 0x2b, 0x3b, 0x2e, 0x38, 0x36, 478 | 0x3b, 0x42, 0x46, 0x34, 0x06, 0x05, 0xae, 0x02, 0x49, 0x3e, 0x52, 0x2f, 479 | 0xc6, 0xab, 0xbb, 0x90, 0xc5, 0xc8, 0xb8, 0x7c, 0x4e, 0x26, 0x46, 0x34, 480 | 0x3b, 0x42, 0x06, 0x0a, 0xeb, 0xaa, 0x0b, 0x22, 0x36, 0x22, 0x36, 0x21, 481 | 0x3f, 0x28, 0x48, 0x24, 0x49, 0x2f, 0x4c, 0x27, 0x4d, 0x2f, 0x4c, 0x3b, 482 | 0x42, 0x38, 0x36, 0x30, 0x2a, 0x2c, 0x2c, 0x28, 0x29, 0x28, 0x29, 0x24, 483 | 0x2d, 0x26, 0x36, 0x06, 0x0a, 0xeb, 0x6e, 0x0a, 0x31, 0x4d, 0x31, 0x4d, 484 | 0x31, 0x54, 0x39, 0x56, 0x3a, 0x51, 0x50, 0x4f, 0x49, 0x55, 0x50, 0x4f, 485 | 0x4e, 0x4c, 0x5a, 0x44, 0x55, 0x4b, 0x5a, 0x44, 0x56, 0x42, 0x40, 0x49, 486 | 0x3e, 0x3b, 0x42, 0x06, 0x04, 0xeb, 0x2f, 0x4c, 0x2f, 0x4c, 0x29, 0x52, 487 | 0x22, 0x57, 0x26, 0x58, 0x31, 0x4d, 0x2c, 0x53, 0x31, 0x4d, 0x08, 0x0a, 488 | 0x00, 0x05, 0x03, 0x05, 0x06, 0x07, 0x04, 0x10, 0x01, 0x17, 0x84, 0x02, 489 | 0x04, 0x0a, 0x06, 0x01, 0x05, 0x00, 0x0a, 0x07, 0x01, 0x06, 0x00, 0x0a, 490 | 0x04, 0x01, 0x03, 0x00, 0x0a, 0x05, 0x01, 0x04, 0x00, 0x0a, 0x02, 0x01, 491 | 0x02, 0x00, 0x0a, 0x08, 0x01, 0x07, 0x00, 0x0a, 0x03, 0x01, 0x01, 0x08, 492 | 0x15, 0xff 493 | }; 494 | 495 | // Leaf 5 - Red 1 496 | const unsigned char kLeaf5[] = { 497 | 0x6e, 0x63, 0x69, 0x66, 0x08, 0x05, 0x00, 0x02, 0x00, 0x12, 0x02, 0x00, 498 | 0x00, 0x00, 0x3d, 0x40, 0x00, 0xbd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4b, 499 | 0x20, 0x00, 0x4a, 0x10, 0x00, 0x00, 0x01, 0x66, 0xff, 0x01, 0x85, 0x02, 500 | 0x00, 0x06, 0x02, 0x3b, 0x9f, 0xd5, 0xbb, 0x5f, 0x70, 0x3e, 0xb9, 0x98, 501 | 0x3e, 0xed, 0x9f, 0x45, 0xbf, 0xbf, 0x47, 0x19, 0x8c, 0x00, 0xc5, 0x53, 502 | 0x30, 0xff, 0xdd, 0x5b, 0x27, 0x02, 0x00, 0x06, 0x02, 0x3b, 0x9f, 0xd5, 503 | 0xbb, 0x5f, 0x70, 0x3e, 0xb9, 0x98, 0x3e, 0xed, 0x9f, 0x45, 0x8f, 0xbf, 504 | 0x46, 0xf9, 0x8c, 0x00, 0xff, 0xa2, 0x5f, 0xff, 0xed, 0x65, 0x46, 0x02, 505 | 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 506 | 0x3c, 0x7f, 0xb1, 0x4a, 0xd6, 0x23, 0x45, 0xf4, 0x80, 0x00, 0xda, 0x05, 507 | 0x05, 0xfe, 0xff, 0x78, 0x43, 0x02, 0x01, 0x06, 0x02, 0x38, 0xa0, 0x81, 508 | 0x3c, 0xe4, 0x69, 0xc0, 0x05, 0xf5, 0x3b, 0xac, 0xe9, 0x4a, 0x36, 0x3c, 509 | 0x4a, 0x20, 0x00, 0x00, 0xfd, 0x73, 0x3d, 0xff, 0xda, 0x05, 0x05, 0x02, 510 | 0x01, 0x06, 0x02, 0xbd, 0x28, 0x86, 0x3d, 0x5c, 0x6c, 0xbc, 0x93, 0x89, 511 | 0xbc, 0x6b, 0xc1, 0x4a, 0x2c, 0xa1, 0x4a, 0x72, 0x01, 0x00, 0xfd, 0x9c, 512 | 0x5b, 0xff, 0xda, 0x05, 0x05, 0x02, 0x00, 0x06, 0x02, 0x34, 0xb4, 0xd1, 513 | 0x37, 0x3c, 0x1e, 0xbc, 0x49, 0x56, 0x39, 0xd3, 0x68, 0x48, 0xda, 0x03, 514 | 0x4a, 0xe2, 0x5a, 0x00, 0xff, 0xa2, 0x5f, 0xff, 0xa4, 0x0a, 0x12, 0x07, 515 | 0x06, 0x0d, 0xae, 0xff, 0xcf, 0x02, 0x24, 0x5a, 0x29, 0x5a, 0x29, 0x5a, 516 | 0x2f, 0x56, 0x34, 0x51, 0x3e, 0x5c, 0x41, 0x54, 0x40, 0x5b, 0x49, 0x58, 517 | 0x5a, 0x54, 0x57, 0x57, 0x5a, 0x4c, 0x4d, 0x4b, 0x4d, 0x4b, 0x55, 0x4a, 518 | 0x60, 0x3f, 0x5f, 0x43, 0x60, 0x3a, 0x52, 0x3a, 0x52, 0x3a, 0x58, 0x36, 519 | 0x5a, 0x2b, 0x5c, 0x2f, 0xc9, 0x69, 0xb6, 0xe2, 0x54, 0x25, 0x4e, 0x25, 520 | 0x4e, 0x28, 0x50, 0x2e, 0x50, 0x06, 0x0a, 0xee, 0xbe, 0x0b, 0x33, 0x4c, 521 | 0x3e, 0x43, 0x39, 0x48, 0xc1, 0xf5, 0xbd, 0xf0, 0x4d, 0x31, 0xbf, 0xe8, 522 | 0xc0, 0x75, 0x47, 0x3b, 0x48, 0x43, 0x52, 0x40, 0xbf, 0x63, 0xc1, 0x06, 523 | 0x47, 0x44, 0xbe, 0x4d, 0xc2, 0x30, 0xbd, 0x68, 0xc3, 0x0a, 0xbe, 0x25, 524 | 0xc2, 0x56, 0x40, 0x4c, 0x4a, 0x4f, 0xbc, 0xf9, 0xc3, 0x8b, 0xc0, 0x32, 525 | 0xc4, 0xfa, 0xbc, 0x3d, 0xc4, 0x39, 0x35, 0x4d, 0x06, 0x0f, 0xee, 0xbb, 526 | 0xfb, 0x2e, 0xba, 0xb8, 0xc4, 0xbb, 0xbc, 0x44, 0x49, 0xbb, 0x84, 0xc4, 527 | 0x01, 0x33, 0x46, 0x2e, 0x40, 0xbc, 0xca, 0xc2, 0xde, 0x35, 0x46, 0xbd, 528 | 0x85, 0xc2, 0x35, 0xbe, 0xd6, 0xc0, 0xfd, 0xbd, 0xae, 0xc2, 0x1d, 0x3d, 529 | 0x3b, 0x3a, 0x33, 0xbf, 0x80, 0xc0, 0x59, 0x3f, 0x3c, 0xc1, 0xe4, 0xbd, 530 | 0xf5, 0xc5, 0x14, 0xb9, 0xf9, 0xc0, 0x0e, 0xc0, 0xa8, 0x47, 0x3c, 0xc3, 531 | 0x16, 0xc1, 0x25, 0x52, 0x40, 0xbf, 0x89, 0xc1, 0x39, 0xc2, 0xb0, 0xc1, 532 | 0x8b, 0xbe, 0x73, 0xc2, 0x63, 0xbd, 0x8e, 0xc3, 0x3d, 0xbe, 0x4b, 0xc2, 533 | 0x89, 0xbf, 0xe6, 0xc4, 0xbb, 0x4a, 0x4f, 0x3a, 0x4a, 0xc0, 0x6f, 0xc5, 534 | 0x5d, 0xbc, 0xa0, 0xc4, 0x6a, 0x35, 0x4f, 0x06, 0x04, 0xae, 0x4e, 0x3a, 535 | 0x52, 0x26, 0x58, 0x2e, 0xc3, 0x89, 0xb5, 0xfd, 0x43, 0x35, 0x3f, 0x42, 536 | 0x06, 0x08, 0xef, 0xba, 0x26, 0x36, 0x30, 0x35, 0x25, 0x3f, 0x2c, 0x48, 537 | 0x2c, 0x48, 0x28, 0x48, 0x25, 0x4b, 0x33, 0x4c, 0x29, 0x4d, 0x33, 0x4c, 538 | 0x3f, 0x42, 0x43, 0x35, 0x38, 0x2a, 0x41, 0x2d, 0x31, 0x32, 0x35, 0x3e, 539 | 0x06, 0x08, 0xfb, 0xae, 0x35, 0x4d, 0x35, 0x4d, 0x35, 0x56, 0x3b, 0x59, 540 | 0x3e, 0x51, 0x3f, 0x54, 0x3e, 0x51, 0x55, 0x52, 0x4b, 0x57, 0x56, 0x4c, 541 | 0x48, 0x49, 0x5c, 0x3b, 0x59, 0x46, 0x5b, 0x37, 0x4e, 0x3a, 0x3f, 0x42, 542 | 0x06, 0x04, 0xeb, 0x33, 0x4c, 0x33, 0x4c, 0x2d, 0x51, 0x23, 0x55, 0x27, 543 | 0x56, 0x35, 0x4d, 0x30, 0x51, 0x35, 0x4d, 0x07, 0x0a, 0x00, 0x04, 0x03, 544 | 0x04, 0x05, 0x06, 0x10, 0x01, 0x17, 0x84, 0x00, 0x04, 0x0a, 0x05, 0x01, 545 | 0x04, 0x00, 0x0a, 0x06, 0x01, 0x05, 0x00, 0x0a, 0x04, 0x01, 0x03, 0x00, 546 | 0x0a, 0x02, 0x01, 0x02, 0x00, 0x0a, 0x07, 0x01, 0x06, 0x00, 0x0a, 0x03, 547 | 0x01, 0x01, 0x08, 0x15, 0xff 548 | }; 549 | 550 | // Leaf 6 - Red 2 551 | const unsigned char kLeaf6[] = { 552 | 0x6e, 0x63, 0x69, 0x66, 0x09, 0x05, 0x00, 0x02, 0x00, 0x12, 0x02, 0x00, 553 | 0x00, 0x00, 0x3d, 0x40, 0x00, 0xbd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4a, 554 | 0xe0, 0x00, 0x4a, 0x10, 0x00, 0x00, 0x01, 0x66, 0xff, 0x01, 0x85, 0x02, 555 | 0x00, 0x06, 0x02, 0xbb, 0x54, 0x89, 0xbb, 0xa9, 0xdc, 0x3d, 0x61, 0x95, 556 | 0xbd, 0x12, 0xd5, 0x47, 0x21, 0xcd, 0x4b, 0x2e, 0xe5, 0x00, 0xff, 0x69, 557 | 0x3c, 0xff, 0xdd, 0x5b, 0x27, 0x02, 0x00, 0x06, 0x02, 0xba, 0x3f, 0xb3, 558 | 0x3b, 0x68, 0x5f, 0xbc, 0xea, 0x1e, 0xbb, 0xd8, 0xc4, 0x4a, 0x9e, 0xae, 559 | 0x4a, 0x75, 0x8e, 0x00, 0xff, 0x84, 0x4b, 0xff, 0xff, 0xa2, 0x5f, 0x02, 560 | 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 561 | 0x3c, 0x7f, 0xb1, 0x4a, 0x96, 0x23, 0x45, 0xf4, 0x80, 0x00, 0xda, 0x17, 562 | 0x05, 0xfe, 0xff, 0x78, 0x43, 0x02, 0x01, 0x06, 0x02, 0x3a, 0x92, 0xa8, 563 | 0x3c, 0xb2, 0x8f, 0xbe, 0x9e, 0xad, 0x3c, 0x7f, 0xb1, 0x4a, 0x96, 0x23, 564 | 0x45, 0xf4, 0x80, 0x00, 0xf7, 0x2e, 0x2e, 0xff, 0xff, 0x9e, 0x59, 0x02, 565 | 0x01, 0x06, 0x02, 0x38, 0xa0, 0x81, 0x3c, 0xe4, 0x69, 0xc0, 0x05, 0xf5, 566 | 0x3b, 0xac, 0xe9, 0x49, 0xec, 0x78, 0x4a, 0x20, 0x00, 0x00, 0xfd, 0x73, 567 | 0x3d, 0xff, 0xda, 0x05, 0x05, 0x02, 0x01, 0x06, 0x02, 0xbd, 0x28, 0x86, 568 | 0x3d, 0x5c, 0x6c, 0xbc, 0x93, 0x89, 0xbc, 0x6b, 0xc1, 0x4a, 0x0c, 0xa1, 569 | 0x4a, 0x82, 0x01, 0x00, 0xff, 0x9e, 0x59, 0xff, 0xf7, 0x2e, 0x2e, 0x02, 570 | 0x00, 0x06, 0x02, 0x35, 0x9e, 0x73, 0x37, 0x00, 0xe5, 0xbc, 0x1f, 0x7a, 571 | 0x3a, 0x8e, 0xd7, 0x48, 0x5d, 0xc8, 0x4a, 0xdf, 0x90, 0x00, 0xff, 0xa2, 572 | 0x5f, 0xff, 0xa4, 0x0a, 0x10, 0x08, 0x06, 0x0e, 0xee, 0xeb, 0xbb, 0x0b, 573 | 0x22, 0x5a, 0x28, 0x5a, 0x28, 0x5a, 0x2e, 0x55, 0x31, 0x51, 0x3d, 0x58, 574 | 0x39, 0x58, 0x3d, 0x58, 0x3d, 0x53, 0x3d, 0x53, 0x48, 0x58, 0x54, 0x52, 575 | 0x53, 0x4f, 0x60, 0x48, 0x5b, 0x4e, 0x60, 0x41, 0x4f, 0x3f, 0x4f, 0x3f, 576 | 0x57, 0x3a, 0x58, 0x30, 0x54, 0x2a, 0x53, 0x2e, 0x51, 0x2b, 0x4e, 0x2b, 577 | 0x23, 0x4d, 0x23, 0x4d, 0x26, 0x4f, 0x2d, 0x4f, 0x06, 0x0a, 0xee, 0xbe, 578 | 0x0b, 0x2f, 0x4c, 0x38, 0x44, 0xba, 0x74, 0xc3, 0x37, 0x41, 0x3c, 0x4c, 579 | 0x29, 0xbd, 0x1e, 0xc1, 0xa7, 0x42, 0x3c, 0x42, 0x45, 0x4d, 0x45, 0xbc, 580 | 0x99, 0xc2, 0x38, 0x43, 0x46, 0xbc, 0x99, 0xc2, 0x38, 0xbb, 0xd0, 0xc3, 581 | 0x0a, 0xbb, 0xd0, 0xc3, 0x0a, 0x3c, 0x4c, 0x46, 0x4f, 0xbb, 0x61, 0xc3, 582 | 0x8b, 0xbe, 0x9a, 0xc4, 0xfa, 0xba, 0xa5, 0xc4, 0x39, 0x31, 0x4d, 0x06, 583 | 0x0f, 0xee, 0xbb, 0xfb, 0x2e, 0xb9, 0x20, 0xc4, 0xbb, 0xba, 0xac, 0x49, 584 | 0xb9, 0xec, 0xc4, 0x01, 0x2f, 0x46, 0x2c, 0x42, 0xbb, 0x32, 0xc2, 0xde, 585 | 0x31, 0x46, 0xbb, 0x32, 0xc2, 0xde, 0xbc, 0x0c, 0xc2, 0x2f, 0xbc, 0x0c, 586 | 0xc2, 0x2f, 0x35, 0x40, 0x2d, 0x34, 0x38, 0x45, 0xbb, 0x9d, 0xbf, 0x8d, 587 | 0x3e, 0x3e, 0x48, 0x31, 0xbd, 0x44, 0xc1, 0xda, 0x40, 0x40, 0xc0, 0x4c, 588 | 0xc2, 0x57, 0x53, 0x44, 0xbc, 0xbf, 0xc2, 0x6b, 0x40, 0x49, 0xbc, 0xbf, 589 | 0xc2, 0x6b, 0x37, 0x49, 0x37, 0x49, 0xbe, 0x81, 0xc4, 0xd3, 0x3f, 0x4e, 590 | 0x36, 0x4a, 0x3a, 0x4d, 0xbb, 0x08, 0xc4, 0x6a, 0x31, 0x4f, 0x06, 0x05, 591 | 0xae, 0x02, 0x4e, 0x26, 0x42, 0x2a, 0x46, 0x2b, 0x3b, 0x2e, 0x38, 0x36, 592 | 0x3b, 0x42, 0x46, 0x34, 0x06, 0x05, 0xae, 0x02, 0x49, 0x3e, 0x52, 0x2f, 593 | 0xc6, 0xab, 0xbb, 0x90, 0xc5, 0xc8, 0xb8, 0x7c, 0x4e, 0x26, 0x46, 0x34, 594 | 0x3b, 0x42, 0x06, 0x0a, 0xeb, 0xaa, 0x0b, 0x22, 0x36, 0x22, 0x36, 0x21, 595 | 0x3f, 0x28, 0x48, 0x24, 0x49, 0x2f, 0x4c, 0x27, 0x4d, 0x2f, 0x4c, 0x3b, 596 | 0x42, 0x38, 0x36, 0x30, 0x2a, 0x2c, 0x2c, 0x28, 0x29, 0x28, 0x29, 0x24, 597 | 0x2d, 0x26, 0x36, 0x06, 0x0a, 0xeb, 0x6e, 0x0a, 0x31, 0x4d, 0x31, 0x4d, 598 | 0x31, 0x54, 0x39, 0x56, 0x3a, 0x51, 0x50, 0x4f, 0x49, 0x55, 0x50, 0x4f, 599 | 0x4e, 0x4c, 0x5a, 0x44, 0x55, 0x4b, 0x5a, 0x44, 0x56, 0x42, 0x40, 0x49, 600 | 0x3e, 0x3b, 0x42, 0x06, 0x04, 0xeb, 0x2f, 0x4c, 0x2f, 0x4c, 0x29, 0x52, 601 | 0x22, 0x57, 0x26, 0x58, 0x31, 0x4d, 0x2c, 0x53, 0x31, 0x4d, 0x08, 0x0a, 602 | 0x00, 0x05, 0x03, 0x05, 0x06, 0x07, 0x04, 0x10, 0x01, 0x17, 0x84, 0x02, 603 | 0x04, 0x0a, 0x06, 0x01, 0x05, 0x00, 0x0a, 0x07, 0x01, 0x06, 0x00, 0x0a, 604 | 0x04, 0x01, 0x03, 0x00, 0x0a, 0x05, 0x01, 0x04, 0x00, 0x0a, 0x02, 0x01, 605 | 0x02, 0x00, 0x0a, 0x08, 0x01, 0x07, 0x00, 0x0a, 0x03, 0x01, 0x01, 0x08, 606 | 0x15, 0xff 607 | }; 608 | 609 | 610 | const int32 kNumLeafTypes = 6; 611 | 612 | 613 | BBitmap* 614 | FallLeaves::_RandomBitmap(int32 size) 615 | { 616 | BBitmap* bitmap = new BBitmap(BRect(0, 0, size, size), B_RGBA32); 617 | 618 | // Randomly select one of the leaf images 619 | switch (RAND_NUM(1, kNumLeafTypes)) { 620 | 621 | case 1: 622 | BIconUtils::GetVectorIcon(kLeaf1, sizeof(kLeaf1), bitmap); 623 | break; 624 | case 2: 625 | BIconUtils::GetVectorIcon(kLeaf2, sizeof(kLeaf2), bitmap); 626 | break; 627 | case 3: 628 | BIconUtils::GetVectorIcon(kLeaf3, sizeof(kLeaf3), bitmap); 629 | break; 630 | case 4: 631 | BIconUtils::GetVectorIcon(kLeaf4, sizeof(kLeaf4), bitmap); 632 | break; 633 | case 5: 634 | BIconUtils::GetVectorIcon(kLeaf5, sizeof(kLeaf5), bitmap); 635 | break; 636 | case 6: 637 | BIconUtils::GetVectorIcon(kLeaf6, sizeof(kLeaf6), bitmap); 638 | break; 639 | } 640 | 641 | return bitmap; 642 | } 643 | 644 | 645 | extern "C" _EXPORT BScreenSaver* 646 | instantiate_screen_saver(BMessage* msg, image_id id) 647 | { 648 | return new FallLeaves(msg, id); 649 | } 650 | -------------------------------------------------------------------------------- /FallLeaves/FallLeaves.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 David Couzelis. All rights reserved. 3 | * Distributed under the terms of the MIT License. 4 | */ 5 | #ifndef _FALLLEAVES_H_ 6 | #define _FALLLEAVES_H_ 7 | 8 | 9 | #include 10 | #include 11 | 12 | 13 | // The number of leaves on the screen 14 | const int32 kMaxAmount = 50; 15 | const int32 kMinAmount = 10; 16 | const int32 kDefaultAmount = 35; 17 | 18 | // The speed of the leaves 19 | const int32 kMaxSpeed = 10; 20 | const int32 kMinSpeed = 1; 21 | const int32 kDefaultSpeed = 5; 22 | 23 | 24 | typedef class Leaf; 25 | 26 | 27 | class FallLeaves : public BScreenSaver 28 | { 29 | public: 30 | FallLeaves(BMessage* archive, image_id thisImage); 31 | ~FallLeaves(); 32 | 33 | void StartConfig(BView* configView); 34 | status_t StartSaver(BView* view, bool preview); 35 | status_t SaveState(BMessage* into) const; 36 | 37 | void Draw(BView* view, int32 frame); 38 | 39 | void SetAmount(int32 amount); 40 | void SetSpeed(int32 speed); 41 | private: 42 | Leaf* _CreateLeaf(BView* view, bool above); 43 | BBitmap* _RandomBitmap(int32 size); 44 | 45 | BObjectList* fLeaves; 46 | 47 | int32 fSize; 48 | // The size of the biggest possible leaf 49 | 50 | int32 fAmount; 51 | // The amount of leaves on the screen 52 | int32 fSpeed; 53 | // The speed of the fastest leaf 54 | 55 | BBitmap* fBackBitmap; 56 | BView* fBackView; 57 | // For double buffering, 58 | // used to reduce flicker 59 | 60 | bool fZUsed[101]; 61 | // Used to give each leaf a unique Z depth 62 | }; 63 | 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /FallLeaves/FallLeaves.pld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcouzelis/HaikuApiExamples/3872f479d1ba982a9a07afbbf48886ec8ee7f30f/FallLeaves/FallLeaves.pld -------------------------------------------------------------------------------- /FallLeaves/IconUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2008, Haiku. All rights reserved. 3 | * Distributed under the terms of the MIT License. 4 | */ 5 | #ifndef _ICON_UTILS_H 6 | #define _ICON_UTILS_H 7 | 8 | 9 | #include 10 | 11 | class BBitmap; 12 | class BNode; 13 | 14 | 15 | // This class is a little different from many other classes. 16 | // You don't create an instance of it; you just call its various 17 | // static member functions for utility-like operations. 18 | class BIconUtils { 19 | BIconUtils(); 20 | ~BIconUtils(); 21 | BIconUtils(const BIconUtils&); 22 | BIconUtils& operator=(const BIconUtils&); 23 | 24 | public: 25 | 26 | // Utility function to import an icon from the node that 27 | // has either of the provided attribute names. Which icon type 28 | // is preferred (vector, small or large B_CMAP8 icon) depends 29 | // on the colorspace of the provided bitmap. If the colorspace 30 | // is B_CMAP8, B_CMAP8 icons are preferred. In that case, the 31 | // bitmap size must also match the provided icon_size "size"! 32 | static status_t GetIcon(BNode* node, 33 | const char* vectorIconAttrName, 34 | const char* smallIconAttrName, 35 | const char* largeIconAttrName, 36 | icon_size size, BBitmap* result); 37 | 38 | // Utility functions to import a vector icon in "flat icon" 39 | // format from a BNode attribute or from a flat buffer in 40 | // memory into the preallocated BBitmap "result". 41 | // The colorspace of result needs to be B_RGBA32 or at 42 | // least B_RGB32 (though that makes less sense). The icon 43 | // will be scaled from it's "native" size of 64x64 to the 44 | // size of the bitmap, the scale is derived from the bitmap 45 | // width, the bitmap should have square dimension, or the 46 | // icon will be cut off at the bottom (or have room left). 47 | static status_t GetVectorIcon(BNode* node, 48 | const char* attrName, BBitmap* result); 49 | 50 | static status_t GetVectorIcon(const uint8* buffer, 51 | size_t size, BBitmap* result); 52 | 53 | // Utility function to import an "old" BeOS icon in B_CMAP8 54 | // colorspace from either the small icon attribute or the 55 | // large icon attribute as given in "smallIconAttrName" and 56 | // "largeIconAttrName". Which icon is loaded depends on 57 | // the given "size". 58 | static status_t GetCMAP8Icon(BNode* node, 59 | const char* smallIconAttrName, 60 | const char* largeIconAttrName, 61 | icon_size size, BBitmap* icon); 62 | 63 | // Utility functions to convert from old icon colorspace 64 | // into colorspace of BBitmap "result" (should be B_RGBA32 65 | // to make any sense). 66 | static status_t ConvertFromCMAP8(BBitmap* source, 67 | BBitmap* result); 68 | static status_t ConvertToCMAP8(BBitmap* source, 69 | BBitmap* result); 70 | 71 | static status_t ConvertFromCMAP8(const uint8* data, 72 | uint32 width, uint32 height, 73 | uint32 bytesPerRow, BBitmap* result); 74 | 75 | static status_t ConvertToCMAP8(const uint8* data, 76 | uint32 width, uint32 height, 77 | uint32 bytesPerRow, BBitmap* result); 78 | }; 79 | 80 | #endif // _ICON_UTILS_H 81 | -------------------------------------------------------------------------------- /FallLeaves/PackageRoot/.PackageInfo: -------------------------------------------------------------------------------- 1 | name fallleaves 2 | version 0.1-1 3 | architecture x86_gcc2 4 | summary "Screensaver featuring beautiful falling leaves" 5 | description "A screensaver featuring falling leaves of various colors. 6 | The amount of leaves and the speed that they fall can be configured." 7 | vendor "David Couzelis" 8 | packager "David Couzelis " 9 | copyrights { 10 | "Copyright (C) 2014 by David Couzelis " 11 | } 12 | licenses { 13 | "MIT" 14 | } 15 | provides { 16 | fallleaves = 0.1 17 | } 18 | urls { 19 | "https://github.com/HaikuArchives/HaikuApiExamples" 20 | } 21 | -------------------------------------------------------------------------------- /FallLeaves/compile: -------------------------------------------------------------------------------- 1 | echo "Compiling FallLeaves..." 2 | gcc -o FallLeaves *.cpp -lbe -lscreensaver -llocalestub -nostart -Xlinker -soname=FallLeaves 3 | 4 | echo "Creating package..." 5 | mkdir -p "PackageRoot/add-ons/Screen Savers" 6 | cp -f FallLeaves "PackageRoot/add-ons/Screen Savers/" 7 | package create -C PackageRoot fallleaves-0.1-1-x86_gcc2.hpkg 8 | -------------------------------------------------------------------------------- /FileDialog/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | #include 6 | 7 | class App : public BApplication 8 | { 9 | public: 10 | 11 | App(void) 12 | : BApplication("application/x-vnd.OpenFileDemo") 13 | { 14 | /* Empty */ 15 | } 16 | 17 | void MessageReceived(BMessage *msg) 18 | { 19 | switch (msg->what) 20 | { 21 | case B_REFS_RECEIVED: 22 | /* User selected "Open" */ 23 | /* CONTINUE DOWN... */ 24 | case B_SAVE_REQUESTED: 25 | /* User selected "Save" */ 26 | /* CONTINUE DOWN... */ 27 | case B_CANCEL: 28 | /* User selected "Cancel" */ 29 | /* CONTINUE DOWN... */ 30 | default: 31 | /* No matter what message what received, just quit the demo. */ 32 | be_app->Quit(); 33 | break; 34 | } 35 | } 36 | }; 37 | 38 | 39 | 40 | int 41 | main(void) 42 | { 43 | App *app = new App(); 44 | 45 | BFilePanel panel(B_OPEN_PANEL); 46 | panel.Show(); 47 | 48 | app->Run(); 49 | 50 | delete app; 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /FileDialog/ReadMe: -------------------------------------------------------------------------------- 1 | Create and show an "Open File" dialog. 2 | -------------------------------------------------------------------------------- /FileDialog/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe -ltracker 2 | -------------------------------------------------------------------------------- /HaikuAPISamples: -------------------------------------------------------------------------------- 1 | Ideas for future demos 2 | ---------------------- 3 | 4 | WindowControls 5 | LoadImage 6 | ReadFile 7 | PlayAudio 8 | MenuBar 9 | DirectWindow 10 | DragAndDrop 11 | NetConnection 12 | TextArea 13 | MouseControl 14 | KeyboardControl 15 | SavePrefs 16 | -------------------------------------------------------------------------------- /HaikuFortune/App.cpp: -------------------------------------------------------------------------------- 1 | #include "App.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "FortuneFunctions.h" 9 | #include "MainWindow.h" 10 | 11 | App::App(void) 12 | : BApplication("application/x-vnd.test-HaikuFortune") 13 | { 14 | BPath path; 15 | 16 | // We have to use an #ifdef here because the fortune files under R5 17 | // and Zeta are in the system/etc/ directory, but in Haiku they're 18 | // kept in the system/data directory. 19 | #ifdef __HAIKU__ 20 | find_directory(B_SYSTEM_DATA_DIRECTORY,&path); 21 | #else 22 | find_directory(B_BEOS_ETC_DIRECTORY,&path); 23 | #endif 24 | 25 | path.Append("fortunes"); 26 | gFortunePath = path.Path(); 27 | 28 | // If we want the rand() function to actually be pretty close to random 29 | // we will need to seed the random number generator with the time. If we 30 | // don't, we will get the same "random" numbers each time the program is 31 | // run. 32 | srand(system_time()); 33 | 34 | MainWindow *win = new MainWindow(); 35 | win->Show(); 36 | } 37 | 38 | 39 | int 40 | main(void) 41 | { 42 | srand(system_time()); 43 | 44 | App *app = new App(); 45 | app->Run(); 46 | delete app; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /HaikuFortune/App.h: -------------------------------------------------------------------------------- 1 | #ifndef APP_H 2 | #define APP_H 3 | 4 | #include 5 | 6 | class App : public BApplication 7 | { 8 | public: 9 | App(void); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /HaikuFortune/FortuneFunctions.cpp: -------------------------------------------------------------------------------- 1 | #include "FortuneFunctions.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // Initialize the global path to a hardcoded value just in case. 14 | // This happens to be different under Haiku than under previous versions 15 | // of BeOS 16 | BString gFortunePath = "/boot/system/data/fortunes"; 17 | 18 | 19 | FortuneAccess::FortuneAccess(void) 20 | { 21 | } 22 | 23 | 24 | FortuneAccess::FortuneAccess(const char *folder) 25 | { 26 | SetFolder(folder); 27 | } 28 | 29 | 30 | FortuneAccess::~FortuneAccess(void) 31 | { 32 | // We have to call MakeEmpty because the BList class 33 | // does not delete any items that it contains 34 | MakeEmpty(); 35 | } 36 | 37 | 38 | status_t 39 | FortuneAccess::SetFolder(const char *folder) 40 | { 41 | if (!folder) 42 | return B_BAD_VALUE; 43 | 44 | fPath = folder; 45 | ScanFolder(); 46 | 47 | return B_OK; 48 | } 49 | 50 | 51 | status_t 52 | FortuneAccess::GetFortune(BString &target) 53 | { 54 | // Here's the meat of this class: 55 | if (fPath.CountChars() == 0) 56 | return B_NO_INIT; 57 | 58 | if (fRefList.CountItems() < 1) 59 | return B_ERROR; 60 | 61 | int32 index = int32(float(rand()) / RAND_MAX * fRefList.CountItems()); 62 | 63 | entry_ref *ref = static_cast(fRefList.ItemAt(index)); 64 | 65 | BFile file(ref,B_READ_ONLY); 66 | if (file.InitCheck() != B_OK) 67 | return file.InitCheck(); 68 | 69 | fLastFile = ref->name; 70 | 71 | off_t size; 72 | file.GetSize(&size); 73 | 74 | if (size < 1) 75 | return B_ERROR; 76 | 77 | BString data; 78 | char *buffer = data.LockBuffer(size + 10); 79 | file.Read(buffer, size); 80 | data.UnlockBuffer(); 81 | buffer = NULL; 82 | 83 | // We can't depend on a .dat file, so calculate the number of entries manually 84 | int32 entrycount = 0; 85 | int32 entrystart = 0; 86 | do 87 | { 88 | entrystart = data.FindFirst("%\n", entrystart + 1); 89 | entrycount++; 90 | } while (entrystart > 0); 91 | 92 | int32 entry = int32(float(rand()) / RAND_MAX * (entrycount - 1)); 93 | 94 | entrystart = 0; 95 | for (int32 i = 0; i < entry; i++) 96 | entrystart = data.FindFirst("%\n",entrystart + 1); 97 | 98 | BString entrydata; 99 | entrydata = data.String() + entrystart + 2; 100 | int32 entrylength = entrydata.FindFirst("%\n"); 101 | if (entrylength > 0) 102 | entrydata.Truncate(entrylength); 103 | 104 | target = entrydata; 105 | return B_OK; 106 | } 107 | 108 | 109 | void 110 | FortuneAccess::ScanFolder(void) 111 | { 112 | // Scan the directory that the object was set to and create a list of all 113 | // of the names of the files in the directory. 114 | BDirectory dir(fPath.String()); 115 | if (dir.InitCheck() != B_OK) 116 | return; 117 | 118 | MakeEmpty(); 119 | entry_ref ref; 120 | while (dir.GetNextRef(&ref) == B_OK) 121 | { 122 | BEntry entry(&ref); 123 | if (entry.IsFile()) 124 | fRefList.AddItem(new entry_ref(ref)); 125 | } 126 | } 127 | 128 | 129 | void 130 | FortuneAccess::MakeEmpty(void) 131 | { 132 | // This method is needed because BList doesn't free the memory of the items 133 | // that it holds. 134 | for (int32 i = 0; i < fRefList.CountItems(); i++) 135 | { 136 | entry_ref *ref = (entry_ref*)fRefList.ItemAt(i); 137 | delete ref; 138 | } 139 | fRefList.MakeEmpty(); 140 | } 141 | 142 | 143 | int32 144 | FortuneAccess::CountFiles(void) const 145 | { 146 | return fRefList.CountItems(); 147 | } 148 | 149 | 150 | status_t 151 | FortuneAccess::LastFilename(BString &target) 152 | { 153 | // This function exists so that outside code can find out the name of the file 154 | // the most recent fortune came from. 155 | if (fPath.CountChars() == 0) 156 | return B_NO_INIT; 157 | 158 | target = fLastFile; 159 | 160 | return B_OK; 161 | } 162 | 163 | -------------------------------------------------------------------------------- /HaikuFortune/FortuneFunctions.h: -------------------------------------------------------------------------------- 1 | #ifndef FORTUNEFUNCTIONS_H 2 | #define FORTUNEFUNCTIONS_H 3 | 4 | #include 5 | #include 6 | 7 | extern BString gFortunePath; 8 | 9 | class FortuneAccess 10 | { 11 | public: 12 | FortuneAccess(void); 13 | FortuneAccess(const char *folder); 14 | ~FortuneAccess(void); 15 | 16 | status_t SetFolder(const char *folder); 17 | status_t GetFortune(BString &target); 18 | int32 CountFiles(void) const; 19 | status_t LastFilename(BString &target); 20 | 21 | private: 22 | void ScanFolder(void); 23 | void MakeEmpty(void); 24 | 25 | BString fPath, 26 | fLastFile; 27 | BList fRefList; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /HaikuFortune/HaikuFortune.rsrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcouzelis/HaikuApiExamples/3872f479d1ba982a9a07afbbf48886ec8ee7f30f/HaikuFortune/HaikuFortune.rsrc -------------------------------------------------------------------------------- /HaikuFortune/HaikuFortune16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcouzelis/HaikuApiExamples/3872f479d1ba982a9a07afbbf48886ec8ee7f30f/HaikuFortune/HaikuFortune16.png -------------------------------------------------------------------------------- /HaikuFortune/HaikuFortune32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcouzelis/HaikuApiExamples/3872f479d1ba982a9a07afbbf48886ec8ee7f30f/HaikuFortune/HaikuFortune32.png -------------------------------------------------------------------------------- /HaikuFortune/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | enum 11 | { 12 | M_GET_ANOTHER_FORTUNE = 'gafn', 13 | M_ABOUT_REQUESTED = 'abrq' 14 | }; 15 | 16 | 17 | MainWindow::MainWindow(void) 18 | : BWindow(BRect(0,0,300,300), "HaikuFortune", B_DOCUMENT_WINDOW, 19 | B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE), 20 | fFortune(gFortunePath.String()) 21 | { 22 | // Create all of the controls for our window. 23 | BView *back = new BView(Bounds(), "background", B_FOLLOW_ALL, B_WILL_DRAW); 24 | back->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 25 | AddChild(back); 26 | 27 | BButton *close = new BButton(BRect(0,0,1,1), "closebutton", "Close", 28 | new BMessage(B_QUIT_REQUESTED), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 29 | close->ResizeToPreferred(); 30 | close->MoveTo(Bounds().right - 15 - close->Frame().Width(), 31 | Bounds().bottom - 15 - close->Frame().Height()); 32 | back->AddChild(close); 33 | close->MakeDefault(true); 34 | 35 | BButton *next = new BButton(BRect(0,0,1,1), "nextbutton", "Get Another", 36 | new BMessage(M_GET_ANOTHER_FORTUNE), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 37 | next->ResizeToPreferred(); 38 | next->MoveTo(close->Frame().left - 15 - next->Frame().Width(), 39 | Bounds().bottom - 15 - next->Frame().Height()); 40 | back->AddChild(next); 41 | 42 | BButton *about = new BButton(BRect(0,0,1,1), "aboutbutton", "About…", 43 | new BMessage(M_ABOUT_REQUESTED), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 44 | about->ResizeToPreferred(); 45 | about->MoveTo(next->Frame().left - 15 - about->Frame().Width(), 46 | Bounds().bottom - 15 - about->Frame().Height()); 47 | back->AddChild(about); 48 | 49 | 50 | BRect r(15,15,Bounds().right - B_V_SCROLL_BAR_WIDTH - 15, next->Frame().top - 15); 51 | fTextView = new BTextView(r, "textview", r.OffsetToCopy(0,0).InsetByCopy(10,10), B_FOLLOW_ALL, 52 | B_WILL_DRAW | B_PULSE_NEEDED | B_FRAME_EVENTS); 53 | fTextView->MakeEditable(false); 54 | 55 | // BScrollViews are a little weird. You can't create one without having created its target. 56 | // It also automatically calls AddChild() to attach its target to itself, so all that is 57 | // necessary is to instantiate it and attach it to the window. It's not even necessary (or 58 | // possible) to specify the size of the BScrollView because it calculates its size based 59 | // on that of its target. 60 | BScrollView *sv = new BScrollView("scrollview", fTextView, B_FOLLOW_ALL, 0, false, true); 61 | back->AddChild(sv); 62 | 63 | BString fortune; 64 | status_t status = fFortune.GetFortune(fortune); 65 | if (status == B_OK) 66 | { 67 | BString title; 68 | title.Prepend("Fortune: "); 69 | SetTitle(title.String()); 70 | 71 | fTextView->SetText(fortune.String()); 72 | } 73 | else 74 | { 75 | fTextView->SetText("HaikuFortune had a problem getting a fortune.\n\n" 76 | "Please make sure that you have installed fortune files to " 77 | "the folder "); 78 | fTextView->Insert(gFortunePath.String()); 79 | } 80 | 81 | // This line is for working around a problem in Zeta. BButton::MakeDefault doesn't 82 | // do anything except change the focus. The idea is to be able to press Enter to close 83 | // HaikuFortune and the space bar to get another fortune. Zeta doesn't let us do this, so 84 | // we'll leave focus on the Close button. 85 | if (B_BEOS_VERSION <= B_BEOS_VERSION_5) 86 | next->MakeFocus(true); 87 | 88 | // Calculate a good width for the window and center it 89 | SetSizeLimits(45 + close->Bounds().Width() + next->Bounds().Width(), 30000, 200, 30000) ; 90 | r = BScreen().Frame(); 91 | MoveTo((r.Width()-Bounds().Width()) / 2.0, r.Height() / 4.0); 92 | } 93 | 94 | 95 | void 96 | MainWindow::MessageReceived(BMessage *msg) 97 | { 98 | switch (msg->what) 99 | { 100 | case M_GET_ANOTHER_FORTUNE: 101 | { 102 | BString fortune; 103 | status_t status = fFortune.GetFortune(fortune); 104 | if (status == B_OK) 105 | { 106 | BString title; 107 | fFortune.LastFilename(title); 108 | title.Prepend("Fortune: "); 109 | SetTitle(title.String()); 110 | 111 | fTextView->SetText(fortune.String()); 112 | } 113 | else 114 | { 115 | fTextView->SetText("HaikuFortune had a problem getting a fortune.\n\n" 116 | "Please make sure that you have installed fortune files to " 117 | "the folder "); 118 | fTextView->Insert(gFortunePath.String()); 119 | } 120 | break; 121 | } 122 | case M_ABOUT_REQUESTED: 123 | { 124 | // Using a BAlert for the About window is a common occurrence. They take 125 | // care of all of the layout, so all that needs done is write the text that 126 | // goes in the alert. 127 | BAlert *alert = new BAlert("HaikuFortune", 128 | "A graphical fortune program for Haiku.\n\n", 129 | "OK"); 130 | alert->Go(); 131 | break; 132 | } 133 | default: 134 | { 135 | BWindow::MessageReceived(msg); 136 | break; 137 | } 138 | } 139 | } 140 | 141 | 142 | void 143 | MainWindow::FrameResized(float w, float h) 144 | { 145 | // The BWindow::FrameResized() method is called whenever the window is resized. 146 | // In this case, we change the size of the text rectangle in the text view used 147 | // for the fortune. We have to do this because it won't do it itself. Lazy. 148 | BRect textrect = fTextView->TextRect(); 149 | 150 | textrect.right = textrect.left + (w - B_V_SCROLL_BAR_WIDTH - 40); 151 | fTextView->SetTextRect(textrect); 152 | } 153 | 154 | -------------------------------------------------------------------------------- /HaikuFortune/MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include "FortuneFunctions.h" 7 | 8 | class MainWindow : public BWindow 9 | { 10 | public: 11 | MainWindow(void); 12 | void MessageReceived(BMessage *msg); 13 | void FrameResized(float w, float h); 14 | 15 | private: 16 | BTextView *fTextView; 17 | FortuneAccess fFortune; 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /HaikuFortune/ReadMe: -------------------------------------------------------------------------------- 1 | From "Learning to Program with Haiku" by Jon Yoder (DarkWyrm) 2 | http://haiku-os.org/development/learning_to_program_with_haiku 3 | 4 | Create and show a window with "fortune" quotes. 5 | A resource file is used to set the application icon. -------------------------------------------------------------------------------- /HaikuFortune/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe -ltranslation 2 | xres -o Run HaikuFortune.rsrc 3 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | Distributed under the terms of the MIT License. 2 | 3 | Copyright (c) 2010 David Couzelis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /ListDirectory/App.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // It's better to use constant global integers instead of #defines because constants 8 | // provide strong typing and don't lead to weird errors like #defines can. 9 | const uint16 BYTES_PER_KB = 1024; 10 | const uint32 BYTES_PER_MB = 1048576; 11 | const uint64 BYTES_PER_GB = 1099511627776ULL; 12 | 13 | int ListDirectory(const entry_ref &dirRef); 14 | BString MakeSizeString(const uint64 &size); 15 | 16 | 17 | int 18 | main(int argc, char **argv) 19 | { 20 | // We want to require one argument in addition to the program name when invoked 21 | // from the command line. 22 | if (argc != 2) 23 | { 24 | printf("Usage: listdir \n"); 25 | return 0; 26 | } 27 | 28 | // Here we'll do some sanity checks to make sure that the path we were given 29 | // actually exists and it's not a file. 30 | 31 | BEntry entry(argv[1]); 32 | if (!entry.Exists()) 33 | { 34 | printf("%s does not exist\n",argv[1]); 35 | return 1; 36 | } 37 | 38 | if (!entry.IsDirectory()) 39 | { 40 | printf("%s is not a directory\n",argv[1]); 41 | return 1; 42 | } 43 | 44 | // An entry_ref is a typedef'ed structure which points to a file, directory, or 45 | // symlink on disk. The entry must actually exist, but unlike a BFile or BEntry, it 46 | // doesn't use up a file handle. 47 | entry_ref ref; 48 | entry.GetRef(&ref); 49 | return ListDirectory(ref); 50 | } 51 | 52 | 53 | int 54 | ListDirectory(const entry_ref &dirRef) 55 | { 56 | // This function does all the work of the program 57 | 58 | BDirectory dir(&dirRef); 59 | if (dir.InitCheck() != B_OK) 60 | { 61 | printf("Couldn't read directory %s\n",dirRef.name); 62 | return 1; 63 | } 64 | 65 | // First thing we'll do is quickly scan the directory to find the length of the 66 | // longest entry name. This makes it possible to left justify the file sizes 67 | int32 entryCount = 0; 68 | uint32 maxChars = 0; 69 | entry_ref ref; 70 | 71 | // Calling Rewind() moves the BDirectory's index to the beginning of the list. 72 | dir.Rewind(); 73 | 74 | // GetNextRef() will return B_ERROR when the BDirectory has gotten to the end of 75 | // its list of entries. 76 | while (dir.GetNextRef(&ref) == B_OK) 77 | { 78 | if (ref.name) 79 | maxChars = MAX(maxChars,strlen(ref.name)); 80 | } 81 | maxChars++; 82 | char padding[maxChars]; 83 | 84 | BEntry entry; 85 | dir.Rewind(); 86 | 87 | // Here we'll call GetNextEntry() instead of GetNextRef() because a BEntry will 88 | // enable us to get certain information about each entry, such as the entry's size. 89 | // Also, because it inherits from BStatable, we can differentiate between 90 | // directories and files with just one function call. 91 | while (dir.GetNextEntry(&entry) == B_OK) 92 | { 93 | char name[B_FILE_NAME_LENGTH]; 94 | entry.GetName(name); 95 | 96 | BString formatString; 97 | formatString << "%s"; 98 | 99 | unsigned int length = strlen(name); 100 | if (length < maxChars) 101 | { 102 | uint32 padLength = maxChars - length; 103 | memset(padding, ' ', padLength); 104 | padding[padLength - 1] = '\0'; 105 | formatString << padding; 106 | } 107 | 108 | if (entry.IsDirectory()) 109 | { 110 | // We'll display the "size" of a directory by listing how many 111 | // entries it contains 112 | BDirectory subdir(&entry); 113 | formatString << "\t" << subdir.CountEntries() << " items"; 114 | } 115 | else 116 | { 117 | off_t fileSize; 118 | entry.GetSize(&fileSize); 119 | formatString << "\t" << MakeSizeString(fileSize); 120 | } 121 | formatString << "\n"; 122 | printf(formatString.String(),name); 123 | entryCount++; 124 | } 125 | printf("%ld entries\n",entryCount); 126 | return 0; 127 | } 128 | 129 | 130 | BString 131 | MakeSizeString(const uint64 &size) 132 | { 133 | // This function just makes converts the raw byte counts provided by 134 | // BEntry's GetSize() method into something more people-friendly. 135 | BString sizeString; 136 | if (size < BYTES_PER_KB) 137 | sizeString << size << " bytes"; 138 | else if (size < BYTES_PER_MB) 139 | sizeString << (float(size) / float(BYTES_PER_KB)) << " KB"; 140 | else if (size < BYTES_PER_GB) 141 | sizeString << (float(size) / float(BYTES_PER_MB)) << " MB"; 142 | else 143 | sizeString << (float(size) / float(BYTES_PER_GB)) << " GB"; 144 | return sizeString; 145 | } 146 | 147 | -------------------------------------------------------------------------------- /ListDirectory/ReadMe: -------------------------------------------------------------------------------- 1 | From "Learning to Program with Haiku" by Jon Yoder (DarkWyrm) 2 | http://haiku-os.org/development/learning_to_program_with_haiku 3 | 4 | This is a command line application. 5 | It will read and print the contents of a directory. -------------------------------------------------------------------------------- /ListDirectory/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe -------------------------------------------------------------------------------- /ListItems/App.cpp: -------------------------------------------------------------------------------- 1 | #include "App.h" 2 | #include "MainWindow.h" 3 | 4 | 5 | App::App(void) 6 | : BApplication("application/x-vnd.dw-ListColors") 7 | { 8 | MainWindow *mainwin = new MainWindow(); 9 | mainwin->Show(); 10 | } 11 | 12 | 13 | int 14 | main(void) 15 | { 16 | App *app = new App(); 17 | app->Run(); 18 | delete app; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ListItems/App.h: -------------------------------------------------------------------------------- 1 | #ifndef APP_H 2 | #define APP_H 3 | 4 | #include 5 | 6 | class App : public BApplication 7 | { 8 | public: 9 | App(void); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /ListItems/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | enum 8 | { 9 | M_RESET_WINDOW = 'rswn', 10 | M_SET_TITLE = 'sttl' 11 | }; 12 | 13 | MainWindow::MainWindow(void) 14 | : BWindow(BRect(100,100,500,400),"The Weird World of Sports",B_TITLED_WINDOW, 15 | B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE) 16 | { 17 | // Here we will make a BView that covers the white area so that we can set the 18 | // "background color" 19 | BRect r(Bounds()); 20 | BView *top = new BView(r,"topview",B_FOLLOW_ALL,B_WILL_DRAW); 21 | AddChild(top); 22 | 23 | // ui_color() returns a system color, such as the window tab color, menu text color, 24 | // and so forth. 25 | top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 26 | 27 | // Create a button and place it at the bottom right corner of the window. The empty BRect 28 | // that we use for the BButton's frame is because we're going to have it resize itself and 29 | // then move it to the corner based on the actual size of the button 30 | BButton *reset = new BButton(BRect(),"resetbutton","Reset", new BMessage(M_RESET_WINDOW), 31 | B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 32 | top->AddChild(reset); 33 | reset->ResizeToPreferred(); 34 | 35 | // Bottom right corner of the window with 10 pixels of padding between the button and the 36 | // window edge. 10 pixels is kind of a de facto standard for control padding. 37 | reset->MoveTo(Bounds().right - reset->Bounds().Width() - 10.0, 38 | Bounds().bottom - reset->Bounds().Height() - 10.0); 39 | 40 | r = Bounds(); 41 | r.InsetBy(10.0,10.0); 42 | 43 | // When working with BScrollViews, you must compensate for the width/height of the scrollbars. 44 | // B_V_SCROLL_BAR_WIDTH is a defined constant for the width of the vertical scroll bar. 45 | r.right -= B_V_SCROLL_BAR_WIDTH; 46 | 47 | // Frame() works like Bounds() except that it returns the size and location of the control 48 | // in the coordinate space of the parent view. This will make fListView's bottom stop 10 49 | // pixels above the button. 50 | r.bottom = reset->Frame().top - 10.0 - B_H_SCROLL_BAR_HEIGHT; 51 | 52 | // Most of these parameters are exactly the same as for BView except that we can also 53 | // specify whether the user is able to select just 1 item in the list or multiple items by 54 | // clicking on items while holding a modifier key on the keyboard. 55 | fListView = new BListView(r,"sportlist",B_SINGLE_SELECTION_LIST,B_FOLLOW_ALL); 56 | 57 | // We didn't call AddChild on fListView because our BScrollView will do that for us. When 58 | // created, it creates scrollbars and targets the specified view for any scrolling they do. 59 | // When the BScrollView is attached to the window, it calls AddChild on fListView for us. 60 | 61 | // If we call AddChild on fListView before we create this scrollview, our program will drop 62 | // to the debugger when we call AddChild on the BScrollView -- a BView can have only one parent. 63 | BScrollView *scrollView = new BScrollView("scrollview",fListView, B_FOLLOW_ALL, 0,true,true); 64 | top->AddChild(scrollView); 65 | 66 | // A BListView's selection message is sent to the window any time that the list's selection 67 | // changes. 68 | fListView->SetSelectionMessage(new BMessage(M_SET_TITLE)); 69 | 70 | fListView->AddItem(new BStringItem("Toe Wrestling")); 71 | fListView->AddItem(new BStringItem("Electric Toilet Racing")); 72 | fListView->AddItem(new BStringItem("Bog Snorkeling")); 73 | fListView->AddItem(new BStringItem("Chess Boxing")); 74 | fListView->AddItem(new BStringItem("Cheese Rolling")); 75 | fListView->AddItem(new BStringItem("Unicycle Polo")); 76 | } 77 | 78 | 79 | void 80 | MainWindow::MessageReceived(BMessage *msg) 81 | { 82 | switch (msg->what) 83 | { 84 | case M_RESET_WINDOW: 85 | { 86 | fListView->DeselectAll(); 87 | break; 88 | } 89 | case M_SET_TITLE: 90 | { 91 | int32 selection = fListView->CurrentSelection(); 92 | 93 | if (selection < 0) 94 | { 95 | // This code is here because when we press the Reset button, the selection 96 | // changes and an M_SET_TITLE message is sent, but because nothing is 97 | // selected, CurrentSelection() returns -1. 98 | SetTitle("The Weird World of Sports"); 99 | break; 100 | } 101 | 102 | BStringItem *item = dynamic_cast(fListView->ItemAt(selection)); 103 | if (item) 104 | SetTitle(item->Text()); 105 | break; 106 | } 107 | default: 108 | { 109 | BWindow::MessageReceived(msg); 110 | break; 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /ListItems/MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | 7 | class MainWindow : public BWindow 8 | { 9 | public: 10 | MainWindow(void); 11 | void MessageReceived(BMessage *msg); 12 | 13 | private: 14 | BListView *fListView; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ListItems/ReadMe: -------------------------------------------------------------------------------- 1 | From "Learning to Program with Haiku" by Jon Yoder (DarkWyrm) 2 | http://haiku-os.org/development/learning_to_program_with_haiku 3 | 4 | Create and show a window that has a list of items. 5 | The application window changes as you select different items 6 | in the list. -------------------------------------------------------------------------------- /ListItems/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe -------------------------------------------------------------------------------- /LoadResources/App.cpp: -------------------------------------------------------------------------------- 1 | #include "App.h" 2 | #include "MainWindow.h" 3 | 4 | 5 | App::App(void) 6 | : BApplication("application/x-vnd.dw-Emo") 7 | { 8 | MainWindow *mainwin = new MainWindow(); 9 | mainwin->Show(); 10 | } 11 | 12 | 13 | int 14 | main(void) 15 | { 16 | App *app = new App(); 17 | app->Run(); 18 | delete app; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /LoadResources/App.h: -------------------------------------------------------------------------------- 1 | #ifndef APP_H 2 | #define APP_H 3 | 4 | #include 5 | 6 | class App : public BApplication 7 | { 8 | public: 9 | App(void); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LoadResources/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "PictureView.h" 7 | 8 | MainWindow::MainWindow(void) 9 | : BWindow(BRect(300,300,450,450),"Emo",B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS) 10 | { 11 | // Once again, we will make a background view to make things look nice 12 | BView *top = new BView(Bounds(),"top",B_FOLLOW_ALL,B_WILL_DRAW); 13 | top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 14 | AddChild(top); 15 | 16 | // This is our own BView subclass which draws one of several pictures 17 | PictureView *picview = new PictureView(); 18 | 19 | // Note that we have the background view add our picture view as a child. 20 | // Unpredictable drawing results will result when views overlap each other. You 21 | // can also run into problems where a view which is drawn on the screen doesn't 22 | // receive mouse events and other bizarre situations. 23 | top->AddChild(picview); 24 | 25 | // Move our picture view to the center of the window. This code right here is 26 | // very common, so get used to seeing and/or using it. 27 | picview->MoveTo((Bounds().Width() - picview->Bounds().Width()) / 2.0, 28 | (Bounds().Height() - picview->Bounds().Height()) / 2.0); 29 | } 30 | 31 | 32 | // QuitRequested() is a BWindow hook function which is called when the window is asked 33 | // to close. When it returns true, the window is given "permission" to quit and it does. 34 | // If QuitRequested() returns false, the window just keeps on running as if nothing 35 | // happened. Implementing this hook to send a quit message to the global application 36 | // instance is the old way of making an app quit when the main window is closed. It is 37 | // included here because legacy apps do it this way instead of using the 38 | // B_QUIT_ON_WINDOW_CLOSE flag in the constructor. This function also has its uses for 39 | // situations where you need to ask the user "Would you like to save your changes?" and 40 | // giving the user a chance to cancel the window closing altogether. 41 | bool 42 | MainWindow::QuitRequested(void) 43 | { 44 | be_app->PostMessage(B_QUIT_REQUESTED); 45 | return true; 46 | } 47 | -------------------------------------------------------------------------------- /LoadResources/MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | class MainWindow : public BWindow 7 | { 8 | public: 9 | MainWindow(void); 10 | bool QuitRequested(void); 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /LoadResources/PictureView.cpp: -------------------------------------------------------------------------------- 1 | #include "PictureView.h" 2 | #include 3 | #include 4 | 5 | // This class is our own special control. It loads five images from the application 6 | // resources and places them in an array. Once loaded, it resizes itself to exactly 7 | // fit the first bitmap. Since they are all the same size, this assumption is OK. 8 | PictureView::PictureView(void) 9 | : BView(BRect(0,0,100,100), "picview", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW), 10 | fBitmapIndex(0) 11 | { 12 | // Load up all our pictures using a loop. There are 5 different versions of 13 | // BTranslationUtils::GetBitmap. This is one of two which load images from program 14 | // resources. 15 | for (int8 i = 1; i <= 5; i++) 16 | { 17 | BBitmap *smiley = BTranslationUtils::GetBitmap(B_PNG_FORMAT,i); 18 | fBitmaps[i - 1] = (smiley && smiley->IsValid()) ? smiley : NULL; 19 | } 20 | 21 | if (fBitmaps[0] && fBitmaps[0]->IsValid()) 22 | ResizeTo(fBitmaps[0]->Bounds().Width(),fBitmaps[0]->Bounds().Height()); 23 | } 24 | 25 | 26 | PictureView::~PictureView(void) 27 | { 28 | } 29 | 30 | 31 | // The BView's Draw() function is called whenever it is asked to draw itself 32 | // on the screen. This is one of the few places where its drawing commands can be 33 | // called. 34 | void 35 | PictureView::Draw(BRect rect) 36 | { 37 | // Alpha transparency is ignored in the default drawing mode for performance reasons, 38 | // so we will set the drawing mode to utilizes transparency information. 39 | SetDrawingMode(B_OP_ALPHA); 40 | 41 | // Set the foreground color of the BView to white 42 | SetHighColor(255,255,255); 43 | 44 | // Fill the BView's area with white. Like with most BView drawing commands, the last 45 | // argument is the color to use which defaults to the high color. Other color choices are 46 | // B_SOLID_LOW, which uses the background color, and B_MIXED_COLORS, which mixes the high 47 | // and low colors. 48 | FillRect(Bounds()); 49 | 50 | // Draw the current bitmap on the screen 51 | if (fBitmaps[fBitmapIndex]) 52 | DrawBitmap(fBitmaps[fBitmapIndex]); 53 | 54 | // Set the foreground color to black 55 | SetHighColor(0,0,0); 56 | 57 | // Draw a black border around the view 58 | StrokeRect(Bounds()); 59 | } 60 | 61 | 62 | // Mouse handling is kinda funny. BView has three hook functions for it: MouseDown(), which is 63 | // called whenever the user presses down a mouse button while the pointer is over the view, MouseUp, 64 | // which is called whenever the user releases a mouse button while the pointer is over the view, 65 | // and MouseMoved(), which is called whenever the mouse changes position while over the view. This 66 | // gives you, the developer, a great deal of control over how your view reacts to any kind of mouse 67 | // event. 68 | void 69 | PictureView::MouseUp(BPoint pt) 70 | { 71 | // Go to the next image in the array or loop around to the beginning if at the end. 72 | if (fBitmapIndex == sizeof(*fBitmaps)) 73 | fBitmapIndex = 0; 74 | else 75 | fBitmapIndex++; 76 | 77 | // Force a redraw of the entire view because we've changed pictures 78 | Invalidate(); 79 | } 80 | -------------------------------------------------------------------------------- /LoadResources/PictureView.h: -------------------------------------------------------------------------------- 1 | #ifndef PICTUREVIEW_H 2 | #define PICTUREVIEW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class PictureView : public BView 10 | { 11 | public: 12 | PictureView(void); 13 | ~PictureView(void); 14 | 15 | void Draw(BRect rect); 16 | void MouseUp(BPoint pt); 17 | 18 | private: 19 | BBitmap *fBitmaps[5]; 20 | int8 fBitmapIndex; 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /LoadResources/ReadMe: -------------------------------------------------------------------------------- 1 | From "Learning to Program with Haiku" by Jon Yoder (DarkWyrm) 2 | http://haiku-os.org/development/learning_to_program_with_haiku 3 | 4 | Create and show a window that shows images loaded from a resource file. 5 | See the "compile" file to learn how to add data from a resource file 6 | to an application. -------------------------------------------------------------------------------- /LoadResources/Resources.rsrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcouzelis/HaikuApiExamples/3872f479d1ba982a9a07afbbf48886ec8ee7f30f/LoadResources/Resources.rsrc -------------------------------------------------------------------------------- /LoadResources/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe -ltranslation 2 | xres -o Run Resources.rsrc 3 | -------------------------------------------------------------------------------- /MenuBar/App.cpp: -------------------------------------------------------------------------------- 1 | #include "App.h" 2 | #include "MainWindow.h" 3 | 4 | 5 | App::App(void) 6 | : BApplication("application/x-vnd.dw-MenuColors") 7 | { 8 | MainWindow *mainwin = new MainWindow(); 9 | mainwin->Show(); 10 | } 11 | 12 | 13 | int 14 | main(void) 15 | { 16 | App *app = new App(); 17 | app->Run(); 18 | delete app; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /MenuBar/App.h: -------------------------------------------------------------------------------- 1 | #ifndef APP_H 2 | #define APP_H 3 | 4 | #include 5 | 6 | class App : public BApplication 7 | { 8 | public: 9 | App(void); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /MenuBar/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | // Create a list of message types for this application. 10 | // A message type needs to be an int. 11 | // Create a rather unique int by casting a string of characters. 12 | enum 13 | { 14 | M_SET_COLOR_RED = 'sred', 15 | M_SET_COLOR_GREEN = 'sgrn', 16 | M_SET_COLOR_BLUE = 'sblu', 17 | M_SET_COLOR_BLACK = 'sblk' 18 | }; 19 | 20 | 21 | // http://www.haiku-os.org/legacy-docs/bebook/BWindow.html#BWindow_Constructor 22 | MainWindow::MainWindow(void) 23 | : 24 | BWindow(BRect(100,100,500,400),"MenuApp",B_TITLED_WINDOW, 25 | B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE) 26 | { 27 | BRect r(Bounds()); 28 | r.bottom = 20; 29 | 30 | // The menu bar is created inside a rectangle area "r" 31 | // http://www.haiku-os.org/legacy-docs/bebook/BMenuBar.html#BMenuBar_Constructor 32 | BMenuBar *menuBar = new BMenuBar(r,"menubar"); 33 | 34 | // Add the menu bar to the window 35 | AddChild(menuBar); 36 | 37 | // Create a menu to go in the menu bar 38 | http://www.haiku-os.org/legacy-docs/bebook/BMenu.html#BMenu_Constructor 39 | BMenu *menu = new BMenu("Colors"); 40 | 41 | // A menu item only needs a text label and 42 | // a message to send when it's pressed. 43 | // You can also provide a keyboard shortcut character. 44 | // http://www.haiku-os.org/legacy-docs/bebook/BMenuItem.html#BMenuItem_Constructor 45 | menu->AddItem(new BMenuItem("Red",new BMessage(M_SET_COLOR_RED),'R')); 46 | menu->AddItem(new BMenuItem("Green",new BMessage(M_SET_COLOR_GREEN),'G')); 47 | menu->AddItem(new BMenuItem("Blue",new BMessage(M_SET_COLOR_BLUE),'B')); 48 | menu->AddItem(new BMenuItem("Black",new BMessage(M_SET_COLOR_BLACK),'K')); 49 | menuBar->AddItem(menu); 50 | 51 | // Create a "view" to do some drawing commands to. 52 | // In this example, we will be changing its color. 53 | // http://www.haiku-os.org/legacy-docs/bebook/BView.html#BView_Constructor 54 | BView *view = new BView(BRect(100,100,300,200),"colorview",B_FOLLOW_ALL, B_WILL_DRAW); 55 | AddChild(view); 56 | view->SetViewColor(0,0,160); 57 | } 58 | 59 | 60 | void 61 | MainWindow::MessageReceived(BMessage *msg) 62 | { 63 | // http://www.haiku-os.org/legacy-docs/bebook/BWindow.html#BWindow_FindView 64 | BView *view = FindView("colorview"); 65 | 66 | // Find out what type of message was recieved 67 | // and act accordingly. 68 | // http://www.haiku-os.org/legacy-docs/bebook/BMessage.html#BMessage_what 69 | switch (msg->what) 70 | { 71 | case M_SET_COLOR_RED: 72 | { 73 | view->SetViewColor(160,0,0); 74 | 75 | // An invalidated view will be forced to be redrawn. 76 | // http://www.haiku-os.org/legacy-docs/bebook/BView.html#BView_Invalidate 77 | view->Invalidate(); 78 | break; 79 | } 80 | case M_SET_COLOR_GREEN: 81 | { 82 | view->SetViewColor(0,160,0); 83 | view->Invalidate(); 84 | break; 85 | } 86 | case M_SET_COLOR_BLUE: 87 | { 88 | view->SetViewColor(0,0,160); 89 | view->Invalidate(); 90 | break; 91 | } 92 | case M_SET_COLOR_BLACK: 93 | { 94 | view->SetViewColor(0,0,0); 95 | view->Invalidate(); 96 | break; 97 | } 98 | default: 99 | { 100 | // Some other message was recieved! 101 | // Just send it to the parent "BWindow" class. 102 | BWindow::MessageReceived(msg); 103 | break; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /MenuBar/MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | class MainWindow : public BWindow 7 | { 8 | public: 9 | MainWindow(void); 10 | void MessageReceived(BMessage *msg); 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /MenuBar/ReadMe: -------------------------------------------------------------------------------- 1 | From "Learning to Program with Haiku" by Jon Yoder (DarkWyrm) 2 | http://haiku-os.org/development/learning_to_program_with_haiku 3 | 4 | Create and show a window that has a menu bar. 5 | The menu items in the menu bar uses messages to change 6 | the applicatin. -------------------------------------------------------------------------------- /MenuBar/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A collection of small and simple applications that show how to do various things with the Haiku API. You can use them to learn the Haiku API or to begin writing your next Haiku application. 2 | 3 | You can contribute. It's easy! 4 | 5 | Are you learning how to use the Haiku API? Are you creating little example applications that never leave your computer? Please consider donating them to this project. I could give you commit access, or you could simply email me your code. You will retain the copyright, but I ask that it be licensed under the MIT license. 6 | 7 | Many of the examples come from the excellent Haiku tutorial books by DarkWyrm. 8 | -------------------------------------------------------------------------------- /VerticalSlider/App.cpp: -------------------------------------------------------------------------------- 1 | #include "App.h" 2 | #include "MainWindow.h" 3 | 4 | 5 | App::App(void) 6 | : BApplication("application/x-vnd.dw-ButtonDemo") 7 | { 8 | MainWindow *mainwin = new MainWindow(); 9 | mainwin->Show(); 10 | } 11 | 12 | 13 | int 14 | main(void) 15 | { 16 | App *app = new App(); 17 | app->Run(); 18 | delete app; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /VerticalSlider/App.h: -------------------------------------------------------------------------------- 1 | #ifndef APP_H 2 | #define APP_H 3 | 4 | #include 5 | 6 | class App : public BApplication 7 | { 8 | public: 9 | App(void); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /VerticalSlider/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | #include 3 | 4 | // The BString class is a phenomenally useful class which eliminates 5 | // almost all hassle associated with manipulating strings. 6 | #include 7 | 8 | // The BView class is the generic class used for creating controls and 9 | // drawing things inside a window. 10 | #include 11 | 12 | // This defines the identifier for the message that our button will send. The 13 | // letters inside the single quotes are translated into an integer. The value 14 | // for M_BUTTON_CLICKED is arbitrary, so as long as it's unique, it's not too 15 | // important what it is. 16 | enum 17 | { 18 | M_BUTTON_CLICKED = 'btcl', 19 | M_SLIDE = 'slde' 20 | }; 21 | 22 | 23 | MainWindow::MainWindow(void) 24 | : BWindow(BRect(100,100,300,300),"ClickMe",B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | 25 | B_QUIT_ON_WINDOW_CLOSE), 26 | fCount(0) 27 | { 28 | // Create a slider. It has min and max value, a name, a label, and a message sent on 29 | // mouse clicks. It can be vertical or horizontal, and have a block or triangle thumb 30 | slider = new BSlider(BRect(10,10,11,110),"slider","Slide me!", 31 | new BMessage(M_BUTTON_CLICKED), 0.0f, 100.0f, B_VERTICAL, B_BLOCK_THUMB, B_FOLLOW_LEFT|B_FOLLOW_TOP); 32 | 33 | // This message is sent when the slider values changes. We will handle it in 34 | // Messagereceived. 35 | slider->SetModificationMessage(new BMessage(M_SLIDE)); 36 | 37 | slider->ResizeToPreferred(); 38 | 39 | // Add our button to the window 40 | AddChild(slider); 41 | } 42 | 43 | 44 | void 45 | MainWindow::MessageReceived(BMessage *msg) 46 | { 47 | // The way that BMessages are identified is by the public property 'what'. 48 | switch (msg->what) 49 | { 50 | // If the message was the one sent to the window by the slider 51 | case M_BUTTON_CLICKED: 52 | { 53 | fCount++; 54 | 55 | BString labelString("Clicks: "); 56 | 57 | // This adds the value of fCount to the end of labelString. More on this later. 58 | labelString << fCount; 59 | 60 | // Set the window's title to the new string we've made 61 | SetTitle(labelString.String()); 62 | break; 63 | } 64 | case M_SLIDE: 65 | { 66 | // Change the slider label to its current value. Notice how this happens as 67 | // you slide the slider, while the window title is changed only when you 68 | // release it. 69 | BString labelString; 70 | int32 val; 71 | msg->FindInt32("be:value", 0, &val); 72 | 73 | labelString << val; 74 | slider->SetLabel(labelString); 75 | break; 76 | } 77 | default: 78 | { 79 | // If the message doesn't match one of the ones we explicitly define, it must 80 | // be some sort of system message, so we will call the version of MessageReceived() 81 | // created for BWindow so that it can handle them. THIS IS REQUIRED if you want 82 | // your window to act the way that you expect it to. 83 | BWindow::MessageReceived(msg); 84 | break; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /VerticalSlider/MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | class BSlider; 7 | 8 | class MainWindow : public BWindow 9 | { 10 | public: 11 | MainWindow(void); 12 | 13 | // We are implementing the virtual BWindow method MessageReceived so 14 | // that we can do something with the message that the button sends. 15 | void MessageReceived(BMessage *msg); 16 | 17 | private: 18 | // This property will hold the number of 19 | // times the button has been clicked. 20 | int32 fCount; 21 | BSlider* slider; 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /VerticalSlider/ReadMe: -------------------------------------------------------------------------------- 1 | Create a window with a slider inside. 2 | Shows how to handle the slider's messages. 3 | -------------------------------------------------------------------------------- /VerticalSlider/compile: -------------------------------------------------------------------------------- 1 | gcc -o Run *.cpp -lbe --------------------------------------------------------------------------------