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:
@@ -42,7 +42,7 @@ IconDisplay::~IconDisplay()
|
||||
|
||||
|
||||
void
|
||||
IconDisplay::Run(VectorIcon* icon, BRect frame)
|
||||
IconDisplay::Run(vector_icon* icon, BRect frame)
|
||||
{
|
||||
delete fBitmap;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user