From 32b3986c09e9a1d9dcbebd35fdcf3d63f6c08780 Mon Sep 17 00:00:00 2001 From: Philippe Houdoin Date: Thu, 24 Sep 2009 21:03:51 +0000 Subject: [PATCH] Added a very nice Icons screensaver, by Vincent Duvert. Thanks. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33268 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/screen_savers/Jamfile | 3 +- .../screen_savers/icons/IconDisplay.cpp | 126 +++++++++++ src/add-ons/screen_savers/icons/IconDisplay.h | 43 ++++ .../screen_savers/icons/IconsSaver.cpp | 203 ++++++++++++++++++ src/add-ons/screen_savers/icons/IconsSaver.h | 38 ++++ src/add-ons/screen_savers/icons/Jamfile | 8 + 6 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 src/add-ons/screen_savers/icons/IconDisplay.cpp create mode 100644 src/add-ons/screen_savers/icons/IconDisplay.h create mode 100644 src/add-ons/screen_savers/icons/IconsSaver.cpp create mode 100644 src/add-ons/screen_savers/icons/IconsSaver.h create mode 100644 src/add-ons/screen_savers/icons/Jamfile diff --git a/src/add-ons/screen_savers/Jamfile b/src/add-ons/screen_savers/Jamfile index 899819a609..8c9a3b7b21 100644 --- a/src/add-ons/screen_savers/Jamfile +++ b/src/add-ons/screen_savers/Jamfile @@ -3,8 +3,9 @@ SubDir HAIKU_TOP src add-ons screen_savers ; SubInclude HAIKU_TOP src add-ons screen_savers debugnow ; SubInclude HAIKU_TOP src add-ons screen_savers flurry ; SubInclude HAIKU_TOP src add-ons screen_savers haiku ; +SubInclude HAIKU_TOP src add-ons screen_savers icons ; 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 simpleclock ; SubInclude HAIKU_TOP src add-ons screen_savers slideshowsaver ; SubInclude HAIKU_TOP src add-ons screen_savers spider ; -SubInclude HAIKU_TOP src add-ons screen_savers simpleclock ; diff --git a/src/add-ons/screen_savers/icons/IconDisplay.cpp b/src/add-ons/screen_savers/icons/IconDisplay.cpp new file mode 100644 index 0000000000..67cbdcba2a --- /dev/null +++ b/src/add-ons/screen_savers/icons/IconDisplay.cpp @@ -0,0 +1,126 @@ +/* + Copyright 2009 Vincent Duvert, vincent.duvert@free.fr + All rights reserved. Distributed under the terms of the MIT License. +*/ + + +#include "IconDisplay.h" + +#include +#include + +#include +#include + + +#define RAND_BETWEEN(a, b) ((rand() % ((b) - (a) + 1) + (a))) +#define SHOW_TICKS_MIN 20 +#define SHOW_TICKS_MAX 50 +#define STAY_TICKS_MIN 50 +#define STAY_TICKS_MAX 100 +#define HIDE_TICKS_MIN 20 +#define HIDE_TICKS_MAX 50 + + +IconDisplay::IconDisplay() + : + fIsRunning(false), + fBitmap(NULL) +{ +} + + +IconDisplay::~IconDisplay() +{ + delete fBitmap; +} + + +void +IconDisplay::Run(VectorIcon* icon, BRect frame) +{ + delete fBitmap; + + fBitmap = new BBitmap(BRect(0, 0, frame.Width(), frame.Height()), 0, + B_RGBA32); + BIconUtils::GetVectorIcon(icon->data, icon->size, fBitmap); + + fState = 0; + fTicks = 0; + fDelay = RAND_BETWEEN(SHOW_TICKS_MIN, SHOW_TICKS_MAX); + fFrame = frame; + + fIsRunning = true; +} + + +void +IconDisplay::ClearOn(BView* view) +{ + if (!fIsRunning || fState == 2) + return; + + view->FillRect(fFrame); +} + + +void +IconDisplay::DrawOn(BView* view, uint32 delta) +{ + if (!fIsRunning) + return; + + fTicks += delta; + + rgb_color backColor = view->HighColor(); + + switch (fState) { + case 0: + // Progressive showing + if (fTicks < fDelay) + backColor.alpha = (fTicks * 255) / fDelay; + else + fState++; + break; + + case 1: + // Completed showing + backColor.alpha = 255; + fTicks = 0; + fDelay = RAND_BETWEEN(STAY_TICKS_MIN, STAY_TICKS_MAX); + fState++; + break; + + case 2: + // Waiting + if (fTicks < fDelay) + return; + fTicks = 0; + backColor.alpha = 255; + fDelay = RAND_BETWEEN(HIDE_TICKS_MIN, HIDE_TICKS_MAX); + fState++; + return; + break; + + case 3: + // Progressive hiding + if (fTicks < fDelay) { + backColor.alpha = 255 - (fTicks * 255) / fDelay; + } else { + backColor.alpha = 0; + fState++; + } + break; + + default: + // Finished + fIsRunning = false; + return; + break; + }; + + view->SetHighColor(backColor); + view->DrawBitmap(fBitmap, BPoint(fFrame.left, fFrame.top)); + backColor.alpha = 255; + view->SetHighColor(backColor); +} diff --git a/src/add-ons/screen_savers/icons/IconDisplay.h b/src/add-ons/screen_savers/icons/IconDisplay.h new file mode 100644 index 0000000000..f9441e61b5 --- /dev/null +++ b/src/add-ons/screen_savers/icons/IconDisplay.h @@ -0,0 +1,43 @@ +/* + Copyright 2009 Vincent Duvert, vincent.duvert@free.fr + All rights reserved. Distributed under the terms of the MIT License. +*/ +#ifndef ICON_DISPLAY_H +#define ICON_DISPLAY_H + +#include +#include + +struct VectorIcon { + uint8* data; + size_t size; +}; + + +class BBitmap; + + +class IconDisplay { +public: + IconDisplay(); + ~IconDisplay(); + + void Run(VectorIcon* icon, BRect frame); + inline bool IsRunning() { return fIsRunning; }; + inline BRect GetFrame() { return fFrame; }; + + void ClearOn(BView* view); + void DrawOn(BView* view, uint32 delta); + +private: + bool fIsRunning; + uint8 fState; + + int32 fTicks; + int32 fDelay; + + BBitmap* fBitmap; + BRect fFrame; +}; + +#endif diff --git a/src/add-ons/screen_savers/icons/IconsSaver.cpp b/src/add-ons/screen_savers/icons/IconsSaver.cpp new file mode 100644 index 0000000000..0df95a2561 --- /dev/null +++ b/src/add-ons/screen_savers/icons/IconsSaver.cpp @@ -0,0 +1,203 @@ +/* + Copyright 2009 Vincent Duvert, vincent.duvert@free.fr + All rights reserved. Distributed under the terms of the MIT License. +*/ + + +#include "IconsSaver.h" + +#include +#include + +#include +#include +#include + +#include "IconDisplay.h" + + +#define MAX_ICONS 15 +#define MAX_SIZE 20 // In percentage of the screen width +#define MIN_SIZE 5 // Same here +#define RAND_BETWEEN(a, b) ((rand() % ((b) - (a) + 1) + (a))) + + +const rgb_color kBackgroundColor = ui_color(B_DESKTOP_COLOR); + + +BScreenSaver* instantiate_screen_saver(BMessage* msg, image_id image) +{ + return new IconsSaver(msg, image); +} + + +IconsSaver::IconsSaver(BMessage* msg, image_id image) + : + BScreenSaver(msg, image), + fVectorIconsCount(0), + fIcons(NULL), + fBackBitmap(NULL), + fBackView(NULL), + fMinSize(0), + fMaxSize(0) +{ +} + + +IconsSaver::~IconsSaver() +{ +} + + +status_t +IconsSaver::StartSaver(BView *view, bool /*preview*/) +{ + if (fVectorIconsCount <= 0) { + // Load the vector icons from the MIME types + BMessage types; + BMimeType::GetInstalledTypes(&types); + + for (int32 index = 0 ; ; index++) { + const char* type; + if (types.FindString("types", index, &type) != B_OK) + break; + + BMimeType mimeType(type); + uint8* vectorData = NULL; + size_t size = 0; + + if (mimeType.GetIcon(&vectorData, &size) != B_OK || size == 0) + continue; + + VectorIcon* icon = new VectorIcon; + icon->data = vectorData; + icon->size = size; + + fVectorIcons.AddItem(icon); + } + + fVectorIconsCount = fVectorIcons.CountItems(); + } + + srand(system_time() % INT_MAX); + + BRect screenRect(0, 0, view->Frame().Width(), view->Frame().Height()); + fBackBitmap = new BBitmap(screenRect, B_RGBA32, true); + if (!fBackBitmap->IsValid()) + return B_NO_MEMORY; + + fBackView = new BView(screenRect, "back view", 0, 0); + if (fBackView == NULL) + return B_NO_MEMORY; + + fBackView->SetViewColor(kBackgroundColor); + fBackView->SetHighColor(kBackgroundColor); + + fBackBitmap->AddChild(fBackView); + if (fBackBitmap->Lock()) { + fBackView->FillRect(fBackView->Frame()); + fBackView->SetDrawingMode(B_OP_ALPHA); + fBackView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); + fBackView->Sync(); + fBackBitmap->Unlock(); + } + + fIcons = new IconDisplay[MAX_ICONS]; + + fMaxSize = (screenRect.IntegerWidth() * MAX_SIZE) / 100; + fMinSize = (screenRect.IntegerWidth() * MIN_SIZE) / 100; + if (fMaxSize > 255) + fMaxSize = 255; + + if (fMaxSize > screenRect.IntegerHeight()) + fMaxSize = screenRect.IntegerHeight(); + + if (fMinSize > fMaxSize) + fMinSize = fMaxSize; + + return B_OK; +} + + +void +IconsSaver::StopSaver() +{ + delete[] fIcons; +} + + +void +IconsSaver::Draw(BView *view, int32 frame) +{ + static int32 previousFrame = 0; + + // Update drawing + if (fBackBitmap->Lock()) { + for (uint8 i = 0 ; i < MAX_ICONS ; i++) { + fIcons[i].ClearOn(fBackView); + } + + int32 delta = frame - previousFrame; + + for (uint8 i = 0 ; i < MAX_ICONS ; i++) { + fIcons[i].DrawOn(fBackView, delta); + } + fBackView->Sync(); + fBackBitmap->Unlock(); + } + + // Sync the view with the back buffer + view->DrawBitmap(fBackBitmap); + previousFrame = frame; + + if (fVectorIconsCount <= 0) + return; + + // Restart one icon + for (uint8 i = 0 ; i < MAX_ICONS ; i++) { + if (!fIcons[i].IsRunning()) { + uint16 size = RAND_BETWEEN(fMinSize, fMaxSize); + uint16 maxX = view->Frame().IntegerWidth() - size; + uint16 maxY = view->Frame().IntegerHeight() - size; + + BRect iconFrame(0, 0, size, size); + iconFrame.OffsetTo(RAND_BETWEEN(0, maxX), RAND_BETWEEN(0, maxY)); + + // Check that the icon doesn't overlap with others + for (uint8 j = 0 ; j < MAX_ICONS ; j++) { + if (fIcons[j].IsRunning() && + iconFrame.Intersects(fIcons[j].GetFrame())) + return; + } + + int32 index = RAND_BETWEEN(0, fVectorIconsCount - 1); + + fIcons[i].Run((VectorIcon*)fVectorIcons.ItemAt(index), iconFrame); + + return; + } + } +} + + +void +IconsSaver::StartConfig(BView* view) +{ + const uint8 spacer = 5; + BRect frame = view->Frame(); + BRect position(spacer, spacer, frame.Width() - 2 * spacer, 0); + + view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + BStringView* stringView = new BStringView(position, "", "Icons"); + stringView->SetFont(be_bold_font); + stringView->ResizeToPreferred(); + position.top += stringView->Frame().Height(); + view->AddChild(stringView); + + stringView = new BStringView(position, "", "By Vincent Duvert"); + stringView->ResizeToPreferred(); + position.top += stringView->Frame().Height(); + view->AddChild(stringView); +} + diff --git a/src/add-ons/screen_savers/icons/IconsSaver.h b/src/add-ons/screen_savers/icons/IconsSaver.h new file mode 100644 index 0000000000..b2ed86c468 --- /dev/null +++ b/src/add-ons/screen_savers/icons/IconsSaver.h @@ -0,0 +1,38 @@ +/* + Copyright 2009 Vincent Duvert, vincent.duvert@free.fr + All rights reserved. Distributed under the terms of the MIT License. +*/ +#ifndef ICONS_SAVER_H +#define ICONS_SAVER_H + +#include +#include + + +class IconDisplay; + + +class IconsSaver: public BScreenSaver { +public: + IconsSaver(BMessage* archive, image_id); + virtual ~IconsSaver(); + + virtual status_t StartSaver(BView *view, bool preview); + virtual void StopSaver(); + + virtual void Draw(BView *view, int32 frame); + + virtual void StartConfig(BView* view); + +private: + BList fVectorIcons; + int32 fVectorIconsCount; + IconDisplay* fIcons; + + BBitmap* fBackBitmap; + BView* fBackView; + + uint16 fMinSize, fMaxSize; +}; + +#endif diff --git a/src/add-ons/screen_savers/icons/Jamfile b/src/add-ons/screen_savers/icons/Jamfile new file mode 100644 index 0000000000..5a15d881ea --- /dev/null +++ b/src/add-ons/screen_savers/icons/Jamfile @@ -0,0 +1,8 @@ +SubDir HAIKU_TOP src add-ons screen_savers icons ; + +UseLibraryHeaders icon ; + +ScreenSaver Icons : + IconDisplay.cpp IconsSaver.cpp : + be libscreensaver.so libicon.a $(TARGET_LIBSUPC++) +;