* integration of vector icons with the registrar and the mime data base

* additional versions of SetIcon[ForType] and GetIcon[ForType] in BMimeType
  and BAppFileInfo, which handle flat vector icon data
* changes in Tracker to support scalable icons (currently broken for
non-vector icons and needs cleanup) and drawing icons correctly with alpha
channel (large parts of this work done by Michael Lotz)

If someone feels like looking over the changes, that would be much
appreciated! :-)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18699 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2006-08-29 17:06:23 +00:00
parent 324e3770e6
commit 7fb6186f3c
22 changed files with 865 additions and 174 deletions
+7
View File
@@ -77,13 +77,20 @@ class BAppFileInfo: public BNodeInfo {
virtual status_t GetIcon(BBitmap *icon, icon_size which) const;
virtual status_t SetIcon(const BBitmap *icon, icon_size which);
status_t GetIcon(uint8** data, size_t* size) const;
status_t SetIcon(const uint8* data, size_t size);
status_t GetVersionInfo(version_info *info, version_kind kind) const;
status_t SetVersionInfo(const version_info *info, version_kind kind);
status_t GetIconForType(const char *type, BBitmap *icon,
icon_size which) const;
status_t GetIconForType(const char *type, uint8** data,
size_t* size) const;
status_t SetIconForType(const char *type, const BBitmap *icon,
icon_size which);
status_t SetIconForType(const char *type, const uint8* data,
size_t size);
void SetInfoLocation(info_location location);
bool IsUsingAttributes() const;
+4
View File
@@ -110,6 +110,7 @@ class BMimeType {
status_t Delete();
bool IsInstalled() const;
status_t GetIcon(BBitmap *icon, icon_size size) const;
status_t GetIcon(uint8** data, size_t* size) const;
status_t GetPreferredApp(char *signature, app_verb verb = B_OPEN) const;
status_t GetAttrInfo(BMessage *info) const;
status_t GetFileExtensions(BMessage *extensions) const;
@@ -118,6 +119,7 @@ class BMimeType {
status_t GetSupportingApps(BMessage *signatures) const;
status_t SetIcon(const BBitmap *icon, icon_size size);
status_t SetIcon(const uint8* data, size_t size);
status_t SetPreferredApp(const char *signature, app_verb verb = B_OPEN);
status_t SetAttrInfo(const BMessage *info);
status_t SetFileExtensions(const BMessage *extensions);
@@ -139,6 +141,8 @@ class BMimeType {
icon_size which) const;
status_t SetIconForType(const char *type, const BBitmap *icon,
icon_size which);
status_t SetIconForType(const char* type, const uint8* data,
size_t size);
/* sniffer rule manipulation */
status_t GetSnifferRule(BString *result) const;
+7 -2
View File
@@ -58,8 +58,11 @@ class Database {
status_t SetFileExtensions(const char *type, const BMessage *extensions);
status_t SetIcon(const char *type, const void *data, size_t dataSize,
icon_size which);
status_t SetIconForType(const char *type, const char *fileType, const void *data,
size_t dataSize, icon_size which);
status_t SetIcon(const char *type, const void *data, size_t dataSize);
status_t SetIconForType(const char *type, const char *fileType,
const void *data, size_t dataSize, icon_size which);
status_t SetIconForType(const char *type, const char *fileType,
const void *data, size_t dataSize);
status_t SetPreferredApp(const char *type, const char *signature,
app_verb verb = B_OPEN);
status_t SetSnifferRule(const char *type, const char *rule);
@@ -89,8 +92,10 @@ class Database {
status_t DeleteLongDescription(const char *type);
status_t DeleteFileExtensions(const char *type);
status_t DeleteIcon(const char *type, icon_size size);
status_t DeleteIcon(const char *type);
status_t DeleteIconForType(const char *type, const char *fileType,
icon_size which);
status_t DeleteIconForType(const char *type, const char *fileType);
status_t DeletePreferredApp(const char *type, app_verb verb = B_OPEN);
status_t DeleteSnifferRule(const char *type);
status_t DeleteSupportedTypes(const char *type, bool fullSync);
@@ -27,8 +27,11 @@ status_t get_short_description(const char *type, char *description);
status_t get_long_description(const char *type, char *description);
status_t get_file_extensions(const char *type, BMessage *extensions);
status_t get_icon(const char *type, BBitmap *icon, icon_size size);
status_t get_icon_for_type(const char *type, const char *fileType, BBitmap *icon,
icon_size which);
status_t get_icon(const char *type, uint8** data, size_t* size);
status_t get_icon_for_type(const char *type, const char *fileType,
BBitmap *icon, icon_size which);
status_t get_icon_for_type(const char *type, const char *fileType,
uint8** data, size_t* size);
status_t get_preferred_app(const char *type, char *signature, app_verb verb);
status_t get_sniffer_rule(const char *type, BString *result);
status_t get_supported_types(const char *type, BMessage *types);
+156 -4
View File
@@ -43,9 +43,11 @@ static const int32 kAppFlagsResourceID = 1;
static const int32 kSupportedTypesResourceID = 1;
static const int32 kMiniIconResourceID = 101;
static const int32 kLargeIconResourceID = 101;
static const int32 kIconResourceID = 101;
static const int32 kVersionInfoResourceID = 1;
static const int32 kMiniIconForTypeResourceID = 0;
static const int32 kLargeIconForTypeResourceID = 0;
static const int32 kIconForTypeResourceID = 0;
// type codes
enum {
@@ -615,6 +617,22 @@ BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const
return GetIconForType(NULL, icon, which);
}
// GetIcon
/*! \brief Gets the file's icon.
\param data The pointer in which the flat icon data will be returned.
\param size The pointer in which the size of the data found will be returned.
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The object is not properly initialized.
- \c B_BAD_VALUE: \c NULL \a data or \c NULL size.
- other error codes
*/
status_t
BAppFileInfo::GetIcon(uint8** data, size_t* size) const
{
return GetIconForType(NULL, data, size);
}
// SetIcon
/*! \brief Sets the file's icon.
@@ -637,6 +655,26 @@ BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which)
return SetIconForType(NULL, icon, which);
}
// SetIcon
/*! \brief Sets the file's icon.
If \a icon is \c NULL the file's icon is unset.
\param data A pointer to the data buffer containing the vector icon
to be set. May be \c NULL.
\param size Specifies the size of buffer pointed to by \a data.
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The object is not properly initialized.
- \c B_BAD_VALUE: \c NULL data.
- other error codes
*/
status_t
BAppFileInfo::SetIcon(const uint8* data, size_t size)
{
return SetIconForType(NULL, data, size);
}
// GetVersionInfo
/*! \brief Gets the file's version info.
\param info A pointer to a pre-allocated version_info structure into which
@@ -813,8 +851,10 @@ BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
status_t error = _ReadData(attribute, -1, B_RAW_TYPE, NULL, 0,
bytesRead, &allocatedBuffer);
if (error == B_OK) {
return BIconUtils::GetVectorIcon((uint8*)allocatedBuffer,
bytesRead, icon);
error = BIconUtils::GetVectorIcon((uint8*)allocatedBuffer,
bytesRead, icon);
free(allocatedBuffer);
return error;
}
// no vector icon if we got this far
@@ -888,6 +928,56 @@ BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
return error;
}
// GetIconForType
/*! \brief Gets the icon the application provides for a given MIME type.
If \a type is \c NULL, the application's icon is retrieved.
\param type The MIME type in question. May be \c NULL.
\param data A pointer in which the icon data will be returned. When you
are done with the data, you should use free() to deallocate it.
\param size A pointer in which the size of the retrieved data is returned.
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The object is not properly initialized.
- \c B_BAD_VALUE: \c NULL \a data and/or \a size. Or the supplied
\a type is not a valid MIME type.
- other error codes
*/
status_t
BAppFileInfo::GetIconForType(const char *type, uint8** data,
size_t* size) const
{
if (InitCheck() != B_OK)
return B_NO_INIT;
if (!data || !size)
return B_BAD_VALUE;
// get vector icon
BString attributeName(kIconAttribute);
// check type param
if (type) {
if (BMimeType::IsValid(type))
attributeName += type;
else
return B_BAD_VALUE;
} else {
attributeName += kIconType;
}
void* allocatedBuffer = NULL;
status_t ret = _ReadData(attributeName.String(), -1,
B_RAW_TYPE, NULL, 0, *size, &allocatedBuffer);
if (ret < B_OK)
return ret;
*data = (uint8*)allocatedBuffer;
return B_OK;
}
// SetIconForType
/*! \brief Sets the icon the application provides for a given MIME type.
@@ -906,8 +996,9 @@ BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The object is not properly initialized.
- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
and icon size (\a which) do not match.
- \c B_BAD_VALUE: Either the icon size \a which is unkown, bitmap dimensions (\a icon)
and icon size (\a which) do not match, or the provided \a type is
not a valid MIME type.
- other error codes
*/
status_t
@@ -991,6 +1082,67 @@ BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
return error;
}
// SetIconForType
/*! \brief Sets the icon the application provides for a given MIME type.
If \a type is \c NULL, the application's icon is set.
If \a data is \c NULL the icon is unset.
If the file has a signature, then the icon is also set on the MIME type.
If the type for the signature has not been installed yet, it is installed
before.
\param type The MIME type in question. May be \c NULL.
\param data A pointer to the data containing the icon to be set.
May be \c NULL.
\param size Specifies the size of buffer provided in \a data.
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The object is not properly initialized.
- \c B_BAD_VALUE: The provided \a type is not a valid MIME type.
- other error codes
*/
status_t
BAppFileInfo::SetIconForType(const char* type, const uint8* data,
size_t size)
{
if (InitCheck() != B_OK)
return B_NO_INIT;
// set some icon related variables
BString attributeString = kIconAttribute;
int32 resourceID = type ? kIconForTypeResourceID : kIconResourceID;
uint32 attrType = B_RAW_TYPE;
// check type param
if (type) {
if (BMimeType::IsValid(type))
attributeString += type;
else
return B_BAD_VALUE;
} else
attributeString += kIconType;
const char *attribute = attributeString.String();
status_t error;
// write/remove the attribute
if (data)
error = _WriteData(attribute, resourceID, attrType, data, size, true);
else // no icon given => remove
error = _RemoveData(attribute, attrType);
// set the attribute on the MIME type, if the file has a signature
BMimeType mimeType;
if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
if (!mimeType.IsInstalled())
error = mimeType.Install();
if (error == B_OK)
error = mimeType.SetIconForType(type, data, size);
}
return error;
}
// SetInfoLocation
/*! \brief Specifies the location where the meta data shall be stored.
+113
View File
@@ -443,6 +443,30 @@ BMimeType::GetIcon(BBitmap *icon, icon_size size) const
return err;
}
// GetIcon
//! Fetches the vector icon associated with the MIME type
/*! The icon data is returned in \c data.
\param data Pointer in which the allocated icon data is returned. You need to
delete the buffer when you are done with it.
\param size Pointer in which the size of the allocated icon data is returned.
\return
- \c B_OK: Success
- \c B_ENTRY_NOT_FOUND: No icon of the given size exists for the given type
- other error code: Failure
*/
status_t
BMimeType::GetIcon(uint8** data, size_t* size) const
{
status_t err = InitCheck();
if (!err)
err = get_icon(Type(), data, size);
return err;
}
// GetPreferredApp
//! Fetches the signature of the MIME type's preferred application from the MIME database
/*! The preferred app is the application that's used to access a file when, for example, the user
@@ -713,6 +737,26 @@ BMimeType::SetIcon(const BBitmap *icon, icon_size which)
return SetIconForType(NULL, icon, which);
}
// SetIcon
//! Sets the vector icon for the MIME type
/*! The icon is copied from the provided \a data which must contain \a size bytes.
If you want to erase the current icon, pass \c NULL as the \a data argument.
\param data Pointer to a buffer containing the new icon, or \c NULL to clear
the current icon.
\param size Size of the provided buffer.
\return
- \c B_OK: Success
- other error code: Failure
*/
status_t
BMimeType::SetIcon(const uint8* data, size_t size)
{
return SetIconForType(NULL, data, size);
}
// SetPreferredApp
//! Sets the preferred application for the MIME type
/*! The preferred app is the application that's used to access a file when, for example, the user
@@ -1321,6 +1365,75 @@ BMimeType::SetIconForType(const char *type, const BBitmap *icon, icon_size which
return err;
}
// SetIconForType
/*! \brief Sets the large or mini icon used by an application of this type for
files of the given type.
This can be confusing, so here's how this function is intended to be used:
- The actual \c BMimeType object should be set to the MIME signature of an
application to whom you want to assign custom icons for custom MIME types.
- The \c type parameter specifies the file type whose custom icon you are
setting.
The type of the \c BMimeType object is not required to actually be a subtype of
\c "application/"; that is the intended use however, and application-specific
icons are not expected to be present for non-application types.
The icon is copied from the \c BBitmap pointed to by \c icon. The bitmap must
be the proper size: \c 32x32 for the large icon, \c 16x16 for the mini icon.
If you want to erase the current icon, pass \c NULL as the \c icon argument.
\param type Pointer to a pre-allocated string containing the MIME type whose
custom icon you wish to set.
\param icon Pointer to a pre-allocated \c BBitmap of proper size and colorspace
containing the new icon, or \c NULL to clear the current icon.
\param icon_size Value that specifies which icon to update. Currently \c B_LARGE_ICON
and \c B_MINI_ICON are supported.
\return
- \c B_OK: Success
- other error code: Failure
*/
status_t
BMimeType::SetIconForType(const char* type, const uint8* data, size_t dataSize)
{
status_t err = InitCheck();
BMessage msg(data ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
BMessage reply;
status_t result;
// Build and send the message, read the reply
if (!err)
err = msg.AddString("type", Type());
if (!err)
err = msg.AddInt32("which", (type ? B_REG_MIME_ICON_FOR_TYPE : B_REG_MIME_ICON));
if (data) {
if (!err)
err = msg.AddData("icon data", B_RAW_TYPE, data, dataSize);
}
if (!err)
err = msg.AddInt32("icon size", -1);
// -1 indicates size should be ignored (vector icon data)
if (type) {
if (!err)
err = BMimeType::IsValid(type) ? B_OK : B_BAD_VALUE;
if (!err)
err = msg.AddString("file type", type);
}
if (!err)
err = BRoster::Private().SendTo(&msg, &reply, true);
if (!err)
err = reply.what == B_REG_RESULT ? (status_t)B_OK : (status_t)B_BAD_REPLY;
if (!err)
err = reply.FindInt32("result", &result);
if (!err)
err = result;
return err;
}
// GetSnifferRule
/*! \brief Retrieves the MIME type's sniffer rule.
\param result Pointer to a pre-allocated BString into which the value is
@@ -96,6 +96,15 @@ CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK))
status = mime.SetAppHint(ref);
// Vector Icon
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
uint8* data = NULL;
size_t size = 0;
if (appInfo.GetIcon(&data, &size) == B_OK) {
status = mime.SetIcon(data, size);
free(data);
}
}
// Mini Icon
BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
@@ -119,6 +128,13 @@ CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
// Icons for supported types
const char* type;
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) {
// vector icon
uint8* data = NULL;
size_t size = 0;
if (status == B_OK && appInfo.GetIconForType(type, &data, &size) == B_OK) {
status = mime.SetIconForType(type, data, size);
free(data);
}
// mini icon
if (status == B_OK && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK)
status = mime.SetIconForType(type, &miniIcon, B_MINI_ICON);
+125 -1
View File
@@ -352,6 +352,12 @@ Database::SetIcon(const char *type, const void *data, size_t dataSize,
return SetIconForType(type, NULL, data, dataSize, which);
}
status_t
Database::SetIcon(const char *type, const void *data, size_t dataSize)
{
return SetIconForType(type, NULL, data, dataSize);
}
// SetIconForType
/*! \brief Sets the large or mini icon used by an application of this type for
files of the given type.
@@ -436,6 +442,67 @@ Database::SetIconForType(const char *type, const char *fileType,
return err;
}
// SetIconForType
/*! \brief Sets the vector icon used by an application of this type for
files of the given type.
The type of the \c BMimeType object is not required to actually be a subtype of
\c "application/"; that is the intended use however, and application-specific
icons are not expected to be present for non-application types.
\param type The MIME type
\param fileType The MIME type whose custom icon you wish to set.
\param data Pointer to an array of vector data
\param dataSize The length of the array pointed to by \c data
\return
- \c B_OK: Success
- "error code": Failure
*/
status_t
Database::SetIconForType(const char *type, const char *fileType,
const void *data, size_t dataSize)
{
DBG(OUT("Database::SetIconForType()\n"));
if (type == NULL || data == NULL)
return B_BAD_VALUE;
int32 attrType = B_RAW_TYPE;
// Construct our attribute name
std::string attr;
if (fileType) {
attr = kIconAttrPrefix + BPrivate::Storage::to_lower(fileType);
} else
attr = kIconAttr;
// Write the icon data
BNode node;
bool didCreate = false;
status_t err = open_or_create_type(type, &node, &didCreate);
if (!err && didCreate)
_SendInstallNotification(type);
if (!err)
err = node.WriteAttr(attr.c_str(), attrType, 0, data, dataSize);
if (err >= 0)
err = err == (ssize_t)dataSize ? (status_t)B_OK : (status_t)B_FILE_ERROR;
if (!err) {
// TODO: extra notification for vector icons (currently
// passing "true" for B_LARGE_ICON)?
if (fileType) {
_SendMonitorUpdate(B_ICON_FOR_TYPE_CHANGED, type, fileType,
true, B_META_MIME_MODIFIED);
} else {
_SendMonitorUpdate(B_ICON_CHANGED, type, true,
B_META_MIME_MODIFIED);
}
}
return err;
}
// SetPreferredApp
/*! \brief Sets the signature of the preferred application for the given app verb
@@ -993,6 +1060,28 @@ Database::DeleteIcon(const char *type, icon_size which)
}
/*! \brief Deletes the vector icon for the given type
A \c B_ICON_CHANGED notification is sent to the mime monitor service.
\param type The mime type of interest
\return
- B_OK: success
- B_ENTRY_NOT_FOUND: no such attribute existed
- "error code": failure
*/
status_t
Database::DeleteIcon(const char *type)
{
// TODO: exta notification for vector icon (uses B_LARGE_ICON now)
status_t status = delete_attribute(type, kIconAttr);
if (status == B_OK)
_SendMonitorUpdate(B_ICON_CHANGED, type, B_LARGE_ICON,
B_META_MIME_DELETED);
return status;
}
/*! \brief Deletes the icon of the given size associated with the given file
type for the given application signature.
@@ -1001,7 +1090,7 @@ Database::DeleteIcon(const char *type, icon_size which)
A \c B_ICON_FOR_TYPE_CHANGED notification is sent to the mime monitor service.
\param type The mime type of the application whose custom icon you are deleting.
\param which The mime type for which you no longer wish \c type to have a custom icon.
\param fileType The mime type for which you no longer wish \c type to have a custom icon.
\param which The icon size of interest
\return
- B_OK: success
@@ -1026,6 +1115,41 @@ Database::DeleteIconForType(const char *type, const char *fileType, icon_size wh
return status;
}
/*! \brief Deletes the vector icon associated with the given file
type for the given application signature.
(If this function seems confusing, please see BMimeType::GetIconForType() for a
better description of what the *IconForType() functions are used for.)
A \c B_ICON_FOR_TYPE_CHANGED notification is sent to the mime monitor service.
\param type The mime type of the application whose custom icon you are deleting.
\param fileType The mime type for which you no longer wish \c type to have a custom icon.
\return
- B_OK: success
- B_ENTRY_NOT_FOUND: no such attribute existed
- "error code": failure
*/
status_t
Database::DeleteIconForType(const char *type, const char *fileType)
{
if (fileType == NULL)
return B_BAD_VALUE;
std::string attr = kIconAttrPrefix + BPrivate::Storage::to_lower(fileType);
// TODO: introduce extra notification for vector icons?
// (uses B_LARGE_ICON now)
status_t status = delete_attribute(type, attr.c_str());
if (status == B_OK) {
_SendMonitorUpdate(B_ICON_FOR_TYPE_CHANGED, type, fileType,
true, B_META_MIME_DELETED);
}
return status;
}
// DeletePreferredApp
//! Deletes the preferred app for the given app verb for the given type
/*! A \c B_PREFERRED_APP_CHANGED notification is sent to the mime monitor service.
@@ -36,6 +36,25 @@ update_icon(BAppFileInfo &appFileInfoRead, BAppFileInfo &appFileInfoWrite,
return err;
}
// update_icon
static status_t
update_icon(BAppFileInfo &appFileInfoRead, BAppFileInfo &appFileInfoWrite,
const char *type)
{
uint8* data = NULL;
size_t size = 0;
status_t err = appFileInfoRead.GetIconForType(type, &data, &size);
if (err == B_OK)
err = appFileInfoWrite.SetIconForType(type, data, size);
else if (err == B_ENTRY_NOT_FOUND)
err = appFileInfoWrite.SetIconForType(type, NULL, size);
free(data);
return err;
}
// is_shared_object_mime_type
static bool
is_shared_object_mime_type(BMimeType &type)
@@ -151,6 +170,11 @@ UpdateMimeInfoThread::DoMimeUpdate(const entry_ref *entry, bool *entryIsDir)
if (err != B_OK)
return err;
// vector icon
err = update_icon(appFileInfoRead, appFileInfoWrite, NULL);
if (err != B_OK)
return err;
// small icon
BBitmap smallIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK,
B_CMAP8);
@@ -192,6 +216,12 @@ UpdateMimeInfoThread::DoMimeUpdate(const entry_ref *entry, bool *entryIsDir)
for (int32 i = 0;
supportedTypes.FindString("types", i, &supportedType) == B_OK;
i++) {
// vector icon
err = update_icon(appFileInfoRead, appFileInfoWrite,
supportedType);
if (err != B_OK)
return err;
// small icon
err = update_icon(appFileInfoRead, appFileInfoWrite,
supportedType, smallIcon, B_MINI_ICON);
+91 -2
View File
@@ -185,6 +185,19 @@ get_icon(const char *type, BBitmap *icon, icon_size which)
return get_icon_for_type(type, NULL, icon, which);
}
// get_icon
//! Fetches the vector icon associated with the given MIME type
/* \param type The mime type
\param data Pointer in which the allocated icon data is returned. You need to
free the buffer once you're done with it.
\param size Pointer in which the size of the icon data is returned.
*/
status_t
get_icon(const char *type, uint8** data, size_t* size)
{
return get_icon_for_type(type, NULL, data, size);
}
// get_icon_for_type
/*! \brief Fetches the large or mini icon used by an application of this type for files of the
given type.
@@ -197,8 +210,8 @@ get_icon(const char *type, BBitmap *icon, icon_size which)
be the proper size: \c 32x32 for the large icon, \c 16x16 for the mini icon.
\param type The MIME type
\param type Pointer to a pre-allocated string containing the MIME type whose
custom icon you wish to fetch. If NULL, works just like get_icon().
\param fileType Pointer to a pre-allocated string containing the MIME type whose
custom icon you wish to fetch. If NULL, works just like get_icon().
\param icon Pointer to a pre-allocated \c BBitmap of proper size and colorspace into
which the icon is copied.
\param icon_size Value that specifies which icon to return. Currently \c B_LARGE_ICON
@@ -323,6 +336,82 @@ get_icon_for_type(const char* type, const char* fileType, BBitmap* icon,
// return err;
}
// get_icon_for_type
/*! \brief Fetches the vector icon used by an application of this type for files of the
given type.
The type of the \c BMimeType object is not required to actually be a subtype of
\c "application/"; that is the intended use however, and calling \c get_icon_for_type()
on a non-application type will likely return \c B_ENTRY_NOT_FOUND.
The icon data is allocated and returned in \a data.
\param type The MIME type
\param fileType Pointer to a pre-allocated string containing the MIME type whose
custom icon you wish to fetch. If NULL, works just like get_icon().
\param data Pointer in which the icon data is returned on success.
\param size Pointer in which the size of the icon data is returned.
\return
- \c B_OK: Success
- \c B_ENTRY_NOT_FOUND: No vector icon exists for the given type
- "error code": Failure
*/
status_t
get_icon_for_type(const char* type, const char* fileType, uint8** data,
size_t* size)
{
if (!type || !data || !size)
return B_BAD_VALUE;
// open the node for the given type
BNode node;
ssize_t err = open_type(type, &node);
if (err < B_OK)
return (status_t)err;
// construct our attribute name
std::string iconAttrName;
if (fileType)
iconAttrName = kIconAttrPrefix + BPrivate::Storage::to_lower(fileType);
else
iconAttrName = kIconAttr;
// get info about attribute for that name
attr_info info;
if (!err)
err = node.GetAttrInfo(iconAttrName.c_str(), &info);
// validate attribute type
if (!err)
err = (info.type == B_RAW_TYPE) ? B_OK : B_BAD_VALUE;
// allocate a buffer and read the attribute data into it
if (!err) {
uint8* buffer = new(std::nothrow) uint8[info.size];
if (!buffer)
err = B_NO_MEMORY;
if (!err) {
err = node.ReadAttr(iconAttrName.c_str(), B_RAW_TYPE,
0, buffer, info.size);
}
if (err >= 0)
err = (err == info.size) ? (ssize_t)B_OK : (ssize_t)B_FILE_ERROR;
if (!err) {
// success, set data pointer and size
*data = buffer;
*size = info.size;
} else {
delete[] buffer;
}
}
return err;
}
// get_preferred_app
//! Fetches signature of the MIME type's preferred application for the given action.
/*! The string pointed to by \c signature must be long enough to
+3 -3
View File
@@ -127,9 +127,6 @@ BImageResources::LoadResource(type_code type, const char *name, size_t *out_size
status_t
BImageResources::GetIconResource(int32 id, icon_size size, BBitmap *dest) const
{
if (size != B_LARGE_ICON && size != B_MINI_ICON )
return B_ERROR;
size_t length = 0;
const void *data;
@@ -140,6 +137,9 @@ BImageResources::GetIconResource(int32 id, icon_size size, BBitmap *dest) const
return B_OK;
// fall back to R5 icon
if (size != B_LARGE_ICON && size != B_MINI_ICON)
return B_ERROR;
length = 0;
data = LoadResource(size == B_LARGE_ICON ? 'ICON' : 'MICN', id, &length);
+19 -3
View File
@@ -1879,9 +1879,25 @@ BContainerWindow::AddWindowMenu(BMenu *menu)
{
BMenuItem *item;
item = new BMenuItem("Icon View", new BMessage(kIconMode), '1');
BMenu* iconSizeMenu = new BMenu("Icon View");
item = new BMenuItem("32 x 32", new BMessage(kIconMode), '1');
item->SetTarget(PoseView());
menu->AddItem(item);
iconSizeMenu->AddItem(item);
BMessage* message = new BMessage(kScaleIconMode);
message->AddInt32("size", 48);
item = new BMenuItem("48 x 48", message);
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
message = new BMessage(kScaleIconMode);
message->AddInt32("size", 64);
item = new BMenuItem("64 x 64", message);
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
menu->AddItem(iconSizeMenu);
item = new BMenuItem("Mini Icon View", new BMessage(kMiniIconMode), '2');
item->SetTarget(PoseView());
@@ -2849,7 +2865,7 @@ BContainerWindow::UpdateMenu(BMenu *menu, UpdateMenuContext context)
}
if (context == kMenuBarContext || context == kWindowPopUpContext) {
MarkNamedMenuItem(menu, kIconMode, PoseView()->ViewMode() == kIconMode);
// MarkNamedMenuItem(menu, kIconMode, PoseView()->ViewMode() == kIconMode);
MarkNamedMenuItem(menu, kListMode, PoseView()->ViewMode() == kListMode);
MarkNamedMenuItem(menu, kMiniIconMode,
PoseView()->ViewMode() == kMiniIconMode);
+10 -8
View File
@@ -175,12 +175,14 @@ IconCacheEntry::HaveIconBitmap(IconDrawMode mode, icon_size size) const
if (size == B_MINI_ICON)
return fMiniIcon != NULL;
else
return fLargeIcon != NULL;
return fLargeIcon != NULL
&& fLargeIcon->Bounds().IntegerWidth() + 1 == size;
} else if (mode == kSelected) {
if (size == B_MINI_ICON)
return fHilitedMiniIcon != NULL;
else
return fHilitedLargeIcon != NULL;
return fHilitedLargeIcon != NULL
&& fHilitedLargeIcon->Bounds().IntegerWidth() + 1 == size;
}
return false;
}
@@ -280,15 +282,15 @@ IconCacheEntry::SetIcon(BBitmap *bitmap, IconDrawMode mode, icon_size size,
bool /*create*/)
{
if (mode == kNormalIcon) {
if (size == B_LARGE_ICON)
fLargeIcon = bitmap;
else
if (size == B_MINI_ICON)
fMiniIcon = bitmap;
} else if (mode == kSelectedIcon) {
if (size == B_LARGE_ICON)
fHilitedLargeIcon = bitmap;
else
fLargeIcon = bitmap;
} else if (mode == kSelectedIcon) {
if (size == B_MINI_ICON)
fHilitedMiniIcon = bitmap;
else
fHilitedLargeIcon = bitmap;
} else
TRESPASS();
}
+77 -62
View File
@@ -319,18 +319,14 @@ BPose::UpdateIcon(BPoint poseLoc, BPoseView *poseView)
if (poseView->ViewMode() == kListMode) {
rect = CalcRect(poseLoc, poseView);
rect.left += kListOffset;
// TODO: make this depend on IconSizeInt() as well?
rect.right = rect.left + B_MINI_ICON;
rect.top = rect.bottom - B_MINI_ICON;
} else if (poseView->ViewMode() == kIconMode) {
rect.left = fLocation.x;
rect.top = fLocation.y;
rect.right = rect.left + B_LARGE_ICON;
rect.bottom = rect.top + B_LARGE_ICON;
} else {
rect.left = fLocation.x;
rect.top = fLocation.y;
rect.right = rect.left + B_MINI_ICON;
rect.bottom = rect.top + B_MINI_ICON;
rect.right = rect.left + poseView->IconSizeInt();
rect.bottom = rect.top + poseView->IconSizeInt();
}
poseView->Invalidate(rect);
@@ -439,23 +435,27 @@ BPose::PointInPose(const BPoseView *poseView, BPoint where) const
{
ASSERT(poseView->ViewMode() != kListMode);
if (poseView->ViewMode() == kIconMode) {
if (poseView->ViewMode() == kIconMode
|| poseView->ViewMode() == kScaleIconMode) {
// check icon rect, then actual icon pixel
BRect rect(fLocation, fLocation);
rect.right += B_LARGE_ICON - 1;
rect.bottom += B_LARGE_ICON - 1;
rect.right += poseView->IconSizeInt() - 1;
rect.bottom += poseView->IconSizeInt() - 1;
if (rect.Contains(where))
return TestLargeIconPixel(where - fLocation);
return IconCache::sIconCache->IconHitTest(where - fLocation,
ResolvedModel(),
kNormalIcon,
poseView->IconSize());
BTextWidget *widget = WidgetFor(poseView->FirstColumn()->AttrHash());
if (widget) {
float textWidth = ceilf(widget->TextWidth(poseView) + 1);
rect.left += (B_LARGE_ICON - textWidth) / 2;
rect.left += (poseView->IconSizeInt() - textWidth) / 2;
rect.right = rect.left + textWidth;
}
rect.top = fLocation.y + B_LARGE_ICON;
rect.top = fLocation.y + poseView->IconSizeInt();
rect.bottom = rect.top + poseView->FontHeight();
return rect.Contains(where);
@@ -509,16 +509,14 @@ void
BPose::Draw(BRect rect, BPoseView *poseView, BView *drawView, bool fullDraw,
const BRegion *updateRgn, BPoint offset, bool selected, bool recalculateText)
{
if (fClipboardMode == kMoveSelectionTo) {
// If the background wasn't cleared and Draw() is not called after
// having edited a name or similar (with fullDraw)
if (!fBackgroundClean && !fullDraw) {
fBackgroundClean = true;
poseView->Invalidate(rect);
return;
} else
fBackgroundClean = false;
}
// If the background wasn't cleared and Draw() is not called after
// having edited a name or similar (with fullDraw)
if (!fBackgroundClean && !fullDraw) {
fBackgroundClean = true;
poseView->Invalidate(rect);
return;
} else
fBackgroundClean = false;
bool directDraw = (drawView == poseView);
bool windowActive = poseView->Window()->IsActive();
@@ -528,17 +526,23 @@ BPose::Draw(BRect rect, BPoseView *poseView, BView *drawView, bool fullDraw,
ModelNodeLazyOpener modelOpener(fModel);
if (poseView->ViewMode() == kListMode) {
uint32 size = poseView->IconSizeInt();
BRect iconRect(rect);
iconRect.OffsetBy(offset);
iconRect.left += kListOffset;
iconRect.right = iconRect.left + B_MINI_ICON;
iconRect.top = iconRect.bottom - B_MINI_ICON;
if (!updateRgn || updateRgn->Intersects(iconRect))
DrawIcon(iconRect.LeftTop(), drawView, B_MINI_ICON, directDraw,
iconRect.right = iconRect.left + size;
iconRect.top = iconRect.bottom - size;
if (!updateRgn || updateRgn->Intersects(iconRect)) {
DrawIcon(iconRect.LeftTop(), drawView, poseView->IconSize(), directDraw,
!windowActive && !showSelectionWhenInactive);
}
// draw text
for (int32 index = 0; ; index++) {
int32 columnsToDraw = 1;
if (fullDraw)
columnsToDraw = poseView->CountColumns();
for (int32 index = 0; index < columnsToDraw; index++) {
BColumn *column = poseView->ColumnAt(index);
if (!column)
break;
@@ -557,10 +561,25 @@ BPose::Draw(BRect rect, BPoseView *poseView, BView *drawView, bool fullDraw,
if (recalculateText)
widget->RecalculateText(poseView);
widget->Draw(widgetRect, widgetTextRect, column->Width(),
poseView, drawView, selected, fClipboardMode, offset, directDraw);
bool selectDuringDraw = directDraw && selected
&& (windowActive && !poseView->EraseWidgetTextBackground());
if (index == 0 && selected) {
if (index == 0 && selectDuringDraw) {
//draw with dark background to select text
drawView->PushState();
drawView->SetLowColor(0, 0, 0);
}
if (index == 0)
widget->Draw(widgetRect, widgetTextRect, column->Width(),
poseView, drawView, selected, fClipboardMode, offset, directDraw);
else
widget->Draw(widgetTextRect, widgetTextRect, column->Width(),
poseView, drawView, false, fClipboardMode, offset, directDraw);
if (index == 0 && selectDuringDraw)
drawView->PopState();
else if (index == 0 && selected) {
if (windowActive || isDrawingSelectionRect) {
widgetTextRect.OffsetBy(offset);
drawView->InvertRect(widgetTextRect);
@@ -575,9 +594,6 @@ BPose::Draw(BRect rect, BPoseView *poseView, BView *drawView, bool fullDraw,
}
}
}
if (!fullDraw)
break;
}
} else {
@@ -588,9 +604,8 @@ BPose::Draw(BRect rect, BPoseView *poseView, BView *drawView, bool fullDraw,
BPoint iconOrigin(fLocation);
iconOrigin += offset;
DrawIcon(iconOrigin, drawView, poseView->ViewMode() == kIconMode ?
B_LARGE_ICON : B_MINI_ICON, directDraw,
!windowActive && !showSelectionWhenInactive && !poseView->IsDesktopWindow());
DrawIcon(iconOrigin, drawView, poseView->IconSize(), directDraw,
!windowActive && !showSelectionWhenInactive);
BColumn *column = poseView->FirstColumn();
if (!column)
@@ -642,8 +657,7 @@ BPose::DeselectWithoutErasingBackground(BRect, BPoseView *poseView)
// draw icon directly
if (fPercent == -1)
DrawIcon(fLocation, poseView, poseView->ViewMode() == kIconMode ?
B_LARGE_ICON : B_MINI_ICON, true);
DrawIcon(fLocation, poseView, poseView->IconSize(), true);
else
UpdateIcon(fLocation, poseView);
@@ -696,7 +710,7 @@ BPose::MoveTo(BPoint point, BPoseView *poseView, bool inval)
BTextWidget *
BPose::ActiveWidget() const
{
for (int32 i = fWidgetList.CountItems();i-- > 0;) {
for (int32 i = fWidgetList.CountItems(); i-- > 0;) {
BTextWidget *widget = fWidgetList.ItemAt(i);
if (widget->IsActive())
return widget;
@@ -734,12 +748,14 @@ BPose::WidgetFor(BColumn *column, BPoseView *poseView, ModelNodeLazyOpener &open
}
/* deprecated */
bool
BPose::TestLargeIconPixel(BPoint point) const
{
return IconCache::sIconCache->IconHitTest(point, ResolvedModel(),
kNormalIcon, B_LARGE_ICON);
}
/* deprecated */
void
@@ -747,7 +763,7 @@ BPose::DrawIcon(BPoint where, BView *view, icon_size kind, bool direct, bool dra
{
if (fClipboardMode == kMoveSelectionTo) {
view->SetDrawingMode(B_OP_ALPHA);
view->SetHighColor(0,0,0,64); // set the level of transparency
view->SetHighColor(0, 0, 0, 64); // set the level of transparency
view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
} else if (direct)
view->SetDrawingMode(B_OP_OVER);
@@ -765,29 +781,29 @@ BPose::DrawBar(BPoint where,BView *view,icon_size kind)
{
view->PushState();
int32 size,barWidth,barHeight,yOffset;
if (kind == B_LARGE_ICON) {
size = B_LARGE_ICON - 1;
barWidth = 7;
int32 size, barWidth, barHeight, yOffset;
if (kind >= B_LARGE_ICON) {
size = kind - 1;
barWidth = (int32)((float)7 / (float)32 * (float)kind);
yOffset = 2;
barHeight = size - 4 - 2*yOffset;
barHeight = size - 4 - 2 * yOffset;
} else {
size = B_MINI_ICON;
barWidth = 4;
yOffset = 0;
barHeight = size - 4 - 2*yOffset;
barHeight = size - 4 - 2 * yOffset;
}
// the black shadowed line
view->SetHighColor(32,32,32,92);
view->MovePenTo(BPoint(where.x + size,where.y + 1 + yOffset));
view->StrokeLine(BPoint(where.x + size,where.y + size - yOffset));
view->StrokeLine(BPoint(where.x + size - barWidth + 1,where.y + size - yOffset));
view->SetHighColor(32, 32, 32, 92);
view->MovePenTo(BPoint(where.x + size, where.y + 1 + yOffset));
view->StrokeLine(BPoint(where.x + size, where.y + size - yOffset));
view->StrokeLine(BPoint(where.x + size - barWidth + 1, where.y + size - yOffset));
view->SetDrawingMode(B_OP_ALPHA);
// the gray frame
view->SetHighColor(76,76,76,192);
view->SetHighColor(76, 76, 76, 192);
BRect rect( where.x + size - barWidth,where.y + yOffset,
where.x + size - 1,where.y + size - 1 - yOffset);
view->StrokeRect(rect);
@@ -801,8 +817,7 @@ BPose::DrawBar(BPoint where,BView *view,icon_size kind)
barPos = barHeight;
// the free space bar
TrackerSettings settings;
view->SetHighColor(settings.FreeSpaceColor());
view->SetHighColor(TrackerSettings().FreeSpaceColor());
rect.InsetBy(1,1);
BRect bar(rect);
@@ -813,7 +828,7 @@ BPose::DrawBar(BPoint where,BView *view,icon_size kind)
// the used space bar
bar.top = bar.bottom + 1;
bar.bottom = rect.bottom;
view->SetHighColor(fPercent < -1 ? settings.WarningSpaceColor() : settings.UsedSpaceColor());
view->SetHighColor(fPercent < -1 ? TrackerSettings().WarningSpaceColor() : TrackerSettings().UsedSpaceColor());
view->FillRect(bar);
view->PopState();
@@ -852,19 +867,19 @@ BPose::CalcRect(BPoint loc, const BPoseView *poseView, bool minimalRect)
BRect
BPose::CalcRect(const BPoseView *poseView)
{
ASSERT(poseView->ViewMode() != kListMode);
BRect rect;
if (poseView->ViewMode() == kIconMode) {
if (poseView->ViewMode() == kIconMode
|| poseView->ViewMode() == kScaleIconMode) {
rect.left = fLocation.x;
rect.right = rect.left + B_LARGE_ICON;
rect.right = rect.left + poseView->IconSizeInt();
BTextWidget *widget = WidgetFor(poseView->FirstColumn()->AttrHash());
if (widget) {
float textWidth = ceilf(widget->TextWidth(poseView) + 1);
if (textWidth > B_LARGE_ICON) {
rect.left += (B_LARGE_ICON - textWidth) / 2;
if (textWidth > poseView->IconSizeInt()) {
rect.left += (poseView->IconSizeInt() - textWidth) / 2;
rect.right = rect.left + textWidth;
}
}
@@ -892,7 +907,6 @@ void
BPose::PrintToStream()
{
TargetModel()->PrintToStream();
PRINT(("%sselected\n", IsSelected() ? "" : "not "));
switch (fClipboardMode) {
case kMoveSelectionTo:
PRINT(("clipboardMode: Cut\n"));
@@ -903,10 +917,11 @@ BPose::PrintToStream()
default:
PRINT(("clipboardMode: 0 - not in clipboard\n"));
}
PRINT(("%sselected\n", IsSelected() ? "" : "not "));
PRINT(("location %s x:%f y:%f\n", HasLocation() ? "" : "unknown ",
HasLocation() ? Location().x : 0,
HasLocation() ? Location().y : 0));
PRINT(("%sautoplaced \n", WasAutoPlaced() ? "was " : "not "));
PRINT(("%s autoplaced \n", WasAutoPlaced() ? "was" : "not"));
}
#endif
+63 -17
View File
@@ -905,14 +905,22 @@ BPoseView::SetIconPoseHeight()
{
switch (ViewMode()) {
case kIconMode:
fIconPoseHeight = ceilf(B_LARGE_ICON + fFontHeight + 1);
fViewState->SetIconSize(B_LARGE_ICON);
fIconPoseHeight = ceilf(IconSizeInt() + fFontHeight + 1);
break;
case kMiniIconMode:
fIconPoseHeight = ceilf(fFontHeight < B_MINI_ICON ? B_MINI_ICON : fFontHeight + 1);
fViewState->SetIconSize(B_MINI_ICON);
fIconPoseHeight = ceilf(fFontHeight < IconSizeInt() ? IconSizeInt() : fFontHeight + 1);
break;
case kScaleIconMode:
// IconSize should allready be set in MessageReceived()
fIconPoseHeight = ceilf(IconSizeInt() + fFontHeight + 1);
break;
default:
fViewState->SetIconSize(B_MINI_ICON);
fIconPoseHeight = fListElemHeight;
break;
}
@@ -933,9 +941,14 @@ BPoseView::GetLayoutInfo(uint32 mode, BPoint *grid, BPoint *offset) const
offset->Set(20, 20);
break;
case kScaleIconMode:
grid->Set(IconSizeInt() + 28, IconSizeInt() + 28);
offset->Set(20, 20);
break;
default:
offset->Set(5, 5);
grid->Set(0, 0);
offset->Set(5, 5);
break;
}
}
@@ -1669,6 +1682,7 @@ BPoseView::CreatePoses(Model **models, PoseInfo *poseInfoArray, int32 count,
case kIconMode:
case kMiniIconMode:
case kScaleIconMode:
if (poseInfo->fInitedDirectory == -1LL || fAlwaysAutoPlace) {
if (pose->HasLocation())
RemoveFromVSList(pose);
@@ -1909,8 +1923,8 @@ BPoseView::AddCountView()
Window()->AddChild(fCountView);
if (fHScrollBar) {
fHScrollBar->MoveBy(kCountViewWidth+1, 0);
fHScrollBar->ResizeBy(-kCountViewWidth-1, 0);
fHScrollBar->MoveBy(kCountViewWidth + 1, 0);
fHScrollBar->ResizeBy(-kCountViewWidth - 1, 0);
}
}
@@ -1974,6 +1988,17 @@ BPoseView::MessageReceived(BMessage *message)
pendingNodeMonitorCache.Add(message);
break;
case kScaleIconMode: {
int32 size;
if (message->FindInt32("size", &size) == B_OK) {
if (size != (int32)IconSizeInt()) {
fViewState->SetIconSize(size);
Refresh(); // we need to refresh since the icons need
// to be rescaled
} else
break; // no change
}
} // fall thru
case kListMode:
case kIconMode:
case kMiniIconMode:
@@ -2636,7 +2661,7 @@ BPoseView::ReadExtendedPoseInfo(Model *model)
void
BPoseView::SetViewMode(uint32 newMode)
{
if (newMode == ViewMode())
if (newMode == ViewMode() && newMode != kScaleIconMode)
return;
ASSERT(!IsFilePanel());
@@ -2729,7 +2754,7 @@ BPoseView::SetViewMode(uint32 newMode)
}
// sort poselist if we are switching to list mode
if (ViewMode() == kListMode)
if (newMode == kListMode)
SortPoses();
else
RecalcExtent();
@@ -3139,6 +3164,9 @@ BPoseView::PlacePose(BPose *pose, BRect &viewBounds)
void
BPoseView::CheckAutoPlacedPoses()
{
if (ViewMode() == kListMode)
return;
BRect viewBounds(Bounds());
int32 count = fPoseList->CountItems();
@@ -3843,7 +3871,7 @@ BPoseView::HandleMessageDropped(BMessage *message)
return true;
}
if (fDropTarget)
if (fDropTarget && !DragSelectionContains(fDropTarget, message))
HiliteDropTarget(false);
fDropTarget = NULL;
@@ -4847,7 +4875,8 @@ BPoseView::FSNotification(const BMessage *message)
if (TargetModel() != NULL && TargetModel()->IsRoot()) {
BVolume volume(device);
CreateVolumePose(&volume, false);
if (volume.InitCheck() == B_OK)
CreateVolumePose(&volume, false);
} else if (ContainerWindow()->IsTrash()) {
// add trash items from newly mounted volume
@@ -6864,8 +6893,12 @@ BPoseView::SelectPosesListMode(BRect selectionRect, BList **oldList)
newList->AddItem((void *)index); // this sucks, need to clean up
// using a vector class instead of BList
if ((selected != pose->IsSelected()) && poseRect.Intersects(bounds))
pose->Draw(poseRect, this, false);
if ((selected != pose->IsSelected()) && poseRect.Intersects(bounds)) {
if (pose->IsSelected() || EraseWidgetTextBackground())
pose->Draw(poseRect, this, false);
else
Invalidate(poseRect);
}
// First Pose selected gets to be the pivot.
if ((fSelectionPivotPose == NULL) && (selected == false))
@@ -6889,8 +6922,12 @@ BPoseView::SelectPosesListMode(BRect selectionRect, BList **oldList)
loc.Set(0, oldIndex * fListElemHeight);
BRect poseRect(pose->CalcRect(loc, this));
if (poseRect.Intersects(bounds))
pose->Draw(poseRect, this, false);
if (poseRect.Intersects(bounds)) {
if (pose->IsSelected() || EraseWidgetTextBackground())
pose->Draw(poseRect, this, false);
else
Invalidate(poseRect);
}
}
}
@@ -6924,11 +6961,12 @@ BPoseView::SelectPosesIconMode(BRect selectionRect, BList **oldList)
pose->Select(!fSelectionList->HasItem(pose));
newList->AddItem((void *)index);
if ((selected != pose->IsSelected()) && poseRect.Intersects(bounds))
if ((selected != pose->IsSelected()) && poseRect.Intersects(bounds)) {
if (pose->IsSelected() || EraseWidgetTextBackground())
pose->Draw(poseRect, this, false);
else
Invalidate(poseRect);
}
// First Pose selected gets to be the pivot.
if ((fSelectionPivotPose == NULL) && (selected == false))
@@ -7370,7 +7408,11 @@ BPoseView::UnmountSelectedVolumes()
int32 select_count = fSelectionList->CountItems();
for (int32 index = 0; index < select_count; index++) {
Model *model = fSelectionList->ItemAt(index)->TargetModel();
BPose *pose = fSelectionList->ItemAt(index);
if (!pose)
continue;
Model *model = pose->TargetModel();
if (model->IsVolume()) {
BVolume volume(model->NodeRef()->device);
if (volume != boot) {
@@ -7705,7 +7747,11 @@ BPoseView::ClearSelection()
BPose *pose = fPoseList->ItemAt(index);
if (pose->IsSelected()) {
pose->Select(false);
pose->Draw(pose->CalcRect(loc, this, false), this, false);
BRect poseRect(pose->CalcRect(loc, this, false));
if (EraseWidgetTextBackground())
pose->Draw(poseRect, this, false);
else
Invalidate(poseRect);
}
loc.y += fListElemHeight;
@@ -8678,7 +8724,7 @@ BPoseView::UpdateDropTarget(BPoint mouseLoc, const BMessage *dragMessage,
// no change
return false;
if (fDropTarget)
if (fDropTarget && !DragSelectionContains(fDropTarget, dragMessage))
HiliteDropTarget(false);
fDropTarget = targetPose;
+15
View File
@@ -79,6 +79,7 @@ const int32 kListOffset = 20;
const uint32 kMiniIconMode = 'Tmic';
const uint32 kIconMode = 'Ticn';
const uint32 kListMode = 'Tlst';
const uint32 kScaleIconMode = 'Tsic'; // new mode for scaled icons
const uint32 kCheckTypeahead = 'Tcty';
@@ -195,6 +196,8 @@ class BPoseView : public BView {
void SetIconPoseHeight();
float IconPoseHeight() const;
uint32 IconSizeInt() const;
icon_size IconSize() const;
BRect Extent() const;
void GetLayoutInfo(uint32 viewMode, BPoint *grid, BPoint *offset) const;
@@ -724,6 +727,18 @@ BPoseView::IconPoseHeight() const
return fIconPoseHeight;
}
inline uint32
BPoseView::IconSizeInt() const
{
return fViewState->IconSize();
}
inline icon_size
BPoseView::IconSize() const
{
return (icon_size)fViewState->IconSize();
}
inline PoseList *
BPoseView::SelectionList() const
{
+11 -5
View File
@@ -169,11 +169,14 @@ BTextWidget::CalcRectCommon(BPoint poseLoc, const BColumn *column,
result.bottom = poseLoc.y + (view->ListElemHeight() - 1);
} else {
if (view->ViewMode() == kIconMode)
result.left = poseLoc.x + (B_LARGE_ICON - textWidth) / 2;
else
// MINI_ICON_MODE rect calc
if (view->ViewMode() == kIconMode
|| view->ViewMode() == kScaleIconMode) {
// large/scaled icon mode
result.left = poseLoc.x + (view->IconSizeInt() - textWidth) / 2;
} else {
// mini icon mode
result.left = poseLoc.x + B_MINI_ICON + kMiniIconSeparator;
}
result.right = result.left + textWidth;
result.bottom = poseLoc.y + view->IconPoseHeight();
@@ -345,8 +348,10 @@ BTextWidget::StartEdit(BRect bounds, BPoseView *view, BPose *pose)
rect.right = rect.left + textView->LineWidth() + 3;
// center new width, if necessary
if (view->ViewMode() == kIconMode
|| view->ViewMode() == kListMode && fAlignment == B_ALIGN_CENTER)
|| view->ViewMode() == kScaleIconMode
|| view->ViewMode() == kListMode && fAlignment == B_ALIGN_CENTER) {
rect.OffsetBy(bounds.Width() / 2 - rect.Width() / 2, 0);
}
rect.bottom = rect.top + textView->LineHeight() + 1;
textRect = rect.OffsetToCopy(2, 1);
@@ -371,6 +376,7 @@ BTextWidget::StartEdit(BRect bounds, BPoseView *view, BPose *pose)
// configure text view
switch (view->ViewMode()) {
case kIconMode:
case kScaleIconMode:
textView->SetAlignment(B_ALIGN_CENTER);
break;
+42 -42
View File
@@ -1334,50 +1334,50 @@ GetAppIconFromAttr(BFile *file, BBitmap *result, icon_size size)
// app icons -- the call is expensive because by default
// the resource fork is scanned to read the icons
#ifdef B_APP_FILE_INFO_IS_FAST
//#ifdef B_APP_FILE_INFO_IS_FAST
BAppFileInfo appFileInfo(file);
return appFileInfo.GetIcon(result, size);
#else
const char *attrName = kAttrIcon;
uint32 type = B_RAW_TYPE;
// try vector icon
attr_info ainfo;
status_t ret = file->GetAttrInfo(attrName, &ainfo);
if (ret == B_OK) {
uint8 buffer[ainfo.size];
ssize_t readResult = file->ReadAttr(attrName, type, 0, buffer,
ainfo.size);
if (readResult == ainfo.size) {
if (BIconUtils::GetVectorIcon(buffer, ainfo.size, result) == B_OK)
return B_OK;
}
}
// try again with R5 icons
attrName = size == B_LARGE_ICON ? kAttrLargeIcon : kAttrMiniIcon;
type = size == B_LARGE_ICON ? LARGE_ICON_TYPE : MINI_ICON_TYPE;
ret = file->GetAttrInfo(attrName, &ainfo);
if (ret < B_OK)
return ret;
uint8 buffer[ainfo.size];
ssize_t readResult = file->ReadAttr(attrName, type, 0, buffer, ainfo.size);
if (readResult <= 0)
return (status_t)readResult;
if (result->ColorSpace() != B_CMAP8) {
ret = BIconUtils::ConvertFromCMAP8(buffer, size, size, size, result);
} else {
result->SetBits(buffer, result->BitsLength(), 0, B_CMAP8);
}
return ret;
#endif // B_APP_FILE_INFO_IS_FAST
//#else
//
// const char *attrName = kAttrIcon;
// uint32 type = B_RAW_TYPE;
//
// // try vector icon
// attr_info ainfo;
// status_t ret = file->GetAttrInfo(attrName, &ainfo);
//
// if (ret == B_OK) {
// uint8 buffer[ainfo.size];
// ssize_t readResult = file->ReadAttr(attrName, type, 0, buffer,
// ainfo.size);
// if (readResult == ainfo.size) {
// if (BIconUtils::GetVectorIcon(buffer, ainfo.size, result) == B_OK)
// return B_OK;
// }
// }
//
// // try again with R5 icons
// attrName = size == B_LARGE_ICON ? kAttrLargeIcon : kAttrMiniIcon;
// type = size == B_LARGE_ICON ? LARGE_ICON_TYPE : MINI_ICON_TYPE;
//
// ret = file->GetAttrInfo(attrName, &ainfo);
// if (ret < B_OK)
// return ret;
//
// uint8 buffer[ainfo.size];
//
// ssize_t readResult = file->ReadAttr(attrName, type, 0, buffer, ainfo.size);
// if (readResult <= 0)
// return (status_t)readResult;
//
// if (result->ColorSpace() != B_CMAP8) {
// ret = BIconUtils::ConvertFromCMAP8(buffer, size, size, size, result);
// } else {
// result->SetBits(buffer, result->BitsLength(), 0, B_CMAP8);
// }
//
// return ret;
//#endif // B_APP_FILE_INFO_IS_FAST
}
+27 -3
View File
@@ -124,11 +124,11 @@ BColumn::InstantiateFromStream(BMallocIO *stream, bool endianSwap)
version = SwapInt32(version);
}
// PRINT(("validating key %x, version %d\n", key, version));
// PRINT(("validating key %x, version %d\n", key, version));
if (!ValidateStream(stream, key, version))
return 0;
// PRINT(("instantiating column, %s\n", endianSwap ? "endian swapping," : ""));
// PRINT(("instantiating column, %s\n", endianSwap ? "endian swapping," : ""));
BColumn *result = new BColumn(stream, endianSwap);
// sanity-check the resulting column
@@ -191,7 +191,7 @@ BColumn::ArchiveToStream(BMallocIO *stream) const
int32 version = kColumnStateArchiveVersion;
stream->Write(&version, sizeof(int32));
// PRINT(("ArchiveToStream column, key %x, version %d\n", key, version));
// PRINT(("ArchiveToStream column, key %x, version %d\n", key, version));
StringToStream(&fTitle, stream);
stream->Write(&fOffset, sizeof(float));
@@ -230,11 +230,13 @@ const char *kViewStatePrimarySortTypeName = "ViewState:fPrimarySortType";
const char *kViewStateSecondarySortAttrName = "ViewState:fSecondarySortAttr";
const char *kViewStateSecondarySortTypeName = "ViewState:fSecondarySortType";
const char *kViewStateReverseSortName = "ViewState:fReverseSort";
const char *kViewStateIconSizeName = "ViewState:fIconSize";
BViewState::BViewState()
{
fViewMode = kListMode;
fLastIconMode = 0;
fIconSize = 32;
fListOrigin.Set(0, 0);
fIconOrigin.Set(0, 0);
fPrimarySortAttr = AttrHashString(kAttrStatName, B_STRING_TYPE);
@@ -256,11 +258,13 @@ BViewState::BViewState(BMallocIO *stream, bool endianSwap)
stream->Read(&fSecondarySortAttr, sizeof(uint32));
stream->Read(&fSecondarySortType, sizeof(uint32));
stream->Read(&fReverseSort, sizeof(bool));
stream->Read(&fIconSize, sizeof(uint32));
if (endianSwap) {
PRINT(("endian swapping view state\n"));
fViewMode = B_SWAP_INT32(fViewMode);
fLastIconMode = B_SWAP_INT32(fLastIconMode);
fIconSize = B_SWAP_INT32(fIconSize);
swap_data(B_POINT_TYPE, &fListOrigin, sizeof(fListOrigin), B_SWAP_ALWAYS);
swap_data(B_POINT_TYPE, &fIconOrigin, sizeof(fIconOrigin), B_SWAP_ALWAYS);
fPrimarySortAttr = B_SWAP_INT32(fPrimarySortAttr);
@@ -268,6 +272,13 @@ BViewState::BViewState(BMallocIO *stream, bool endianSwap)
fPrimarySortType = B_SWAP_INT32(fPrimarySortType);
fSecondarySortType = B_SWAP_INT32(fSecondarySortType);
}
// assure a sane state
if (fIconSize < 16)
fIconSize = 16;
if (fIconSize > 64)
fIconSize = 64;
fStateNeedsSaving = false;
}
@@ -282,6 +293,13 @@ BViewState::BViewState(const BMessage &message)
message.FindInt32(kViewStateSecondarySortAttrName, (int32 *)&fSecondarySortAttr);
message.FindInt32(kViewStateSecondarySortTypeName, (int32 *)&fSecondarySortType);
message.FindBool(kViewStateReverseSortName, &fReverseSort);
message.FindInt32(kViewStateIconSizeName, (int32 *)&fIconSize);
// assure a sane state
if (fIconSize < 16)
fIconSize = 16;
if (fIconSize > 64)
fIconSize = 64;
fStateNeedsSaving = false;
}
@@ -304,6 +322,7 @@ BViewState::ArchiveToStream(BMallocIO *stream) const
stream->Write(&fSecondarySortAttr, sizeof(uint32));
stream->Write(&fSecondarySortType, sizeof(uint32));
stream->Write(&fReverseSort, sizeof(bool));
stream->Write(&fIconSize, sizeof(uint32));
}
@@ -321,6 +340,7 @@ BViewState::ArchiveToMessage(BMessage &message) const
message.AddInt32(kViewStateSecondarySortAttrName, static_cast<int32>(fSecondarySortAttr));
message.AddInt32(kViewStateSecondarySortTypeName, static_cast<int32>(fSecondarySortType));
message.AddBool(kViewStateReverseSortName, fReverseSort);
message.AddInt32(kViewStateIconSizeName, static_cast<int32>(fIconSize));
}
@@ -346,10 +366,12 @@ BViewState::InstantiateFromStream(BMallocIO *stream, bool endianSwap)
if ((result->fViewMode != kListMode
&& result->fViewMode != kIconMode
&& result->fViewMode != kMiniIconMode
&& result->fViewMode != kScaleIconMode
&& result->fViewMode != 0)
|| (result->fLastIconMode != kListMode
&& result->fLastIconMode != kIconMode
&& result->fLastIconMode != kMiniIconMode
&& result->fLastIconMode != kScaleIconMode
&& result->fLastIconMode != 0)) {
PRINT(("Bad data instantiating ViewState, view mode %x, lastIconMode %x\n",
@@ -384,10 +406,12 @@ BViewState::InstantiateFromMessage(const BMessage &message)
if ((result->fViewMode != kListMode
&& result->fViewMode != kIconMode
&& result->fViewMode != kMiniIconMode
&& result->fViewMode != kScaleIconMode
&& result->fViewMode != 0)
|| (result->fLastIconMode != kListMode
&& result->fLastIconMode != kIconMode
&& result->fLastIconMode != kMiniIconMode
&& result->fLastIconMode != kScaleIconMode
&& result->fLastIconMode != 0)) {
PRINT(("Bad data instantiating ViewState, view mode %x, lastIconMode %x\n",
+15
View File
@@ -99,6 +99,7 @@ class BViewState {
uint32 ViewMode() const;
uint32 LastIconMode() const;
uint32 IconSize() const;
BPoint ListOrigin() const;
BPoint IconOrigin() const;
uint32 PrimarySort() const;
@@ -109,6 +110,7 @@ class BViewState {
void SetViewMode(uint32);
void SetLastIconMode(uint32);
void SetIconSize(uint32);
void SetListOrigin(BPoint);
void SetIconOrigin(BPoint);
void SetPrimarySort(uint32);
@@ -123,6 +125,7 @@ class BViewState {
private:
uint32 fViewMode;
uint32 fLastIconMode;
uint32 fIconSize;
BPoint fListOrigin;
BPoint fIconOrigin;
uint32 fPrimarySortAttr;
@@ -211,6 +214,12 @@ BViewState::LastIconMode() const
return fLastIconMode;
}
inline uint32
BViewState::IconSize() const
{
return fIconSize;
}
inline BPoint
BViewState::ListOrigin() const
{
@@ -271,6 +280,12 @@ BViewState::SetLastIconMode(uint32 mode)
fLastIconMode = mode;
}
inline void
BViewState::SetIconSize(uint32 size)
{
fIconSize = size;
}
inline void
BViewState::SetListOrigin(BPoint newOrigin)
{
+2 -2
View File
@@ -334,10 +334,10 @@ BIconUtils::ConvertFromCMAP8(const uint8* src,
const rgb_color* colorMap = system_colors()->color_list;
for (uint32 y = 0; y < dstHeight; y++) {
for (uint32 y = 0; y < height; y++) {
uint32* d = (uint32*)dst;
const uint8* s = src;
for (uint32 x = 0; x < dstWidth; x++) {
for (uint32 x = 0; x < width; x++) {
const rgb_color c = colorMap[*s];
uint8 alpha = 255;
if (*s == B_TRANSPARENT_MAGIC_CMAP8)
+13 -4
View File
@@ -353,11 +353,16 @@ MIMEManager::HandleSetParam(BMessage *message)
if (!err)
err = message->FindString("file type", &fileType);
if (!err)
err = fDatabase.SetIconForType(type, fileType, data,
err = size == -1 ?
fDatabase.SetIconForType(type, fileType, data,
dataSize) :
fDatabase.SetIconForType(type, fileType, data,
dataSize, (icon_size)size);
} else {
if (!err)
err = fDatabase.SetIcon(type, data, dataSize,
err = size == -1 ?
fDatabase.SetIcon(type, data, dataSize) :
fDatabase.SetIcon(type, data, dataSize,
(icon_size)size);
}
break;
@@ -457,10 +462,14 @@ MIMEManager::HandleDeleteParam(BMessage *message)
if (!err)
err = message->FindString("file type", &fileType);
if (!err)
err = fDatabase.DeleteIconForType(type, fileType, (icon_size)size);
err = (size == -1) ?
fDatabase.DeleteIconForType(type, fileType) :
fDatabase.DeleteIconForType(type, fileType, (icon_size)size);
} else {
if (!err)
err = fDatabase.DeleteIcon(type, (icon_size)size);
err = (size == -1) ?
fDatabase.DeleteIcon(type) :
fDatabase.DeleteIcon(type, (icon_size)size);
}
break;
}