From 251a065e2be9920d5b5303aa5c0caa9eeffc6101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 20 Dec 2007 23:29:09 +0000 Subject: [PATCH] A small demo app I wrote that is quite appropriate for the season :) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23144 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/bsnow/BSnow.rdef | 91 ++++++ src/apps/bsnow/Flakes.cpp | 40 +++ src/apps/bsnow/Flakes.h | 12 + src/apps/bsnow/Jamfile | 11 + src/apps/bsnow/README.html | 38 +++ src/apps/bsnow/SnowApp.cpp | 23 ++ src/apps/bsnow/SnowView.cpp | 618 ++++++++++++++++++++++++++++++++++++ src/apps/bsnow/SnowView.h | 79 +++++ src/apps/bsnow/makefile | 120 +++++++ 9 files changed, 1032 insertions(+) create mode 100644 src/apps/bsnow/BSnow.rdef create mode 100644 src/apps/bsnow/Flakes.cpp create mode 100644 src/apps/bsnow/Flakes.h create mode 100644 src/apps/bsnow/Jamfile create mode 100644 src/apps/bsnow/README.html create mode 100644 src/apps/bsnow/SnowApp.cpp create mode 100644 src/apps/bsnow/SnowView.cpp create mode 100644 src/apps/bsnow/SnowView.h create mode 100644 src/apps/bsnow/makefile diff --git a/src/apps/bsnow/BSnow.rdef b/src/apps/bsnow/BSnow.rdef new file mode 100644 index 0000000000..8200983d80 --- /dev/null +++ b/src/apps/bsnow/BSnow.rdef @@ -0,0 +1,91 @@ +/* +** BSnow.rdef +** +** Automatically generated by BResourceParser on +** Friday, December 21, 2007 at 00:15:36. +** +*/ + +resource(1, "BEOS:APP_FLAGS") (#'APPF') $"00000000"; + +resource(1, "BEOS:APP_VERSION") #'APPV' array { + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000000000000000000000000000000000000000000000000000" + $"0000000000000000" +}; + +resource(101, "BEOS:L:STD_ICON") #'ICON' array { + $"FFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFF3FFF3FFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFF3FFFFF" + $"FFFFFF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFF" + $"FFFF3FFF3FFF3FFFFFFFFFFFFFFFFF3FFF3FFFFFFFFFFFFFFFFFFF3FFF3FFFFF" + $"FFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFF3FFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFF3FFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFF3FFF3FFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFF3FFF3FFFFFFFFFFFFFFF3FFF3FFFFF" + $"FFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFF3FFFFFFF" + $"FFFFFFFFFF3FFF3FFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFF3FFFFF" + $"FFFFFFFFFFFF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFF3FFF3FFF3FFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF3FFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFF00FFFF00FFFFFF00FFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF00FF00FF00FF00FF00FF00FF00FFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF0000FFFF00FF00FFFF00FFFFFF00FF00FFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF3FFF3FFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFF3FFF3FFF3FFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF3FFF3FFFFFFFFFFFFF3F3F3FFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFF3FFF3FFFFFFFFFFFFF3F" + $"FFFFFFFF3F3F3F3F3F3F3F3F3F3F3FFFFFFFFFFFFFFF3FFFFFFFFFFFFF3F3F3F" + $"FFFF3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3FFFFFFFFFFFFFFF3F3F3F3F3F" + $"FF3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F" + $"3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F" +}; + +resource(101, "BEOS:M:STD_ICON") #'MICN' array { + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFF3FFF3FFFFF" + $"FFFFFFFF3FFFFFFFFFFFFFFF3FFFFFFF" + $"FFFF3FFF3FFF3FFFFFFFFF3FFF3FFFFF" + $"FFFFFF3F3F3FFFFFFFFFFFFFFFFFFFFF" + $"FFFF3FFF3FFF3FFFFF3FFF3FFFFFFFFF" + $"FFFFFFFF3FFFFFFFFFFF3FFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFF3FFF3FFFFFFFFF" + $"FFFF0000FFFFFFFFFFFFFFFFFFFFFFFF" + $"FF0000FFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFF0000FF0013FF0000FF001313FFFF" + $"FF0000FFFF0000FF0000FFFF0000FFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F" + $"FFFF3F3F3F3F3F3F3F3F3FFFFF3F3F3F" + $"FF3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F" + $"3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F" +}; + +resource(1, "BEOS:APP_SIG") (#'MIMS') "application/x-vnd.mmu_man.BSnow"; + diff --git a/src/apps/bsnow/Flakes.cpp b/src/apps/bsnow/Flakes.cpp new file mode 100644 index 0000000000..7613e0406b --- /dev/null +++ b/src/apps/bsnow/Flakes.cpp @@ -0,0 +1,40 @@ +#include "Flakes.h" + +#define TRAN 0xFF +#define WHIT 0x3F + +const char gFlakeBits[NUM_PATTERNS][64] = { +{ +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, WHIT, TRAN, WHIT, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, WHIT, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, WHIT, TRAN, WHIT, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN +}, +{ +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, WHIT, TRAN, TRAN, TRAN, TRAN, +TRAN, WHIT, TRAN, WHIT, TRAN, WHIT, TRAN, TRAN, +TRAN, TRAN, WHIT, WHIT, WHIT, TRAN, TRAN, TRAN, +TRAN, WHIT, TRAN, WHIT, TRAN, WHIT, TRAN, TRAN, +TRAN, TRAN, TRAN, WHIT, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN +} +/* +{ +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, +TRAN, WHIT, TRAN, TRAN, TRAN, WHIT, TRAN, TRAN, +TRAN, TRAN, WHIT, TRAN, WHIT, TRAN, TRAN, TRAN, +TRAN, WHIT, WHIT, WHIT, WHIT, WHIT, TRAN, TRAN, +TRAN, TRAN, WHIT, TRAN, WHIT, TRAN, TRAN, TRAN, +TRAN, WHIT, TRAN, TRAN, TRAN, WHIT, TRAN, TRAN, +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, +TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN, TRAN +} +*/ +}; + diff --git a/src/apps/bsnow/Flakes.h b/src/apps/bsnow/Flakes.h new file mode 100644 index 0000000000..35158dda63 --- /dev/null +++ b/src/apps/bsnow/Flakes.h @@ -0,0 +1,12 @@ +#ifndef _FLAKES_H +#define _FLAKES_H +#include + +#define NUM_PATTERNS 2 + +#define PAT_HOTSPOT 3,3 + +extern const char gFlakeBits[NUM_PATTERNS][64]; + + +#endif diff --git a/src/apps/bsnow/Jamfile b/src/apps/bsnow/Jamfile new file mode 100644 index 0000000000..b644fffdcc --- /dev/null +++ b/src/apps/bsnow/Jamfile @@ -0,0 +1,11 @@ +SubDir HAIKU_TOP src apps bsnow ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +Application BSnow : + Flakes.cpp + SnowView.cpp + SnowApp.cpp + : be + : BSnow.rdef + ; diff --git a/src/apps/bsnow/README.html b/src/apps/bsnow/README.html new file mode 100644 index 0000000000..22423561d1 --- /dev/null +++ b/src/apps/bsnow/README.html @@ -0,0 +1,38 @@ + + + +BSnow - winter weather for BeOS + + + +              *        .                .            .
+  .                         *                             .        *                 +BSnow - winter weather for BeOS,                         *                 .
+              *     .              *               .
+ +
+
+
+
+
+ +© 2003 François Revol. +
+
+Features: + +
+
+Limitations: + +
+Sources released under the MIT licence. + + diff --git a/src/apps/bsnow/SnowApp.cpp b/src/apps/bsnow/SnowApp.cpp new file mode 100644 index 0000000000..1cad765bbf --- /dev/null +++ b/src/apps/bsnow/SnowApp.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include "SnowView.h" + +int main(int argc, char **argv) +{ + BApplication app(APP_SIG); + BWindow *win; + bool draggersShown = BDragger::AreDraggersDrawn(); + win = new BWindow(BRect(SNOW_VIEW_RECT), "BSnow", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE|B_NOT_RESIZABLE); + SnowView *view = new SnowView(); + win->AddChild(view); + win->MoveTo(50, 50); + win->Show(); + win->SetPulseRate(500000); + BDragger::ShowAllDraggers(); + app.Run(); + if (!draggersShown) + BDragger::HideAllDraggers(); + return 0; +} + diff --git a/src/apps/bsnow/SnowView.cpp b/src/apps/bsnow/SnowView.cpp new file mode 100644 index 0000000000..8fa0c6fe4d --- /dev/null +++ b/src/apps/bsnow/SnowView.cpp @@ -0,0 +1,618 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "SnowView.h" +#include "Flakes.h" +#include + +#include + +#define FORWARD_TO_PARENT + +SnowView::SnowView() + : BView(BRect(SNOW_VIEW_RECT), "BSnow", B_FOLLOW_NONE, B_WILL_DRAW|B_PULSE_NEEDED) +{ + fAttached = false; + fMsgRunner = NULL; + fCachedParent = NULL; + fFallenBmp = NULL; + fFallenView = NULL; + fFallenReg = NULL; + fInvalidator = -1; + fShowClickMe = false; + for (int i = 0; i < WORKSPACES_COUNT; i++) + fFlakes[i] = NULL; + for (int i = 0; i < NUM_PATTERNS; i++) + fFlakeBitmaps[i] = NULL; + BRect r(Frame()); + r.left = r.right - 7; + r.top = r.bottom - 7; + fDragger = new BDragger(r, this); + AddChild(fDragger); + SetHighColor(255,255,255); +} +/* +filter_result msgfilter(BMessage *message, BHandler **target, BMessageFilter *filter) +{ + switch (message->what) { + case B_MOUSE_DOWN: + case B_MOUSE_UP: + case B_MOUSE_MOVED: + case '_EVP': + case '_UPD': + case '_PUL': + case 'NTCH': + case 'NMDN': + break; + default: + printf("For: 0x%08lx: %s\n", *target, (*target)->Name()); + message->PrintToStream(); + } + return B_DISPATCH_MESSAGE; +} +*/ + +SnowView::SnowView(BMessage *archive) + : BView(archive) +{ + system_info si; + //printf("SnowView()\n"); + //archive->PrintToStream(); + fDragger = NULL; + fAttached = false; + fMsgRunner = NULL; + fFallenBmp = NULL; + fFallenView = NULL; + fFallenReg = NULL; + fCachedParent = NULL; + fShowClickMe = false; + SetFlags(Flags() & ~B_PULSE_NEEDED); /* it's only used when in the app */ + get_system_info(&si); + fNumFlakes = ((int32)(si.cpu_clock_speed/1000000)) * si.cpu_count / 3; //; + printf("BSnow: using %d flakes\n", fNumFlakes); + for (int i = 0; i < WORKSPACES_COUNT; i++) { + fFlakes[i] = new flake[fNumFlakes]; + memset(fFlakes[i], 0, fNumFlakes * sizeof(flake)); + } + for (int i = 0; i < NUM_PATTERNS; i++) { + fFlakeBitmaps[i] = new BBitmap(BRect(0,0,7,7), B_CMAP8); + fFlakeBitmaps[i]->SetBits(gFlakeBits[i], 8*8, 0, B_CMAP8); + } + fCurrentWorkspace = 0; + SetHighColor(255,255,255); + SetDrawingMode(B_OP_OVER); +} + +SnowView::~SnowView() +{ + for (int i = 0; i < WORKSPACES_COUNT; i++) + if (fFlakes[i]) + delete [] fFlakes[i]; + if (fFallenBmp) + delete fFallenBmp; /* the view goes away with it */ +} + +BArchivable *SnowView::Instantiate(BMessage *data) +{ + return new SnowView(data); +} + +status_t SnowView::Archive(BMessage *data, bool deep) const +{ + status_t err; + err = BView::Archive(data, deep); + if (err < B_OK) + return err; + data->AddString("add_on", APP_SIG); + return B_OK; +} + +void SnowView::AttachedToWindow() +{ + BView *p; + rgb_color col; + fAttached = true; +/* if (!fMsgRunner) + fMsgRunner = new BMessageRunner(BMessenger(this), + new BMessage(MSG_PULSE_ME), + INTERVAL); +*/ + p = Parent(); + if (p) + col = B_TRANSPARENT_32_BIT;//Parent()->ViewColor(); + else + col = ui_color(B_PANEL_BACKGROUND_COLOR); + SetViewColor(col); +// BScreen bs; +// fCachedWsWidth = bs.Frame().IntegerWidth(); +// fCachedWsHeight = bs.Frame().IntegerHeight(); + fDragger = dynamic_cast(FindView("_dragger_")); + if (fDragger && p) { + fCachedParent = p; + fCachedWsWidth = p->Frame().IntegerWidth(); + fCachedWsHeight = p->Frame().IntegerHeight(); + fDragger->SetViewColor(col); + if (fDragger->InShelf()) { + p->SetFlags(p->Flags() | B_DRAW_ON_CHILDREN); + ResizeTo(p->Bounds().Width(), p->Bounds().Height()); + MoveTo(0,0); + fDragger->MoveTo(p->Bounds().Width()-7, p->Bounds().Height()-7); + } + BRect fallenRect(p->Bounds()); + fallenRect.top = fallenRect.bottom - FALLEN_HEIGHT; + fFallenBmp = new BBitmap(fallenRect, B_BITMAP_ACCEPTS_VIEWS, B_CMAP8); + memset(fFallenBmp->Bits(), B_TRANSPARENT_MAGIC_CMAP8, (size_t)(fallenRect.Height()*fFallenBmp->BytesPerRow())); + fFallenView = new BView(fallenRect, "offscreen fallen snow", B_FOLLOW_NONE, 0); + fFallenBmp->AddChild(fFallenView); + fFallenReg = new BRegion; + fInvalidator = spawn_thread(SnowMakerThread, INVALIDATOR_THREAD_NAME, B_LOW_PRIORITY, (void *)this); + resume_thread(fInvalidator); + printf("BSnow: OK: ws = %ld x %ld\n", fCachedWsWidth, fCachedWsHeight); + //Window()->AddCommonFilter(new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, msgfilter)); + } +} + +void SnowView::DetachedFromWindow() +{ + fAttached = false; +/* + if (Parent()) { + Parent()->Invalidate(Parent()->Bounds()); + } +*/ + if (fMsgRunner) + delete fMsgRunner; + fMsgRunner = NULL; + status_t err; + fCachedParent = NULL; + if (fInvalidator > B_OK) + wait_for_thread(fInvalidator, &err); + fInvalidator = -1; + if (fFallenReg) + delete fFallenReg; +} + +void SnowView::MessageReceived(BMessage *msg) +{ + BAlert *info; + //msg->PrintToStream(); + switch (msg->what) { + case MSG_PULSE_ME: + if (Parent()) { + Calc(); + InvalFlakes(); + } + break; + case B_ABOUT_REQUESTED: + info = new BAlert("BSnow info", + "BSnow, just in case you don't have real one...\n" + "" B_UTF8_COPYRIGHT " 2003, François Revol.", + "Where is Santa ??"); + info->SetFeel(B_NORMAL_WINDOW_FEEL); + info->SetLook(B_FLOATING_WINDOW_LOOK); + info->SetFlags(info->Flags()|B_NOT_ZOOMABLE); + info->Go(NULL); + break; + default: +//#ifdef FORWARD_TO_PARENT +/* + if (fAttached && Parent()) + Parent()->MessageReceived(msg); + else +*/ +//#endif + BView::MessageReceived(msg); + } +} + +void SnowView::Draw(BRect ur) +{ + int i; + if (!fCachedParent) { + if (!fShowClickMe) { /* show "drag me" */ + SetLowColor(ViewColor()); + SetHighColor(0,0,0); + SetFontSize(12); + DrawString(MSG_DRAG_ME, BPoint(15,25)); + BPoint arrowHead(Bounds().RightBottom()+BPoint(-10,-10)); + StrokeLine(arrowHead, arrowHead - BPoint(7,0)); + StrokeLine(arrowHead, arrowHead - BPoint(0,7)); + StrokeLine(arrowHead, arrowHead - BPoint(12,12)); + return; + } else { + SetLowColor(ViewColor()); + SetHighColor(0,0,0); + SetFontSize(12); + DrawString(MSG_CLICK_ME, BPoint(15,25)); + return; + } + } + //printf("Draw()\n"); + uint32 cw = fCurrentWorkspace; + if (fFlakes[cw] == NULL) + return; + /* draw the snow already fallen */ +// BRect fallenRect(Bounds()); +// fallenRect.top = fallenRect.bottom - FALLEN_HEIGHT; +// if (ur.Intersects(fallenRect)) { + //if (fFallenBmp->Lock()) { + // DrawBitmap(fFallenBmp, fallenRect); + // fFallenBmp->Unlock(); + //} + int32 cnt = fFallenReg->CountRects(); +// drawing_mode oldmode = DrawingMode(); +// SetDrawingMode(B_OP_ADD); + + for (i=0; iRectAt(i); +// SetHighColor(245, 245, 245, 200); +// FillRect(r); +// SetHighColor(255, 255, 255, 255); +// r.InsetBy(1,1); + FillRect(r); + } +// SetDrawingMode(oldmode); +// } + /* draw our flakes */ + for (i=0; i3)?1:0; + //FillRect(BRect(fFlakes[cw][i].pos-BPoint(PAT_HOTSPOT),fFlakes[cw][i].pos-BPoint(PAT_HOTSPOT)+BPoint(7,7)), gFlakePatterns[pat]); +/* + StrokeLine(fFlakes[cw][i].pos+BPoint(-1,-1), + fFlakes[cw][i].pos+BPoint(1,1)); + StrokeLine(fFlakes[cw][i].pos+BPoint(-1,1), + fFlakes[cw][i].pos+BPoint(1,-1)); +*/ + DrawBitmap(fFlakeBitmaps[pat], fFlakes[cw][i].pos-BPoint(PAT_HOTSPOT)); + } +} + +void SnowView::Pulse() +{ + if (fShowClickMe) + return; /* done */ + if (fCachedParent) + return; /* we are in Tracker! */ + BMessenger msgr("application/x-vnd.Be-TRAK"); + BMessage msg(B_GET_PROPERTY), reply; + msg.AddSpecifier("Frame"); + msg.AddSpecifier("View", "BSnow"); + msg.AddSpecifier("Window", 1); /* 0 is Twitcher */ + if (msgr.SendMessage(&msg, &reply) == B_OK && reply.what == B_REPLY) { + //reply.PrintToStream(); + Invalidate(Bounds()); + fShowClickMe = true; + } +} + +void SnowView::Calc() +{ + int i; + uint32 cw = fCurrentWorkspace; + + /* check if the parent changed size */ + BRect pFrame = fCachedParent->Frame(); + if (fCachedWsWidth != pFrame.Width() || fCachedWsHeight != pFrame.Height()) { + fCachedWsWidth = pFrame.IntegerWidth(); + fCachedWsHeight = pFrame.IntegerHeight(); + printf("BSnow: Parent resized to %ld %ld\n", fCachedWsWidth, fCachedWsHeight); + fFallenReg->MakeEmpty(); /* remove all the fallen snow */ + ResizeTo(pFrame.IntegerWidth(), pFrame.IntegerHeight()); + fDragger->MoveTo(pFrame.IntegerWidth()-7, pFrame.IntegerHeight()-7); + } + + /* make new flakes */ + for (i=0; i 0) + fFlakes[cw][i].pos.x = 0; + else + fFlakes[cw][i].pos.x = fCachedWsWidth; + } + if (fFlakes[cw][i].pos.x > fCachedWsWidth+10) { + fFlakes[cw][i].pos.y = fFlakes[cw][i].pos.x - fCachedWsWidth; + if (fWind > 0) + fFlakes[cw][i].pos.x = 0; + else + fFlakes[cw][i].pos.x = fCachedWsWidth; + } + } + } + + /* like a candle in the wind... */ + if (fWindDuration < system_time()) { + fWindDuration = system_time() + ((((bigtime_t)rand())*1000) % WIND_MAX_DURATION); + fWind = (rand() % WIND_SPAN) - WIND_SPAN/2; + printf("BSnow: wind change: %f\n", fWind); + } + + +// if (fFallenView->LockLooperWithTimeout(5000)) { +// if (fFallenBmp) { +// uint8 *fallenBits = (uint8 *)fFallenBmp->Bits(); + + BRegion desktopReg; + GetClippingRegion(&desktopReg); + + /* let's add some gravity and wind */ + for (i=0; i (fCachedWsHeight-FALLEN_HEIGHT)) { + + bool fallen = false; + bool keepfalling = false; + + /* fallen on the flour */ + if (fFlakes[cw][i].pos.y > fCachedWsHeight-2) + fallen = true; + /* fallon on another fallen flake */ + else if (fFallenReg->Intersects(BRect(fFlakes[cw][i].pos - BPoint(0,1), + fFlakes[cw][i].pos + BPoint(0,1)))) { + /* don't accumulate too much */ + if ((fFlakes[cw][i].pos.y > fCachedWsHeight-30) || + !desktopReg.Intersects( + BRect(fFlakes[cw][i].pos + BPoint(0,6), + fFlakes[cw][i].pos + BPoint(0,10)))) + fallen = true; + /* fallen on a window */ + } else if (!desktopReg.Intersects( + BRect(fFlakes[cw][i].pos + BPoint(-1,-1-2), + fFlakes[cw][i].pos + BPoint(1,1-1))) && + desktopReg.Intersects( + BRect(fFlakes[cw][i].pos + BPoint(-1,-1-3), + fFlakes[cw][i].pos + BPoint(1,1-3)))) { + //printf("fallen3 @ %f %f\n", fFlakes[cw][i].pos.x, fFlakes[cw][i].pos.y); + fFlakes[cw][i].pos = fFlakes[cw][i].opos; + fallen = true; + keepfalling = true; /* but keep one falling */ + } + +/* else if (fallenBits[ (long)(fFlakes[cw][i].pos.y + * fFallenBmp->BytesPerRow() + + fFlakes[cw][i].pos.y + - (fCachedWsHeight-FALLEN_HEIGHT)) ] != B_TRANSPARENT_MAGIC_CMAP8) { + fallen = true; + }*/ + +// if (fallen) { +// int pat = (fFlakes[cw][i].weight>3)?1:0; +// if (fFlakes[cw][i].pos.y > fCachedWsHeight-1) +// fFlakes[cw][i].pos.y = fCachedWsHeight-(rand()%4); + //fFallenView->DrawBitmap(fFlakeBitmaps[pat], fFlakes[cw][i].pos-BPoint(PAT_HOTSPOT)); +// fallenBits[ (long)(fFlakes[cw][i].pos.y * fFallenBmp->BytesPerRow() +// + fFlakes[cw][i].pos.y-(fCachedWsHeight-FALLEN_HEIGHT)) ] = 0x56; +// printf("fallen @ %f, %f\n", fFlakes[cw][i].pos.x, fFlakes[cw][i].pos.y); +// } + if (fallen) { + if (!keepfalling) + fFlakes[cw][i].weight = 0; + fFallenReg->Include(BRect(fFlakes[cw][i].pos - BPoint(2,0), + fFlakes[cw][i].pos + BPoint(2,2))); + if (keepfalling) { + fFlakes[cw][i].pos += BPoint(0,10); + /* except if under the desktop */ + if (fFlakes[cw][i].pos.y > fCachedWsHeight-1) + fFlakes[cw][i].weight = 0; + } + } + + /* cleanup, when a window hides the snow */ + fFallenReg->IntersectWith(&desktopReg); + + /* cleanup, when a window is moved */ + /* seems to lockup Tracker */ +/* + int32 cnt = fFallenReg->CountRects(); + for (i=0; iRectAt(i); + if (desktopReg.Intersects(r.OffsetByCopy(0,15))) { + fFallenReg->Exclude(r); + cnt--; + } + } +*/ + /* add the effect of the wind */ + fFlakes[cw][i].pos.x += fWind + (rand() % 6 - 3); + if ((fFlakes[cw][i].pos.x > fCachedWsWidth+50)||(fFlakes[cw][i].pos.x < -50)) + fFlakes[cw][i].weight = 0; + } +// fFallenView->UnlockLooper(); +// } +#if 0 + for (i=0; i<10; i++) + printf("f[%d] = {%f, %f}, {%f, %f}, %d\n", i, + fFlakes[cw][i].opos.x, fFlakes[cw][i].opos.y, + fFlakes[cw][i].pos.x, fFlakes[cw][i].pos.y, + fFlakes[cw][i].weight); +#endif +} + +void SnowView::InvalFlakes() +{ + int i; + BView *p = Parent(); + if (!p) + return; + //printf("InvalFlakes()\n"); + uint32 cw = fCurrentWorkspace; + + for (i=0; iMouseDown(where); +#endif +} + +void SnowView::MouseUp(BPoint where) +{ +#ifdef FORWARD_TO_PARENT + if (fAttached && Parent()) + Parent()->MouseUp(where); +#endif + if (fCachedParent) + return; /* we are *inside* the Tracker, + * don't even try talking to ourselve + * with the window locked + */ + BMessenger msgr("application/x-vnd.Be-TRAK"); + BMessage msg(B_DELETE_PROPERTY), reply; + msg.AddSpecifier("Replicant", "BSnow"); + msg.AddSpecifier("Shelf"); + msg.AddSpecifier("View", "PoseView"); + msg.AddSpecifier("Window", 1); /* 0 is Twitcher */ + if ((msgr.SendMessage(&msg, &reply) == B_OK) && + (reply.what == B_NO_REPLY || reply.what == B_REPLY)) { + //reply.PrintToStream(); + fShowClickMe = false; + Invalidate(Bounds()); + } + /* + BMessage: what = JAHA (0x4a414841, or 1245792321) + entry index, type='LONG', c=1, size= 4, data[0]: 0x2 (2, '') + entry when, type='LLNG', c=1, size= 8, data[0]: 0xf6a1b09ac (66204666284, '') + entry source, type='PNTR', c=1, size= 4, + entry be:sender, type='MSNG', c=1, size=24, + */ +} + +void SnowView::MouseMoved(BPoint where, uint32 code, const BMessage *a_message) +{ +#ifdef FORWARD_TO_PARENT + if (fAttached && Parent()) + Parent()->MouseMoved(where, code, a_message); +#endif +} + +void SnowView::KeyDown(const char *bytes, int32 numBytes) +{ +#ifdef FORWARD_TO_PARENT + if (fAttached && Parent()) + Parent()->KeyDown(bytes, numBytes); +#endif +} + +void SnowView::KeyUp(const char *bytes, int32 numBytes) +{ +#ifdef FORWARD_TO_PARENT + if (fAttached && Parent()) + Parent()->KeyUp(bytes, numBytes); +#endif +} + +#define PORTION_GRAN 20 + +int32 SnowView::SnowMakerThread(void *p_this) +{ + SnowView *_this = (SnowView *)p_this; + bigtime_t nextDraw = 0LL; + int current=0; + BView *p = _this->Parent(); + BRect portion(0,0,(_this->fCachedWsWidth/PORTION_GRAN)-1, (_this->fCachedWsHeight/PORTION_GRAN)-1); + int nf = _this->fNumFlakes; + BRegion reg(BRect(-1,-1,-1,-1)); + while (p && _this->fAttached) { + snooze(INTERVAL/(10*(nf?nf:1))); + int32 cw = _this->fCurrentWorkspace; + bool drawThisOne = false; +//printf("processing flake %d...\n", current); + //for (; (current%(fNumFlakes/4); current++) + if (reg.Intersects(portion)) { + for (int i = 0; !drawThisOne && i < nf; i++) { + /* if we find at least one flake in this rect, draw it */ + if ((_this->fFlakes[cw][i].weight) && ( + portion.Intersects(BRect(_this->fFlakes[cw][i].opos - BPoint(4,4), _this->fFlakes[cw][i].opos + BPoint(4,4))) || + portion.Intersects(BRect(_this->fFlakes[cw][i].pos - BPoint(4,4), _this->fFlakes[cw][i].pos + BPoint(4,4))))) { + drawThisOne = true; + } + } + } + //if (!drawThisOne) + //printf("!Invalidate(%f, %f, %f, %f)\n", portion.left, portion.top, portion.right, portion.bottom); + /* avoid deadlock on exit */ + if (drawThisOne && (_this->LockLooperWithTimeout(2000) == B_OK)) { +// printf("Invalidate(%f, %f, %f, %f)\n", portion.left, portion.top, portion.right, portion.bottom); + p->Invalidate(portion); + _this->UnlockLooper(); + } + portion.OffsetBy(_this->fCachedWsWidth/PORTION_GRAN, 0); + if (portion.left >= _this->fCachedWsWidth) { /* right wrap */ + //printf("rigth wrap to %ld\n", _this->fCachedWsWidth); + portion.OffsetTo(0, portion.top+(_this->fCachedWsHeight/PORTION_GRAN)); + } + if (portion.top >= _this->fCachedWsHeight) { + portion.OffsetTo(0,0); + /* avoid deadlock on exit */ + if (_this->LockLooperWithTimeout(5000) == B_OK) { +//printf("calculating flakes...\n"); + _this->Calc(); +//printf("done calculating flakes.\n"); + _this->GetClippingRegion(®); + //printf("Region:\n"); + //reg.PrintToStream(); + _this->UnlockLooper(); + } + } + } +#if 0 + BView *p = _this->Parent(); + while (p && _this->fAttached) { + snooze(INTERVAL/_this->fNumFlakes); +//printf("processing flake %d...\n", current); + //for (; (current%(fNumFlakes/4); current++) + /* avoid deadlock on exit */ + if (_this->LockLooperWithTimeout(2000) == B_OK) { + if (_this->fFlakes[_this->fCurrentWorkspace][current].weight) { + p->Invalidate(BRect(_this->fFlakes[_this->fCurrentWorkspace][current].opos - BPoint(4,4), + _this->fFlakes[_this->fCurrentWorkspace][current].opos + BPoint(4,4))); + p->Invalidate(BRect(_this->fFlakes[_this->fCurrentWorkspace][current].pos - BPoint(4,4), + _this->fFlakes[_this->fCurrentWorkspace][current].pos + BPoint(4,4))); + } + _this->UnlockLooper(); + current++; + current %= _this->fNumFlakes; + if (!current) { + /* avoid deadlock on exit */ + if (_this->LockLooperWithTimeout(2000) == B_OK) { +printf("calculating flakes...\n"); + _this->Calc(); +printf("done calculating flakes.\n"); + _this->UnlockLooper(); + } + } + } + } +#endif + return B_OK; +} diff --git a/src/apps/bsnow/SnowView.h b/src/apps/bsnow/SnowView.h new file mode 100644 index 0000000000..6ab66dabcd --- /dev/null +++ b/src/apps/bsnow/SnowView.h @@ -0,0 +1,79 @@ +#ifndef _SNOW_VIEW_H +#define _SNOW_VIEW_H +#include +#include +#include +#include +#include +#include +#include "Flakes.h" + +#define APP_SIG "application/x-vnd.mmu_man.BSnow" +#define SNOW_VIEW_RECT 0,0,200,40 +#define NUM_FLAKES 200 +#define INTERVAL 200000 +#define MSG_PULSE_ME 'PulS' +#define MSG_DRAW_ME 'DraW' +#define WORKSPACES_COUNT 32 +#define WEIGHT_SPAN 50 +#define WEIGHT_GRAN 10 +#define WIND_SPAN 25 +#define WIND_MAX_DURATION 10000000 +#define FALLEN_HEIGHT 30 +#define INVALIDATOR_THREAD_NAME "You're Neo? I'm the Snow Maker!" + + +#define MSG_DRAG_ME "Drag me on your desktop..." +#define MSG_CLICK_ME "Click me to remove BSnow..." + +typedef struct flake { + BPoint pos; + BPoint opos; + float weight; +} flake; + +class SnowView : public BView +{ +public: + SnowView(); + SnowView(BMessage *archive); + ~SnowView(); +static BArchivable *Instantiate(BMessage *data); +virtual status_t Archive(BMessage *data, bool deep = true) const; +void AttachedToWindow(); +void DetachedFromWindow(); +void MessageReceived(BMessage *msg); +void Draw(BRect ur); +void Pulse(); + +virtual void MouseDown(BPoint where); +virtual void MouseUp(BPoint where); +virtual void MouseMoved(BPoint where, uint32 code, const BMessage *a_message); +virtual void KeyDown(const char *bytes, int32 numBytes); +virtual void KeyUp(const char *bytes, int32 numBytes); + +static int32 SnowMakerThread(void *p_this); +void Calc(); +void InvalFlakes(); +private: + BMessageRunner *fMsgRunner; + BDragger *fDragger; + long fNumFlakes; + flake *fFlakes[WORKSPACES_COUNT]; + BList *fFallenFlakes[WORKSPACES_COUNT]; + uint32 fCurrentWorkspace; + uint32 fCachedWsWidth; + uint32 fCachedWsHeight; + float fWind; + bigtime_t fWindDuration; + bool fAttached; + BBitmap *fFlakeBitmaps[NUM_PATTERNS]; + thread_id fInvalidator; + BView *fCachedParent; + BBitmap *fFallenBmp; + BView *fFallenView; + BRegion *fFallenReg; + bool fShowClickMe; +}; + +#endif diff --git a/src/apps/bsnow/makefile b/src/apps/bsnow/makefile new file mode 100644 index 0000000000..ac39343b6b --- /dev/null +++ b/src/apps/bsnow/makefile @@ -0,0 +1,120 @@ +## BeOS Generic Makefile v2.2 ## + +## Fill in this file to specify the project being created, and the referenced +## makefile-engine will do all of the hard work for you. This handles both +## Intel and PowerPC builds of the BeOS. + +## Application Specific Settings --------------------------------------------- + +# specify the name of the binary +NAME= BSnow + +# specify the type of binary +# APP: Application +# SHARED: Shared library or add-on +# STATIC: Static library archive +# DRIVER: Kernel Driver +TYPE= APP + +# add support for new Pe and Eddie features +# to fill in generic makefile + +#%{ +# @src->@ + +# specify the source files to use +# full paths or paths relative to the makefile can be included +# all files, regardless of directory, will have their object +# files created in the common object directory. +# Note that this means this makefile will not work correctly +# if two source files with the same name (source.c or source.cpp) +# are included from different directories. Also note that spaces +# in folder names do not work well with this makefile. +SRCS= SnowApp.cpp SnowView.cpp Flakes.cpp + +# specify the resource files to use +# full path or a relative path to the resource file can be used. +RSRCS= BSnow.rsrc + +# @<-src@ +#%} + +# end support for Pe and Eddie + +# specify additional libraries to link against +# there are two acceptable forms of library specifications +# - if your library follows the naming pattern of: +# libXXX.so or libXXX.a you can simply specify XXX +# library: libbe.so entry: be +# +# - if your library does not follow the standard library +# naming scheme you need to specify the path to the library +# and it's name +# library: my_lib.a entry: my_lib.a or path/my_lib.a +LIBS= be + +# specify additional paths to directories following the standard +# libXXX.so or libXXX.a naming scheme. You can specify full paths +# or paths relative to the makefile. The paths included may not +# be recursive, so include all of the paths where libraries can +# be found. Directories where source files are found are +# automatically included. +LIBPATHS= + +# additional paths to look for system headers +# thes use the form: #include
+# source file directories are NOT auto-included here +SYSTEM_INCLUDE_PATHS = + +# additional paths to look for local headers +# thes use the form: #include "header" +# source file directories are automatically included +LOCAL_INCLUDE_PATHS = + +# specify the level of optimization that you desire +# NONE, SOME, FULL +OPTIMIZE= + +# specify any preprocessor symbols to be defined. The symbols will not +# have their values set automatically; you must supply the value (if any) +# to use. For example, setting DEFINES to "DEBUG=1" will cause the +# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" +# would pass "-DDEBUG" on the compiler's command line. +DEFINES= DEBUG=1 + +# specify special warning levels +# if unspecified default warnings will be used +# NONE = supress all warnings +# ALL = enable all warnings +WARNINGS = + +# specify whether image symbols will be created +# so that stack crawls in the debugger are meaningful +# if TRUE symbols will be created +SYMBOLS = + +# specify debug settings +# if TRUE will allow application to be run from a source-level +# debugger. Note that this will disable all optimzation. +DEBUGGER = TRUE + +# specify additional compiler flags for all files +COMPILER_FLAGS = + +# specify additional linker flags +LINKER_FLAGS = + +# specify the version of this particular item +# (for example, -app 3 4 0 d 0 -short 340 -long "340 "`echo -n -e '\302\251'`"1999 GNU GPL") +# This may also be specified in a resource. +APP_VERSION = + +# (for TYPE == DRIVER only) Specify desired location of driver in the /dev +# hierarchy. Used by the driverinstall rule. E.g., DRIVER_PATH = video/usb will +# instruct the driverinstall rule to place a symlink to your driver's binary in +# ~/add-ons/kernel/drivers/dev/video/usb, so that your driver will appear at +# /dev/video/usb when loaded. Default is "misc". +DRIVER_PATH = + +## include the makefile-engine +include $(BUILDHOME)/etc/makefile-engine