Icons Screensaver: Grab vector icons via query, fixes #10166

Iterate through each BFS volume and find vector icon data in apps
using a BFS query. Cap off at 128 total icons, we could get more if
desired. Default install comes with ~100 at present.

Make sure we have at least 20 icons (15 display at a time) before we
start drawing icons.

Rename VectorIcon to vector_icon and treat it like the POD struct that it is.
Also add a type_code parame to vector_icon that should be set to
B_VECTOR_ICON.

Some style fixes also included, e.g. turned defines into static const int32’s.
This commit is contained in:
John Scipione
2014-01-22 20:43:22 -05:00
parent 3cbb1132f8
commit 0def0b0d62
4 changed files with 98 additions and 58 deletions
@@ -42,7 +42,7 @@ IconDisplay::~IconDisplay()
void
IconDisplay::Run(VectorIcon* icon, BRect frame)
IconDisplay::Run(vector_icon* icon, BRect frame)
{
delete fBitmap;
+10 -7
View File
@@ -12,11 +12,14 @@
#include <Rect.h>
#include <SupportDefs.h>
#include <View.h>
struct VectorIcon {
uint8* data;
size_t size;
struct vector_icon {
uint8* data;
size_t size;
type_code type;
};
@@ -27,10 +30,10 @@ class IconDisplay {
public:
IconDisplay();
~IconDisplay();
void Run(VectorIcon* icon, BRect frame);
inline bool IsRunning() { return fIsRunning; };
inline BRect GetFrame() { return fFrame; };
void Run(vector_icon* icon, BRect frame);
inline bool IsRunning() const { return fIsRunning; };
inline BRect GetFrame() const { return fFrame; };
void ClearOn(BView* view);
void DrawOn(BView* view, uint32 delta);
+82 -45
View File
@@ -16,8 +16,14 @@
#include <Bitmap.h>
#include <Catalog.h>
#include <Entry.h>
#include <MimeType.h>
#include <Node.h>
#include <NodeInfo.h>
#include <StringView.h>
#include <Query.h>
#include <Volume.h>
#include <VolumeRoster.h>
#include <BuildScreenSaverDefaultSettingsView.h>
@@ -28,12 +34,18 @@
#define B_TRANSLATION_CONTEXT "Screensaver Icons"
#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)))
static const int32 kMaxConcurrentIcons = 15;
static const int32 kMinIconWidthPercentage = 5;
// percentage of the screen width
static const int32 kMaxIconWidthPercentage = 20;
// same here
static const int32 kMinIconCount = 20;
static const int32 kMaxIconCount = 128;
const rgb_color kBackgroundColor = ui_color(B_DESKTOP_COLOR);
@@ -67,32 +79,8 @@ 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();
}
if (fVectorIcons.CountItems() < kMinIconCount)
_GetVectorIcons();
srand(system_time() % INT_MAX);
@@ -117,10 +105,10 @@ IconsSaver::StartSaver(BView* view, bool /*preview*/)
fBackBitmap->Unlock();
}
fIcons = new IconDisplay[MAX_ICONS];
fIcons = new IconDisplay[kMaxConcurrentIcons];
fMaxSize = (screenRect.IntegerWidth() * MAX_SIZE) / 100;
fMinSize = (screenRect.IntegerWidth() * MIN_SIZE) / 100;
fMaxSize = (screenRect.IntegerWidth() * kMaxIconWidthPercentage) / 100;
fMinSize = (screenRect.IntegerWidth() * kMinIconWidthPercentage) / 100;
if (fMaxSize > 255)
fMaxSize = 255;
@@ -148,15 +136,13 @@ IconsSaver::Draw(BView* view, int32 frame)
// update drawing
if (fBackBitmap->Lock()) {
for (uint8 i = 0 ; i < MAX_ICONS ; i++) {
for (uint8 i = 0 ; i < kMaxConcurrentIcons ; i++)
fIcons[i].ClearOn(fBackView);
}
int32 delta = frame - previousFrame;
for (uint8 i = 0 ; i < MAX_ICONS ; i++) {
for (uint8 i = 0 ; i < kMaxConcurrentIcons ; i++)
fIcons[i].DrawOn(fBackView, delta);
}
fBackView->Sync();
fBackBitmap->Unlock();
}
@@ -165,11 +151,11 @@ IconsSaver::Draw(BView* view, int32 frame)
view->DrawBitmap(fBackBitmap);
previousFrame = frame;
if (fVectorIconsCount <= 0)
if (fVectorIcons.CountItems() < kMinIconCount)
return;
// Restart one icon
for (uint8 i = 0 ; i < MAX_ICONS ; i++) {
// restart one icon
for (uint8 i = 0 ; i < kMaxConcurrentIcons ; i++) {
if (!fIcons[i].IsRunning()) {
uint16 size = RAND_BETWEEN(fMinSize, fMaxSize);
uint16 maxX = view->Frame().IntegerWidth() - size;
@@ -179,16 +165,14 @@ IconsSaver::Draw(BView* view, int32 frame)
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++) {
for (uint8 j = 0 ; j < kMaxConcurrentIcons ; 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);
int32 index = RAND_BETWEEN(0, fVectorIcons.CountItems() - 1);
fIcons[i].Run((vector_icon*)fVectorIcons.ItemAt(index), iconFrame);
return;
}
}
@@ -202,3 +186,56 @@ IconsSaver::StartConfig(BView* view)
B_TRANSLATE("by Vincent Duvert"));
}
// #pragma mark - IconsSaver private methods
void
IconsSaver::_GetVectorIcons()
{
BVolumeRoster volumeRoster;
BVolume volume;
while (volumeRoster.GetNextVolume(&volume) == B_OK) {
if (!volume.KnowsAttr() || !volume.KnowsMime() || !volume.KnowsQuery())
continue;
BQuery query;
query.SetVolume(&volume);
query.SetPredicate("BEOS:APP_SIG=*");
query.Fetch();
entry_ref ref;
while (query.GetNextRef(&ref) == B_OK) {
BFile file(&ref, B_READ_ONLY);
if (file.InitCheck() != B_OK)
continue;
struct vector_icon* icon
= (struct vector_icon*)malloc(sizeof(struct vector_icon));
if (icon == NULL)
continue;
BNode node(&ref);
BNodeInfo nodeInfo(&node);
if (nodeInfo.InitCheck() != B_OK
|| nodeInfo.GetIcon(&icon->data, &icon->size, &icon->type)
!= B_OK) {
// didn't find an icon
continue;
}
if (icon->type != B_VECTOR_ICON_TYPE) {
// found an icon, but it's not a vector icon
delete icon;
continue;
}
// found a vector icon, add it to the list
fVectorIcons.AddItem(icon);
if (fVectorIcons.CountItems() >= kMaxIconCount) {
// this is enough to choose from, stop eating memory...
return;
}
}
}
}
+5 -5
View File
@@ -31,13 +31,13 @@ public:
virtual void StartConfig(BView* view);
private:
BList fVectorIcons;
int32 fVectorIconsCount;
IconDisplay* fIcons;
void _GetVectorIcons();
BBitmap* fBackBitmap;
BView* fBackView;
BList fVectorIcons;
IconDisplay* fIcons;
BBitmap* fBackBitmap;
BView* fBackView;
uint16 fMinSize;
uint16 fMaxSize;