Another recreation of a favorite BeOS screensaver of mine: Message, originally
by Jon Watte. This was a tough but interesting problem. My version still isn't quite as nice as his. I think the color generation could be improved, and I KNOW the x and y placement of the text could be improved. I also think it would be nice to display the full message at the bottom of the screen (similar to ShowImage showing the file type and name in full screen mode.) But this is a good base to work from. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20035 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b1d2a4fe26
commit
41ecd34905
@ -3,4 +3,5 @@ SubDir HAIKU_TOP src add-ons screen_savers ;
|
||||
SubInclude HAIKU_TOP src add-ons screen_savers buynow ;
|
||||
SubInclude HAIKU_TOP src add-ons screen_savers haiku ;
|
||||
SubInclude HAIKU_TOP src add-ons screen_savers ifs ;
|
||||
SubInclude HAIKU_TOP src add-ons screen_savers message ;
|
||||
SubInclude HAIKU_TOP src add-ons screen_savers slideshowsaver ;
|
||||
|
13
src/add-ons/screen_savers/message/Jamfile
Normal file
13
src/add-ons/screen_savers/message/Jamfile
Normal file
@ -0,0 +1,13 @@
|
||||
SubDir HAIKU_TOP src add-ons screen_savers message ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
ScreenSaver Message :
|
||||
Message.cpp :
|
||||
be libscreensaver.so ;
|
||||
|
||||
Package haiku-screensaverkit-cvs :
|
||||
Message :
|
||||
boot home config add-ons Screen\ Savers
|
||||
;
|
||||
|
221
src/add-ons/screen_savers/message/Message.cpp
Normal file
221
src/add-ons/screen_savers/message/Message.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ryan Leavengood
|
||||
*/
|
||||
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Font.h>
|
||||
#include <List.h>
|
||||
#include <Picture.h>
|
||||
#include <Screen.h>
|
||||
#include <ScreenSaver.h>
|
||||
#include <String.h>
|
||||
#include <StringView.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Double brackets to satisfy a compiler warning
|
||||
const pattern kCheckered = { { 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33 } };
|
||||
|
||||
|
||||
// Get a clever message from fortune
|
||||
BString *get_message()
|
||||
{
|
||||
BString *result = new BString();
|
||||
system("fortune > /tmp/fortune_msg");
|
||||
FILE *file = fopen("/tmp/fortune_msg", "r");
|
||||
if (file) {
|
||||
char buf[512];
|
||||
int bytesRead;
|
||||
while (!feof(file)) {
|
||||
bytesRead = fread(buf, 1, 512, file);
|
||||
result->Append(buf, bytesRead);
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
remove("/tmp/fortune_msg");
|
||||
|
||||
// Just in case
|
||||
if (result->Length() <= 0) {
|
||||
result->Append("Insert clever anecdote or phrase here!");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Inspired by the classic BeOS screensaver, of course.
|
||||
// Thanks to Jon Watte for writing the original.
|
||||
class Message : public BScreenSaver
|
||||
{
|
||||
public:
|
||||
Message(BMessage *archive, image_id);
|
||||
~Message();
|
||||
void Draw(BView *view, int32 frame);
|
||||
void StartConfig(BView *view);
|
||||
status_t StartSaver(BView *view, bool preview);
|
||||
|
||||
private:
|
||||
BList *fFontFamilies;
|
||||
float fScaleFactor;
|
||||
};
|
||||
|
||||
|
||||
BScreenSaver *instantiate_screen_saver(BMessage *msg, image_id image)
|
||||
{
|
||||
return new Message(msg, image);
|
||||
}
|
||||
|
||||
|
||||
Message::Message(BMessage *archive, image_id id)
|
||||
: BScreenSaver(archive, id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Message::~Message()
|
||||
{
|
||||
if (fFontFamilies) {
|
||||
for (int32 i = 0; i < fFontFamilies->CountItems(); i++) {
|
||||
if (fFontFamilies->ItemAt(i))
|
||||
delete ((font_family) fFontFamilies->ItemAt(i));
|
||||
}
|
||||
delete fFontFamilies;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Message::StartConfig(BView *view)
|
||||
{
|
||||
view->AddChild(new BStringView(BRect(20, 10, 200, 35), "", "Message, by Ryan Leavengood"));
|
||||
view->AddChild(new BStringView(BRect(20, 40, 200, 65), "", "Inspired by Jon Watte's Original"));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Message::StartSaver(BView *view, bool preview)
|
||||
{
|
||||
// Scale factor is based on the system I developed this on, in
|
||||
// other words other factors below depend on this.
|
||||
fScaleFactor = view->Bounds().Height() / 1024;
|
||||
|
||||
// Get font families
|
||||
int numFamilies = count_font_families();
|
||||
fFontFamilies = new BList();
|
||||
for (int32 i = 0; i < numFamilies; i++) {
|
||||
font_family *family = new font_family[1];
|
||||
uint32 flags;
|
||||
if (get_font_family(i, family, &flags) == B_OK) {
|
||||
// Do not add fixed fonts
|
||||
if (!(flags & B_IS_FIXED))
|
||||
fFontFamilies->AddItem(*family);
|
||||
}
|
||||
}
|
||||
|
||||
// Seed the random number generator
|
||||
srand((int)system_time());
|
||||
|
||||
// Set tick size to 30,000,000 microseconds = 30 seconds
|
||||
SetTickSize(30000000);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Message::Draw(BView *view, int32 frame)
|
||||
{
|
||||
// Double-buffered drawing
|
||||
BScreen screen;
|
||||
BBitmap buffer(view->Bounds(), screen.ColorSpace(), true);
|
||||
BView offscreen(view->Bounds(), NULL, 0, 0);
|
||||
buffer.AddChild(&offscreen);
|
||||
buffer.Lock();
|
||||
|
||||
// Set up the colors
|
||||
rgb_color base_color = {rand() % 25, rand() % 25, rand() % 25};
|
||||
offscreen.SetHighColor(base_color);
|
||||
offscreen.SetLowColor(tint_color(base_color, 0.815F));
|
||||
offscreen.FillRect(offscreen.Bounds(), kCheckered);
|
||||
rgb_color colors[8] = {
|
||||
tint_color(base_color, B_LIGHTEN_1_TINT),
|
||||
tint_color(base_color, 0.795F),
|
||||
tint_color(base_color, 0.851F),
|
||||
tint_color(base_color, 0.926F),
|
||||
tint_color(base_color, 1.05F),
|
||||
tint_color(base_color, B_DARKEN_1_TINT),
|
||||
tint_color(base_color, B_DARKEN_2_TINT),
|
||||
tint_color(base_color, B_DARKEN_3_TINT),
|
||||
};
|
||||
|
||||
// Set the basic font parameters, including random font family
|
||||
BFont font;
|
||||
offscreen.GetFont(&font);
|
||||
font.SetFlags(B_DISABLE_ANTIALIASING);
|
||||
font.SetFace(B_BOLD_FACE);
|
||||
font.SetFamilyAndStyle((font_family) fFontFamilies->ItemAt(rand() % fFontFamilies->CountItems()), NULL);
|
||||
offscreen.SetFont(&font);
|
||||
|
||||
// Get the message
|
||||
// TODO: Display the whole message at the bottom of the screen
|
||||
// in a translucent rect
|
||||
BString *message = get_message();
|
||||
// Replace newlines and tabs with spaces
|
||||
message->ReplaceSet("\n\t", ' ');
|
||||
|
||||
int height = (int) offscreen.Bounds().Height();
|
||||
int width = (int) offscreen.Bounds().Width();
|
||||
|
||||
// From 8 to 16 iterations
|
||||
int32 iterations = (rand() % 9) + 8;
|
||||
for (int32 i = 0; i < iterations; i++) {
|
||||
// Randomly set font size and shear
|
||||
BFont font;
|
||||
offscreen.GetFont(&font);
|
||||
float fontSize = ((rand() % 320) + 42) * fScaleFactor;
|
||||
font.SetSize(fontSize);
|
||||
// Set the shear off 90 about 1/2 of the time
|
||||
if (rand() % 2 == 1)
|
||||
font.SetShear((float) ((rand() % 135) + (rand() % 45)));
|
||||
else
|
||||
font.SetShear(90.0);
|
||||
offscreen.SetFont(&font);
|
||||
|
||||
// Randomly set drawing location
|
||||
// TODO: Improve this
|
||||
int x = (rand() % width) - (rand() % width/((rand() % 8)+1));
|
||||
int y = (rand() % height) - (rand() % height/((rand() % 8)+1));
|
||||
|
||||
// Draw new text
|
||||
offscreen.SetHighColor(colors[rand() % 8]);
|
||||
int strLength = message->Length();
|
||||
// See how wide this string is with the current font
|
||||
float strWidth = offscreen.StringWidth(message->String());
|
||||
int drawingLength = (int) (strLength * (width / strWidth));
|
||||
int start = 0;
|
||||
if (drawingLength >= strLength)
|
||||
drawingLength = strLength;
|
||||
else
|
||||
start = rand() % (strLength - drawingLength);
|
||||
char *toDraw = new char[drawingLength+1];
|
||||
strncpy(toDraw, message->String()+start, drawingLength);
|
||||
toDraw[drawingLength] = 0;
|
||||
offscreen.DrawString(toDraw, BPoint(x, y));
|
||||
delete toDraw;
|
||||
}
|
||||
|
||||
offscreen.Sync();
|
||||
buffer.Unlock();
|
||||
view->DrawBitmap(&buffer);
|
||||
buffer.RemoveChild(&offscreen);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user