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:
Stephan Aßmus
2006-09-11 10:52:01 +00:00
parent 92bc2d0fc5
commit 59deaf10bc
9 changed files with 210 additions and 41 deletions
+5
View File
@@ -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
+11 -6
View File
@@ -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));
+2 -1
View File
@@ -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);
+12 -6
View File
@@ -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());
}
+8 -3
View File
@@ -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
+4 -2
View File
@@ -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.)
}
}
}
+40 -6
View File
@@ -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);
+38 -2
View File
@@ -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
View File
@@ -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