various changes to improve integration of vector icons
* Deskbar uses 32 bit icons now * vector icons are now correctly converted to B_CMAP8 bitmaps if no B_CMAP8 icon is available * small fixes in Tracker (window mode menu) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18803 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -75,6 +75,11 @@ class BIconUtils {
|
||||
uint32 width, uint32 height,
|
||||
uint32 bytesPerRow,
|
||||
BBitmap* result);
|
||||
|
||||
static status_t ConvertToCMAP8(const uint8* data,
|
||||
uint32 width, uint32 height,
|
||||
uint32 bytesPerRow,
|
||||
BBitmap* result);
|
||||
};
|
||||
|
||||
#endif // ICON_UTILS_H
|
||||
|
||||
@@ -80,6 +80,13 @@ const uint32 kShowTeamMenu = 'TmMn';
|
||||
|
||||
const BRect kIconSize(0.0f, 0.0f, 15.0f, 15.0f);
|
||||
|
||||
#if __HAIKU__
|
||||
static const color_space kIconFormat = B_RGBA32;
|
||||
#else
|
||||
static const color_space kIconFormat = B_CMAP8;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int
|
||||
main()
|
||||
@@ -531,9 +538,8 @@ TBarApp::Subscribe(const BMessenger &subscriber, BList *list)
|
||||
for (int32 i = 0; i < numTeams; i++) {
|
||||
BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i);
|
||||
BList *tList = new BList(*(barInfo->teams));
|
||||
BBitmap *icon = new BBitmap(kIconSize, B_COLOR_8_BIT);
|
||||
BBitmap *icon = new BBitmap(barInfo->icon);
|
||||
ASSERT(icon);
|
||||
icon->SetBits(barInfo->icon->Bits(), icon->BitsLength(), 0, B_COLOR_8_BIT);
|
||||
list->AddItem(new BarTeamInfo(tList, barInfo->flags, strdup(barInfo->sig), icon, strdup(barInfo->name)));
|
||||
}
|
||||
|
||||
@@ -605,14 +611,14 @@ TBarApp::AddTeam(team_id team, uint32 flags, const char *sig, entry_ref *ref)
|
||||
BAppFileInfo appMime(&file);
|
||||
|
||||
BarTeamInfo *barInfo = new BarTeamInfo(new BList(), flags, strdup(sig),
|
||||
new BBitmap(kIconSize, B_COLOR_8_BIT), strdup(ref->name));
|
||||
new BBitmap(kIconSize, kIconFormat), strdup(ref->name));
|
||||
|
||||
barInfo->teams->AddItem((void *)team);
|
||||
if (appMime.GetIcon(barInfo->icon, B_MINI_ICON) != B_OK) {
|
||||
const BBitmap* generic = AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_GenericAppIcon);
|
||||
if (generic)
|
||||
barInfo->icon->SetBits(generic->Bits(), barInfo->icon->BitsLength(),
|
||||
0, B_COLOR_8_BIT);
|
||||
0, kIconFormat);
|
||||
}
|
||||
|
||||
sBarTeamInfoList.AddItem(barInfo);
|
||||
@@ -626,10 +632,9 @@ TBarApp::AddTeam(team_id team, uint32 flags, const char *sig, entry_ref *ref)
|
||||
BList *tList = new BList(*(barInfo->teams));
|
||||
message.AddPointer("teams", tList);
|
||||
|
||||
BBitmap *icon = new BBitmap(kIconSize, B_COLOR_8_BIT);
|
||||
BBitmap *icon = new BBitmap(barInfo->icon);
|
||||
ASSERT(icon);
|
||||
|
||||
icon->SetBits(barInfo->icon->Bits(), icon->BitsLength(), 0, B_COLOR_8_BIT);
|
||||
message.AddPointer("icon", icon);
|
||||
|
||||
message.AddInt32("flags", static_cast<int32>(barInfo->flags));
|
||||
|
||||
@@ -743,7 +743,8 @@ MountMenu::AddDynamicItem(add_state s)
|
||||
int32 countFound;
|
||||
reply.GetInfo("DisplayName", &code, &countFound);
|
||||
for (int32 vol = 0; vol < countFound; vol++) {
|
||||
BBitmap *icon = new BBitmap(BRect(0,0,15,15),B_COLOR_8_BIT);
|
||||
// TODO: get_device_icon version that supports B_RGBA32
|
||||
BBitmap *icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8);
|
||||
get_device_icon(reply.FindString("DeviceName", vol), icon->Bits(), B_MINI_ICON);
|
||||
BMessage *invokeMessage = new BMessage;
|
||||
reply.FindMessage("InvokeMessage", vol, invokeMessage);
|
||||
|
||||
@@ -60,6 +60,12 @@ static bool OKToUse(const TTeamGroup *);
|
||||
static bool IsWindowOK(const window_info *);
|
||||
static int SmartStrcmp(const char *s1, const char *s2);
|
||||
|
||||
#if __HAIKU__
|
||||
static const color_space kIconFormat = B_RGBA32;
|
||||
#else
|
||||
static const color_space kIconFormat = B_CMAP8;
|
||||
#endif
|
||||
|
||||
|
||||
static int32
|
||||
LowBitIndex(uint32 value)
|
||||
@@ -121,8 +127,8 @@ TTeamGroup::TTeamGroup(BList *teams, uint32 flags, char *name,
|
||||
{
|
||||
strcpy(fSignature, signature);
|
||||
|
||||
fSmallIcon = new BBitmap(BRect(0,0,15,15), B_COLOR_8_BIT);
|
||||
fLargeIcon = new BBitmap(BRect(0,0,31,31), B_COLOR_8_BIT);
|
||||
fSmallIcon = new BBitmap(BRect(0, 0, 15, 15), kIconFormat);
|
||||
fLargeIcon = new BBitmap(BRect(0, 0, 31, 31), kIconFormat);
|
||||
|
||||
app_info appInfo;
|
||||
if (be_roster->GetAppInfo(signature, &appInfo) == B_OK) {
|
||||
@@ -1469,8 +1475,8 @@ TIconView::TIconView(BRect frame, TSwitchManager *manager, TSwitcherWindow *swit
|
||||
fOffBitmap = new BBitmap(rect, B_RGB32, true);
|
||||
fOffBitmap->AddChild(fOffView);
|
||||
|
||||
fCurrentSmall = new BBitmap(BRect(0, 0, 15, 15), B_COLOR_8_BIT);
|
||||
fCurrentLarge = new BBitmap(BRect(0, 0, 31, 31), B_COLOR_8_BIT);
|
||||
fCurrentSmall = new BBitmap(BRect(0, 0, 15, 15), kIconFormat);
|
||||
fCurrentLarge = new BBitmap(BRect(0, 0, 31, 31), kIconFormat);
|
||||
|
||||
SetViewColor(color);
|
||||
SetLowColor(color);
|
||||
@@ -1497,12 +1503,12 @@ TIconView::CacheIcons(TTeamGroup *teamGroup)
|
||||
const BBitmap *bitmap = teamGroup->SmallIcon();
|
||||
ASSERT(bitmap);
|
||||
fCurrentSmall->SetBits(bitmap->Bits(), bitmap->BitsLength(), 0,
|
||||
B_COLOR_8_BIT);
|
||||
bitmap->ColorSpace());
|
||||
|
||||
bitmap = teamGroup->LargeIcon();
|
||||
ASSERT(bitmap);
|
||||
fCurrentLarge->SetBits(bitmap->Bits(), bitmap->BitsLength(), 0,
|
||||
B_COLOR_8_BIT);
|
||||
bitmap->ColorSpace());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ TTeamMenuItem::GetContentSize(float *width, float *height)
|
||||
if (fIcon)
|
||||
iconBounds = fIcon->Bounds();
|
||||
else
|
||||
iconBounds = BRect(0,0,15,15);
|
||||
iconBounds = BRect(0, 0, 15, 15);
|
||||
|
||||
BMenuItem::GetContentSize(width, height);
|
||||
|
||||
@@ -281,7 +281,12 @@ TTeamMenuItem::DrawContent()
|
||||
{
|
||||
BMenu *menu = Menu();
|
||||
if (fIcon) {
|
||||
menu->SetDrawingMode(B_OP_OVER);
|
||||
if (fIcon->ColorSpace() == B_RGBA32) {
|
||||
menu->SetDrawingMode(B_OP_ALPHA);
|
||||
menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
} else {
|
||||
menu->SetDrawingMode(B_OP_OVER);
|
||||
}
|
||||
BRect frame(Frame());
|
||||
|
||||
if (!fVertical)
|
||||
@@ -307,7 +312,7 @@ TTeamMenuItem::DrawContent()
|
||||
// set the pen to black so that either method will draw in the same color
|
||||
// low color is set in inherited::DrawContent, override makes sure its what we want
|
||||
if (fDrawLabel) {
|
||||
menu->SetHighColor(0,0,0);
|
||||
menu->SetHighColor(0, 0, 0);
|
||||
|
||||
// override the drawing of the content when the item is disabled
|
||||
// the wrong lowcolor is used when the item is disabled since the
|
||||
|
||||
@@ -679,8 +679,10 @@ BNodeInfo::GetTrackerIcon(BBitmap *icon, icon_size iconSize) const
|
||||
} else if (S_ISLNK(stat.st_mode))
|
||||
type.SetTo(B_SYMLINK_MIME_TYPE);
|
||||
|
||||
error = type.GetIcon(icon, iconSize);
|
||||
success = (error == B_OK);
|
||||
success = (type.GetIcon(icon, iconSize) == B_OK);
|
||||
// NOTE: if there is an icon but getting it failes for some reason,
|
||||
// the error is not reported, and the fall back retrieval methods
|
||||
// are still tried. (IAW, we can't differentiate the reason for error.)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1881,11 +1881,19 @@ BContainerWindow::AddWindowMenu(BMenu *menu)
|
||||
|
||||
BMenu* iconSizeMenu = new BMenu("Icon View");
|
||||
|
||||
item = new BMenuItem("32 x 32", new BMessage(kIconMode), '1');
|
||||
BMessage* message = new BMessage(kIconMode);
|
||||
message->AddInt32("size", 32);
|
||||
item = new BMenuItem("32 x 32", message, '1');
|
||||
item->SetTarget(PoseView());
|
||||
iconSizeMenu->AddItem(item);
|
||||
|
||||
BMessage* message = new BMessage(kScaleIconMode);
|
||||
message = new BMessage(kScaleIconMode);
|
||||
message->AddInt32("size", 40);
|
||||
item = new BMenuItem("40 x 40", message);
|
||||
item->SetTarget(PoseView());
|
||||
iconSizeMenu->AddItem(item);
|
||||
|
||||
message = new BMessage(kScaleIconMode);
|
||||
message->AddInt32("size", 48);
|
||||
item = new BMenuItem("48 x 48", message);
|
||||
item->SetTarget(PoseView());
|
||||
@@ -2865,10 +2873,36 @@ BContainerWindow::UpdateMenu(BMenu *menu, UpdateMenuContext context)
|
||||
}
|
||||
|
||||
if (context == kMenuBarContext || context == kWindowPopUpContext) {
|
||||
// MarkNamedMenuItem(menu, kIconMode, PoseView()->ViewMode() == kIconMode);
|
||||
MarkNamedMenuItem(menu, kListMode, PoseView()->ViewMode() == kListMode);
|
||||
MarkNamedMenuItem(menu, kMiniIconMode,
|
||||
PoseView()->ViewMode() == kMiniIconMode);
|
||||
BMenu* sizeMenu = NULL;
|
||||
if (BMenuItem* item = menu->FindItem("Icon View")) {
|
||||
sizeMenu = item->Submenu();
|
||||
}
|
||||
|
||||
uint32 viewMode = PoseView()->ViewMode();
|
||||
if (sizeMenu) {
|
||||
if (viewMode == kIconMode || viewMode == kScaleIconMode) {
|
||||
int32 iconSize = (int32)PoseView()->IconSizeInt();
|
||||
for (int32 i = 0; BMenuItem* item = sizeMenu->ItemAt(i); i++) {
|
||||
BMessage* message = item->Message();
|
||||
if (!message) {
|
||||
item->SetMarked(false);
|
||||
continue;
|
||||
}
|
||||
int32 size;
|
||||
if (message->FindInt32("size", &size) < B_OK)
|
||||
size = -1;
|
||||
item->SetMarked(iconSize == size);
|
||||
}
|
||||
} else {
|
||||
for (int32 i = 0; BMenuItem* item = sizeMenu->ItemAt(i); i++)
|
||||
item->SetMarked(false);
|
||||
}
|
||||
} else {
|
||||
MarkNamedMenuItem(menu, kIconMode, viewMode == kIconMode);
|
||||
}
|
||||
|
||||
MarkNamedMenuItem(menu, kListMode, viewMode == kListMode);
|
||||
MarkNamedMenuItem(menu, kMiniIconMode, viewMode == kMiniIconMode);
|
||||
|
||||
SetCloseItem(menu);
|
||||
SetCleanUpItem(menu);
|
||||
|
||||
@@ -261,9 +261,45 @@ BDeskWindow::AddWindowContextMenus(BMenu *menu)
|
||||
tempateMenu->SetFont(be_plain_font);
|
||||
|
||||
menu->AddSeparatorItem();
|
||||
menu->AddItem(new BMenuItem("Icon View", new BMessage(kIconMode)));
|
||||
menu->AddItem(new BMenuItem("Mini Icon View", new BMessage(kMiniIconMode)));
|
||||
|
||||
BMenu* iconSizeMenu = new BMenu("Icon View");
|
||||
|
||||
BMessage* message = new BMessage(kIconMode);
|
||||
message->AddInt32("size", 32);
|
||||
BMenuItem* item = new BMenuItem("32 x 32", message, '1');
|
||||
item->SetMarked(PoseView()->IconSizeInt() == 32);
|
||||
item->SetTarget(PoseView());
|
||||
iconSizeMenu->AddItem(item);
|
||||
|
||||
message = new BMessage(kScaleIconMode);
|
||||
message->AddInt32("size", 40);
|
||||
item = new BMenuItem("40 x 40", message);
|
||||
item->SetMarked(PoseView()->IconSizeInt() == 40);
|
||||
item->SetTarget(PoseView());
|
||||
iconSizeMenu->AddItem(item);
|
||||
|
||||
message = new BMessage(kScaleIconMode);
|
||||
message->AddInt32("size", 48);
|
||||
item = new BMenuItem("48 x 48", message);
|
||||
item->SetMarked(PoseView()->IconSizeInt() == 48);
|
||||
item->SetTarget(PoseView());
|
||||
iconSizeMenu->AddItem(item);
|
||||
|
||||
message = new BMessage(kScaleIconMode);
|
||||
message->AddInt32("size", 64);
|
||||
item = new BMenuItem("64 x 64", message);
|
||||
item->SetMarked(PoseView()->IconSizeInt() == 64);
|
||||
item->SetTarget(PoseView());
|
||||
iconSizeMenu->AddItem(item);
|
||||
|
||||
menu->AddItem(iconSizeMenu);
|
||||
|
||||
item = new BMenuItem("Mini Icon View", new BMessage(kMiniIconMode));
|
||||
item->SetMarked(PoseView()->ViewMode() == kMiniIconMode);
|
||||
menu->AddItem(item);
|
||||
|
||||
menu->AddSeparatorItem();
|
||||
|
||||
#ifdef CUT_COPY_PASTE_IN_CONTEXT_MENU
|
||||
BMenuItem *pasteItem;
|
||||
menu->AddItem(pasteItem = new BMenuItem("Paste", new BMessage(B_PASTE), 'V'));
|
||||
|
||||
+90
-15
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <new>
|
||||
#include <fs_attr.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Node.h>
|
||||
@@ -80,11 +81,12 @@ BIconUtils::GetIcon(BNode* node,
|
||||
uint32 width = temp.Bounds().IntegerWidth() + 1;
|
||||
uint32 height = temp.Bounds().IntegerHeight() + 1;
|
||||
uint32 bytesPerRow = temp.BytesPerRow();
|
||||
ret = ConvertFromCMAP8((uint8*)temp.Bits(),
|
||||
width,height, bytesPerRow, result);
|
||||
ret = ConvertToCMAP8((uint8*)temp.Bits(),
|
||||
width, height, bytesPerRow, result);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("BIconUtils::GetIcon() - unsupported colorspace\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -197,6 +199,17 @@ BIconUtils::GetCMAP8Icon(BNode* node,
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t ret = B_OK;
|
||||
|
||||
// NOTE: this might be changed if other icon
|
||||
// sizes are supported in B_CMAP8 attributes,
|
||||
// but this is currently not the case, so we
|
||||
// relax the requirement to pass an icon
|
||||
// of just the right size
|
||||
if (size < B_LARGE_ICON)
|
||||
size = B_MINI_ICON;
|
||||
else
|
||||
size = B_LARGE_ICON;
|
||||
|
||||
// set some icon size related variables
|
||||
const char *attribute = NULL;
|
||||
BRect bounds;
|
||||
@@ -216,14 +229,11 @@ BIconUtils::GetCMAP8Icon(BNode* node,
|
||||
attrSize = 32 * 32;
|
||||
break;
|
||||
default:
|
||||
// can not happen, see above
|
||||
ret = B_BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: relax this requirement?
|
||||
if (icon->Bounds() != bounds)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get the attribute info and check type and size of the attr contents
|
||||
attr_info attrInfo;
|
||||
if (ret == B_OK)
|
||||
@@ -235,10 +245,11 @@ BIconUtils::GetCMAP8Icon(BNode* node,
|
||||
|
||||
// read the attribute
|
||||
if (ret == B_OK) {
|
||||
bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
|
||||
bool tempBuffer = (icon->ColorSpace() != B_CMAP8
|
||||
|| icon->Bounds() != bounds);
|
||||
uint8* buffer = NULL;
|
||||
ssize_t read;
|
||||
if (otherColorSpace) {
|
||||
if (tempBuffer) {
|
||||
// other color space than stored in attribute
|
||||
buffer = new(nothrow) uint8[attrSize];
|
||||
if (!buffer)
|
||||
@@ -257,7 +268,7 @@ BIconUtils::GetCMAP8Icon(BNode* node,
|
||||
else if (read != attrInfo.size)
|
||||
ret = B_ERROR;
|
||||
}
|
||||
if (otherColorSpace) {
|
||||
if (tempBuffer) {
|
||||
// other color space than stored in attribute
|
||||
if (ret == B_OK) {
|
||||
ret = ConvertFromCMAP8(buffer,
|
||||
@@ -316,13 +327,14 @@ BIconUtils::ConvertFromCMAP8(const uint8* src,
|
||||
} else if (dstWidth > width || dstHeight > height) {
|
||||
// TODO: up scaling
|
||||
// (currently copies bitmap into result at left-top)
|
||||
memset(result->Bits(), 255, result->BitsLength());
|
||||
}
|
||||
|
||||
#if __HAIKU__
|
||||
|
||||
return result->ImportBits(src, height * srcBPR, srcBPR, 0, B_CMAP8);
|
||||
|
||||
#else
|
||||
//#if __HAIKU__
|
||||
//
|
||||
// return result->ImportBits(src, height * srcBPR, srcBPR, 0, B_CMAP8);
|
||||
//
|
||||
//#else
|
||||
|
||||
if (result->ColorSpace() != B_RGBA32 && result->ColorSpace() != B_RGB32) {
|
||||
// TODO: support other color spaces
|
||||
@@ -352,7 +364,70 @@ BIconUtils::ConvertFromCMAP8(const uint8* src,
|
||||
|
||||
return B_OK;
|
||||
|
||||
#endif // __HAIKU__
|
||||
//#endif // __HAIKU__
|
||||
}
|
||||
|
||||
// ConvertToCMAP8
|
||||
status_t
|
||||
BIconUtils::ConvertToCMAP8(const uint8* src,
|
||||
uint32 width, uint32 height, uint32 srcBPR,
|
||||
BBitmap* result)
|
||||
{
|
||||
if (!src || !result || srcBPR == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t ret = result->InitCheck();
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
uint32 dstWidth = result->Bounds().IntegerWidth() + 1;
|
||||
uint32 dstHeight = result->Bounds().IntegerHeight() + 1;
|
||||
|
||||
if (dstWidth < width || dstHeight < height) {
|
||||
// TODO: down scaling
|
||||
return B_ERROR;
|
||||
} else if (dstWidth > width || dstHeight > height) {
|
||||
// TODO: up scaling
|
||||
// (currently copies bitmap into result at left-top)
|
||||
memset(result->Bits(), 255, result->BitsLength());
|
||||
}
|
||||
|
||||
//#if __HAIKU__
|
||||
//
|
||||
// return result->ImportBits(src, height * srcBPR, srcBPR, 0, B_RGBA32);
|
||||
//
|
||||
//#else
|
||||
|
||||
if (result->ColorSpace() != B_CMAP8)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
uint8* dst = (uint8*)result->Bits();
|
||||
uint32 dstBPR = result->BytesPerRow();
|
||||
|
||||
const color_map* colorMap = system_colors();
|
||||
uint16 index;
|
||||
|
||||
for (uint32 y = 0; y < height; y++) {
|
||||
uint8* d = dst;
|
||||
const uint8* s = src;
|
||||
for (uint32 x = 0; x < width; x++) {
|
||||
if (s[3] < 128) {
|
||||
*d = B_TRANSPARENT_MAGIC_CMAP8;
|
||||
} else {
|
||||
index = ((s[2] & 0xf8) << 7) | ((s[1] & 0xf8) << 2)
|
||||
| (s[0] >> 3);
|
||||
*d = colorMap->index_map[index];
|
||||
}
|
||||
s += 4;
|
||||
d += 1;
|
||||
}
|
||||
src += srcBPR;
|
||||
dst += dstBPR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
//#endif // __HAIKU__
|
||||
}
|
||||
|
||||
// #pragma mark - forbidden
|
||||
|
||||
Reference in New Issue
Block a user