From a323457e9d861c2e5834e2c95fafb49bf7afc20d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 11 Jan 2008 18:06:15 +0000 Subject: [PATCH] The current version of the Theme Manager I wrote for zeta (yes I own that code, I wasn't asked for it in the first place, it only got some small changes). Missing ThemesPopupText stuff I used from zeta, will write a better, BAlert based one anyway. Still needs a container app an Haiku support. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23406 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- 3rdparty/themes/CompareMessages.cpp | 46 + 3rdparty/themes/DumpMessage.cpp | 237 +++ 3rdparty/themes/DumpMessage.h | 10 + 3rdparty/themes/FileUtils.cpp | 272 ++++ 3rdparty/themes/FileUtils.h | 17 + 3rdparty/themes/Jamfile | 40 + 3rdparty/themes/MakeScreenshot.cpp | 72 + 3rdparty/themes/ParseMessage.cpp | 465 ++++++ 3rdparty/themes/ParseMessage.h | 10 + 3rdparty/themes/ThemeAddonItem.cpp | 122 ++ 3rdparty/themes/ThemeAddonItem.h | 38 + 3rdparty/themes/ThemeInterfaceView.cpp | 713 +++++++++ 3rdparty/themes/ThemeInterfaceView.h | 77 + 3rdparty/themes/ThemeItem.cpp | 71 + 3rdparty/themes/ThemeItem.h | 24 + 3rdparty/themes/ThemeManager.cpp | 1320 +++++++++++++++++ 3rdparty/themes/ThemeManager.h | 132 ++ 3rdparty/themes/Themes.rdef | 98 ++ 3rdparty/themes/ThemesAddon.cpp | 229 +++ 3rdparty/themes/ThemesAddon.h | 97 ++ 3rdparty/themes/UITheme.h | 43 + 3rdparty/themes/ViewItem.cpp | 66 + 3rdparty/themes/ViewItem.h | 19 + 3rdparty/themes/addons/BackgroundsAddon.cpp | 266 ++++ 3rdparty/themes/addons/BeIDEAddon.cpp | 191 +++ .../themes/addons/DanoWindowDecorAddon.cpp | 157 ++ 3rdparty/themes/addons/DeskbarAddon.cpp | 151 ++ 3rdparty/themes/addons/EddieAddon.cpp | 147 ++ 3rdparty/themes/addons/PeAddon.cpp | 147 ++ 3rdparty/themes/addons/ScreensaverAddon.cpp | 180 +++ .../themes/addons/SoundplayColorAddon.cpp | 128 ++ 3rdparty/themes/addons/SoundsAddon.cpp | 200 +++ 3rdparty/themes/addons/TerminalAddon.cpp | 325 ++++ 3rdparty/themes/addons/UISettingsAddon.cpp | 202 +++ 3rdparty/themes/addons/WinampSkinAddon.cpp | 425 ++++++ 35 files changed, 6737 insertions(+) create mode 100644 3rdparty/themes/CompareMessages.cpp create mode 100644 3rdparty/themes/DumpMessage.cpp create mode 100644 3rdparty/themes/DumpMessage.h create mode 100644 3rdparty/themes/FileUtils.cpp create mode 100644 3rdparty/themes/FileUtils.h create mode 100644 3rdparty/themes/Jamfile create mode 100644 3rdparty/themes/MakeScreenshot.cpp create mode 100644 3rdparty/themes/ParseMessage.cpp create mode 100644 3rdparty/themes/ParseMessage.h create mode 100644 3rdparty/themes/ThemeAddonItem.cpp create mode 100644 3rdparty/themes/ThemeAddonItem.h create mode 100644 3rdparty/themes/ThemeInterfaceView.cpp create mode 100644 3rdparty/themes/ThemeInterfaceView.h create mode 100644 3rdparty/themes/ThemeItem.cpp create mode 100644 3rdparty/themes/ThemeItem.h create mode 100644 3rdparty/themes/ThemeManager.cpp create mode 100644 3rdparty/themes/ThemeManager.h create mode 100644 3rdparty/themes/Themes.rdef create mode 100644 3rdparty/themes/ThemesAddon.cpp create mode 100644 3rdparty/themes/ThemesAddon.h create mode 100644 3rdparty/themes/UITheme.h create mode 100644 3rdparty/themes/ViewItem.cpp create mode 100644 3rdparty/themes/ViewItem.h create mode 100644 3rdparty/themes/addons/BackgroundsAddon.cpp create mode 100644 3rdparty/themes/addons/BeIDEAddon.cpp create mode 100644 3rdparty/themes/addons/DanoWindowDecorAddon.cpp create mode 100644 3rdparty/themes/addons/DeskbarAddon.cpp create mode 100644 3rdparty/themes/addons/EddieAddon.cpp create mode 100644 3rdparty/themes/addons/PeAddon.cpp create mode 100644 3rdparty/themes/addons/ScreensaverAddon.cpp create mode 100644 3rdparty/themes/addons/SoundplayColorAddon.cpp create mode 100644 3rdparty/themes/addons/SoundsAddon.cpp create mode 100644 3rdparty/themes/addons/TerminalAddon.cpp create mode 100644 3rdparty/themes/addons/UISettingsAddon.cpp create mode 100644 3rdparty/themes/addons/WinampSkinAddon.cpp diff --git a/3rdparty/themes/CompareMessages.cpp b/3rdparty/themes/CompareMessages.cpp new file mode 100644 index 0000000000..bde953d586 --- /dev/null +++ b/3rdparty/themes/CompareMessages.cpp @@ -0,0 +1,46 @@ +/* + * function to compare 2 BMessages + */ +#include + +#include + +/* returns true if == */ +bool CompareMessages(BMessage &a, BMessage &b) +{ + void *cookie = NULL; + const char *name; + type_code code; + int32 count, i; + const void *adata, *bdata; + ssize_t asize, bsize; + + if (a.what != b.what) + return false; + while (a.GetNextName(&cookie, &name, &code, &count) == B_OK) { + for (i = 0; i < count; i++) { + if (a.FindData(name, code, i, &adata, &asize) != B_OK) + return false; + if (b.FindData(name, code, i, &bdata, &bsize) != B_OK) + return false; + if (asize != bsize) + return false; + if (memcmp(adata, bdata, asize)) + return false; + } + } + cookie = NULL; + /* cross compare */ + while (b.GetNextName(&cookie, &name, &code, &count) == B_OK) { + type_code acode; + int32 acount; + if (a.GetInfo(name, &acode, &acount) < B_OK) + return false; + if (code != acode) + return false; + if (count != acount) + return false; + } + return true; +} + diff --git a/3rdparty/themes/DumpMessage.cpp b/3rdparty/themes/DumpMessage.cpp new file mode 100644 index 0000000000..4ff75a073e --- /dev/null +++ b/3rdparty/themes/DumpMessage.cpp @@ -0,0 +1,237 @@ +#include +#include +#include +#include +#include +#include +#include "DumpMessage.h" + +//#define WHAT_ALWAYS_HEX 1 + +const char *msg_header_comment = "// new BMessage\n"; // avoids mime to think it's a .bmp ("BM") + +status_t HexDumpToStream(const void *data, size_t len, BDataIO &stream, const char *prefix = NULL) +{ + const unsigned char *p = (unsigned char *)data; + char buffer[100]; + size_t i, j; + for (i=0; i= len) + sprintf(buffer, " "); + //else if (p[i+j] < 255 && p[i+j] >= 0x20) + else if (isalpha(p[i+j])) + sprintf(buffer, "%c", p[i+j]); + else + sprintf(buffer, "."); + stream.Write(buffer, 1); + } + sprintf(buffer, "'\n"); + stream.Write(buffer, strlen(buffer)); + } + return B_OK; +} + +/* look up human readable names from an other BMessage */ +bool LookUpFieldName(const char **name, const char *field_name, BMessage *names) +{ + if (names == NULL) + return false; + if (names->FindString(field_name, name) == B_OK) + return true; + return false; +} + +status_t DumpMessageToStream(BMessage *message, BDataIO &stream, int tabCount, BMessage *names) +{ + int32 index; + void *cookie = NULL; + const char *field_name; + type_code field_code; + int32 field_count; + char buffer[80]; + char tabs[20]; + const char *easy_name; + + if (message == NULL) + return EINVAL; + + if (tabCount < 1) + stream.Write(msg_header_comment, strlen(msg_header_comment)); + + memset(tabs, '\t', (++tabCount) + 1); + tabs[tabCount+1] = '\0'; + //tabCount; + +#ifndef WHAT_ALWAYS_HEX + if ( isalnum(message->what & 0x0ff) && + isalnum((message->what >> 8) & 0x0ff) && + isalnum((message->what >> 16) & 0x0ff) && + isalnum((message->what >> 24) & 0x0ff)) + sprintf(buffer, "BMessage('%c%c%c%c') {\n", + (char)(message->what >> 24) & 0x0ff, + (char)(message->what >> 16) & 0x0ff, + (char)(message->what >> 8) & 0x0ff, + (char)message->what & 0x0ff); + else +#endif + sprintf(buffer, "BMessage(0x%08lx) {\n", message->what); +// stream.Write(tabs+2, tabCount-2); + stream.Write(buffer, strlen(buffer)); + + while (message->GetNextName(&cookie, + &field_name, + &field_code, + &field_count) == B_OK) { + if (LookUpFieldName(&easy_name, field_name, names)) { + stream.Write(tabs+1, tabCount); + stream.Write("// ", 3); + stream.Write(easy_name, strlen(easy_name)); + stream.Write("\n", 1); + } + + for (index=0; index < field_count; index++) { + stream.Write(tabs+1, tabCount); + stream.Write(field_name, strlen(field_name)); + if (field_count > 1) { + sprintf(buffer, "[%ld]", index); + stream.Write(buffer, strlen(buffer)); + } + stream.Write(" = ", 3); + + switch (field_code) { + case 'MSGG': + { + BMessage m; + if (message->FindMessage(field_name, index, &m) >= B_OK) + DumpMessageToStream(&m, stream, tabCount, names); + } + break; + case 'FONt': + { + BFont f; + if (message->FindFlat(field_name, index, &f) >= B_OK) + stream << f; + stream.Write("\n", 1); + } + break; + case B_RGB_COLOR_TYPE: + { + rgb_color c; + if (message->FindRGBColor(field_name, index, &c) >= B_OK) { + sprintf(buffer, "rgb_color(%d,%d,%d,%d)", + c.red, c.green, c.blue, c.alpha); + stream.Write(buffer, strlen(buffer)); + } + stream.Write("\n", 1); + } + break; + case B_BOOL_TYPE: + { + bool value; + if (message->FindBool(field_name, index, &value) >= B_OK) { + sprintf(buffer, "bool(%s)", value?"true":"false"); + stream.Write(buffer, strlen(buffer)); + } + stream.Write("\n", 1); + } + break; + case B_INT32_TYPE: + { + int32 value; + if (message->FindInt32(field_name, index, &value) >= B_OK) { +#if 1 + if (value == 0) + sprintf(buffer, "int32(0 or (nil))"); + else +#endif +// sprintf(buffer, "int32(%d)", value); + sprintf(buffer, "int32(%ld or 0x%lx)", value, value); + stream.Write(buffer, strlen(buffer)); + } + stream.Write("\n", 1); + } + break; + case B_FLOAT_TYPE: + { + float value; + if (message->FindFloat(field_name, index, &value) >= B_OK) { + sprintf(buffer, "float(%f)", value); + stream.Write(buffer, strlen(buffer)); + } + stream.Write("\n", 1); + } + break; + case B_STRING_TYPE: + { + const char *value; + if (message->FindString(field_name, index, &value) >= B_OK) { + BString str(value); + str.CharacterEscape("\\\"\n", '\\'); + //sprintf(buffer, "string(\"%s\", %ld bytes)", str.String(), strlen(value)); + // DO NOT use buffer! + str.Prepend("string(\""); + str << "\", " << strlen(value) << " bytes)"; + stream.Write(str.String(), strlen(str.String())); + } + stream.Write("\n", 1); + } + break; + case B_POINT_TYPE: + { + BPoint value; + if (message->FindPoint(field_name, index, &value) >= B_OK) { + sprintf(buffer, "BPoint(%1.1f, %1.1f)", value.x, value.y); + stream.Write(buffer, strlen(buffer)); + } + stream.Write("\n", 1); + } + break; + default: + { + const void *data; + ssize_t numBytes = 0; + if (message->FindData(field_name, field_code, index, &data, &numBytes) != B_OK) { + //stream.Write("\n", 1); + break; + } + + if ( isalnum(field_code & 0x0ff) && + isalnum((field_code >> 8) & 0x0ff) && + isalnum((field_code >> 16) & 0x0ff) && + isalnum((field_code >> 24) & 0x0ff)) + sprintf(buffer, "'%c%c%c%c' %ld bytes:\n", + (char)(field_code >> 24) & 0x0ff, + (char)(field_code >> 16) & 0x0ff, + (char)(field_code >> 8) & 0x0ff, + (char)field_code & 0x0ff, + numBytes); + else + sprintf(buffer, "0x%08lx %ld bytes:\n", field_code, numBytes); + stream.Write(buffer, strlen(buffer)); + stream.Write("\n", 1); + HexDumpToStream(data, numBytes, stream, tabs); + } + break; + } + } + } + stream.Write(tabs+2, tabCount-1); + stream.Write("}\n", 2); + return B_OK; +} + diff --git a/3rdparty/themes/DumpMessage.h b/3rdparty/themes/DumpMessage.h new file mode 100644 index 0000000000..c1431d62ce --- /dev/null +++ b/3rdparty/themes/DumpMessage.h @@ -0,0 +1,10 @@ +#ifndef _DUMP_MESSAGE_H +#define _DUMP_MESSAGE_H + +class BMessage; +class BDataIO; + +status_t DumpMessageToStream(BMessage *message, BDataIO &stream, int tabCount = 0, BMessage *names = NULL); + +#endif /* _DUMP_MESSAGE_H */ + diff --git a/3rdparty/themes/FileUtils.cpp b/3rdparty/themes/FileUtils.cpp new file mode 100644 index 0000000000..5ad8f972fd --- /dev/null +++ b/3rdparty/themes/FileUtils.cpp @@ -0,0 +1,272 @@ +#include "FileUtils.h" +#include +#include +#include +#include +#include + + +// some private font information structs +namespace BPrivate { + +typedef struct font_folder_info { + //char name[256]; + char *name; + uint32 flags; +} font_folder_info; +typedef struct font_file_info { + char *name; + uint32 flags; + font_family family; + font_style style; + uint32 dummy; +} font_file_info; + +}; + +using namespace BPrivate; + +// this is PRIVATE to libbe and NOT in R5!!! +extern long _count_font_folders_(void); +extern long _count_font_files_(long); +extern status_t _get_nth_font_file_(long, font_file_info **); +extern status_t _get_nth_font_folder_(long, font_folder_info **); + +status_t find_font_file(entry_ref *to, font_family family, font_style style, float size) +{ + status_t err; + long i, fontcount, foldercount; + font_file_info *ffi; + font_folder_info *fdi; + bool found = false; + (void)size; + + fontcount = _count_font_files_(0); + for (i = 0; i < fontcount; i++) { + err = _get_nth_font_file_(i, &ffi); + if (err) + continue; + if (strcmp(ffi->family, family) || strcmp(ffi->style, style)) + continue; + found = true; + break; + } + if (!found) + return ENOENT; + foldercount = _count_font_folders_(); + for (i = 0; i < fontcount; i++) { + err = _get_nth_font_folder_(i, &fdi); + if (err) + continue; + BPath ffile(fdi->name); + ffile.Append(ffi->name); + printf("find_font_file: looking for '%s' in '%s'\n", ffi->name, fdi->name); + BEntry ent(ffile.Path()); + if (ent.InitCheck()) + continue; + printf("find_font_file: found\n."); + return ent.GetRef(to); + } + return ENOENT; +} + +#define _BORK(_t) \ + err = find_directory(_t, &path); \ + if (!err && (s = dir->FindFirst(path.Path())) >= 0) { \ + printf("found %s\n", #_t); \ + dir->Remove(s, strlen(path.Path()) - s); \ + BString tok(#_t); \ + tok.Prepend("${"); \ + tok.Append("}"); \ + dir->Insert(tok, s); \ + return B_OK; \ + } \ + +status_t escape_find_directory(BString *dir) +{ + status_t err; + BPath path; + int32 s; + + _BORK(B_DESKTOP_DIRECTORY); + _BORK(B_TRASH_DIRECTORY); + //_BORK(B_ROOT_DIRECTORY); + + //_BORK(B_BEOS_BOOT_DIRECTORY); + _BORK(B_BEOS_FONTS_DIRECTORY); + _BORK(B_BEOS_LIB_DIRECTORY); + _BORK(B_BEOS_SERVERS_DIRECTORY); + _BORK(B_BEOS_APPS_DIRECTORY); + _BORK(B_BEOS_BIN_DIRECTORY); + _BORK(B_BEOS_ETC_DIRECTORY); + _BORK(B_BEOS_DOCUMENTATION_DIRECTORY); + _BORK(B_BEOS_PREFERENCES_DIRECTORY); + _BORK(B_BEOS_TRANSLATORS_DIRECTORY); + _BORK(B_BEOS_MEDIA_NODES_DIRECTORY); + _BORK(B_BEOS_SOUNDS_DIRECTORY); + // not in the declared order, so others are picked first + _BORK(B_BEOS_ADDONS_DIRECTORY); + _BORK(B_BEOS_SYSTEM_DIRECTORY); + _BORK(B_BEOS_DIRECTORY); + + _BORK(B_USER_BOOT_DIRECTORY); + _BORK(B_USER_FONTS_DIRECTORY); + _BORK(B_USER_LIB_DIRECTORY); + _BORK(B_USER_SETTINGS_DIRECTORY); + _BORK(B_USER_DESKBAR_DIRECTORY); + _BORK(B_USER_PRINTERS_DIRECTORY); + _BORK(B_USER_TRANSLATORS_DIRECTORY); + _BORK(B_USER_MEDIA_NODES_DIRECTORY); + _BORK(B_USER_SOUNDS_DIRECTORY); + // + _BORK(B_USER_ADDONS_DIRECTORY); + _BORK(B_USER_CONFIG_DIRECTORY); + _BORK(B_USER_DIRECTORY); + + // same for the whole block, prefer user over common + _BORK(B_COMMON_BOOT_DIRECTORY); + _BORK(B_COMMON_FONTS_DIRECTORY); + _BORK(B_COMMON_LIB_DIRECTORY); + _BORK(B_COMMON_SERVERS_DIRECTORY); + _BORK(B_COMMON_BIN_DIRECTORY); + _BORK(B_COMMON_ETC_DIRECTORY); + _BORK(B_COMMON_DOCUMENTATION_DIRECTORY); + _BORK(B_COMMON_SETTINGS_DIRECTORY); + _BORK(B_COMMON_DEVELOP_DIRECTORY); + _BORK(B_COMMON_LOG_DIRECTORY); + _BORK(B_COMMON_SPOOL_DIRECTORY); + _BORK(B_COMMON_TEMP_DIRECTORY); + _BORK(B_COMMON_VAR_DIRECTORY); + _BORK(B_COMMON_TRANSLATORS_DIRECTORY); + _BORK(B_COMMON_MEDIA_NODES_DIRECTORY); + _BORK(B_COMMON_SOUNDS_DIRECTORY); + // + _BORK(B_COMMON_ADDONS_DIRECTORY); + _BORK(B_COMMON_SYSTEM_DIRECTORY); + _BORK(B_COMMON_DIRECTORY); + + _BORK(B_APPS_DIRECTORY); + _BORK(B_PREFERENCES_DIRECTORY); + _BORK(B_UTILITIES_DIRECTORY); + + return B_OK; +} +#undef _BORK + +#define _BORK(_t) \ + if (tok == #_t) { \ + err = find_directory(_t, &path); \ + if (err) return err; \ + dir->Remove(s, e - s + 1); \ + dir->Insert(path.Path(), s); \ + return B_OK; \ + } \ + + +status_t unescape_find_directory(BString *dir) +{ + status_t err; + int32 s, e; + BString tok; + BPath path; + s = dir->FindFirst("${"); + if (s < 0) + return B_OK; + e = dir->FindFirst("}", s); + if (e < 0) + return B_OK; + dir->CopyInto(tok, s + 2, e - s - 2); + //printf("tok '%s'\n", tok.String()); + + _BORK(B_DESKTOP_DIRECTORY); + _BORK(B_TRASH_DIRECTORY); + _BORK(B_ROOT_DIRECTORY); + + _BORK(B_BEOS_DIRECTORY); + _BORK(B_BEOS_SYSTEM_DIRECTORY); + _BORK(B_BEOS_ADDONS_DIRECTORY); + _BORK(B_BEOS_BOOT_DIRECTORY); + _BORK(B_BEOS_FONTS_DIRECTORY); + _BORK(B_BEOS_LIB_DIRECTORY); + _BORK(B_BEOS_SERVERS_DIRECTORY); + _BORK(B_BEOS_APPS_DIRECTORY); + _BORK(B_BEOS_BIN_DIRECTORY); + _BORK(B_BEOS_ETC_DIRECTORY); + _BORK(B_BEOS_DOCUMENTATION_DIRECTORY); + _BORK(B_BEOS_PREFERENCES_DIRECTORY); + _BORK(B_BEOS_TRANSLATORS_DIRECTORY); + _BORK(B_BEOS_MEDIA_NODES_DIRECTORY); + _BORK(B_BEOS_SOUNDS_DIRECTORY); + + _BORK(B_COMMON_DIRECTORY); + _BORK(B_COMMON_SYSTEM_DIRECTORY); + _BORK(B_COMMON_ADDONS_DIRECTORY); + _BORK(B_COMMON_BOOT_DIRECTORY); + _BORK(B_COMMON_FONTS_DIRECTORY); + _BORK(B_COMMON_LIB_DIRECTORY); + _BORK(B_COMMON_SERVERS_DIRECTORY); + _BORK(B_COMMON_BIN_DIRECTORY); + _BORK(B_COMMON_ETC_DIRECTORY); + _BORK(B_COMMON_DOCUMENTATION_DIRECTORY); + _BORK(B_COMMON_SETTINGS_DIRECTORY); + _BORK(B_COMMON_DEVELOP_DIRECTORY); + _BORK(B_COMMON_LOG_DIRECTORY); + _BORK(B_COMMON_SPOOL_DIRECTORY); + _BORK(B_COMMON_TEMP_DIRECTORY); + _BORK(B_COMMON_VAR_DIRECTORY); + _BORK(B_COMMON_TRANSLATORS_DIRECTORY); + _BORK(B_COMMON_MEDIA_NODES_DIRECTORY); + _BORK(B_COMMON_SOUNDS_DIRECTORY); + + _BORK(B_USER_DIRECTORY); + _BORK(B_USER_CONFIG_DIRECTORY); + _BORK(B_USER_ADDONS_DIRECTORY); + _BORK(B_USER_BOOT_DIRECTORY); + _BORK(B_USER_FONTS_DIRECTORY); + _BORK(B_USER_LIB_DIRECTORY); + _BORK(B_USER_SETTINGS_DIRECTORY); + _BORK(B_USER_DESKBAR_DIRECTORY); + _BORK(B_USER_PRINTERS_DIRECTORY); + _BORK(B_USER_TRANSLATORS_DIRECTORY); + _BORK(B_USER_MEDIA_NODES_DIRECTORY); + _BORK(B_USER_SOUNDS_DIRECTORY); + + _BORK(B_APPS_DIRECTORY); + _BORK(B_PREFERENCES_DIRECTORY); + _BORK(B_UTILITIES_DIRECTORY); + + return B_OK; +} + +#undef _BORK + +// copy a file including its attributes +#define BUFF_SZ 1024*1024 +status_t copy_file(entry_ref *ref, const char *to) +{ + char *buff; + status_t err = B_OK; + //off_t off; + //size_t got; + (void)ref; (void)to; + + buff = (char *)malloc(BUFF_SZ); + // XXX: TODO + + + free(buff); + return err; +} + + +int testhook() +{ + status_t err; + BString str("/boot/home/config/fonts/ttfonts/toto.ttf"); + err = escape_find_directory(&str); + printf("error 0x%08lx %s\n", err, str.String()); + err = unescape_find_directory(&str); + printf("error 0x%08lx %s\n", err, str.String()); + return 0; + return 1; +} diff --git a/3rdparty/themes/FileUtils.h b/3rdparty/themes/FileUtils.h new file mode 100644 index 0000000000..8d734ad48e --- /dev/null +++ b/3rdparty/themes/FileUtils.h @@ -0,0 +1,17 @@ +#ifndef _FILE_UTILS_H +#define _FILE_UTILS_H + +#include +#include + +// find the font file corresponding to family/style +extern status_t find_font_file(entry_ref *to, font_family family, font_style style, float size =-1); + +// replace part of paths by symbolic strings "${B_FOO_DIRECTORY}" +extern status_t escape_find_directory(BString *dir); +extern status_t unescape_find_directory(BString *dir); + +// copy a file including its attributes +extern status_t copy_file(entry_ref *ref, const char *to); + +#endif /* _FILE_UTILS_H */ diff --git a/3rdparty/themes/Jamfile b/3rdparty/themes/Jamfile new file mode 100644 index 0000000000..e622d14dd3 --- /dev/null +++ b/3rdparty/themes/Jamfile @@ -0,0 +1,40 @@ +SubDir HAIKU_TOP 3rdparty themes ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) 3rdparty themes addons ] ; + +local addonSources ; +addonSources = + BackgroundsAddon.cpp + BeIDEAddon.cpp + DanoWindowDecorAddon.cpp + DeskbarAddon.cpp + EddieAddon.cpp + PeAddon.cpp + ScreensaverAddon.cpp + SoundplayColorAddon.cpp + SoundsAddon.cpp + TerminalAddon.cpp + UISettingsAddon.cpp + WinampSkinAddon.cpp +; + +Application <3rdparty>Themes : + CompareMessages.cpp + DumpMessage.cpp + FileUtils.cpp + MakeScreenshot.cpp + ParseMessage.cpp + ThemeAddonItem.cpp + ThemeInterfaceView.cpp + ThemeItem.cpp + ThemeManager.cpp + ThemePopupTextWindow.cpp + ThemesAddon.cpp + ViewItem.cpp + $(addonSources) + : be media translation $(TARGET_NETAPI_LIB) $(TARGET_LIBSTDC++) + : Themes.rdef +; + diff --git a/3rdparty/themes/MakeScreenshot.cpp b/3rdparty/themes/MakeScreenshot.cpp new file mode 100644 index 0000000000..f78478cc3e --- /dev/null +++ b/3rdparty/themes/MakeScreenshot.cpp @@ -0,0 +1,72 @@ +/* + * MakeScreenshot function + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// PRIVATE: in libzeta for now. +extern status_t ScaleBitmap(const BBitmap& inBitmap, BBitmap& outBitmap); + +status_t MakeScreenshot(BBitmap **here) +{ + status_t err; + BScreen bs; + BWindow *win; + BBitmap *shot; + BBitmap *scaledBmp = NULL; + be_app->Lock(); + win = be_app->WindowAt(0); + if (win) { + win->Lock(); + win->Hide(); + win->Unlock(); + } + snooze(500000); + err = bs.GetBitmap(&shot); + if (!err) { + BRect scaledBounds(0,0,640-1,480-1); + scaledBmp = new BBitmap(scaledBounds, B_BITMAP_ACCEPTS_VIEWS, B_RGB32/*shot->ColorSpace()*/); + err = scaledBmp->InitCheck(); + if (!err) { + err = ScaleBitmap(*shot, *scaledBmp); + if (err) { + // filtered scaling didn't work, do it manually + BView *v = new BView(scaledBounds, "scaleview", B_FOLLOW_NONE, 0); + scaledBmp->AddChild(v); + v->LockLooper(); + v->DrawBitmap(shot); + v->Sync(); + v->UnlockLooper(); + scaledBmp->RemoveChild(v); + delete v; + err = B_OK; + } + } + delete shot; + } + + if (win) { + win->Lock(); + win->Show(); + win->Unlock(); + } + be_app->Unlock(); + + if (err) + return err; + + *here = scaledBmp; + + return B_OK; +} diff --git a/3rdparty/themes/ParseMessage.cpp b/3rdparty/themes/ParseMessage.cpp new file mode 100644 index 0000000000..4785dfd671 --- /dev/null +++ b/3rdparty/themes/ParseMessage.cpp @@ -0,0 +1,465 @@ +#include +#include +#include +#include +#include +#include +#include +#include "DumpMessage.h" + +#define MAX_TEXT_LINE_INPUT_SIZE 4096 + +class TextLineInputDataIO : public BDataIO { +public: + TextLineInputDataIO(BDataIO *input); + ssize_t Read(void *buffer, size_t size); + char GetByte(); + ssize_t Write(const void *data, size_t len); + status_t FillTextLine(); +private: + BDataIO *fIn; + char fTextLine[MAX_TEXT_LINE_INPUT_SIZE]; + char *fCurrent; /* current char in fTextLine */ + int fLeft; +}; + +TextLineInputDataIO::TextLineInputDataIO(BDataIO *input) +{ + fIn = input; + fCurrent = fTextLine; + fLeft = 0; +} + +char TextLineInputDataIO::GetByte() +{ + char buf[2]; + if (Read(buf, 1) == 1) + return buf[0]; + return 0; +} +ssize_t TextLineInputDataIO::Read(void *buffer, size_t size) +{ + size = MIN(size, (size_t)fLeft); + if (size <= 0) + return 0; + fLeft -= size; + memcpy(buffer, fCurrent, size); + fCurrent += size; + return size; +} + +ssize_t TextLineInputDataIO::Write(const void *, size_t) +{ + return EINVAL; +} + +/* + * \return 1 useful line, 0 blank lin or comment, <0 error + */ +status_t TextLineInputDataIO::FillTextLine() +{ + status_t err = ENOENT; + + fCurrent = fTextLine; + while ((fCurrent < (fTextLine + MAX_TEXT_LINE_INPUT_SIZE)) + && ((err = fIn->Read(fCurrent, 1)) > 0) + && *fCurrent != '\n') + fCurrent++; + *fCurrent = '\0'; + fLeft = fCurrent - fTextLine; + fCurrent = fTextLine; +// printf("line: '%s'\n", fCurrent); + + if (err < B_OK) + return err; + if (err == 0) + return -1; // EOF + if (strlen(fCurrent) && strncmp(fCurrent, "//", 2)) + return 1; + return 0; +} + +status_t ParseHexDumpFromStream(const void **, size_t *, BDataIO &) +{ + return B_OK; +} + +status_t Parse_Msg_bool(BMessage *msg, TextLineInputDataIO *st, char *name) +{ + char c; + bool v = false; + c = st->GetByte(); + if (c == '1' || c == 't') + v = true; + msg->AddBool(name, v); + return B_OK; +} + +status_t Parse_Msg_int32(BMessage *msg, TextLineInputDataIO *st, char *name) +{ + char c; + int64 v = 0; // to forget about overflow + bool opposite = false; + while (isdigit(c = st->GetByte()) || c == '-') { + if (c == '-') + opposite = true; + else + v = v * 10 + (c - '0'); + } + if (c == 'x' && v == 0) { + // hex + while (isalnum(c = st->GetByte())) { + v = v * 16; + if (isdigit(c)) + v += (c - '0'); + else if (isupper(c)) + v += (c - 'A' + 10); + else + v += (c - 'a' + 10); + } + } + if (opposite) + v = -v; + msg->AddInt32(name, (int32)v); + return B_OK; +} + +status_t Parse_Msg_float(BMessage *msg, TextLineInputDataIO *st, char *name) +{ + char c; + float v = 0; + int32 div = 1; + bool opposite = false; + while (isdigit(c = st->GetByte()) || c == '-') { + if (c == '-') + opposite = true; + else + v = v * 10 + (c - '0'); + } + if (c == '.') + while (isdigit(c = st->GetByte())) { + div *= 10; + v += (float)(c - '0') / div; + } + if (opposite) + v = -v; + msg->AddFloat(name, v); + return B_OK; +} + +status_t Parse_Msg_string(BMessage *msg, TextLineInputDataIO *st, char *name) +{ + char c; + BString v; + bool esc = false; + if (st->GetByte() != '"') + return EINVAL; + while ((c = st->GetByte()) || esc) { + if (esc && !c) { + v << '\n'; + esc = false; + st->FillTextLine(); + continue; + } + if (esc) { + esc = false; + } else if (c == '\\') { + esc = true; + continue; + } else if (c == '"') + break; + v << c; + } + msg->AddString(name, v.String()); + return B_OK; +} + +status_t Parse_Msg_rgb_color(BMessage *msg, TextLineInputDataIO *st, char *name) +{ + char c; + rgb_color v = {0, 0, 0, 0}; + bool has_alpha = false; + while (isdigit(c = st->GetByte())) + v.red = v.red * 10 + (c - '0'); + while (isdigit(c = st->GetByte())) + v.green = v.green * 10 + (c - '0'); + while (isdigit(c = st->GetByte())) + v.blue = v.blue * 10 + (c - '0'); + while (isdigit(c = st->GetByte())) { + has_alpha = true; + v.alpha = v.alpha * 10 + (c - '0'); + } + if (!has_alpha) + v.alpha = 255; + //msg->AddRGBColor(name, v); + msg->AddData(name, (type_code)'RGBC', &v, 4); + return B_OK; +} + +float Parse_Msg_read_float(TextLineInputDataIO *st) +{ + char c; + int i; + float f = 0.0F; + float scale = 0.1F; + bool isNegative = false; + + i=0; + while ((c = st->GetByte())) + { + if (isdigit(c)) + { + f = f * 10 + c - '0'; + } + else if (c == '-') + { + isNegative = true; + } + else + { + break; + } + } + while (isdigit(c = st->GetByte())) { + f += (c - '0') * scale; + scale /= 10; + } + + if (isNegative) + f *= -1.0; + + return f; +} + +status_t Parse_Msg_BFont(BMessage *msg, TextLineInputDataIO *st, char *name) +{ + char c; + int i; + font_family ff; + font_style fs; + float size = 0.0f; + BFont f; + + i=0; + while ((c = st->GetByte()) != '/') + ff[i++] = c; + ff[i] = '\0'; + i=0; + while ((c = st->GetByte()) != '/') + fs[i++] = c; + fs[i] = '\0'; + + size = Parse_Msg_read_float(st); + +//printf("fam '%s', style '%s'\n", ff, fs); + f.SetFamilyAndStyle(ff, fs); + f.SetSize(size); + //f.PrintToStream(); + msg->AddFlat(name, &f); + return B_OK; +} + +status_t Parse_Msg_BPoint(BMessage *msg, TextLineInputDataIO *st, char *name) +{ + char c; + int i; + BPoint p; + + i=0; + p.x = Parse_Msg_read_float(st); + if ((c = st->GetByte()) != ' ') + return B_ERROR; + p.y = Parse_Msg_read_float(st); + +//printf("BPoint(%f, %f)\n", p.x, p.y); + msg->AddPoint(name, p); + return B_OK; +} + +status_t Parse_Msg_HexDump(BMessage *msg, TextLineInputDataIO *st, char *name, int32 field_code) +{ + (void)msg; + (void)st; + (void)name; + (void)field_code; + return B_OK; +} + +status_t Parse_Msg_BMessage(BMessage *msg, TextLineInputDataIO *st) +{ + char field_name[B_FIELD_NAME_LENGTH]; + char field_code_name[B_FIELD_NAME_LENGTH]; + type_code field_code; + int32 index; // unused ! + int i = 0; + char c; + status_t err; + + c = st->GetByte(); + if (c == '\'') { + msg->what = ((st->GetByte() << 24) & 0xff000000) | + ((st->GetByte() << 16) & 0x0ff0000) | + ((st->GetByte() << 8) & 0x0ff00) | + (st->GetByte() & 0x0ff); + if (st->GetByte() != '\'') + return EINVAL; + if (st->GetByte() != ')') + return EINVAL; + } else if (c == '0') { + if (st->GetByte() != 'x') + return EINVAL; + while (isalnum(c = st->GetByte())) { + //printf("[%c]", c); + if (c >= 'a' && c <= 'f') + msg->what = (msg->what << 4) | (c - 'a' + 10); + else if (c >= 'A' && c <= 'F') + msg->what = (msg->what << 4) | (c - 'A' + 10); + else if (c >= '0' && c <= '9') + msg->what = (msg->what << 4) | (c - '0'); + else return EINVAL; + } + } else + return EINVAL; + if (st->GetByte() != ' ') + return EINVAL; + if (st->GetByte() != '{') + return EINVAL; + //printf("what=0x%08lx\n", msg->what); + + while ((err = st->FillTextLine()) >= 0) { + if (err == 0) + continue; + + + do + c = field_name[0] = st->GetByte(); + while (c == '\t' || c == ' '); + + for (i = 1; (c = st->GetByte()) && (c != '=') && (c != '['); i++) + field_name[i] = c; + field_name[i] = '\0'; + if (i>1 && field_name[i-1] == ' ') + field_name[i-1] = '\0'; + + if (!strcmp(field_name, "}")) + return B_OK; + + if (c == '[') { + for (index = 0; (c = st->GetByte()) && isdigit(c); index = index * 10 + c - '0'); + for (; (c = st->GetByte()) && (c != '='); ); + //PRINT(("index ignored (%ld) for item '%s'\n", index, field_name)); + } + + i = 0; + do + c = field_code_name[0] = st->GetByte(); + while (c && (c == '\t' || c == ' ')); + +// while ((field_code_name[++i] = st->GetByte()) != '('); + for (i = 1; (c = st->GetByte()) && (c != '(') && (c != ' '); i++) + field_code_name[i] = c; + field_code_name[i] = '\0'; + + if (!strncmp(field_name, "//", 2)) + continue; + +// printf("name:'%s' code'%s'\n", field_name, field_code_name); + + if (!strcmp(field_code_name, "BMessage")) { + BMessage *m; + m = new BMessage; + err = Parse_Msg_BMessage(m, st); + if (err < B_OK) { + delete m; + return err; + } + msg->AddMessage(field_name, m); + } else if (!strcmp(field_code_name, "bool")) { + err = Parse_Msg_bool(msg, st, field_name); + if (err < B_OK) + return err; + } else if (!strcmp(field_code_name, "int32")) { + err = Parse_Msg_int32(msg, st, field_name); + if (err < B_OK) + return err; + } else if (!strcmp(field_code_name, "float")) { + err = Parse_Msg_float(msg, st, field_name); + if (err < B_OK) + return err; + } else if (!strcmp(field_code_name, "string")) { + err = Parse_Msg_string(msg, st, field_name); + if (err < B_OK) + return err; + } else if (!strcmp(field_code_name, "rgb_color")) { + err = Parse_Msg_rgb_color(msg, st, field_name); + if (err < B_OK) + return err; + } else if (!strcmp(field_code_name, "BPoint")) { + err = Parse_Msg_BPoint(msg, st, field_name); + if (err < B_OK) + return err; + } else if (!strcmp(field_code_name, "BFont")) { + err = Parse_Msg_BFont(msg, st, field_name); + if (err < B_OK) + return err; + } else if (!strncmp(field_code_name, "'", 1)) { + field_code = ((st->GetByte() << 24) & 0xff000000) | + ((st->GetByte() << 16) & 0x0ff0000) | + ((st->GetByte() << 8) & 0x0ff00) | + (st->GetByte() & 0x0ff); + err = Parse_Msg_HexDump(msg, st, field_name, field_code); + if (err < B_OK) + return err; + } else + return EINVAL; + + } + return B_OK; +} + +status_t ParseMessageFromStream(BMessage **message, BDataIO &stream) +{ +// char field_name[B_FIELD_NAME_LENGTH]; + char field_code_name[B_FIELD_NAME_LENGTH]; +// type_code field_code; +// int32 field_count; + int i = 0; + char c; + status_t err; + + if (message == NULL) + return EINVAL; + + BMessage *msg = *message = new BMessage; + TextLineInputDataIO *st = new TextLineInputDataIO(&stream); + while ((err = st->FillTextLine()) == 0); + if (err < 0) + return EINVAL; + + + i = 0; + do + c = field_code_name[0] = st->GetByte(); + while (c && (c == '\t' || c == ' ')); + +// while ((field_code_name[++i] = st->GetByte()) != '('); + for (i = 1; (c = st->GetByte()) && (c != '('); i++) + field_code_name[i] = c; + field_code_name[i] = '\0'; + + + //printf("code'%s'\n", field_code_name); + if (strcmp(field_code_name, "BMessage")) { + PRINT(("bad code name (%s)\n", field_code_name)); + return EINVAL; + } + err = Parse_Msg_BMessage(msg, st); + if (err < B_OK) { + delete msg; + *message = NULL; + return B_ERROR; + } + + return B_OK; +} + diff --git a/3rdparty/themes/ParseMessage.h b/3rdparty/themes/ParseMessage.h new file mode 100644 index 0000000000..e9c9876fa9 --- /dev/null +++ b/3rdparty/themes/ParseMessage.h @@ -0,0 +1,10 @@ +#ifndef _PARSE_MESSAGE_H +#define _PARSE_MESSAGE_H + +class BMessage; +class BDataIO; + +status_t ParseMessageFromStream(BMessage **message, BDataIO &stream); + +#endif /* _PARSE_MESSAGE_H */ + diff --git a/3rdparty/themes/ThemeAddonItem.cpp b/3rdparty/themes/ThemeAddonItem.cpp new file mode 100644 index 0000000000..fcf0a82f34 --- /dev/null +++ b/3rdparty/themes/ThemeAddonItem.cpp @@ -0,0 +1,122 @@ +#include "ThemeAddonItem.h" +#include "ThemeInterfaceView.h" +#include "ThemeManager.h" +#include "UITheme.h" +#include +#include +#include +#include +#include +#include + +#define CTRL_OFF_X 40 +#define CTRL_OFF_Y 25 +#define CTRL_SPACING 10 + +//#define HAVE_PREF_BTN + +ThemeAddonItem::ThemeAddonItem(BRect bounds, ThemeInterfaceView *iview, int32 id) + : ViewItem(bounds, "addonitem", B_FOLLOW_NONE, B_WILL_DRAW) +{ + ThemeManager *tman; + fId = id; + fIView = iview; + tman = iview->GetThemeManager(); + fAddonName = tman->AddonName(id); + BString tip(tman->AddonDescription(id)); + SetToolTipText(tip.String()); + SetViewUIColor(B_UI_PANEL_BACKGROUND_COLOR); + SetLowUIColor(B_UI_PANEL_BACKGROUND_COLOR); + SetHighUIColor(B_UI_PANEL_TEXT_COLOR); + BMessage *apply = new BMessage(CB_APPLY); + apply->AddInt32("addon", id); + BMessage *save = new BMessage(CB_SAVE); + save->AddInt32("addon", id); + BMessage *prefs = new BMessage(BTN_PREFS); + prefs->AddInt32("addon", id); + fApplyBox = new BCheckBox(BRect(CTRL_OFF_X, CTRL_OFF_Y, CTRL_OFF_X+50, CTRL_OFF_Y+30), "apply", _T("Apply"), apply); + fApplyBox->SetToolTipText(_T("Use this information from themes")); + fApplyBox->SetValue((tman->AddonFlags(id) & Z_THEME_ADDON_DO_SET_ALL)?B_CONTROL_ON:B_CONTROL_OFF); + fSaveBox = new BCheckBox(BRect(CTRL_OFF_X+50+CTRL_SPACING, CTRL_OFF_Y, CTRL_OFF_X+100+CTRL_SPACING, CTRL_OFF_Y+30), "save", _T("Save"), save); + fSaveBox->SetToolTipText(_T("Save this information to themes")); + fSaveBox->SetValue((tman->AddonFlags(id) & Z_THEME_ADDON_DO_RETRIEVE)?B_CONTROL_ON:B_CONTROL_OFF); +#ifdef HAVE_PREF_BTN + fPrefsBtn = new BButton(BRect(CTRL_OFF_X+100+CTRL_SPACING*2, CTRL_OFF_Y, CTRL_OFF_X+150+CTRL_SPACING*2, CTRL_OFF_Y+30), "prefs", _T("Preferences"), prefs); + fPrefsBtn->SetToolTipText(_T("Run the preferences panel for this topic.")); +#endif + BFont fnt; + GetFont(&fnt); + fnt.SetSize(fnt.Size()+1); + fnt.SetFace(B_ITALIC_FACE); + SetFont(&fnt); +} + +ThemeAddonItem::~ThemeAddonItem() +{ + delete fApplyBox; + delete fSaveBox; +#ifdef HAVE_PREF_BTN + delete fPrefsBtn; +#endif +} + +void ThemeAddonItem::DrawItem(BView *ownerview, BRect frame, bool complete) +{ + ViewItem::DrawItem(ownerview, frame, complete); +} + +void ThemeAddonItem::AttachedToWindow() +{ + AddChild(fApplyBox); + fApplyBox->SetTarget(fIView); + AddChild(fSaveBox); + fSaveBox->SetTarget(fIView); +#ifdef HAVE_PREF_BTN + AddChild(fPrefsBtn); + fPrefsBtn->SetTarget(fIView); +#endif + RelayoutButtons(); +} + +void ThemeAddonItem::MessageReceived(BMessage *message) +{ + switch (message->what) { + case B_LANGUAGE_CHANGED: + break; + } + BView::MessageReceived(message); +} + +void ThemeAddonItem::Draw(BRect) +{ + DrawString(fAddonName.String(), BPoint(10, 15/*Bounds().Height()/2*/)); +} + +void ThemeAddonItem::RelocalizeStrings() +{ + fApplyBox->SetLabel(_T("Apply")); + fApplyBox->SetToolTipText(_T("Use this information from themes")); + fSaveBox->SetLabel(_T("Save")); + fSaveBox->SetToolTipText(_T("Save this information to themes")); +#ifdef HAVE_PREF_BTN + fPrefsBtn->SetLabel(_T("Preferences")); + fPrefsBtn->SetToolTipText(_T("Run the preferences panel for this topic.")); +#endif + RelayoutButtons(); +} + +void ThemeAddonItem::RelayoutButtons() +{ + fApplyBox->ResizeToPreferred(); + fSaveBox->MoveTo(fApplyBox->Frame().right+CTRL_SPACING, fApplyBox->Frame().top); + fSaveBox->ResizeToPreferred(); +#ifdef HAVE_PREF_BTN + fPrefsBtn->MoveTo(fSaveBox->Frame().right+CTRL_SPACING, fSaveBox->Frame().top); + fPrefsBtn->ResizeToPreferred(); +#endif +} + +int32 ThemeAddonItem::AddonId() +{ + return fId; +} diff --git a/3rdparty/themes/ThemeAddonItem.h b/3rdparty/themes/ThemeAddonItem.h new file mode 100644 index 0000000000..a0f5f4585c --- /dev/null +++ b/3rdparty/themes/ThemeAddonItem.h @@ -0,0 +1,38 @@ +#ifndef _ADDON_ITEM_H_ +#define _ADDON_ITEM_H_ + +#include +#include +#include "ViewItem.h" +class ThemeInterfaceView; +class BCheckBox; +class BButton; + +class ThemeAddonItem : public ViewItem +{ + public: + ThemeAddonItem(BRect bounds, ThemeInterfaceView *iview, int32 id); + ~ThemeAddonItem(); + void DrawItem(BView *ownerview, BRect frame, bool complete = false); + void AttachedToWindow(); + void MessageReceived(BMessage *message); + void Draw(BRect updateRect); + + void RelocalizeStrings(); + void RelayoutButtons(); + int32 AddonId(); + + private: + int32 fId; + ThemeInterfaceView *fIView; + BString fAddonName; + BCheckBox *fApplyBox; + BCheckBox *fSaveBox; + BButton *fPrefsBtn; +}; + +#define CB_APPLY 'AiAp' +#define CB_SAVE 'AiSa' +#define BTN_PREFS 'AiPr' + +#endif // _ADDON_ITEM_H_ diff --git a/3rdparty/themes/ThemeInterfaceView.cpp b/3rdparty/themes/ThemeInterfaceView.cpp new file mode 100644 index 0000000000..b9ae602153 --- /dev/null +++ b/3rdparty/themes/ThemeInterfaceView.cpp @@ -0,0 +1,713 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "UITheme.h" + +extern status_t ScaleBitmap(const BBitmap& inBitmap, BBitmap& outBitmap); + +/* gui */ +//#include "ThemeSelector.h" +#include "ThemeInterfaceView.h" +#include "ThemeItem.h" +#include "ThemeAddonItem.h" + +/* impl */ +#include "ThemeManager.h" + +const uint32 kThemeChanged = 'mThC'; +const uint32 kApplyThemeBtn = 'TmAp'; +const uint32 kCreateThemeBtn = 'TmCr'; +const uint32 kReallyCreateTheme = 'TmCR'; +const uint32 kSaveThemeBtn = 'TmSa'; +const uint32 kDeleteThemeBtn = 'TmDe'; +const uint32 kHidePreviewBtn = 'TmHP'; +const uint32 kThemeSelected = 'TmTS'; +const uint32 kMakeScreenshot = 'TmMS'; + +const uint32 kHideSSPulse = 'TmH1'; +const uint32 kShowSSPulse = 'TmH2'; + +static const uint32 skOnlineThemes = 'TmOL'; +static char* skThemeURL = "http://www.zeta-os.com/cms/download.php?list.4"; + +#define HIDESS_OFFSET (Bounds().Width()/2 - 130) +// ------------------------------------------------------------------------------ +filter_result refs_filter(BMessage *message, BHandler **handler, BMessageFilter *filter) +{ + (void)handler; + (void)filter; + switch (message->what) { + case B_REFS_RECEIVED: + message->PrintToStream(); + break; + } + return B_DISPATCH_MESSAGE; +} + +// ------------------------------------------------------------------------------ +//extern "C" BView *get_pref_view(const BRect& Bounds) +extern "C" BView *themes_pref(const BRect& Bounds) +{ + return new ThemeInterfaceView(Bounds); +} + +// ------------------------------------------------------------------------------ +ThemeInterfaceView::ThemeInterfaceView(BRect _bounds) + : BView(_bounds, "Themes", B_FOLLOW_ALL_SIDES, B_WILL_DRAW) + , fThemeManager(NULL) + , fScreenshotPaneHidden(false) + , fHasScreenshot(false) + , fPopupInvoker(NULL) + , fBox(NULL) +{ +/* + BMessageFilter *filt = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, refs_filter); + be_app->Lock(); + be_app->AddCommonFilter(filt); + be_app->Unlock(); +*/ +} + +// ------------------------------------------------------------------------------ +ThemeInterfaceView::~ThemeInterfaceView() +{ + delete fPopupInvoker; + delete fThemeManager; +} + +// ------------------------------------------------------------------------------ +void +ThemeInterfaceView::AllAttached() +{ + BView::AllAttached(); + + fPopupInvoker = new BInvoker(new BMessage(kReallyCreateTheme), this); + SetViewUIColor(B_UI_PANEL_BACKGROUND_COLOR); + + fThemeManager = new ThemeManager; + fThemeManager->LoadThemes(); + + BRect frame = Bounds(); + frame.InsetBy(10.0, 10.0); + + // add the theme listview + BRect list_frame = frame; + list_frame.right = 130; + fThemeList = new BListView(list_frame.InsetByCopy(3.0, 3.0), "themelist"); + fThemeListSV = new BScrollView("themelistsv", fThemeList, B_FOLLOW_LEFT|B_FOLLOW_TOP, 0, false, true); + AddChild(fThemeListSV); + fThemeList->SetSelectionMessage(new BMessage(kThemeSelected)); + fThemeList->SetInvocationMessage(new BMessage(kApplyThemeBtn)); + fThemeList->SetTarget(this); + + // buttons... + fNewBtn = new BButton(BRect(), "create", _T("New"), new BMessage(kCreateThemeBtn)); + AddChild(fNewBtn); + fNewBtn->SetTarget(this); + fNewBtn->ResizeToPreferred(); + fNewBtn->MoveTo(fThemeListSV->Frame().right + 15.0, frame.bottom - fNewBtn->Bounds().Height()); + BPoint lt = fNewBtn->Frame().LeftTop(); + lt.x = fNewBtn->Frame().right + 10.0; + + lt.x = fNewBtn->Frame().right + 10.0; + fSaveBtn = new BButton(BRect(), "save", _T("Save"), new BMessage(kSaveThemeBtn)); + AddChild(fSaveBtn); + fSaveBtn->SetTarget(this); + fSaveBtn->ResizeToPreferred(); + fSaveBtn->MoveTo(lt); + + lt.x = fSaveBtn->Frame().right + 10.0; + fDeleteBtn = new BButton(BRect(), "delete", _T("Delete"), new BMessage(kDeleteThemeBtn)); + AddChild(fDeleteBtn); + fDeleteBtn->SetTarget(this); + fDeleteBtn->ResizeToPreferred(); + fDeleteBtn->MoveTo(lt); + + // buttons... + fSetShotBtn = new BButton(BRect(), "makeshot", _T("Add Screenshot"), new BMessage(kMakeScreenshot), B_FOLLOW_RIGHT | B_FOLLOW_TOP); + AddChild(fSetShotBtn); + fSetShotBtn->SetTarget(this); + fSetShotBtn->ResizeToPreferred(); + + fShowSSPaneBtn = new BButton(BRect(), "hidess", _T("Show Options"), new BMessage(kHidePreviewBtn), B_FOLLOW_RIGHT | B_FOLLOW_TOP); + AddChild(fShowSSPaneBtn); + fShowSSPaneBtn->SetTarget(this); + fShowSSPaneBtn->ResizeToPreferred(); + + fApplyBtn = new BButton(BRect(), "apply", _T("Apply"), new BMessage(kApplyThemeBtn), B_FOLLOW_RIGHT | B_FOLLOW_TOP); + AddChild(fApplyBtn); + fApplyBtn->ResizeToPreferred(); + fApplyBtn->SetTarget(this); + + float widest = max_c(fSetShotBtn->Bounds().Width(), fShowSSPaneBtn->Bounds().Width()); + widest = max_c(widest, fApplyBtn->Bounds().Width()); + float height = fSetShotBtn->Bounds().Height(); + fSetShotBtn->ResizeTo(widest, height); + fShowSSPaneBtn->ResizeTo(widest, height); + fApplyBtn->ResizeTo(widest, height); + + fSetShotBtn->MoveTo(frame.right - widest, frame.top + 5.0); + fShowSSPaneBtn->MoveTo(frame.right - widest, fSetShotBtn->Frame().bottom + 10.0); + fApplyBtn->MoveTo(frame.right - widest, fNewBtn->Frame().top - fApplyBtn->Bounds().Height() - 10); + + // add the preview screen + BRect preview_frame(fNewBtn->Frame().left, fThemeListSV->Frame().top, frame.right - widest - 10, fNewBtn->Frame().top - 10); + + fBox = new BBox(preview_frame, "preview", B_FOLLOW_ALL); + AddChild(fBox); + fBox->SetLabel(_T("Preview")); + + preview_frame.InsetBy(10.0, 15.0); + preview_frame.OffsetTo(10.0, 20.0); + fScreenshotPane = new BView(preview_frame, "screenshot", B_FOLLOW_ALL, B_WILL_DRAW); + fBox->AddChild(fScreenshotPane); + fScreenshotPane->SetViewUIColor(B_UI_PANEL_BACKGROUND_COLOR); + + fScreenshotNone = new BStringView(BRect(), "sshotnone", _T("No Theme selected"), (uint32) 0, B_FOLLOW_ALL); + fScreenshotNone->SetFontSize(20.0); + fScreenshotNone->SetAlignment(B_ALIGN_CENTER); + fBox->AddChild(fScreenshotNone); + fScreenshotNone->ResizeToPreferred(); + fScreenshotNone->ResizeTo(fBox->Bounds().Width() - 10.0, fScreenshotNone->Bounds().Height()); + fScreenshotNone->MoveTo(fBox->Bounds().left + 5.0, + ((fBox->Frame().Height() - fScreenshotNone->Frame().Height()) / 2.0)); + + // Theme hyperlink + BStringView* hlink = new BStringView(BRect(), "theme_hyperlink", _T("More themes online"), new BMessage(skOnlineThemes), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); + AddChild(hlink); + hlink->SetClickText(hlink->GetText(), *this); + hlink->ResizeToPreferred(); + hlink->MoveTo(frame.right - hlink->Bounds().Width(), fNewBtn->Frame().top + 5); + + // the addons list view + preview_frame = fBox->Frame(); + preview_frame.InsetBy(3.0, 3.0); + preview_frame.right -= B_V_SCROLL_BAR_WIDTH; + fAddonList = new BListView(preview_frame, "addonlist"); + fAddonListSV = new BScrollView("addonlistsv", fAddonList, B_FOLLOW_LEFT|B_FOLLOW_TOP, 0, false, true); + AddChild(fAddonListSV); + fAddonList->SetSelectionMessage(new BMessage(kThemeSelected)); + fAddonList->SetInvocationMessage(new BMessage(kApplyThemeBtn)); + fAddonList->SetTarget(this); + fAddonListSV->Hide(); + + PopulateThemeList(); + PopulateAddonList(); +} + +// ------------------------------------------------------------------------------ +void +ThemeInterfaceView::MessageReceived(BMessage *_msg) +{ + ThemeManager *tman; + int32 value; + int32 id; +//_msg->PrintToStream(); + switch(_msg->what) + { + case B_REFS_RECEIVED: + _msg->PrintToStream(); + break; + + case kMakeScreenshot: + AddScreenshot(); + break; + + case kThemeSelected: + ThemeSelected(); + break; + + case kHidePreviewBtn: + HideScreenshotPane(!IsScreenshotPaneHidden()); + break; + + case kApplyThemeBtn: + ApplySelected(); + break; + + case kCreateThemeBtn: + { + ThemePopupTextWindow *tw; + tw = new ThemePopupTextWindow(_T("New Theme Name"), _T("Name"), _T("Accept"), _T("Cancel"), + new BMessage(kReallyCreateTheme), + new BMessage(kReallyCreateTheme+1)); + tw->SetTarget(this); + tw->Show(); + break; + } + + case kReallyCreateTheme: + { + const char *name; + if (_msg->FindString("text", &name) < B_OK) + break; + CreateNew(name); + break; + } + + case kSaveThemeBtn: + SaveSelected(); + break; + + case kDeleteThemeBtn: + DeleteSelected(); + break; +#if 0 + case kColorsChanged: + case kGeneralChanged: + case kFontsChanged: + { + BMessenger msgr (Parent()); + msgr.SendMessage(B_PREF_APP_ENABLE_REVERT); + BMessage changes; + if (_msg->FindMessage("changes", &changes) == B_OK) + { + update_ui_settings(changes); + } + break; + } +#endif + case B_PREF_APP_SET_DEFAULTS: + { + ApplyDefaults(); + break; + } + + case B_PREF_APP_REVERT: + { + Revert(); + break; + } + + case B_PREF_APP_ADDON_REF: + { + break; + } + + case kThemeChanged: + { +/* BMessage data; + BMessage names; + get_ui_settings(&data, &names); + fColorSelector->Update(data); + fFontSelector->Refresh(); + fGeneralSelector->Refresh(data); +*/ + break; + } + + case CB_APPLY: + tman = GetThemeManager(); + _msg->PrintToStream(); + if (_msg->FindInt32("be:value", &value) < B_OK) + value = false; + if (_msg->FindInt32("addon", &id) < B_OK) + break; + //tman->SetAddonFlags(id, (tman->AddonFlags(id) & ~Z_THEME_ADDON_DO_SET_ALL)); + tman->SetAddonFlags(id, (tman->AddonFlags(id) & ~Z_THEME_ADDON_DO_SET_ALL) | (value?Z_THEME_ADDON_DO_SET_ALL:0)); + break; + + case CB_SAVE: + tman = GetThemeManager(); + _msg->PrintToStream(); + if (_msg->FindInt32("be:value", &value) < B_OK) + value = false; + if (_msg->FindInt32("addon", &id) < B_OK) + break; + tman->SetAddonFlags(id, (tman->AddonFlags(id) & ~Z_THEME_ADDON_DO_RETRIEVE) | (value?Z_THEME_ADDON_DO_RETRIEVE:0)); + break; + + case BTN_PREFS: + tman = GetThemeManager(); + if (_msg->FindInt32("addon", &id) < B_OK) + break; + tman->RunPreferencesPanel(id); + break; + + case kHideSSPulse: + break; + + case kShowSSPulse: + break; + + case skOnlineThemes: + be_roster->Launch( "application/x-vnd.Mozilla-Firefox", 1, &skThemeURL); + break; + + default: + { + BView::MessageReceived(_msg); + break; + } + } +} + +// ------------------------------------------------------------------------------ +ThemeManager* ThemeInterfaceView::GetThemeManager() +{ + return fThemeManager; +} + +// ------------------------------------------------------------------------------ +void ThemeInterfaceView::HideScreenshotPane(bool hide) +{ + BString lbl; + if (IsScreenshotPaneHidden() && hide) + return; + if (!IsScreenshotPaneHidden() && !hide) + return; + fScreenshotPaneHidden = hide; + + if (hide) + { + if (!fScreenshotPane->IsHidden()) + { + fBox->Hide(); + fAddonListSV->Show(); + } + fShowSSPaneBtn->SetLabel(_T("Show Preview")); + } + else + { + fShowSSPaneBtn->SetLabel(_T("Show Options")); + if (fScreenshotPane->IsHidden()) + { + fBox->Show(); + fAddonListSV->Hide(); + } + } + // TODO +} + + +// ------------------------------------------------------------------------------ +bool ThemeInterfaceView::IsScreenshotPaneHidden() +{ + return fScreenshotPaneHidden; +} + +// ------------------------------------------------------------------------------ +void ThemeInterfaceView::PopulateThemeList() +{ + status_t err; + int32 i, count; + BString name; + ThemeItem *ti; + bool isro; + ThemeManager* tman = GetThemeManager(); + count = tman->CountThemes(); + fThemeList->MakeEmpty(); + for (i = 0; i < count; i++) { + err = tman->ThemeName(i, name); + isro = tman->ThemeIsReadOnly(i); + if (err) + continue; + ti = new ThemeItem(i, name.String(), isro); + fThemeList->AddItem(ti); + } +} + +// ------------------------------------------------------------------------------ +void ThemeInterfaceView::PopulateAddonList() +{ + int32 i, count; + ViewItem *vi; + ThemeManager* tman = GetThemeManager(); + count = tman->CountAddons(); + fAddonList->MakeEmpty(); + for (i = 0; i < count; i++) { + vi = new ThemeAddonItem(BRect(0,0,200,52), this, i); + fAddonList->AddItem(vi); + } +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::Revert() +{ + status_t err = B_OK; + ThemeManager* tman = GetThemeManager(); + + if (tman->CanRevert()) + err = tman->RestoreCurrent(); + if (err) + return err; + + return B_OK; +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::ApplyDefaults() +{ + status_t err = B_OK; + ThemeManager* tman = GetThemeManager(); + + SetIsRevertable(); + + err = tman->ApplyDefaultTheme(); + return err; +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::ApplySelected() +{ + status_t err; + ThemeManager* tman = GetThemeManager(); + int32 id; + ThemeItem *item; + // find selected theme + id = fThemeList->CurrentSelection(0); + if (id < 0) + return ENOENT; + item = dynamic_cast(fThemeList->ItemAt(id)); + if (!item) + return ENOENT; + id = item->ThemeId(); + if (id < 0) + return ENOENT; + SetIsRevertable(); + err = tman->ApplyTheme(id); + return err; +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::CreateNew(const char *name) +{ + status_t err; + ThemeManager* tman = GetThemeManager(); + int32 id; + ThemeItem *ti; + BString n(name); + + id = tman->MakeTheme(); + if (id < 0) + return B_ERROR; + err = tman->SetThemeName(id, name); + if (err) + return err; + err = tman->ThemeName(id, n); + if (err) + return err; + err = tman->SaveTheme(id, true); + if (err) + return err; + ti = new ThemeItem(id, n.String(), false); + fThemeList->AddItem(ti); + return B_OK; +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::SaveSelected() +{ + status_t err; + ThemeManager* tman = GetThemeManager(); + int32 id; + ThemeItem *item; + BMessage theme; + // find selected theme + id = fThemeList->CurrentSelection(0); + if (id < 0) + return B_OK; + item = dynamic_cast(fThemeList->ItemAt(id)); + if (!item) + return AError(__FUNCTION__, ENOENT); + if (item->IsReadOnly()) + return AError(__FUNCTION__, B_READ_ONLY_DEVICE); + id = item->ThemeId(); + if (id < 0) + return AError(__FUNCTION__, ENOENT); + + err = tman->UpdateTheme(id); + if (err) + return AError(__FUNCTION__, err); + err = tman->SaveTheme(id); + if (err) + return AError(__FUNCTION__, err); + //err = tman->ApplyTheme(theme); + return err; +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::DeleteSelected() +{ + status_t err; + ThemeManager* tman = GetThemeManager(); + int32 id; + ThemeItem *item; + BMessage theme; + // find selected theme + id = fThemeList->CurrentSelection(0); + if (id < 0) + return B_OK; + item = dynamic_cast(fThemeList->ItemAt(id)); + if (!item) + return AError(__FUNCTION__, ENOENT); + if (item->IsReadOnly()) + return AError(__FUNCTION__, B_READ_ONLY_DEVICE); + id = item->ThemeId(); + if (id < 0) + return AError(__FUNCTION__, ENOENT); + // then apply + err = tman->DeleteTheme(id); + if (err) + return AError(__FUNCTION__, err); + fThemeList->RemoveItem(item); + delete item; + //err = tman->ApplyTheme(theme); + return err; +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::AddScreenshot() +{ + status_t err; + ThemeManager* tman = GetThemeManager(); + int32 id; + ThemeItem *item; + BMessage theme; + // find selected theme + id = fThemeList->CurrentSelection(0); + if (id < 0) + return B_OK; + item = dynamic_cast(fThemeList->ItemAt(id)); + if (!item) + return AError(__FUNCTION__, ENOENT); + id = item->ThemeId(); + if (id < 0) + return AError(__FUNCTION__, ENOENT); + // then apply + err = tman->MakeThemeScreenShot(id); + if (err) + return AError(__FUNCTION__, err); + err = tman->SaveTheme(id); + if (err) + return AError(__FUNCTION__, err); + ThemeSelected(); // force reload of description for selected theme. + return err; +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::ThemeSelected() +{ + status_t err; + ThemeManager* tman = GetThemeManager(); + int32 id; + ThemeItem *item; + BString desc; + BBitmap *sshot = NULL; + // find selected theme + id = fThemeList->CurrentSelection(0); + if (id < 0) + { + fScreenshotPane->ClearViewBitmap(); + fScreenshotPane->Invalidate(fScreenshotPane->Bounds()); + + HideScreenshotPane(false); + while(true == fScreenshotNone->IsHidden()) + fScreenshotNone->Show(); + + fScreenshotNone->SetText(_T("No Theme selected")); + return ENOENT; + } + + item = dynamic_cast(fThemeList->ItemAt(id)); + if (!item) + return ENOENT; + id = item->ThemeId(); + if (id < 0) + return ENOENT; + // then apply + + err = tman->ThemeScreenShot(id, &sshot); + if (err) + sshot = NULL; + if (sshot == NULL) + { + SetScreenshot(NULL); + fprintf(stderr, "ThemeManager: no screenshot; error 0x%08lx\n", err); + + HideScreenshotPane(false); + while(true == fScreenshotNone->IsHidden()) + fScreenshotNone->Show(); + + fScreenshotNone->SetText(_T("No Screenshot")); + return err; + } + + SetScreenshot(sshot); + while(false == fScreenshotNone->IsHidden()) + fScreenshotNone->Hide(); + + //err = tman->ApplyTheme(theme); + return err; +} + +// ------------------------------------------------------------------------------ +void ThemeInterfaceView::SetIsRevertable() +{ + BMessenger msgr(Parent()); + msgr.SendMessage(B_PREF_APP_ENABLE_REVERT); +} + +// PRIVATE: in libzeta for now. +extern status_t ScaleBitmap(const BBitmap& inBitmap, BBitmap& outBitmap); + +// ------------------------------------------------------------------------------ +void ThemeInterfaceView::SetScreenshot(BBitmap *shot) +{ + // no screenshotpanel + if(NULL == fScreenshotPane) + return; + + fScreenshotPane->ClearViewBitmap(); + if (shot) + { + BBitmap scaled(fScreenshotPane->Bounds(), B_RGB32); + if( B_OK == ScaleBitmap(*shot, scaled) ) + { + fScreenshotPane->SetViewBitmap(&scaled); + } + else + { + fScreenshotPane->SetViewBitmap(shot, shot->Bounds(), fScreenshotPane->Bounds()); + } + } + + fScreenshotPane->Invalidate(fScreenshotPane->Bounds()); + fHasScreenshot = (shot != NULL); + + if (shot) + delete shot; +} + +// ------------------------------------------------------------------------------ +status_t ThemeInterfaceView::AError(const char *func, status_t err) +{ + BAlert *alert; + BString msg; + char *str = strerror(err); + msg << "Error in " << func << "() : " << str; + alert = new BAlert("error", msg.String(), _T("Ok")); + alert->Go(); + return err; /* pass thru */ +} + diff --git a/3rdparty/themes/ThemeInterfaceView.h b/3rdparty/themes/ThemeInterfaceView.h new file mode 100644 index 0000000000..5dc5718d94 --- /dev/null +++ b/3rdparty/themes/ThemeInterfaceView.h @@ -0,0 +1,77 @@ +#include + +namespace Z { +namespace ThemeManager { + class ThemeManager; +} // ns ThemeManager +} // ns Z +using Z::ThemeManager::ThemeManager; + +class BBitmap; +class BSeparator; +class BBox; +class BListView; +class BButton; +class BScrollView; +class BTextView; +class BMessage; +class BStringView; + +class ThemeInterfaceView : public BView +{ + public: + ThemeInterfaceView(BRect _bounds); + virtual ~ThemeInterfaceView(); + + virtual void AllAttached(); + virtual void MessageReceived(BMessage* _msg); + ThemeManager* GetThemeManager(); + + void HideScreenshotPane(bool hide); + bool IsScreenshotPaneHidden(); + + void PopulateThemeList(); + void PopulateAddonList(); + + status_t Revert(); + status_t ApplyDefaults(); + status_t ApplySelected(); + status_t CreateNew(const char *name); + status_t SaveSelected(); + status_t DeleteSelected(); + status_t AddScreenshot(); + + status_t ThemeSelected(); + + void SetIsRevertable(); + void SetScreenshot(BBitmap *shot); + status_t AError(const char *func, status_t err); + + private: + + ThemeManager* fThemeManager; + bool fScreenshotPaneHidden; + bool fHasScreenshot; + + BInvoker* fPopupInvoker; + BScrollView* fThemeListSV; + BListView* fThemeList; + BButton* fApplyBtn; + BButton* fNewBtn; + BButton* fSaveBtn; + BButton* fDeleteBtn; + BButton* fSetShotBtn; + BButton* fShowSSPaneBtn; + BView* fScreenshotPane; + BStringView* fScreenshotNone; + BBox* fBox; + BScrollView* fAddonListSV; + BListView* fAddonList; +}; + +extern "C" BView *themes_pref(const BRect& Bounds); + +#define SSPANE_WIDTH 320 +#define SSPANE_HEIGHT 240 + + diff --git a/3rdparty/themes/ThemeItem.cpp b/3rdparty/themes/ThemeItem.cpp new file mode 100644 index 0000000000..1ded9606e9 --- /dev/null +++ b/3rdparty/themes/ThemeItem.cpp @@ -0,0 +1,71 @@ +#include "ThemeItem.h" +#include +#include +#include + +ThemeItem::ThemeItem(int32 id, const char *name, bool ro) + : BStringItem(name) +{ + fCurrent = false; + fId = id; + fRo = ro; +} + +ThemeItem::~ThemeItem() +{ +} + +void ThemeItem::DrawItem(BView *owner, BRect frame, bool complete) +{ + rgb_color col; + if (fCurrent || fRo) + owner->PushState(); + if (fCurrent) { + BFont f; + owner->GetFont(&f); + f.SetFace(B_BOLD_FACE); + owner->SetFont(&f); + } + if (fRo) { + col = owner->LowColor(); + if (col.red < 220) + col.red += 15; + else { + if (col.green > 20) + col.green -= 10; + if (col.blue > 20) + col.blue -= 10; + } + owner->SetLowColor(col); + owner->FillRect(frame, B_SOLID_LOW); + } + BStringItem::DrawItem(owner, frame, complete); + if (fCurrent || fRo) + owner->PopState(); +} + +int32 ThemeItem::ThemeId() +{ + return fId; +} + +bool ThemeItem::IsCurrent() +{ + return fCurrent; +} + +void ThemeItem::SetCurrent(bool set) +{ + fCurrent = set; +} + +bool ThemeItem::IsReadOnly() +{ + return fRo; +} + +void ThemeItem::SetReadOnly(bool set) +{ + fRo = set; +} + diff --git a/3rdparty/themes/ThemeItem.h b/3rdparty/themes/ThemeItem.h new file mode 100644 index 0000000000..1bf6015b56 --- /dev/null +++ b/3rdparty/themes/ThemeItem.h @@ -0,0 +1,24 @@ +#ifndef _THEME_ITEM_H_ +#define _THEME_ITEM_H_ + +#include + + +class ThemeItem : public BStringItem +{ + public: + ThemeItem(int32 id, const char *name, bool ro = false); + ~ThemeItem(); + void DrawItem(BView *owner, BRect frame, bool complete = false); + bool IsCurrent(); + void SetCurrent(bool set); + bool IsReadOnly(); + void SetReadOnly(bool set); + int32 ThemeId(); + private: + int32 fId; + bool fRo; + bool fCurrent; +}; + +#endif // _THEME_ITEM_H_ diff --git a/3rdparty/themes/ThemeManager.cpp b/3rdparty/themes/ThemeManager.cpp new file mode 100644 index 0000000000..31861fabc2 --- /dev/null +++ b/3rdparty/themes/ThemeManager.cpp @@ -0,0 +1,1320 @@ +/* + * ThemeManager class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "ThemeManager.h" +#include "ThemesAddon.h" +#include "UITheme.h" + +#include "ParseMessage.h" +#include "DumpMessage.h" + +extern status_t MakeScreenshot(BBitmap **here); + + +#define DEBUG_TM +#ifdef DEBUG_TM +#define FENTRY PRINT(("ThemeManager::%s()\n", __FUNCTION__)) +#else +#define FENTRY +#endif + +ThemeManager::ThemeManager() + : fAddonCount(0) +{ + FENTRY; + fSettings.MakeEmpty(); + fBackupTheme.MakeEmpty(); + fBackupTheme.what = 'null';//Z_THEME_MESSAGE_WHAT; + fSelectedTheme = -1; + fAddonList.MakeEmpty(); + fNames.MakeEmpty(); + LoadAddons(); + AddNames(fNames); + LoadSettings(); + + + // XXX test +/* + BMessage test('plop'); + BMessage *to; + test.AddString("plop-plip", "this is a test...\"line cont'd."); + test.PrintToStream(); + BFile tfile("/tmp/testmsg", B_READ_WRITE|B_CREATE_FILE); + DumpMessageToStream(&test, tfile, 0, NULL); + tfile.Seek(0LL, SEEK_SET); + ParseMessageFromStream(&to, tfile); + if (to) + to->PrintToStream(); + else + PRINT(("no to\n")); +*/ +} + +ThemeManager::~ThemeManager() +{ + FENTRY; + SaveSettings(); + if (CountThemes()) + UnloadThemes(); + if (CountAddons()) + UnloadAddons(); +} + +status_t ThemeManager::LoadAddons() +{ + FENTRY; + ThemesAddon *ta; + BPath path; + BDirectory dir; + entry_ref ref; +#ifndef SINGLE_BINARY + uint32 addonFlags; + int dirwhich; + int32 i; + status_t err; + image_id img; + ThemesAddon *(*instanciate_func)(); +#endif + +#ifndef SINGLE_BINARY + for (dirwhich = 0; dirwhich < 2; dirwhich++) { + if (!dirwhich) /* find system settings dir */ + err = find_directory(B_BEOS_ADDONS_DIRECTORY, &path); + else /* find user settings dir */ + err = find_directory(B_USER_ADDONS_DIRECTORY, &path); + if (err) return err; + + path.Append(Z_THEMES_ADDON_FOLDER); + + err = dir.SetTo(path.Path()); + if (err) continue; + + err = dir.Rewind(); + if (err) continue; + + while ((err = dir.GetNextRef(&ref)) == B_OK) { + bool screwed = false; + BPath imgpath(&ref); + BString p(Z_THEMES_ADDON_FOLDER); + p << "/" << ref.name; + PRINT(("ThemeManager: trying to load_add_on(%s)\n", p.String())); + img = load_add_on(imgpath.Path()); + if (img < B_OK) + fprintf(stderr, "ThemeManager: load_add_on 0x%08lx\n", img); + if (img < B_OK) + continue; + err = get_image_symbol(img, "instanciate_themes_addon", + B_SYMBOL_TYPE_TEXT, (void **)&instanciate_func); + if (err) + fprintf(stderr, "ThemeManager: get_image_symbol 0x%08lx\n", err); + if (err) continue; + ta = instanciate_func(); + if (!ta) + fprintf(stderr, "ThemeManager: instanciate_themes_addon returned NULL\n"); + if (!ta) + continue; + ta->SetImageId(img); + /* check for existing names */ + for (i = 0; i < fAddonList.CountItems(); i++) { + ThemesAddon *a = AddonAt(i); + if (!a) + fprintf(stderr, "ThemeManager: screwed! addon@%ld null\n", i); + if (a->MessageName() && ta->MessageName() && + !strcmp(a->MessageName(), ta->MessageName())) { + fprintf(stderr, "ThemeManager: screwed! addon@%ld has same msgname\n", i); + screwed = true; + break; + } + if (a->Name() && ta->Name() && + !strcmp(a->Name(), ta->Name())) { + fprintf(stderr, "ThemeManager: screwed! addon@%ld has same name\n", i); + screwed = true; + break; + } + } + if (screwed) + continue; + /* add it to the list */ + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); + } + //if (err) return err; + } +#else + ta = instanciate_themes_addon_backgrounds(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); + ta = instanciate_themes_addon_beide(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); + ta = instanciate_themes_addon_deskbar(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); +#if 0 + ta = instanciate_themes_addon_eddie(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); +#endif + ta = instanciate_themes_addon_pe(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); + ta = instanciate_themes_addon_screensaver(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); +#if 0 + ta = instanciate_themes_addon_soundplay(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); +#endif + ta = instanciate_themes_addon_sounds(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); + ta = instanciate_themes_addon_terminal(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); + ta = instanciate_themes_addon_ui_settings(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); +#if 0 + ta = instanciate_themes_addon_winamp_skin(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); +#endif + ta = instanciate_themes_addon_window_decor(); + fAddonList.AddItem((void *)ta); + PRINT(("ThemeManager: Added addon %ld '%s', msgname '%s'\n", ta->ImageId(), ta->Name(), ta->MessageName())); +#endif + //if (err) return err; + fAddonCount = fAddonList.CountItems(); + PRINT(("ThemeManager: %ld addons loaded\n", fAddonCount)); + return B_OK; +} + +status_t ThemeManager::UnloadAddons() +{ + FENTRY; + int32 i; + ThemesAddon *ta; + image_id img; + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + img = ta->ImageId(); + delete ta; +#ifndef SINGLE_BINARY + unload_add_on(img); +#endif + } + fAddonList.MakeEmpty(); + fAddonCount = 0; + return B_OK; +} + +int32 ThemeManager::FindAddon(const char *name) +{ + FENTRY; + int32 i; + ThemesAddon *ta; + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!strcmp(ta->Name(), name)) + return i; + } + return -1; +} + +int32 ThemeManager::CountAddons() +{ + FENTRY; + return fAddonCount; +} + +ThemesAddon *ThemeManager::AddonAt(int32 addon) +{ + FENTRY; + if (addon < 0) + return NULL; + return (ThemesAddon *)fAddonList.ItemAt(addon); +} + +const char *ThemeManager::AddonName(int32 addon) +{ + FENTRY; + if (addon < 0) + return NULL; + return ((ThemesAddon *)fAddonList.ItemAt(addon))->Name(); +} + +const char *ThemeManager::AddonDescription(int32 addon) +{ + FENTRY; + if (addon < 0) + return NULL; + return ((ThemesAddon *)fAddonList.ItemAt(addon))->Description(); +} + +const char *AddonName(int32 addon); + +BView *ThemeManager::OptionsView(int32 addon) +{ + FENTRY; + ThemesAddon *ta; + ta = AddonAt(addon); + if (ta) + return ta->OptionsView(); + return NULL; +} + +status_t ThemeManager::RunPreferencesPanel(int32 addon) +{ + FENTRY; + ThemesAddon *ta; + ta = AddonAt(addon); + if (ta) + return ta->RunPreferencesPanel(); + return B_OK; +} + +status_t ThemeManager::LoadSettings() +{ + FENTRY; + BMessage addonSettings; + int32 i; + ThemesAddon *ta; + uint32 addonFlags; + BPath path; + BFile sFile; + status_t err; + + /* load prefs */ + err = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (!err) { + path.Append(Z_THEME_MANAGER_SETTINGS_FILE); + err = sFile.SetTo(path.Path(), B_READ_ONLY); + if (!err) { + err = fSettings.Unflatten(&sFile); + } + } + + /* tell addons */ + for (i = 0; i < fAddonCount; i++) { + ta = AddonAt(i); + if (!ta || !ta->Name()) + continue; + if (fSettings.FindMessage(ta->Name(), &addonSettings) < B_OK) { + addonSettings.MakeEmpty(); + } + fSettings.RemoveName(ta->Name()); + if (addonSettings.FindInt32("ta:flags", (int32 *)&addonFlags) < B_OK) { + addonFlags = Z_THEME_ADDON_DO_SET_ALL | Z_THEME_ADDON_DO_RETRIEVE; + addonSettings.AddInt32("ta:flags", addonFlags); + } + ta->LoadSettings(addonSettings); + } + return B_OK; +} + +status_t ThemeManager::SaveSettings() +{ + FENTRY; + BMessage addonSettings; + int32 i; + ThemesAddon *ta; + BPath path; + BFile sFile; + status_t err; + + /* ask addons for their prefs */ + for (i = 0; i < fAddonCount; i++) { + ta = AddonAt(i); + if (!ta) + continue; + addonSettings.MakeEmpty(); + if (ta->SaveSettings(addonSettings) == B_OK) + fSettings.AddMessage(ta->Name(), &addonSettings); + } + + /* save the prefs */ + err = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (err) return err; + + path.Append(Z_THEME_MANAGER_SETTINGS_FILE); + err = sFile.SetTo(path.Path(), B_WRITE_ONLY|B_CREATE_FILE); + if (err) return err; + + err = fSettings.Flatten(&sFile); + if (err) return err; + + return B_OK; +} + +void ThemeManager::SetAddonFlags(int32 addon, uint32 flags) +{ + FENTRY; + ThemesAddon *ta; + ta = AddonAt(addon); + if (ta) + ta->SetAddonFlags(flags); +} + +uint32 ThemeManager::AddonFlags(int32 addon) +{ + FENTRY; + ThemesAddon *ta; + ta = AddonAt(addon); + if (ta) + return ta->AddonFlags(); + return 0L; +} + +status_t ThemeManager::AddNames(BMessage &names) +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err, gerr = B_OK; + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + err = ta->AddNames(names); + if (err) + gerr = err; + } + return gerr; +} + +status_t ThemeManager::GetNames(BMessage &names) +{ + FENTRY; + names = fNames; + return B_OK; +} + +status_t ThemeManager::LoadThemes() +{ + FENTRY; + int dirwhich; + BPath path; + BDirectory dir; + entry_ref ref; + status_t err; + + for (dirwhich = 0; dirwhich < 2; dirwhich++) { + if (!dirwhich) /* find system settings dir */ + err = find_directory(B_BEOS_ETC_DIRECTORY, &path); + else /* find user settings dir */ + err = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (err) return err; + + err = dir.SetTo(path.Path()); + if (err) return err; + BEntry ent; + if (dir.FindEntry(Z_THEMES_FOLDER_NAME, &ent) < B_OK) { + dir.CreateDirectory(Z_THEMES_FOLDER_NAME, NULL); + } + + path.Append(Z_THEMES_FOLDER_NAME); + + err = dir.SetTo(path.Path()); + if (err) return err; + + err = dir.Rewind(); + if (err) return err; + + while ((err = dir.GetNextRef(&ref)) == B_OK) { + BPath themepath(&ref); + BDirectory tdir(themepath.Path()); + err = tdir.InitCheck(); + if (err) /* not a dir */ + continue; + err = LoadTheme(themepath.Path()); + } + } + return B_OK; +} + +status_t ThemeManager::AddTheme(BMessage *theme) +{ + FENTRY; + BString name; + + if (!theme) + return EINVAL; +/* err = ThemeName(*theme, name); + if (err) + return err;*/ + if (FindTheme(name.String()) >= 0) + return B_FILE_EXISTS; + fThemeList.AddItem(theme); + return B_OK; +} + +status_t ThemeManager::UnloadThemes() +{ + FENTRY; + int32 i; + BMessage *theme; + + for (i = 0; i < CountThemes(); i++) { + theme = (BMessage *)fThemeList.ItemAt(i); + delete theme; + } + fThemeList.MakeEmpty(); + return B_OK; +} + +int32 ThemeManager::CountThemes() +{ + FENTRY; + + return fThemeList.CountItems(); +} + +BMessage *ThemeManager::ThemeAt(int32 id, bool allowbackup) +{ + FENTRY; + BMessage *theme; + + if (id < 0) { + if (allowbackup && (id == THEME_ID_BACKUP) && (!fBackupTheme.IsEmpty())) + return &fBackupTheme; + return NULL; + } + theme = (BMessage *)fThemeList.ItemAt(id); + return theme; +} + +status_t ThemeManager::SetThemeAt(int32 id, BMessage ©from) +{ + FENTRY; + BMessage *theme; + BMessage finfos; + BMessage tinfos; + BString s, s2; + int32 i; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return ENOENT; + copyfrom.FindMessage(Z_THEME_INFO_MESSAGE, &finfos); + copyfrom.RemoveName(Z_THEME_INFO_MESSAGE); + copyfrom.RemoveName(Z_THEME_LOCATION); + theme->FindMessage(Z_THEME_INFO_MESSAGE, &tinfos); + tinfos.RemoveName(Z_THEME_MODULE_TAG); + for (i = 0; finfos.FindString(Z_THEME_MODULE_TAG, i, &s); i++) + tinfos.AddString(Z_THEME_MODULE_TAG, s); + *theme = copyfrom; + return B_OK; +} + +int32 ThemeManager::FindTheme(const char *name) +{ + FENTRY; + int32 i; + BMessage *theme; + BString tname; + + for (i = 0; i < CountThemes(); i++) { + theme = (BMessage *)fThemeList.ItemAt(i); + if (!theme) + continue; + if (ThemeName(i, tname) < B_OK) + return -1L; + if (!strcmp(tname.String(), name)) + return i; + } + return -1L; +} + +status_t ThemeManager::CurrentTheme(BMessage ©to) +{ + FENTRY; + + if (!strlen(fCurrentThemeName.String())) + return B_NAME_NOT_FOUND; + if (!fBackupTheme.IsEmpty()) { + copyto = fBackupTheme; + return B_OK; + } +/* i = FindTheme(fCurrentThemeName.String()); + if (i < 0) + return B_NAME_NOT_FOUND; + err = ThemeAt(i, fBackupTheme); + if (err) + return err; + copyto = fBackupTheme;*/ + // FIXME + return B_OK; +} + + + +status_t ThemeManager::ApplyTheme(int32 id, uint32 flags) +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err, gerr = B_OK; + BMessage *theme = ThemeAt(id); + if (!theme) + return EINVAL; + err = BackupCurrent(); + /*if (err) + return err;*/ + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + PRINT(("ThemeManager: addon[%s]->Flags = 0x%08lx\n", ta->Name(), ta->AddonFlags())); + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_SET_ALL)) + continue; + err = ta->ApplyTheme(*theme, flags); + if (err) + gerr = err; + } + return gerr; +} + +int32 ThemeManager::MakeTheme(uint32 flags) +{ + FENTRY; + int32 i, id; + ThemesAddon *ta; + status_t err, gerr = B_OK; + BMessage *theme; + theme = new BMessage(Z_THEME_MESSAGE_WHAT); + fThemeList.AddItem(theme); + id = fThemeList.IndexOf(theme); + if (id < 0) { + delete theme; + return -1; + } + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_RETRIEVE)) + continue; + err = ta->MakeTheme(*theme, flags); + if (err) + gerr = err; + } + return id; +} + +status_t ThemeManager::UpdateTheme(int32 id, uint32 flags) +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err, gerr = B_OK; + BMessage *theme; + BMessage infos; + BString loc; + if ((id < 0) || (id >= fThemeList.CountItems())) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return -1; + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &infos); + err = theme->FindString(Z_THEME_LOCATION, &loc); + if (err) + loc = ""; + theme->MakeEmpty(); + err = theme->AddMessage(Z_THEME_INFO_MESSAGE, &infos); + err = theme->AddString(Z_THEME_LOCATION, loc.String()); + if (err) + return err; + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_RETRIEVE)) + continue; + err = ta->MakeTheme(*theme, flags); + if (err) + gerr = err; + } + return B_OK;//gerr; +} + +status_t ThemeManager::DeleteTheme(int32 id) +{ + status_t err; + BMessage *theme; + BString loc; + if ((id < 0) || (id >= fThemeList.CountItems())) + return EINVAL; + theme = (BMessage *)fThemeList.RemoveItem(id); + fThemeList.AddItem(NULL, id); /* keep the place occupied */ + if (!theme) + return -1; + + err = theme->FindString(Z_THEME_LOCATION, &loc); + if (!err) { + // move the files to trash... + BEntry ent(loc.String()); + if (ent.InitCheck() == B_OK) { + BPath trash; + err = find_directory(B_TRASH_DIRECTORY, &trash); + if (!err) { + BDirectory trashDir(trash.Path()); + if (trashDir.InitCheck() == B_OK) { + BNode nod(&ent); + if (nod.InitCheck() == B_OK) { + BPath path; + err = ent.GetPath(&path); + if (!err) { + nod.WriteAttr("_trk/original_path", B_STRING_TYPE, 0LL, path.Path(), strlen(path.Path())+1); + } + } + err = ent.MoveTo(&trashDir, NULL); // don't clober + if (err) { + BString newname("Theme-renamed-"); + newname << system_time(); + err = ent.MoveTo(&trashDir, newname.String(), true); + } + } + } + } + } + + if (id == fSelectedTheme) + fSelectedTheme = -1; + delete theme; + return B_OK; +} + +int32 ThemeManager::SelectedTheme() +{ + BMessage *theme; + theme = ThemeAt(fSelectedTheme); + if (!theme) + return -1; + // XXX: should really check the diff with current. + return fSelectedTheme; +} + +status_t ThemeManager::ApplyDefaultTheme(uint32 flags) +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err, gerr = B_OK; + err = BackupCurrent(); + if (err) + return err; + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_SET_ALL)) + continue; + err = ta->ApplyDefaultTheme(flags); + if (err) + gerr = err; + } + return gerr; +} + + +status_t ThemeManager::BackupCurrent() +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err, gerr = B_OK; + fBackupTheme.MakeEmpty(); + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_RETRIEVE)) + continue; + err = ta->BackupCurrent(fBackupTheme); + if (err) + gerr = err; + } + return gerr; +} + +status_t ThemeManager::RestoreCurrent() +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err, gerr = B_OK; + if (fBackupTheme.IsEmpty()) + return ENOENT; + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_SET_ALL)) + continue; + err = ta->RestoreCurrent(fBackupTheme); + if (err) + gerr = err; + } + fBackupTheme.MakeEmpty(); + return gerr; +} + +bool ThemeManager::CanRevert() +{ + FENTRY; + return !fBackupTheme.IsEmpty(); +} + +status_t ThemeManager::CompareToCurrent(BMessage &theme) +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err; + + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_RETRIEVE)) + continue; + err = ta->CompareToCurrent(theme); + if (err) + return err; + } + return B_OK; +} + + +status_t ThemeManager::InstallFiles(BMessage &theme, BDirectory &folder) +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err, gerr = B_OK; + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_SET_ALL)) + continue; + err = ta->InstallFiles(theme, folder); + if (err) + gerr = err; + } + return gerr; +} + +status_t ThemeManager::BackupFiles(BMessage &theme, BDirectory &folder) +{ + FENTRY; + int32 i; + ThemesAddon *ta; + status_t err, gerr = B_OK; + for (i = 0; i < fAddonCount; i++) { + ta = (ThemesAddon *)fAddonList.ItemAt(i); + if (!ta) + continue; + if (!(ta->AddonFlags() & Z_THEME_ADDON_DO_RETRIEVE)) + continue; + err = ta->BackupFiles(theme, folder); + if (err) + gerr = err; + } + return gerr; +} + +status_t ThemeManager::SaveTheme(int32 id, bool excl) +{ + FENTRY; + status_t err; + BString name, fname; + BPath path; + BDirectory dir; + BDirectory tdir; + BFile tfile; + BMessage names; + BString location; + BMessage *theme; + theme = ThemeAt(id); + if (!theme) + return EINVAL; + err = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (err) return err; + path.Append(Z_THEMES_FOLDER_NAME); + err = dir.SetTo(path.Path()); + if (err) return err; + err = ThemeName(id, name); + if (err) return err; + fname = name; + NormalizeThemeFolderName(fname); + + err = ThemeLocation(id, location); + if (!err) { + if (location.FindFirst("/boot/beos") >= 0) { + PRINT(("trying to save theme '%s' to system dir!\n", name.String())); + return B_PERMISSION_DENIED; + } + } + path.Append(fname.String()); + err = theme->ReplaceString(Z_THEME_LOCATION, path.Path()); + if (err) + err = theme->AddString(Z_THEME_LOCATION, path.Path()); + + if (dir.CreateDirectory(fname.String(), NULL) < B_OK) { + if (excl) + return B_FILE_EXISTS; + } + err = tdir.SetTo(&dir, fname.String()); + if (err) return err; + err = tdir.CreateFile(Z_THEME_FILE_NAME, &tfile); + if (err) return err; + + BMessage tosave(*theme); + err = tosave.RemoveName(Z_THEME_LOCATION); + err = GetNames(names); + + err = DumpMessageToStream(&tosave, tfile, 0, &names); + if (err) return err; + return B_OK; +} + +status_t ThemeManager::PackageTheme(BMessage &theme) +{ + PRINT(("UNIMPLEMENTED %s()\n", __FUNCTION__)); + + (void)theme; + return B_OK; +} + +status_t ThemeManager::LoadTheme(const char *path, BMessage **to) +{ + status_t err; + BDirectory dir; + BFile f; + BMessage *theme; +#ifdef DEBUG_TM + PRINT(("ThemeManager::%s(%s)\n", __FUNCTION__, path)); +#endif + + err = dir.SetTo(path); + if (err) + fprintf(stderr, "ThemeManager:: BDirectory::SetTo 0x%08lx\n", err); + if (err) { /* not a dir, check for a zip */ + // TODO + // unzip + recursive call + return err; + } + err = f.SetTo(&dir, Z_THEME_FILE_NAME, B_READ_ONLY); + if (err) + fprintf(stderr, "ThemeManager:: BFile::SetTo 0x%08lx\n", err); + if (err) + return err; + err = ParseMessageFromStream(&theme, f); + if (err) + fprintf(stderr, "ThemeManager:: ParseMessageFromStream 0x%08lx\n", err); + if (err) + return err; + err = theme->RemoveName(Z_THEME_LOCATION); + err = theme->AddString(Z_THEME_LOCATION, path); + //theme->PrintToStream(); + err = AddTheme(theme); + if (err) + fprintf(stderr, "ThemeManager:: AddTheme 0x%08lx\n", err); + if (err) + delete theme; + if (!err && to) + *to = theme; + return err; +} + +bool ThemeManager::ThemeHasInfoFor(int32 id, BString &module) +{ + FENTRY; + status_t err; + BString m; + int32 i; + BMessage msg; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) + return false; + for (i = 0; msg.FindString(Z_THEME_MODULE_TAG, i, &m) == B_OK; i++) + if (m == module) + return true; + return false; +} + +status_t ThemeManager::ThemeName(int32 id, BString ©to) +{ + FENTRY; + status_t err; + BString s; + BMessage msg; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) + return err; + err = msg.FindString(Z_THEME_NAME, &s); + if (err) + return err; + copyto = s; + return B_OK; +} + +status_t ThemeManager::ThemeLocation(int32 id, BString ©to) +{ + FENTRY; + status_t err; + BString s; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindString(Z_THEME_LOCATION, &s); + if (err) + return err; + copyto = s; + return B_OK; +} + +bool ThemeManager::ThemeIsReadOnly(int32 id) +{ + FENTRY; + status_t err; + BString s; + + if (id < 0) + return true; + + err = ThemeLocation(id, s); + if (err) + return true; + if (s.FindFirst("/boot/beos") >= 0) + return true; + return false; +} + +status_t ThemeManager::ThemeDescription(int32 id, BString ©to) +{ + FENTRY; + status_t err; + BString s; + BMessage msg; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) + return err; + err = msg.FindString(Z_THEME_DESCRIPTION, &s); + if (err) + return err; + copyto = s; + return B_OK; +} + +status_t ThemeManager::ThemeKeywords(int32 id, BString ©to) +{ + FENTRY; + status_t err; + BString s; + BMessage msg; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) + return err; + err = msg.FindString(Z_THEME_KEYWORDS, &s); + if (err) + return err; + copyto = s; + return B_OK; +} + +status_t ThemeManager::ThemeScreenShot(int32 id, BBitmap **copyto) +{ + FENTRY; + status_t err; + BString s, loc; + BMessage msg; + BEntry ent; + entry_ref ref; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + if (!copyto) + return EINVAL; + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) + return err; + err = msg.FindString(Z_THEME_SCREENSHOT_FILENAME, &s); + if (err) + return err; + // TODO + err = ThemeLocation(id, loc); + if (err) + return err; + loc << "/" << s; + err = ent.SetTo(loc.String()); + if (err) + return err; + err = ent.GetRef(&ref); + if (err) + return err; + *copyto = BTranslationUtils::GetBitmap(&ref); + if (!(*copyto)) + return ENOENT; + return B_OK; +} + +status_t ThemeManager::SetThemeHasInfoFor(int32 id, BString module) +{ + FENTRY; + status_t err; + BMessage msg; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) { + msg.MakeEmpty(); + theme->AddMessage(Z_THEME_INFO_MESSAGE, &msg); + } + err = theme->AddString(Z_THEME_MODULE_TAG, module); + if (err) + return err; + err = theme->ReplaceMessage(Z_THEME_INFO_MESSAGE, &msg); + return err; +} + +status_t ThemeManager::SetThemeName(int32 id, BString name) +{ + FENTRY; + status_t err; + BMessage msg; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) { + msg.MakeEmpty(); + theme->AddMessage(Z_THEME_INFO_MESSAGE, &msg); + } + err = msg.ReplaceString(Z_THEME_NAME, name); + if (err) + err = msg.AddString(Z_THEME_NAME, name); + if (err) + return err; + err = theme->ReplaceMessage(Z_THEME_INFO_MESSAGE, &msg); + return err; +} + +status_t ThemeManager::SetThemeDescription(int32 id, BString description) +{ + FENTRY; + status_t err; + BMessage msg; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) { + msg.MakeEmpty(); + theme->AddMessage(Z_THEME_INFO_MESSAGE, &msg); + } + err = msg.ReplaceString(Z_THEME_DESCRIPTION, description); + if (err) + err = msg.AddString(Z_THEME_DESCRIPTION, description); + if (err) + return err; + err = theme->ReplaceMessage(Z_THEME_INFO_MESSAGE, &msg); + return err; +} + +status_t ThemeManager::SetThemeKeywords(int32 id, BString keywords) +{ + FENTRY; + status_t err; + BMessage msg; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) { + msg.MakeEmpty(); + theme->AddMessage(Z_THEME_INFO_MESSAGE, &msg); + } + err = msg.ReplaceString(Z_THEME_KEYWORDS, keywords); + if (err) + err = msg.AddString(Z_THEME_KEYWORDS, keywords); + if (err) + return err; + err = theme->ReplaceMessage(Z_THEME_INFO_MESSAGE, &msg); + return err; +} + +status_t ThemeManager::SetThemeScreenShot(int32 id, BBitmap *bitmap) +{ + FENTRY; + status_t err; + BMessage msg; + BString name; + BString themepath; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + // TODO + err = theme->FindMessage(Z_THEME_INFO_MESSAGE, &msg); + if (err) { + msg.MakeEmpty(); + theme->AddMessage(Z_THEME_INFO_MESSAGE, &msg); + } + err = ThemeLocation(id, themepath); + if (err) + return err; + err = msg.FindString(Z_THEME_SCREENSHOT_FILENAME, &name); + if (!err) { + BPath spath(themepath.String()); + spath.Append(name.String()); + BEntry ent(spath.Path()); + if (ent.InitCheck() == B_OK) + ent.Remove(); + } + + name = "screenshot.png"; + err = msg.ReplaceString(Z_THEME_SCREENSHOT_FILENAME, name); + if (err) + err = msg.AddString(Z_THEME_SCREENSHOT_FILENAME, name); + if (err) + return err; + + // save the BBitmap to a png + BPath spath(themepath.String()); + spath.Append(name.String()); + BFile shotfile(spath.Path(), B_WRITE_ONLY|B_CREATE_FILE); + if (shotfile.InitCheck() != B_OK) + return shotfile.InitCheck(); + BTranslatorRoster *troster = BTranslatorRoster::Default(); + BBitmapStream bmstream(bitmap); + err = troster->Translate(&bmstream, NULL, NULL, &shotfile, 'PNG '/* XXX: hack, should find by mime type */); + if (err) + return err; + + err = theme->ReplaceMessage(Z_THEME_INFO_MESSAGE, &msg); + msg.PrintToStream(); + return err; +} + +status_t ThemeManager::MakeThemeScreenShot(int32 id) +{ + FENTRY; + status_t err; + BBitmap *bmp = NULL; + BMessage *theme; + + if (id < 0) + return EINVAL; + theme = (BMessage *)fThemeList.ItemAt(id); + if (!theme) + return EINVAL; + + // TODO + err = MakeScreenshot(&bmp); + if (err) + return err; + err = SetThemeScreenShot(id, bmp); + + return err; +} + +void ThemeManager::NormalizeThemeFolderName(BString &name) +{ + FENTRY; + name.RemoveSet("\"\\'/&:*~#|`^"); +} + diff --git a/3rdparty/themes/ThemeManager.h b/3rdparty/themes/ThemeManager.h new file mode 100644 index 0000000000..cfa9ddc215 --- /dev/null +++ b/3rdparty/themes/ThemeManager.h @@ -0,0 +1,132 @@ +/* + * ThemeManager class header + */ + +#include +#include +#include + +/* backup of current settings when applying a theme */ +#define THEME_ID_BACKUP -1 + +namespace Z { +namespace ThemeManager { + class ThemeManager; + class ThemesAddon; +} // ns ThemeManager +} // ns Z +using Z::ThemeManager::ThemeManager; +using Z::ThemeManager::ThemesAddon; + +class BDirectory; +class BBitmap; +class BView; + +namespace Z { +namespace ThemeManager { + +class ThemeManager { +public: + ThemeManager(); +virtual ~ThemeManager(); + + /* addon list */ +status_t LoadAddons(); +status_t UnloadAddons(); +int32 FindAddon(const char *name); +int32 CountAddons(); +ThemesAddon *AddonAt(int32 addon); + + /* addon presentation */ + +const char *AddonName(int32 addon); +const char *AddonDescription(int32 addon); +BView *OptionsView(int32 addon); +status_t RunPreferencesPanel(int32 addon); +status_t LoadSettings(); +status_t SaveSettings(); +void SetAddonFlags(int32 addon, uint32 flags); +uint32 AddonFlags(int32 addon); + /* add pretty names */ +status_t AddNames(BMessage &names); +status_t GetNames(BMessage &names); + + /* Theme enumeration - INTERNAL */ + +status_t LoadThemes(); +status_t AddTheme(BMessage *theme); +status_t UnloadThemes(); /* just for cleanup */ +int32 CountThemes(); +BMessage *ThemeAt(int32 id, bool allowbackup = false); +status_t SetThemeAt(int32 id, BMessage ©from); +int32 FindTheme(const char *name); +status_t CurrentTheme(BMessage ©to); + + /* Theme manipulation */ + +status_t ApplyTheme(int32 id, uint32 flags=0L); +int32 MakeTheme(uint32 flags=0L); +status_t UpdateTheme(int32 id, uint32 flags=0L); +status_t DeleteTheme(int32 id); +int32 SelectedTheme(); + +status_t ApplyDefaultTheme(uint32 flags=0L); + +status_t BackupCurrent(); +status_t RestoreCurrent(); +bool CanRevert(); +status_t CompareToCurrent(BMessage &theme); + + /* Theme installation */ + +status_t InstallFiles(BMessage &theme, BDirectory &folder); +status_t BackupFiles(BMessage &theme, BDirectory &folder); + + /* save to disk */ +status_t SaveTheme(int32 id, bool excl = false); + /* make a zip */ +status_t PackageTheme(BMessage &theme); + /* load from disk (zip / folder) */ +status_t LoadTheme(const char *path, BMessage **to=NULL); + + /* Theme properties */ + +bool ThemeHasInfoFor(int32 id, BString &module); +status_t ThemeName(int32 id, BString ©to); +status_t ThemeLocation(int32 id, BString ©to); +bool ThemeIsReadOnly(int32 id); +status_t ThemeDescription(int32 id, BString ©to); +status_t ThemeKeywords(int32 id, BString ©to); +status_t ThemeScreenShot(int32 id, BBitmap **copyto); + +status_t SetThemeHasInfoFor(int32 id, BString module); +status_t SetThemeName(int32 id, BString name); +status_t SetThemeDescription(int32 id, BString description); +status_t SetThemeKeywords(int32 id, BString keywords); +status_t SetThemeScreenShot(int32 id, BBitmap *bitmap); + /* create the screenshot from current and add it */ +status_t MakeThemeScreenShot(int32 id); + + /* utilities */ + + /* remove all bad chars */ +void NormalizeThemeFolderName(BString &name); + +private: + BMessage fSettings; + BMessage fBackupTheme; /* as in last selected */ + BString fCurrentThemeName; + int32 fSelectedTheme; + BList fAddonList; + int32 fAddonCount; + BList fThemeList; + BMessage fNames; /* pretty names for fields */ +}; + +} // ns ThemeManager +} // ns Z + +#define Z_THEME_MANAGER_SETTINGS_FILE "x-vnd.yT-ThemeManager" + +using namespace Z::ThemeManager; + diff --git a/3rdparty/themes/Themes.rdef b/3rdparty/themes/Themes.rdef new file mode 100644 index 0000000000..9be6376f6d --- /dev/null +++ b/3rdparty/themes/Themes.rdef @@ -0,0 +1,98 @@ + +resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.mmu_man.Themes"; + +resource app_version { + major = 0, + middle = 1, + minor = 0, + variety = B_APPV_ALPHA, + internal = 0, + short_info = "Themes", + long_info = "Themes ©2006-2008 François Revol." +}; + +resource app_flags B_SINGLE_LAUNCH; + +resource(1, "BEOS:FILE_TYPES") message; + +#ifdef HAIKU_TARGET_PLATFORM_HAIKU + +resource vector_icon { + $"6E636966050500020106023AB09C387275BA11FB3C46904852304A0DE300FFE7" + $"DCFFE29C7A020002043C233C3AF073BE44203F4BD14A79EB417FF50DF1F6FFCB" + $"7B8288AC67D4F2F7F9B1FFB4BDD79704016B05FF0C0609BF2E034C524C525052" + $"5850C86DC7735C4A60406044603C5E3A5C3CCB50BFBA5E3ECA9EC11F584A5054" + $"4EC819C490C74DC62806062F0F323A3A3C3C3A4034BF59354232423044423644" + $"32C040BC5A383E3E3E383E0607A22B3058363A5C405A445A445A485A46503A48" + $"0204B44B2FB5172DB37F31B3E53AB3E538B3E53CB99342B8C744BA5F40B99335" + $"BA5F37B8C7330204BEA73CBF733ABDDB3EBEA748BE26C1EDBF734CC4D450C408" + $"52C564C58FC4D442C5A044C408400204363EBD353E323E2C4C28483050BDDBC4" + $"3BBD0FC507BE2CC3EABD60C20FBD47C305BD86C096060BEEEC2E3046264A2646" + $"264C284E2652245028542C2C582856305A3456385C345C3C5C3C58445AC037CB" + $"3C48563C4A04032E24B87A3EB5BD3AB42542B755422E04032E4E425A3256345E" + $"305E3A0202263028302230263624362A360202413E433E3D3E40463E46444602" + $"024B494C4C4B4B484E4B4E4C4F070A0303000102000A00040304070810011784" + $"20040A02020304000A000106000A0001051001178400040A010105000A040309" + $"0A0B00" +}; + +#else // HAIKU_TARGET_PLATFORM_HAIKU + +resource large_icon +{ + $"FFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF00F9F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF00F9FBF9F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF00F9FBFBF9F9F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF001717F9F9F9F9F9F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF003F3F1717F9F9F9F9F9F90000FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF003F1B3F3F1717F9F9F9FBF9F900FFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF003F1B1C1B3F3F1717F9F9FBF900FFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF003F00001B1C1B3F3F1717F9F900FFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF003F1B1B00001B1B1B1B3F171700FFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF003F1B1B1B1B1B00001B1C3F3F170000FFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF003F1B1C1B00001C1C3F001C1B3F3F170000FFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFF003F1B1C007B7B000F1B1C00001B1C3F3F170000FFFFFFFFFF" + $"FFFFFFFFFFFFFF003F1B0000DA7B7B001C1C1C1C00001C1B3F3F1700FFFFFFFF" + $"FFFFFFFFFFFFFF003F1B002B2BDA7B001C001B1C1C1C1B00001C1700FFFFFFFF" + $"FFFFFFFFFFFFFF003F1B002B2F2F00001B00001B1B1B1B1B1B1B1700FFFFFFFF" + $"FFFFFFFFFFFFFF003F002B2CEB2F001B1C1C1C1C00001B1B1B1B1700FFFFFFFF" + $"FFFFFFFFFFFFFF003F002B2F2F001B1B00001C1B1C1C1B1C1C1B1700FFFFFFFF" + $"FFFFFFFFFFFFFF00002B2CEB2F001B1C000000001B1C1C1C1B1C1700FFFFFFFF" + $"FFFF000000FFFF00002B2F2F001B1C1B001C1B0000001B1C1C1C1700FFFFFFFF" + $"FF007B7B7B00FF002B2CEB2F001B1B1C001B1C1C1B001C1C1B1C1800FFFFFFFF" + $"007B7B7BDA00FF002B2F2F001B1C1B1C00001B1C1C001C1B1C1C1800FFFFFFFF" + $"002B2CDA7B7B002B2CEB2F001B1C1C1C1C1C00001B001C1B1C1B1700FFFFFFFF" + $"FF002B2CDA7B2B2CEB2F000017171C1C1B1C1C1C00001B1C1C1B1700FFFFFFFF" + $"FF002B2CDA7B2B2CEB2F00FF000017171A1B1C1C1B1B1C1B1C1B1800FFFFFFFF" + $"FFFF002B2C2B2B2F2F00FFFFFFFF000017171A1B1B1C1C1C1B1C1700FFFFFFFF" + $"FFFF002B2C2B2B2F2F00FFFFFFFFFFFF000017171C1C1C1C1B1B1800FFFFFFFF" + $"FFFFFF002B2CEB2F00FFFFFFFFFFFFFFFFFF000017171C1C1B1C1700FFFFFFFF" + $"FFFFFF002B2CEB2F00FFFFFFFFFFFFFFFFFFFFFF000017171C1C1700FFFFFFFF" + $"FFFFFFFF002B2F000E0F0F0F0F0F0F0F0E0FFFFFFFFF0000171718000F0EFFFF" + $"FFFFFFFF0000000E0F0F0F0F0F0F0F0E0F0FFFFFFFFFFFFF000017000F0F0F0E" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000E0F0F0F" +}; + +resource mini_icon +{ + $"FFFFFF000000FFFFFFFFFFFFFFFFFFFF" + $"FFFFFF00E5F90000FFFFFFFFFFFFFFFF" + $"FFFFFF001B63F9F90000FFFFFFFFFFFF" + $"FFFFFF001D1D1B63F9F900FFFFFFFFFF" + $"FFFFFF00160D141D1A6300FFFFFFFFFF" + $"FFFFFF001D1B0D0E151D150000FFFFFF" + $"FFFFFF003F1B001C1B0E0D1D1500FFFF" + $"FFFFFF003F007B001B141B141400FFFF" + $"FFFFFF003F002F001B1B0E1B1B00FFFF" + $"FFFFFF00002F001B1C060D1B1B00FFFF" + $"FF00FF00002F001B1C1B0D1B1B00FFFF" + $"002B00002F0017171C0E061B1B00FFFF" + $"002B7B2CEB000000171B1B1B1B00FFFF" + $"FF002B2F00FFFFFF0000191C1B00FFFF" + $"FF002B2F00FFFFFFFFFF00001900FFFF" + $"FFFF00000E0F0F0F0FFFFFFF00000E0E" +}; + +#endif // HAIKU_TARGET_PLATFORM_HAIKU + diff --git a/3rdparty/themes/ThemesAddon.cpp b/3rdparty/themes/ThemesAddon.cpp new file mode 100644 index 0000000000..992c664186 --- /dev/null +++ b/3rdparty/themes/ThemesAddon.cpp @@ -0,0 +1,229 @@ +/* + * ThemesAddon class + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "ThemesAddon.h" + + +#define DEBUG_TA +#ifdef DEBUG_TA +#define FENTRY PRINT(("ThemesAddon[%s]::%s()\n", Name(), __FUNCTION__)) +#else +#define FENTRY +#endif + + +extern bool CompareMessages(BMessage &a, BMessage &b); + + +ThemesAddon::ThemesAddon(const char *name, const char *message_name) + :fImageId(-1), + fName(NULL), + fMsgName(NULL), + fFlags(0L) +{ + fName = strdup(name); + FENTRY; + if (message_name) + fMsgName = strdup(message_name); + fSettings.MakeEmpty(); +} + +ThemesAddon::~ThemesAddon() +{ + FENTRY; + free(fMsgName); + free(fName); +} + +const char *ThemesAddon::Name() +{ + return (const char *)fName; +} + +const char *ThemesAddon::Description() +{ + FENTRY; + return "No description yet."; +} + +BView *ThemesAddon::OptionsView() +{ + FENTRY; + return NULL; +} + +status_t ThemesAddon::RunPreferencesPanel() +{ + FENTRY; + return B_OK; +} + +status_t ThemesAddon::LoadSettings(BMessage &settings) +{ + FENTRY; + uint32 flags; + fSettings = settings; + if (fSettings.FindInt32("ta:flags", (int32 *)&flags) >= B_OK) + fFlags = flags; + return B_OK; +} + +status_t ThemesAddon::SaveSettings(BMessage &settings) +{ + FENTRY; + status_t err; + err = fSettings.ReplaceInt32("ta:flags", fFlags); + settings = fSettings; + return err; +} + +void ThemesAddon::SetAddonFlags(uint32 flags) +{ + fFlags = flags; +} + +uint32 ThemesAddon::AddonFlags() +{ + return fFlags; +} + +status_t ThemesAddon::AddNames(BMessage &names) +{ + FENTRY; + BString str; + if (MessageName()) + str = Name(); + str << " settings"; + names.AddString(MessageName(), str.String()); + return B_OK; +} + + +status_t ThemesAddon::MyMessage(BMessage &theme, BMessage &mine) +{ + FENTRY; + BMessage msg; + status_t err; + if (!MessageName()) + return B_NAME_NOT_FOUND; + err = theme.FindMessage(MessageName(), &msg); + if (err) + return err; + mine = msg; + return B_OK; +} + +status_t ThemesAddon::SetMyMessage(BMessage &theme, BMessage &mine) +{ + FENTRY; + status_t err; + BMessage msg; + if (!MessageName()) + return B_NAME_NOT_FOUND; + err = theme.FindMessage(MessageName(), &msg); + if (err) + err = theme.AddMessage(MessageName(), &mine); + else + err = theme.ReplaceMessage(MessageName(), &mine); + return err; +} + +const char *ThemesAddon::MessageName() +{ + return (const char *)fMsgName; +} + +status_t ThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + FENTRY; + (void)theme; (void) flags; + return B_OK; +} + +status_t ThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + FENTRY; + (void)theme; (void) flags; + return B_OK; +} + +status_t ThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + FENTRY; + (void) flags; + return B_OK; +} + + +status_t ThemesAddon::BackupCurrent(BMessage &theme) +{ + FENTRY; + return MakeTheme(theme); +} + +status_t ThemesAddon::RestoreCurrent(BMessage &theme) +{ + FENTRY; + return ApplyTheme(theme); +} + +/* by default, try to find the addon's specific message + * and compare them. Some addons don't add any message, + * they'll have to do comparison by hand. + */ +status_t ThemesAddon::CompareToCurrent(BMessage &theme) +{ + FENTRY; + BMessage current, a, b; + BackupCurrent(current); + status_t err; + err = theme.FindMessage(MessageName(), &a); + if (err) + return err; + err = current.FindMessage(MessageName(), &b); + if (err) + return err; + if (!CompareMessages(a, b)) + return 1; + + return B_OK; +} + + +status_t ThemesAddon::InstallFiles(BMessage &theme, BDirectory &folder) +{ + FENTRY; + (void)theme; (void)folder; + return B_OK; +} + +status_t ThemesAddon::BackupFiles(BMessage &theme, BDirectory &folder) +{ + FENTRY; + (void)theme; (void)folder; + return B_OK; +} + + + /* private */ + +void ThemesAddon::SetImageId(image_id id) +{ + fImageId = id; +} + +image_id ThemesAddon::ImageId() +{ + return fImageId; +} + diff --git a/3rdparty/themes/ThemesAddon.h b/3rdparty/themes/ThemesAddon.h new file mode 100644 index 0000000000..42144ad742 --- /dev/null +++ b/3rdparty/themes/ThemesAddon.h @@ -0,0 +1,97 @@ +/* + * ThemesAddon class header + */ + +#include +class BView; +class BMessage; +class BDirectory; + +namespace Z { +namespace ThemeManager { + +class ThemeManager; + +class ThemesAddon { +public: + ThemesAddon(const char *name, const char *message_name); +virtual ~ThemesAddon(); + + /* presentation */ + +virtual const char *Name(); /* pretty name */ +virtual const char *Description(); /* tooltip... */ + +virtual BView *OptionsView(); +virtual status_t RunPreferencesPanel(); + // if you override, call it first +virtual status_t LoadSettings(BMessage &settings); + // if you override, call it last +virtual status_t SaveSettings(BMessage &settings); +void SetAddonFlags(uint32 flags); +uint32 AddonFlags(); +virtual status_t AddNames(BMessage &names); + + /* Theme manipulation */ + + // name of the submessage in the theme, if any +virtual const char *MessageName(); + // retrieve the addons specific message if any +virtual status_t MyMessage(BMessage &theme, BMessage &mine); +virtual status_t SetMyMessage(BMessage &theme, BMessage &mine); + +virtual status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +virtual status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +virtual status_t ApplyDefaultTheme(uint32 flags=0L); + +virtual status_t BackupCurrent(BMessage &theme); +virtual status_t RestoreCurrent(BMessage &theme); + +virtual status_t CompareToCurrent(BMessage &theme); + + /* Theme installation */ + +virtual status_t InstallFiles(BMessage &theme, BDirectory &folder); +virtual status_t BackupFiles(BMessage &theme, BDirectory &folder); + + /* */ + +private: + +friend class Z::ThemeManager::ThemeManager; + void SetImageId(image_id id); + image_id ImageId(); + + image_id fImageId; + char *fName; + char *fMsgName; + uint32 fFlags; + BMessage fSettings; +}; + +} // ns ThemeManager +} // ns Z + +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon(); + +#ifdef SINGLE_BINARY +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_backgrounds(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_beide(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_deskbar(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_eddie(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_pe(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_screensaver(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_soundplay(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_sounds(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_terminal(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_ui_settings(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_winamp_skin(); +extern "C" Z::ThemeManager::ThemesAddon *instanciate_themes_addon_window_decor(); +#endif + +/* in B_*_ADDONS_DIRECTORY */ +#define Z_THEMES_ADDON_FOLDER "ThemeManager" + +using namespace Z::ThemeManager; + diff --git a/3rdparty/themes/UITheme.h b/3rdparty/themes/UITheme.h new file mode 100644 index 0000000000..7d9a1042d4 --- /dev/null +++ b/3rdparty/themes/UITheme.h @@ -0,0 +1,43 @@ +#ifndef _Z_UI_THEME_H +#define _Z_UI_THEME_H + +// the global message what code +#define Z_THEME_MESSAGE_WHAT 'ZThm' + +// reserved field names at top level +#define Z_THEME_NAME "z:theme:name" +#define Z_THEME_DESCRIPTION "z:theme:description" +#define Z_THEME_SCREENSHOT_FILENAME "z:theme:screenshot" +#define Z_THEME_KEYWORDS "z:theme:keywords" + // path of the theme folder/zip +#define Z_THEME_LOCATION "z:theme:location" + // identifies a module this theme has info for. +#define Z_THEME_MODULE_TAG "z:theme:moduletag" + +// the names of the global BMessages +#define Z_THEME_INFO_MESSAGE "z:theme:infos" +#define Z_THEME_UI_SETTINGS "ui_settings" +#define Z_THEME_WINDOW_DECORATIONS "window_decorations" +#define Z_THEME_BACKGROUND_SETTINGS B_BACKGROUND_INFO +#define Z_THEME_DESKBAR_SETTINGS "deskbar_settings" +#define Z_THEME_TERMINAL_SETTINGS "terminal_prefs" +#define Z_THEME_DIRCOLOURS_SETTINGS "dircolours_settings" +#define Z_THEME_BEIDE_SETTINGS "BeIDE_settings" +#define Z_THEME_EDDIE_SETTINGS "Eddie_settings" +#define Z_THEME_PE_SETTINGS "Pe_settings" +#define Z_THEME_SCREENSAVER_SETTINGS "screensaver_settings" +#define Z_THEME_SOUNDS_SETTINGS "sounds_settings" +#define Z_THEME_WINAMP_SKIN_SETTINGS "winamp_skin_settings" + +// Addon Flags + // allow this addon to apply themes +#define Z_THEME_ADDON_DO_APPLY 0x00000001 +#define Z_THEME_ADDON_DO_SAVE 0x00000002 /* not sure about the semantics */ +#define Z_THEME_ADDON_DO_SET_ALL (Z_THEME_ADDON_DO_APPLY|Z_THEME_ADDON_DO_SAVE) + // allow this addon to save things to themes +#define Z_THEME_ADDON_DO_RETRIEVE 0x00000004 + +#define Z_THEMES_FOLDER_NAME "UIThemes" +#define Z_THEME_FILE_NAME "Theme" + +#endif /* _Z_UI_THEME_H */ diff --git a/3rdparty/themes/ViewItem.cpp b/3rdparty/themes/ViewItem.cpp new file mode 100644 index 0000000000..bedd0f9ab2 --- /dev/null +++ b/3rdparty/themes/ViewItem.cpp @@ -0,0 +1,66 @@ +#include "ViewItem.h" +#include +#include +#include +#include + +ViewItem::ViewItem(BRect bounds, const char *name, uint32 resizeMask, uint32 flags, uint32 level, bool expanded) + : BView(bounds, name, resizeMask, flags), BListItem(level, expanded) +{ + fOwner = NULL; + SetWidth(bounds.Width()); + SetHeight(bounds.Height()); +} + +ViewItem::~ViewItem() +{ + if (fOwner) + fOwner->RemoveChild(this); +} + +void ViewItem::DrawItem(BView *ownerview, BRect frame, bool complete) +{ + (void)frame; (void)complete; + if (!fOwner) { + fOwner = dynamic_cast(ownerview); + if (!ownerview) + return; + ownerview->AddChild(this); + } +#if 0 + const BListItem **list = fOwner->Items(); + for (long i = 0; i < fOwner->CountItems(); i++) { + if (list[i] == this) { + BRect frame(fOwner->ItemFrame(i)); + //ResizeTo(frame.Width(), frame.Height()); + //MoveTo(frame.left, frame.top); + } + } +#endif + //BListItem::DrawItem(ownerview, frame, complete); +} + +void ViewItem::Update(BView *ownerview, const BFont *font) +{ + PRINT(("ViewItem::Update()\n")); + (void)font; + if (!fOwner) { + fOwner = dynamic_cast(ownerview); + if (!ownerview) + return; + PRINT(("ViewItem::Update(), fOwner=%p\n", fOwner)); + fOwner->AddChild(this); + } + //BListItem::Update(ownerview, font); + const BListItem **list = fOwner->Items(); + for (long i = 0; i < fOwner->CountItems(); i++) { + if (list[i] == this) { + BRect frame(fOwner->ItemFrame(i)); + ResizeTo(frame.Width(), Bounds().Height()); + MoveTo(frame.left, frame.top); + } + } + SetWidth(Bounds().Width()); + SetHeight(Bounds().Height()); +} + diff --git a/3rdparty/themes/ViewItem.h b/3rdparty/themes/ViewItem.h new file mode 100644 index 0000000000..52decb2164 --- /dev/null +++ b/3rdparty/themes/ViewItem.h @@ -0,0 +1,19 @@ +#ifndef _VIEW_ITEM_H_ +#define _VIEW_ITEM_H_ + +#include +#include +#include + +class ViewItem : public BView, public BListItem +{ + public: + ViewItem(BRect bounds, const char *name, uint32 resizeMask, uint32 flags, uint32 level = 0, bool expanded = true); + virtual ~ViewItem(); +virtual void DrawItem(BView *ownerview, BRect frame, bool complete = false); +virtual void Update(BView *ownerview, const BFont *font); + private: + BListView *fOwner; +}; + +#endif // _VIEW_ITEM_H_ diff --git a/3rdparty/themes/addons/BackgroundsAddon.cpp b/3rdparty/themes/addons/BackgroundsAddon.cpp new file mode 100644 index 0000000000..a27c80d1d6 --- /dev/null +++ b/3rdparty/themes/addons/BackgroundsAddon.cpp @@ -0,0 +1,266 @@ +/* + * backgrounds ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_backgrounds +#endif + +#define A_NAME "Backgrounds" +#define A_MSGNAME Z_THEME_BACKGROUND_SETTINGS +#define A_DESCRIPTION "Desktop backdrops" + +#define B__DESKTOP_COLOR "be:desktop_color" + +class BackgroundThemesAddon : public ThemesAddon { +public: + BackgroundThemesAddon(); + ~BackgroundThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); + +//status_t CompareToCurrent(BMessage &theme); + + /* Theme installation */ + +status_t InstallFiles(BMessage &theme, BDirectory &folder); +status_t BackupFiles(BMessage &theme, BDirectory &folder); + +}; + +BackgroundThemesAddon::BackgroundThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +BackgroundThemesAddon::~BackgroundThemesAddon() +{ +} + +const char *BackgroundThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t BackgroundThemesAddon::RunPreferencesPanel() +{ +/* if (be_roster->Launch("application/x-vnd.obos-Backgrounds") < B_OK) + if (be_roster->Launch("application/x-vnd.Be-Backgrounds") < B_OK) + return B_ERROR;*/ + status_t err; + entry_ref ref; + BEntry ent; + err = ent.SetTo("/boot/beos/preferences/Backgrounds"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + } + } + if (!err) + return B_OK; + err = ent.SetTo("/system/add-ons/Preferences/Backgrounds"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + if (err) { + BMessage msg(B_REFS_RECEIVED); + msg.AddRef("refs", &ref); + be_app_messenger.SendMessage(&msg); + } + } + } + return err; +} + +status_t BackgroundThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_BACKGROUND_SETTINGS, "Desktop backgrounds and color; please respect count and ordering of all fields!"); + names.AddString(B_BACKGROUND_WORKSPACES, "Workspaces each backdrop apply to"); + names.AddString(B_BACKGROUND_IMAGE, "Actual backdrop image file"); + names.AddString(B_BACKGROUND_MODE, "image mode: 0=use_origin, 1=centered, 2=scaled, 3=tiled"); + names.AddString(B_BACKGROUND_ORIGIN, "Origin point for mode 0"); + names.AddString(B_BACKGROUND_ERASE_TEXT, "If true, use desktop color as icon text background"); + names.AddString(B__DESKTOP_COLOR, "one per workspace, up to the last changing one"); + return B_OK; +} + +status_t BackgroundThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage backgrounds; + status_t err = B_OK; + BPath pDesktop; + ssize_t flatSize; + char *pAttr; + + (void)flags; + err = MyMessage(theme, backgrounds); + if (err) + return err; + + // set desktop colors + BScreen bs; + rgb_color col; + //const rgb_color *c; + col = bs.DesktopColor(0); // by + // should work as the rest of the fields (grouping) + for (int i = 0; i < count_workspaces(); i++) { + //ssize_t sz = 4; + if (backgrounds.FindRGBColor(B__DESKTOP_COLOR, i, &col) != B_OK && i == 0) + //if (backgrounds.FindData(B__DESKTOP_COLOR, (type_code)'RGBC', i, (const void **)&c, &sz) != B_OK && i == 0) + break; // if no color at all, don't set them + bs.SetDesktopColor(col, i, true); + } + // make sure we don't leave our garbage in the message + // as it would offset the next call by adding rgb_colors on existing ones + backgrounds.RemoveName(B__DESKTOP_COLOR); + + BMessenger tracker("application/x-vnd.Be-TRAK"); + BMessage m(B_RESTORE_BACKGROUND_IMAGE); + + if (find_directory(B_DESKTOP_DIRECTORY, &pDesktop) < B_OK) + return EINVAL; + BNode nDesktop(pDesktop.Path()); + if (nDesktop.InitCheck() < B_OK) + return nDesktop.InitCheck(); + flatSize = backgrounds.FlattenedSize(); + pAttr = new char[flatSize]; + if (pAttr == NULL) + return ENOMEM; + err = backgrounds.Flatten(pAttr, flatSize); + if (err < B_OK) + goto getout; + err = nDesktop.WriteAttr(B_BACKGROUND_INFO, B_MESSAGE_TYPE, 0LL, pAttr, flatSize); + if (err < B_OK) + goto getout; + + //m.AddSpecifier("Window", "Desktop"); + tracker.SendMessage(&m); + + return B_OK; + +getout: + delete [] pAttr; + return err; +} + +status_t BackgroundThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + BMessage backgrounds; + status_t err = B_OK; + BPath pDesktop; + struct attr_info ai; + char *pAttr; + BScreen bs; + rgb_color last_color = {0, 0, 0, 254}; + rgb_color col; + int last_change = 0; + int i; + + (void)flags; + err = MyMessage(theme, backgrounds); + if (err) + backgrounds.MakeEmpty(); + + if (find_directory(B_DESKTOP_DIRECTORY, &pDesktop) < B_OK) + return EINVAL; + BNode nDesktop(pDesktop.Path()); + if (nDesktop.InitCheck() < B_OK) + return nDesktop.InitCheck(); + if (nDesktop.GetAttrInfo(B_BACKGROUND_INFO, &ai) < B_OK) + return EIO; + pAttr = new char[ai.size]; + if (pAttr == NULL) + return ENOMEM; + err = nDesktop.ReadAttr(B_BACKGROUND_INFO, ai.type, 0LL, pAttr, ai.size); + if (err < B_OK) + goto getout; + err = backgrounds.Unflatten(pAttr); + if (err < B_OK) + goto getout; + + // make sure other colors are removed + backgrounds.RemoveName(B__DESKTOP_COLOR); + + // get desktop color... XXX: move it in ui_settings ? + // should work as the rest of the fields (grouping) + for (i = 0; i < count_workspaces(); i++) { + col = bs.DesktopColor(i); + if (memcmp(&last_color, &col, sizeof(rgb_color))) { + last_change = i; + last_color = col; + } + } + //printf("ws col cnt %d\n", last_change); + for (i = 0; i <= last_change; i++) { + col = bs.DesktopColor(i); + backgrounds.AddRGBColor(B__DESKTOP_COLOR, col); + //backgrounds->AddData(B__DESKTOP_COLOR, (type_code)'RGBC', &col, 4); + } + + err = SetMyMessage(theme, backgrounds); + return err; + +getout: + delete [] pAttr; + return err; +} + +status_t BackgroundThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage backgrounds; + rgb_color col = {51,102,152,255}; // Be Blues... ;) + backgrounds.AddBool(B_BACKGROUND_ERASE_TEXT, true); + backgrounds.AddRGBColor(B__DESKTOP_COLOR, col); + theme.AddMessage(A_MSGNAME, &backgrounds); + return ApplyTheme(theme, flags); +} + +status_t BackgroundThemesAddon::InstallFiles(BMessage &theme, BDirectory &folder) +{ + (void)theme; (void)folder; + return B_OK; +} + +status_t BackgroundThemesAddon::BackupFiles(BMessage &theme, BDirectory &folder) +{ + (void)theme; (void)folder; + return B_OK; +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new BackgroundThemesAddon; +} diff --git a/3rdparty/themes/addons/BeIDEAddon.cpp b/3rdparty/themes/addons/BeIDEAddon.cpp new file mode 100644 index 0000000000..e536fa0d8e --- /dev/null +++ b/3rdparty/themes/addons/BeIDEAddon.cpp @@ -0,0 +1,191 @@ +/* + * BeIDE Color ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_beide +#endif + +#define A_NAME "BeIDE Colors" +#define A_MSGNAME NULL //Z_THEME_BEIDE_SETTINGS +#define A_DESCRIPTION "Make BeIDE use system colors" + +#define BEIDE_SETTINGS_NAME "Metrowerks/BeIDE_Prefs" + +// __PACKED +struct beide_editor_pref { + uint32 dummy; /* BIG ENDIAN */ + rgb_color bg; + rgb_color selbg; + uint32 flashing_delay; /* BIG ENDIAN */ + uint8 balance_while_typing; + uint8 relaxed_c_popup; + uint8 sort_func_popup; + uint8 dummy2; + uint8 remember_sel_pos; + uint8 dummy3; + uint8 dummy4; + uint8 dummy5; +}; + + +class BeIDEThemesAddon : public ThemesAddon { +public: + BeIDEThemesAddon(); + ~BeIDEThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +BeIDEThemesAddon::BeIDEThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +BeIDEThemesAddon::~BeIDEThemesAddon() +{ +} + +const char *BeIDEThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t BeIDEThemesAddon::RunPreferencesPanel() +{ + return B_OK; +} + +status_t BeIDEThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_BEIDE_SETTINGS, "BeIDE Settings"); + return B_OK; +} + +status_t BeIDEThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage uisettings; + status_t err; + struct beide_editor_pref bp; + BPath beideSPath; + rgb_color col; + + (void)flags; + err = theme.FindMessage(Z_THEME_UI_SETTINGS, &uisettings); + if (err) + return err; + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &beideSPath) < B_OK) + return B_ERROR; + beideSPath.Append(BEIDE_SETTINGS_NAME); + BFile beideSettings(beideSPath.Path(), B_READ_WRITE); + if (beideSettings.InitCheck() < B_OK) + return beideSettings.InitCheck(); + if (beideSettings.ReadAttr("AppEditorPrefs", 'rPWM', 0LL, &bp, + sizeof(struct beide_editor_pref)) < B_OK) + return B_ERROR; + if (uisettings.FindRGBColor(B_UI_DOCUMENT_BACKGROUND_COLOR, &col) >= B_OK) + bp.bg = col; + if (uisettings.FindRGBColor(B_UI_MENU_SELECTED_BACKGROUND_COLOR, &col) >= B_OK) + bp.selbg = col; + + if (true/* || flags & UI_THEME_SETTINGS_SAVE*/) { + err = beideSettings.WriteAttr("AppEditorPrefs", 'rPWM', 0LL, &bp, + sizeof(struct beide_editor_pref)); + } + if (true/* || flags & UI_THEME_SETTINGS_APPLY*/) { + BList teamList; + app_info ainfo; + int32 count, i; + be_roster->GetAppList(&teamList); + count = teamList.CountItems(); + for (i = 0; i < count; i++) { + if (be_roster->GetRunningAppInfo((team_id)(teamList.ItemAt(i)), &ainfo) == B_OK) { + if (!strcmp(ainfo.signature, "application/x-mw-BeIDE")) { + BMessenger msgr(NULL, ainfo.team); + BMessage msg(B_PASTE); + BMessage click(B_MOUSE_DOWN); + /* first get the prefs window to map the correct view */ + /* hey BeIDE '_MDN' of View listview of Window 0 with 'be:view_where=BPoint(58.0, 103.0)' */ + click.AddSpecifier("View", "listview"); + click.AddSpecifier("Window", "Environment Preferences"); + click.AddPoint("be:view_where", BPoint(58.0,103.0)); + err = msgr.SendMessage(click); + + msg.AddSpecifier("View", "Background"); + msg.AddSpecifier("View", "colorsview"); + msg.AddSpecifier("Window", "Environment Preferences"); + msg.AddPoint("_drop_point_", BPoint(0,0)); + msg.AddData("RGBColor", B_RGB_COLOR_TYPE, &bp.bg, 4); + err = msgr.SendMessage(msg); + + msg.MakeEmpty(); + msg.AddSpecifier("View", "Hilite"); + msg.AddSpecifier("View", "colorsview"); + msg.AddSpecifier("Window", "Environment Preferences"); + msg.AddPoint("_drop_point_", BPoint(0,0)); + msg.AddData("RGBColor", B_RGB_COLOR_TYPE, &bp.selbg, 4); + err = msgr.SendMessage(msg); + + msg.MakeEmpty(); + msg.what = 'SSav'; + msg.AddSpecifier("Window", "Environment Preferences"); + err = msgr.SendMessage(msg); + } + } + } + } + return B_OK; +} + +status_t BeIDEThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + (void)theme; (void)flags; + return B_OK; +} + +status_t BeIDEThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage uisettings; + rgb_color bg = {255, 255, 255, 255}; + rgb_color selbg = {216, 216, 216, 255}; + uisettings.AddRGBColor(B_UI_DOCUMENT_BACKGROUND_COLOR, bg); + uisettings.AddRGBColor(B_UI_MENU_SELECTED_BACKGROUND_COLOR, selbg); + theme.AddMessage(Z_THEME_UI_SETTINGS, &uisettings); + return ApplyTheme(theme, flags); +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new BeIDEThemesAddon; +} diff --git a/3rdparty/themes/addons/DanoWindowDecorAddon.cpp b/3rdparty/themes/addons/DanoWindowDecorAddon.cpp new file mode 100644 index 0000000000..8c49f4d7bb --- /dev/null +++ b/3rdparty/themes/addons/DanoWindowDecorAddon.cpp @@ -0,0 +1,157 @@ +/* + * window_decor ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_window_decor +#endif + +#define A_NAME "Window Decor" +#define A_MSGNAME Z_THEME_WINDOW_DECORATIONS +#define A_DESCRIPTION "Window decorations and scrollbars" + +class DecorThemesAddon : public ThemesAddon { +public: + DecorThemesAddon(); + ~DecorThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +DecorThemesAddon::DecorThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +DecorThemesAddon::~DecorThemesAddon() +{ +} + +const char *DecorThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t DecorThemesAddon::RunPreferencesPanel() +{ + status_t err; + entry_ref ref; + BEntry ent; + err = ent.SetTo("/system/add-ons/Preferences/Appearance"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + if (err) { + BMessage msg(B_REFS_RECEIVED); + msg.AddRef("refs", &ref); + be_app_messenger.SendMessage(&msg); + } + } + } + return err; +} + +status_t DecorThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_WINDOW_DECORATIONS, "Window decorations and scrollbars"); + names.AddString("window:decor", "Window decor"); + names.AddString("window:decor_globals", "Window decor parameters"); + return B_OK; +} + +status_t DecorThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage window_decor; + BMessage globals; + BString decorName; + status_t err; + + (void)flags; + err = MyMessage(theme, window_decor); + if (err) + return err; + +#ifdef B_BEOS_VERSION_DANO + if (window_decor.FindString("window:decor", &decorName) == B_OK) + set_window_decor(decorName.String(), + (window_decor.FindMessage("window:decor_globals", &globals) == B_OK)?&globals:NULL); +#else +extern void __set_window_decor(int32 theme); + int32 decorNr = 0; + if (window_decor.FindInt32("window:R5:decor", &decorNr) == B_OK) + __set_window_decor(decorNr); +#endif + // XXX: add colors à la WindowShade ? + + return B_OK; +} + +status_t DecorThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + BMessage window_decor; + BMessage globals; + BString decorName; + status_t err; + + (void)flags; + err = MyMessage(theme, window_decor); + if (err) + window_decor.MakeEmpty(); + +#ifdef B_BEOS_VERSION_DANO + err = get_window_decor(&decorName, &globals); + if (err == B_OK) { + window_decor.AddString("window:decor", decorName.String()); + window_decor.AddMessage("window:decor_globals", &globals); + } +#else + window_decor.AddInt32("window:R5:decor", 0); +#endif + + err = SetMyMessage(theme, window_decor); + return err; +} + +status_t DecorThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage window_decor; + window_decor.AddString("window:decor", "R5"); + window_decor.AddInt32("window:R5:decor", 0L); + theme.AddMessage(A_MSGNAME, &window_decor); + return ApplyTheme(theme, flags); +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new DecorThemesAddon; +} diff --git a/3rdparty/themes/addons/DeskbarAddon.cpp b/3rdparty/themes/addons/DeskbarAddon.cpp new file mode 100644 index 0000000000..64481eb56a --- /dev/null +++ b/3rdparty/themes/addons/DeskbarAddon.cpp @@ -0,0 +1,151 @@ +/* + * deskbar ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_deskbar +#endif + +#define A_NAME "Deskbar" +#define A_MSGNAME Z_THEME_DESKBAR_SETTINGS +#define A_DESCRIPTION "Deskbar on-screen position" + +class DeskbarThemesAddon : public ThemesAddon { +public: + DeskbarThemesAddon(); + ~DeskbarThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +DeskbarThemesAddon::DeskbarThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +DeskbarThemesAddon::~DeskbarThemesAddon() +{ +} + +const char *DeskbarThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t DeskbarThemesAddon::RunPreferencesPanel() +{ + status_t err; + entry_ref ref; + BEntry ent; + err = ent.SetTo("/boot/beos/preferences/Deskbar"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + } + } + if (!err) + return B_OK; + err = ent.SetTo("/system/add-ons/Preferences/Deskbar"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + if (err) { + BMessage msg(B_REFS_RECEIVED); + msg.AddRef("refs", &ref); + be_app_messenger.SendMessage(&msg); + } + } + } + return err; +} + +status_t DeskbarThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_DESKBAR_SETTINGS, "Deskbar position"); + names.AddString("db:location", "Deskbar on-screen position"); + names.AddString("db:expanded", "Deskbar is expanded"); + return B_OK; +} + +status_t DeskbarThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage deskbar; + status_t err; + int32 loc = 5; + bool expanded = true; + BDeskbar db; + + (void)flags; + err = MyMessage(theme, deskbar); + if (err) + return err; + + if (deskbar.FindInt32("db:location", &loc) != B_OK) + return ENOENT; + deskbar.FindBool("db:expanded", &expanded); + return db.SetLocation((deskbar_location)loc, expanded); +} + +status_t DeskbarThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + BMessage deskbar; + status_t err; + + (void)flags; + err = MyMessage(theme, deskbar); + if (err) + deskbar.MakeEmpty(); + + deskbar_location loc; + bool expanded; + BDeskbar db; + + loc = db.Location(&expanded); + deskbar.AddInt32("db:location", (int32)loc); + deskbar.AddBool("db:expanded", expanded); + + err = SetMyMessage(theme, deskbar); + return err; +} + +status_t DeskbarThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage deskbar; + deskbar_location loc = B_DESKBAR_RIGHT_TOP; + bool expanded = true; + deskbar.AddInt32("db:location", (int32)loc); + deskbar.AddBool("db:expanded", expanded); + theme.AddMessage(A_MSGNAME, &deskbar); + return ApplyTheme(theme, flags); +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new DeskbarThemesAddon; +} diff --git a/3rdparty/themes/addons/EddieAddon.cpp b/3rdparty/themes/addons/EddieAddon.cpp new file mode 100644 index 0000000000..64aea79798 --- /dev/null +++ b/3rdparty/themes/addons/EddieAddon.cpp @@ -0,0 +1,147 @@ +/* + * Eddie Color ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_eddie +#endif + +#define A_NAME "Eddie Colors" +#define A_MSGNAME NULL //Z_THEME_Eddie_SETTINGS +#define A_DESCRIPTION "Make Eddie use system colors" + +#define EDDIE_SETTINGS_NAME "Eddie/settings" + +class EddieThemesAddon : public ThemesAddon { +public: + EddieThemesAddon(); + ~EddieThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +EddieThemesAddon::EddieThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +EddieThemesAddon::~EddieThemesAddon() +{ +} + +const char *EddieThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t EddieThemesAddon::RunPreferencesPanel() +{ + return B_OK; +} + +status_t EddieThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_EDDIE_SETTINGS, "Eddie Settings"); + return B_OK; +} + +status_t EddieThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage uisettings; + status_t err; + BPath EddieSPath; + rgb_color col; + BString text; + char buffer[10]; + + (void)flags; + err = theme.FindMessage(Z_THEME_UI_SETTINGS, &uisettings); + if (err) + return err; + + if (uisettings.FindRGBColor(B_UI_DOCUMENT_BACKGROUND_COLOR, &col) >= B_OK) { + sprintf(buffer, "%02x%02x%02x", col.red, col.green, col.blue); + text << "BackgroundColor " << buffer << "\n"; + } + if (uisettings.FindRGBColor(B_UI_DOCUMENT_TEXT_COLOR, &col) >= B_OK) { + sprintf(buffer, "%02x%02x%02x", col.red, col.green, col.blue); + text << "TextColor " << buffer << "\n"; + } + if (uisettings.FindRGBColor("be:c:DocSBg", &col) >= B_OK) { + sprintf(buffer, "%02x%02x%02x", col.red, col.green, col.blue); + text << "SelectionColor " << buffer << "\n"; + } else if (uisettings.FindRGBColor(B_UI_MENU_SELECTED_BACKGROUND_COLOR, &col) >= B_OK) { + sprintf(buffer, "%02x%02x%02x", col.red, col.green, col.blue); + text << "SelectionColor " << buffer << "\n"; + } + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &EddieSPath) < B_OK) + return B_ERROR; + EddieSPath.Append(EDDIE_SETTINGS_NAME); + BFile EddieSettings(EddieSPath.Path(), B_WRITE_ONLY|B_OPEN_AT_END); + if (EddieSettings.InitCheck() < B_OK) + return EddieSettings.InitCheck(); + if (true/* || flags & UI_THEME_SETTINGS_SAVE*/) { + if (EddieSettings.Write(text.String(), strlen(text.String())) < B_OK) + return B_ERROR; + } + + if (true/* || flags & UI_THEME_SETTINGS_APPLY*/) { + + } + return B_OK; +} + +status_t EddieThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + (void)theme; (void)flags; + return B_OK; +} + +status_t EddieThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage uisettings; + rgb_color bg = {255, 255, 255, 255}; + rgb_color fg = {0, 0, 0, 255}; + rgb_color selbg = {180, 200, 240, 255}; + uisettings.AddRGBColor(B_UI_DOCUMENT_BACKGROUND_COLOR, bg); + uisettings.AddRGBColor(B_UI_DOCUMENT_TEXT_COLOR, fg); + uisettings.AddRGBColor("be:c:DocSBg", selbg); + theme.AddMessage(Z_THEME_UI_SETTINGS, &uisettings); + return ApplyTheme(theme, flags); +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new EddieThemesAddon; +} diff --git a/3rdparty/themes/addons/PeAddon.cpp b/3rdparty/themes/addons/PeAddon.cpp new file mode 100644 index 0000000000..440c5c00e1 --- /dev/null +++ b/3rdparty/themes/addons/PeAddon.cpp @@ -0,0 +1,147 @@ +/* + * Pe Color ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_pe +#endif + +#define A_NAME "Pe Colors" +#define A_MSGNAME NULL //Z_THEME_PE_SETTINGS +#define A_DESCRIPTION "Make Pe use system colors" + +#define PE_SETTINGS_NAME "pe/settings" + +class PeThemesAddon : public ThemesAddon { +public: + PeThemesAddon(); + ~PeThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +PeThemesAddon::PeThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +PeThemesAddon::~PeThemesAddon() +{ +} + +const char *PeThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t PeThemesAddon::RunPreferencesPanel() +{ + return B_OK; +} + +status_t PeThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_PE_SETTINGS, "Pe Settings"); + return B_OK; +} + +status_t PeThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage uisettings; + status_t err; + BPath PeSPath; + rgb_color col; + BString text; + char buffer[10]; + + (void)flags; + err = theme.FindMessage(Z_THEME_UI_SETTINGS, &uisettings); + if (err) + return err; + + if (uisettings.FindRGBColor(B_UI_DOCUMENT_BACKGROUND_COLOR, &col) >= B_OK) { + sprintf(buffer, "%02x%02x%02x", col.red, col.green, col.blue); + text << "low color=#" << buffer << "\n"; + } + if (uisettings.FindRGBColor(B_UI_DOCUMENT_TEXT_COLOR, &col) >= B_OK) { + sprintf(buffer, "%02x%02x%02x", col.red, col.green, col.blue); + text << "text color=#" << buffer << "\n"; + } + if (uisettings.FindRGBColor("be:c:DocSBg", &col) >= B_OK) { + sprintf(buffer, "%02x%02x%02x", col.red, col.green, col.blue); + text << "selection color=#" << buffer << "\n"; + } else if (uisettings.FindRGBColor(B_UI_MENU_SELECTED_BACKGROUND_COLOR, &col) >= B_OK) { + sprintf(buffer, "%02x%02x%02x", col.red, col.green, col.blue); + text << "selection color=#" << buffer << "\n"; + } + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &PeSPath) < B_OK) + return B_ERROR; + PeSPath.Append(PE_SETTINGS_NAME); + BFile PeSettings(PeSPath.Path(), B_WRITE_ONLY|B_OPEN_AT_END); + if (PeSettings.InitCheck() < B_OK) + return PeSettings.InitCheck(); + if (true/* || flags & UI_THEME_SETTINGS_SAVE*/) { + if (PeSettings.Write(text.String(), strlen(text.String())) < B_OK) + return B_ERROR; + } + + if (true/* || flags & UI_THEME_SETTINGS_APPLY*/) { + + } + return B_OK; +} + +status_t PeThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + (void)theme; (void)flags; + return B_OK; +} + +status_t PeThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage uisettings; + rgb_color bg = {255, 255, 255, 255}; + rgb_color fg = {0, 0, 0, 255}; + rgb_color selbg = {180, 200, 240, 255}; + uisettings.AddRGBColor(B_UI_DOCUMENT_BACKGROUND_COLOR, bg); + uisettings.AddRGBColor(B_UI_DOCUMENT_TEXT_COLOR, fg); + uisettings.AddRGBColor("be:c:DocSBg", selbg); + theme.AddMessage(Z_THEME_UI_SETTINGS, &uisettings); + return ApplyTheme(theme, flags); +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new PeThemesAddon; +} diff --git a/3rdparty/themes/addons/ScreensaverAddon.cpp b/3rdparty/themes/addons/ScreensaverAddon.cpp new file mode 100644 index 0000000000..83c2a5312d --- /dev/null +++ b/3rdparty/themes/addons/ScreensaverAddon.cpp @@ -0,0 +1,180 @@ +/* + * screensaver ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_screensaver +#endif + +#define A_NAME "Screensaver" +#define A_MSGNAME Z_THEME_SCREENSAVER_SETTINGS +#define A_DESCRIPTION "Screensaver settings" + +#define Z_THEME_SS_MODULE "screensaver:modulename" +#define Z_THEME_SS_MODULE_SETTINGS "screensaver:modulesettings" + +#define MS_NAME "modulesettings_" + +class ScreensaverThemesAddon : public ThemesAddon { +public: + ScreensaverThemesAddon(); + ~ScreensaverThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +ScreensaverThemesAddon::ScreensaverThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +ScreensaverThemesAddon::~ScreensaverThemesAddon() +{ +} + +const char *ScreensaverThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t ScreensaverThemesAddon::RunPreferencesPanel() +{ + status_t err; + entry_ref ref; + BEntry ent; + err = ent.SetTo("/boot/beos/preferences/ScreenSaver"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + } + } + if (!err) + return B_OK; + err = ent.SetTo("/system/add-ons/Preferences/ScreenSaver"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + } + } + return err; +} + +status_t ScreensaverThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_SCREENSAVER_SETTINGS, "Screensaver settings"); + names.AddString(Z_THEME_SS_MODULE, "Screensaver active module"); + names.AddString(Z_THEME_SS_MODULE_SETTINGS, "Screensaver active module settings"); + return B_OK; +} + +status_t ScreensaverThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage screensaver; + status_t err; + BPath path; + BString str; + BMessage settings; + BMessage modsettings; + + (void)flags; + err = MyMessage(theme, screensaver); + if (err) + return err; + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK) + return B_ERROR; + path.Append("ScreenSaver_settings"); + BFile f(path.Path(), B_READ_WRITE); + if (settings.Unflatten(&f) < B_OK) + return B_ERROR; + if (screensaver.FindString(Z_THEME_SS_MODULE, &str) >= B_OK) { + if (settings.ReplaceString("modulename", str.String()) < B_OK) + if (settings.AddString("modulename", str.String()) < B_OK) + return B_ERROR; + if (screensaver.FindMessage(Z_THEME_SS_MODULE_SETTINGS, &modsettings) >= B_OK) { + BString msname(MS_NAME); + msname += str.String(); + if (settings.ReplaceMessage(msname.String(), &modsettings) < B_OK) + settings.AddMessage(msname.String(), &modsettings); + } + f.Seek(0LL, SEEK_SET); + if (settings.Flatten(&f) < B_OK) + return B_ERROR; + } + + return err; +} + +status_t ScreensaverThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + BMessage screensaver; + status_t err; + BPath path; + BString str; + BMessage settings; + BMessage modsettings; + + (void)flags; + err = MyMessage(theme, screensaver); + if (err) + screensaver.MakeEmpty(); + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK) + return B_ERROR; + path.Append("ScreenSaver_settings"); + BFile f(path.Path(), B_READ_ONLY); + if (settings.Unflatten(&f) < B_OK) + return B_ERROR; + if (settings.FindString("modulename", &str) >= B_OK) { + screensaver.AddString(Z_THEME_SS_MODULE, str.String()); + BString msname(MS_NAME); + msname += str.String(); + if (settings.FindMessage(msname.String(), &modsettings) >= B_OK) { + screensaver.AddMessage(Z_THEME_SS_MODULE_SETTINGS, &modsettings); + } + } + + err = SetMyMessage(theme, screensaver); + return err; +} + +status_t ScreensaverThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage screensaver; + screensaver.AddString("screensaver:modulename", "Blackness"); + theme.AddMessage(A_MSGNAME, &screensaver); + return ApplyTheme(theme, flags); +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new ScreensaverThemesAddon; +} diff --git a/3rdparty/themes/addons/SoundplayColorAddon.cpp b/3rdparty/themes/addons/SoundplayColorAddon.cpp new file mode 100644 index 0000000000..12f4d8a3b0 --- /dev/null +++ b/3rdparty/themes/addons/SoundplayColorAddon.cpp @@ -0,0 +1,128 @@ +/* + * SoundPlay Color ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_soundplay +#endif + +#define A_NAME "SoundPlay Color" +#define A_MSGNAME NULL //Z_THEME_SOUNDPLAY_SETTINGS +#define A_DESCRIPTION "Make SoundPlay use system colors" + + +class SoundplayThemesAddon : public ThemesAddon { +public: + SoundplayThemesAddon(); + ~SoundplayThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +SoundplayThemesAddon::SoundplayThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +SoundplayThemesAddon::~SoundplayThemesAddon() +{ +} + +const char *SoundplayThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t SoundplayThemesAddon::RunPreferencesPanel() +{ + return B_OK; +} + +status_t SoundplayThemesAddon::AddNames(BMessage &names) +{ + //names.AddString(Z_THEME_BEIDE_SETTINGS, "BeIDE Settings"); + (void)names; + return B_OK; +} + +status_t SoundplayThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage uisettings; + status_t err; + rgb_color panelcol; + int32 wincnt = 1; + + (void)flags; + err = theme.FindMessage(Z_THEME_UI_SETTINGS, &uisettings); + if (err) + return err; + + if (uisettings.FindRGBColor(B_UI_PANEL_BACKGROUND_COLOR, &panelcol) < B_OK) + panelcol = make_color(216,216,216,255); + + BMessenger msgr("application/x-vnd.marcone-soundplay"); + BMessage command(B_COUNT_PROPERTIES); + BMessage answer; + command.AddSpecifier("Window"); + err = msgr.SendMessage(&command, &answer,2E6,2E6); + if(B_OK == err) { + if (answer.FindInt32("result", &wincnt) != B_OK) + wincnt = 1; + } + BMessage msg(B_PASTE); + msg.AddRGBColor("RGBColor", panelcol); + msg.AddPoint("_drop_point_", BPoint(0,0)); + // send to every window (the Playlist window needs it too) + for (int32 i = 0; i < wincnt; i++) { + BMessage wmsg(msg); + wmsg.AddSpecifier("Window", i); + msgr.SendMessage(&wmsg, (BHandler *)NULL, 2E6); + } + + return B_OK; +} + +status_t SoundplayThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + (void)theme; (void)flags; + return B_OK; +} + +status_t SoundplayThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage uisettings; + rgb_color bg = {216, 216, 216, 255}; + uisettings.AddRGBColor(B_UI_PANEL_BACKGROUND_COLOR, bg); + theme.AddMessage(Z_THEME_UI_SETTINGS, &uisettings); + return ApplyTheme(theme, flags); +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new SoundplayThemesAddon; +} diff --git a/3rdparty/themes/addons/SoundsAddon.cpp b/3rdparty/themes/addons/SoundsAddon.cpp new file mode 100644 index 0000000000..f171a12755 --- /dev/null +++ b/3rdparty/themes/addons/SoundsAddon.cpp @@ -0,0 +1,200 @@ +/* + * sounds ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_sounds +#endif + +#define A_NAME "Sounds" +#define A_MSGNAME Z_THEME_SOUNDS_SETTINGS +#define A_DESCRIPTION "System sound events" + +class SoundsThemesAddon : public ThemesAddon { +public: + SoundsThemesAddon(); + ~SoundsThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +SoundsThemesAddon::SoundsThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +SoundsThemesAddon::~SoundsThemesAddon() +{ +} + +const char *SoundsThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t SoundsThemesAddon::RunPreferencesPanel() +{ + status_t err; + entry_ref ref; + BEntry ent; + err = ent.SetTo("/boot/beos/preferences/Sounds"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + } + } + if (!err) + return B_OK; + err = ent.SetTo("/system/add-ons/Preferences/Sounds"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + if (err) { + BMessage msg(B_REFS_RECEIVED); + msg.AddRef("refs", &ref); + be_app_messenger.SendMessage(&msg); + } + } + } + return err; +} + +status_t SoundsThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_SOUNDS_SETTINGS, "Sounds Settings"); + names.AddString("sounds:file", "Filename for this sound event"); + names.AddString("sounds:volume", "Volume for this sound event"); + return B_OK; +} + +status_t SoundsThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage sounds; + status_t err; + BMediaFiles bmfs; + BString item; + entry_ref entry; + BEntry ent; + BPath path; + const char *p; + float gain; + void *cookie = NULL; + const char *field_name; + type_code field_code; + int32 field_count; + BMessage msg; + + (void)flags; + err = MyMessage(theme, sounds); + if (err) + return err; + + bmfs.RewindRefs(BMediaFiles::B_SOUNDS); + while (sounds.GetNextName(&cookie, + &field_name, + &field_code, + &field_count) == B_OK) { + if (field_code != B_MESSAGE_TYPE) + continue; + if (sounds.FindMessage(field_name, &msg) < B_OK) + continue; + /* remove old ref if any */ + if ((bmfs.GetRefFor(BMediaFiles::B_SOUNDS, field_name, &entry) >= B_OK) + && (entry.device >= 0)) + bmfs.RemoveRefFor(BMediaFiles::B_SOUNDS, field_name, entry); + if (msg.FindString("sounds:file", &p) < B_OK) + continue; + path.SetTo(p); + if (ent.SetTo(path.Path()) < B_OK) + continue; + if (ent.GetRef(&entry) < B_OK) + continue; + if (bmfs.SetRefFor(BMediaFiles::B_SOUNDS, field_name, entry) < B_OK) + continue; + if (msg.FindFloat("sounds:volume", &gain) < B_OK) + continue; + if (bmfs.SetAudioGainFor(BMediaFiles::B_SOUNDS, field_name, gain) < B_OK) + continue; + } + + return B_OK; +} + +status_t SoundsThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + BMessage sounds; + status_t err; + BMediaFiles bmfs; + BString item; + entry_ref entry; + BEntry ent; + BPath path; + float gain; + + (void)flags; + err = MyMessage(theme, sounds); + if (err) + sounds.MakeEmpty(); + + bmfs.RewindRefs(BMediaFiles::B_SOUNDS); + while (bmfs.GetNextRef(&item, &entry) == B_OK) { + BMessage msg('SndI'); + path.Unset(); + ent.SetTo(&entry); + ent.GetPath(&path); + //printf("\t%s: %s\n", item.String(), path.Path()); + if (path.Path()) { + msg.AddString("sounds:file", path.Path()); + if (bmfs.GetAudioGainFor(BMediaFiles::B_SOUNDS, item.String(), &gain) >= B_OK) + msg.AddFloat("sounds:volume", gain); + } + sounds.AddMessage(item.String(), &msg); + } + + err = SetMyMessage(theme, sounds); + return err; +} + +status_t SoundsThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage sounds; + (void)flags; + //theme.AddMessage(A_MSGNAME, &deskbar); + //return ApplyTheme(theme, flags); + // TODO + return B_OK; +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new SoundsThemesAddon; +} diff --git a/3rdparty/themes/addons/TerminalAddon.cpp b/3rdparty/themes/addons/TerminalAddon.cpp new file mode 100644 index 0000000000..c530f5dc27 --- /dev/null +++ b/3rdparty/themes/addons/TerminalAddon.cpp @@ -0,0 +1,325 @@ +/* + * BeIDE Color ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" +#include "FileUtils.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_terminal +#endif + +#define A_NAME "Terminal" +#define A_MSGNAME Z_THEME_TERMINAL_SETTINGS +#define A_DESCRIPTION "Terminal color, font and size" + +#define TP_MAGIC 0xf1f2f3f4 +#define TP_VERSION 0x02 +#define TP_FONT_NAME_SZ 128 + +// __PACKED + +struct tpref { + uint32 cols; + uint32 rows; + uint32 tab_width; + uint32 font_size; + char font[TP_FONT_NAME_SZ]; // "Family/Style" + uint32 cursor_blink_rate; // blinktime in µs = 1000000 + uint32 refresh_rate; // ??? = 0 + rgb_color bg; + rgb_color fg; + rgb_color curbg; + rgb_color curfg; + rgb_color selbg; + rgb_color selfg; + char encoding; // index in the menu (0 = UTF-8) + char unknown[3]; +}; /* this is what is sent to the Terminal window... actually not ! It's sent by Terminal to itself. */ + +struct termprefs { + uint32 magic; + uint32 version; + float x; + float y; + struct tpref p; +}; + +#define TP_COLS "term:cols" +#define TP_ROWS "term:rows" +#define TP_TABWIDTH "term:tab" +#define TP_FONT "term:font" +#define TP_BG "term:c:bg" +#define TP_FG "term:c:fg" +#define TP_CURBG "term:c:curbg" +#define TP_CURFG "term:c:curfg" +#define TP_SELBG "term:c:selbg" +#define TP_SELFG "term:c:selfg" +#define TP_ENCODING "term:encoding" + + +class TerminalThemesAddon : public ThemesAddon { +public: + TerminalThemesAddon(); + ~TerminalThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); + + /* Theme installation */ +status_t InstallFiles(BMessage &theme, BDirectory &folder); +status_t BackupFiles(BMessage &theme, BDirectory &folder); +}; + +TerminalThemesAddon::TerminalThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +TerminalThemesAddon::~TerminalThemesAddon() +{ +} + +const char *TerminalThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t TerminalThemesAddon::RunPreferencesPanel() +{ + BAlert *alert; + alert = new BAlert("info", "Please use the Settings menu in the Terminal application.", "Gotcha"); + alert->Go(); + return B_OK; +} + +status_t TerminalThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_TERMINAL_SETTINGS, "Terminal Preferences"); + names.AddString(TP_COLS, "Terminal column count"); + names.AddString(TP_ROWS, "Terminal row count"); + names.AddString(TP_TABWIDTH, "Terminal tab width"); + names.AddString(TP_FONT, "Terminal font"); + names.AddString(TP_BG, "Terminal background color"); + names.AddString(TP_FG, "Terminal foreground color"); + names.AddString(TP_CURBG, "Terminal cursor background color"); + names.AddString(TP_CURFG, "Terminal cursor foreground color"); + names.AddString(TP_SELBG, "Terminal selection background color"); + names.AddString(TP_SELFG, "Terminal selection foreground color"); + names.AddString(TP_ENCODING, "Terminal text encoding"); + return B_OK; +} + +status_t TerminalThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage termpref; + status_t err; + struct termprefs tp; + + (void)flags; + err = MyMessage(theme, termpref); + if (err) + return err; + tp.magic = TP_MAGIC; + tp.version = TP_VERSION; + tp.x = 0; // don't open at specific coords + tp.y = 0; + if (termpref.FindInt32(TP_COLS, (int32 *)&tp.p.cols) != B_OK) + tp.p.cols = 80; + if (termpref.FindInt32(TP_ROWS, (int32 *)&tp.p.rows) != B_OK) + tp.p.rows = 25; + if (termpref.FindInt32(TP_TABWIDTH, (int32 *)&tp.p.tab_width) != B_OK) + tp.p.tab_width = 8; + BFont tFont; + tp.p.font_size = 12; + strcpy(tp.p.font, "Courier10 BT/Roman"); + if (termpref.FindFlat(TP_FONT, &tFont) == B_OK) { + font_family ff; + font_style fs; + tFont.GetFamilyAndStyle(&ff, &fs); + strcpy(tp.p.font, ff); + strcat(tp.p.font, "/"); + strcat(tp.p.font, fs); + tp.p.font_size = (uint32)tFont.Size(); + } + tp.p.cursor_blink_rate = 1000000; + tp.p.refresh_rate = 0; + + if (termpref.FindRGBColor(TP_BG, &tp.p.bg) != B_OK) + tp.p.bg = make_color(255,255,255,255); + if (termpref.FindRGBColor(TP_FG, &tp.p.fg) != B_OK) + tp.p.fg = make_color(0,0,0,255); + if (termpref.FindRGBColor(TP_CURBG, &tp.p.curbg) != B_OK) + tp.p.curbg = make_color(255,255,255,255); + if (termpref.FindRGBColor(TP_CURFG, &tp.p.curfg) != B_OK) + tp.p.curfg = make_color(0,0,0,255); + if (termpref.FindRGBColor(TP_SELBG, &tp.p.selbg) != B_OK) + tp.p.selbg = make_color(0,0,0,255); + if (termpref.FindRGBColor(TP_SELFG, &tp.p.selfg) != B_OK) + tp.p.selfg = make_color(255,255,255,255); + + if (termpref.FindInt32(TP_ENCODING, (int32 *)&tp.p.encoding) != B_OK) + tp.p.encoding = 0; // UTF-8 + + if (true/*flags & UI_THEME_SETTINGS_SAVE*/) { + BPath pTermPref; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &pTermPref) < B_OK) + return EINVAL; + pTermPref.Append("Terminal"); + BFile fTermPref(pTermPref.Path(), B_WRITE_ONLY|B_CREATE_FILE|B_ERASE_FILE); + if (fTermPref.InitCheck() != B_OK) { + return fTermPref.InitCheck(); + } + fTermPref.Write(&tp, sizeof(struct termprefs)); + BNodeInfo ni(&fTermPref); + if (ni.InitCheck() == B_OK) + ni.SetType("application/x-vnd.Be-pref"); + } + if (true/*flags & UI_THEME_SETTINGS_APPLY*/) { + BList teamList; + app_info ainfo; + int32 count, i; + be_roster->GetAppList(&teamList); + count = teamList.CountItems(); + for (i = 0; i < count; i++) { + if (be_roster->GetRunningAppInfo((team_id)(teamList.ItemAt(i)), &ainfo) == B_OK) { + if (!strcmp(ainfo.signature, "application/x-vnd.Be-SHEL")) { + err = B_OK; + BMessage msg('pref'); + BMessenger msgr(NULL, ainfo.team); + tp.x = 0; + tp.y = 0; + + //msg.AddData("", 'UBYT', &(tp.p), sizeof(struct tpref)); + msg.AddData("", 'UBYT', &(tp), sizeof(struct termprefs)); + msg.AddSpecifier("Window", 0L); + err = msgr.SendMessage(msg); + } + } + } + } + + return B_OK; +} + +status_t TerminalThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + BMessage termpref; + status_t err; + struct termprefs tp; + BPath pTermPref; + + (void)flags; + err = MyMessage(theme, termpref); + if (err) + termpref.MakeEmpty(); + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &pTermPref) < B_OK) + return EINVAL; + pTermPref.Append("Terminal"); + BFile fTermPref(pTermPref.Path(), B_READ_ONLY); + if (fTermPref.InitCheck() != B_OK) + return fTermPref.InitCheck(); + if (fTermPref.Read(&tp, sizeof(struct termprefs)) < (ssize_t)sizeof(struct termprefs)) + return EIO; + if ((tp.magic != TP_MAGIC) || (tp.version != TP_VERSION)) + return EINVAL; + termpref.AddInt32(TP_COLS, tp.p.cols); + termpref.AddInt32(TP_ROWS, tp.p.rows); + termpref.AddInt32(TP_TABWIDTH, tp.p.tab_width); + BFont tFont; + font_family ff; + font_style fs; + BString str(tp.p.font); + str.Truncate(str.FindFirst('/')); + strncpy(ff, str.String(), sizeof(ff)); + str.SetTo(tp.p.font); + str.Remove(0, str.FindFirst('/')+1); + strncpy(fs, str.String(), sizeof(fs)); + tFont.SetFamilyAndStyle(ff, fs); + tFont.SetSize(tp.p.font_size); + termpref.AddFlat(TP_FONT, &tFont); + termpref.AddRGBColor(TP_BG, tp.p.bg); + termpref.AddRGBColor(TP_FG, tp.p.fg); + termpref.AddRGBColor(TP_CURBG, tp.p.curbg); + termpref.AddRGBColor(TP_CURFG, tp.p.curfg); + termpref.AddRGBColor(TP_SELBG, tp.p.selbg); + termpref.AddRGBColor(TP_SELFG, tp.p.selfg); + termpref.AddInt32(TP_ENCODING, tp.p.encoding); + + err = SetMyMessage(theme, termpref); + return B_OK; +} + +status_t TerminalThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage termpref; + termpref.AddRGBColor("term:c:bg",make_color(255,255,255,0)); + termpref.AddRGBColor("term:c:fg",make_color(0,0,0,0)); + termpref.AddRGBColor("term:c:curbg",make_color(0,0,0,0)); + termpref.AddRGBColor("term:c:curfg",make_color(255,255,255,0)); + termpref.AddRGBColor("term:c:selbg",make_color(0,0,0,0)); + termpref.AddRGBColor("term:c:selfg",make_color(255,255,255,0)); + theme.AddMessage(Z_THEME_TERMINAL_SETTINGS, &termpref); + return ApplyTheme(theme, flags); +} + +status_t TerminalThemesAddon::InstallFiles(BMessage &theme, BDirectory &folder) +{ + BMessage termpref; + status_t err; + + (void)folder; + err = MyMessage(theme, termpref); + if (err) + termpref.MakeEmpty(); + + return B_OK; +} + +status_t TerminalThemesAddon::BackupFiles(BMessage &theme, BDirectory &folder) +{ + BMessage termpref; + status_t err; + + (void)folder; + err = MyMessage(theme, termpref); + if (err) + termpref.MakeEmpty(); + + entry_ref ref; + //find_font_file(&ref, ff, fs); + return B_OK; +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new TerminalThemesAddon; +} diff --git a/3rdparty/themes/addons/UISettingsAddon.cpp b/3rdparty/themes/addons/UISettingsAddon.cpp new file mode 100644 index 0000000000..f409e44b31 --- /dev/null +++ b/3rdparty/themes/addons/UISettingsAddon.cpp @@ -0,0 +1,202 @@ +/* + * ui_settings ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_ui_settings +#endif + +//#define A_NAME "UI Settings" +#define A_NAME "System Colors and Fonts" +#define A_MSGNAME Z_THEME_UI_SETTINGS +#define A_DESCRIPTION "System colors, fonts and other goodies" + +class UISettingsThemesAddon : public ThemesAddon { +public: + UISettingsThemesAddon(); + ~UISettingsThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); +}; + +UISettingsThemesAddon::UISettingsThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +UISettingsThemesAddon::~UISettingsThemesAddon() +{ +} + +const char *UISettingsThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t UISettingsThemesAddon::RunPreferencesPanel() +{ + status_t err = B_OK; + entry_ref ref; + BEntry ent; + /* + err = ent.SetTo("/boot/beos/preferences/Colors"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + } + } + */ + if (!err) + return B_OK; + err = ent.SetTo("/system/add-ons/Preferences/Appearance"); + if (!err) { + err = ent.GetRef(&ref); + if (!err) { + err = be_roster->Launch(&ref); + if (err) { + BMessage msg(B_REFS_RECEIVED); + msg.AddRef("refs", &ref); + be_app_messenger.SendMessage(&msg); + } + } + } + return err; +} + +status_t UISettingsThemesAddon::AddNames(BMessage &names) +{ + BMessage uisettings; + BMessage uinames; + status_t err; + const char *str, *value; + type_code code; + int32 i; + + err = get_ui_settings(&uisettings, &uinames); + if (err) + return err; + names.AddString(Z_THEME_UI_SETTINGS, "UI Settings"); + // hack for legacy fonts + names.AddString("be:f:be_plain_font", "System Plain"); + names.AddString("be:f:be_bold_font", "System Bold"); + names.AddString("be:f:be_fixed_font", "System Fixed"); + for (i = 0; uinames.GetInfo(B_STRING_TYPE, i, &str, &code) == B_OK;i++) + if (uinames.FindString(str, &value) == B_OK) + names.AddString(str, value); + return B_OK; +} + +status_t UISettingsThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage uisettings; + BFont fnt; + status_t err; + + (void)flags; + err = MyMessage(theme, uisettings); + if (err) + return err; + + // hack for legacy fonts + err = uisettings.FindFlat("be:f:be_plain_font", &fnt); + uisettings.RemoveName("be:f:be_plain_font"); + if (err == B_OK) + BFont::SetStandardFont(B_PLAIN_FONT, &fnt); + + err = uisettings.FindFlat("be:f:be_bold_font", &fnt); + uisettings.RemoveName("be:f:be_bold_font"); + if (err == B_OK) + BFont::SetStandardFont(B_BOLD_FONT, &fnt); + + err = uisettings.FindFlat("be:f:be_fixed_font", &fnt); + uisettings.RemoveName("be:f:be_fixed_font"); + if (err == B_OK) + BFont::SetStandardFont(B_FIXED_FONT, &fnt); + + + update_ui_settings(uisettings); + + + return B_OK; +} + +status_t UISettingsThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + BMessage uisettings; + BMessage names; + BFont fnt; + status_t err; + + (void)flags; + err = MyMessage(theme, uisettings); + if (err) + uisettings.MakeEmpty(); + + err = get_ui_settings(&uisettings, &names); + if (err) + return err; + + // hack for legacy fonts + err = BFont::GetStandardFont(B_PLAIN_FONT, &fnt); + uisettings.AddFlat("be:f:be_plain_font", &fnt); + err = BFont::GetStandardFont(B_BOLD_FONT, &fnt); + uisettings.AddFlat("be:f:be_bold_font", &fnt); + err = BFont::GetStandardFont(B_FIXED_FONT, &fnt); + uisettings.AddFlat("be:f:be_fixed_font", &fnt); + + err = SetMyMessage(theme, uisettings); + return err; +} + +status_t UISettingsThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage uisettings; + BFont fnt; + status_t err; + + err = get_default_settings(&uisettings); + if (err) + return err; + + // hack for legacy fonts + err = BFont::GetStandardFont((font_which)(B_PLAIN_FONT-100), &fnt); + uisettings.AddFlat("be:f:be_plain_font", &fnt); + err = BFont::GetStandardFont((font_which)(B_BOLD_FONT-100), &fnt); + uisettings.AddFlat("be:f:be_bold_font", &fnt); + err = BFont::GetStandardFont((font_which)(B_FIXED_FONT-100), &fnt); + uisettings.AddFlat("be:f:be_fixed_font", &fnt); + + theme.AddMessage(A_MSGNAME, &uisettings); + return ApplyTheme(theme, flags); +} + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new UISettingsThemesAddon; +} diff --git a/3rdparty/themes/addons/WinampSkinAddon.cpp b/3rdparty/themes/addons/WinampSkinAddon.cpp new file mode 100644 index 0000000000..8ffa8cf53c --- /dev/null +++ b/3rdparty/themes/addons/WinampSkinAddon.cpp @@ -0,0 +1,425 @@ +/* + * WinampSkin ThemesAddon class + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ThemesAddon.h" +#include "UITheme.h" + +#ifdef SINGLE_BINARY +#define instanciate_themes_addon instanciate_themes_addon_winamp_skin +#endif + +#define A_NAME "Winamp Skin" +#define A_MSGNAME Z_THEME_WINAMP_SKIN_SETTINGS +#define A_DESCRIPTION "Handle CL-Amp and SoundPlay (not yet) Skins - requires SkinSelector plugin to be activated in CL-Amp and SoundPlay." + +#define CL_SETTINGS_NAME "CL-Amp/CL-Amp.preferences" +#define CL_APP_SIG "application/x-vnd.ClaesL-CLAmp" +#define SP_SETTINGS_NAME "PrefServer/pref0:$USER:application:x-vnd.marcone-soundplay" +//BMessage('save') { +//skinpath = string("/wincrash/Program Files/Winamp/Skins", 37 bytes) +//skinname = string("/wincrash/Program Files/Winamp/Skins/XP_Amp_2.wsz", 50 bytes) } +#define SP_APP_SIG "application/x-vnd.marcone-soundplay" +#define USE_CL 1 +#define USE_SP 2 + + +class WinampSkinThemesAddon : public ThemesAddon { +public: + WinampSkinThemesAddon(); + ~WinampSkinThemesAddon(); + +const char *Description(); + +status_t RunPreferencesPanel(); + +status_t AddNames(BMessage &names); + +status_t ApplyTheme(BMessage &theme, uint32 flags=0L); +status_t MakeTheme(BMessage &theme, uint32 flags=0L); + +status_t ApplyDefaultTheme(uint32 flags=0L); + +int32 WhichApp(); /* which app should I use to repport current skin? */ +status_t CLSkin(BString *to, bool preffile = false); +status_t SPSkin(BString *to, bool preffile = false); +status_t CLSkinPath(BPath *to); +status_t SPSkinPath(BPath *to); +status_t SetCLSkin(BString *from); +status_t SetSPSkin(BString *from); +status_t StripPath(BString *path); +}; + +WinampSkinThemesAddon::WinampSkinThemesAddon() + : ThemesAddon(A_NAME, A_MSGNAME) +{ +} + +WinampSkinThemesAddon::~WinampSkinThemesAddon() +{ +} + +const char *WinampSkinThemesAddon::Description() +{ + return A_DESCRIPTION; +} + +status_t WinampSkinThemesAddon::RunPreferencesPanel() +{ + return B_OK; +} + +status_t WinampSkinThemesAddon::AddNames(BMessage &names) +{ + names.AddString(Z_THEME_WINAMP_SKIN_SETTINGS, "CLAmp/SoundPlay Skin Settings"); + return B_OK; +} + +status_t WinampSkinThemesAddon::ApplyTheme(BMessage &theme, uint32 flags) +{ + BMessage skin; + BString name; + status_t err; + + (void)flags; + err = MyMessage(theme, skin); + if (err) + return err; + + err = skin.FindString("winamp:skin", &name); + if (err) + return err; + SetCLSkin(&name); + SetSPSkin(&name); + return B_OK; +} + +status_t WinampSkinThemesAddon::MakeTheme(BMessage &theme, uint32 flags) +{ + BMessage skin; + BString name; + status_t err = B_ERROR; + + (void)flags; + err = MyMessage(theme, skin); + if (err) + skin.MakeEmpty(); + + if (WhichApp() == USE_CL) + err = CLSkin(&name); + else + err = SPSkin(&name); + /* try the other way round */ + if (err) + if (WhichApp() == USE_CL) + err = CLSkin(&name, true); + else + err = SPSkin(&name, true); + if (!err) + skin.AddString("winamp:skin", name); + err = SetMyMessage(theme, skin); + return err; +} + +status_t WinampSkinThemesAddon::ApplyDefaultTheme(uint32 flags) +{ + BMessage theme; + BMessage skin; + skin.AddString("skin", "none"); + theme.AddMessage(Z_THEME_WINAMP_SKIN_SETTINGS, &skin); + return ApplyTheme(theme, flags); +} + +int32 WinampSkinThemesAddon::WhichApp() +{ + // XXX +/* + BMessenger spmsgr(SP_APP_SIG); + if (spmsgr.IsValid()) { + PRINT(("WinampSkinThemesAddon: SoundPlay BMessenger valid\n")); + return USE_SP; + }*/ + BMessenger clmsgr(CL_APP_SIG); + if (clmsgr.IsValid()) { + PRINT(("WinampSkinThemesAddon: CL-Amp BMessenger valid\n")); + return USE_CL; + } + return USE_SP; +} + +status_t WinampSkinThemesAddon::CLSkin(BString *to, bool preffile) +{ + if (preffile) { + BPath CLSPath; + char buffer[B_FILE_NAME_LENGTH+1]; + + if (!to) + return EINVAL; + buffer[B_FILE_NAME_LENGTH] = '\0'; + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &CLSPath) < B_OK) + return B_ERROR; + CLSPath.Append(CL_SETTINGS_NAME); + BFile CLSettings(CLSPath.Path(), B_READ_ONLY); + if (CLSettings.InitCheck() < B_OK) + return CLSettings.InitCheck(); + ssize_t got = CLSettings.ReadAt(0x8LL, buffer, B_FILE_NAME_LENGTH); + if (got < B_FILE_NAME_LENGTH) + return EIO; + *to = buffer; + StripPath(to); + return B_ERROR; + } + BMessenger msgr(CL_APP_SIG); + BMessage msg('skin'); + BMessage reply; + msgr.SendMessage(&msg, &reply, 500000, 500000); + if (reply.FindString("result", to) >= B_OK) { + StripPath(to); + return B_OK; + } + return B_ERROR; +} + +status_t WinampSkinThemesAddon::SPSkin(BString *to, bool preffile) +{ + if (preffile) { + status_t err; + BMessage settings; + BPath SPSPath; + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &SPSPath) < B_OK) + return B_ERROR; + BString leaf(SP_SETTINGS_NAME); + BString user(getenv("USER")); + user.RemoveFirst("USER="); + leaf.IReplaceFirst("$USER", user.String()); + SPSPath.Append(leaf.String()); + PRINT(("SPP %s\n", SPSPath.Path())); + BFile SPSettings(SPSPath.Path(), B_READ_ONLY); + if (SPSettings.InitCheck() < B_OK) + return SPSettings.InitCheck(); + if (settings.Unflatten(&SPSettings) < B_OK) + return EIO; + err = settings.FindString("skinname", to); + StripPath(to); + return err; + } + BMessenger msgr(SP_APP_SIG); + BMessage msg('skin'); + BMessage reply; + msgr.SendMessage(&msg, (BHandler *)NULL, 500000); + if (reply.FindString("result", to) >= B_OK) { + StripPath(to); + return B_OK; + } + return B_ERROR; +} + +status_t WinampSkinThemesAddon::CLSkinPath(BPath *to) +{ + char buffer[B_FILE_NAME_LENGTH+1]; + BPath CLSPath; + + buffer[B_FILE_NAME_LENGTH] = '\0'; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &CLSPath) < B_OK) + return B_ERROR; + CLSPath.Append(CL_SETTINGS_NAME); + BFile CLSettings(CLSPath.Path(), B_READ_ONLY); + if (CLSettings.InitCheck() < B_OK) + return CLSettings.InitCheck(); + ssize_t got = CLSettings.ReadAt(0x150LL, buffer, B_FILE_NAME_LENGTH); + if (got < B_FILE_NAME_LENGTH) + return EIO; + to->SetTo(buffer); + return B_OK; +} + +status_t WinampSkinThemesAddon::SPSkinPath(BPath *to) +{ + status_t err; + BMessage settings; + BPath SPSPath; + BString str; + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &SPSPath) < B_OK) + return B_ERROR; + BString leaf(SP_SETTINGS_NAME); + BString user(getenv("USER")); + user.RemoveFirst("USER="); + leaf.IReplaceFirst("$USER", user.String()); + SPSPath.Append(leaf.String()); + BFile SPSettings(SPSPath.Path(), B_READ_ONLY); + if (SPSettings.InitCheck() < B_OK) + return SPSettings.InitCheck(); + if (settings.Unflatten(&SPSettings) < B_OK) + return EIO; + err = settings.FindString("skinpath", &str); + PRINT(("SPSP %s\n", str.String())); + to->SetTo(str.String()); + return err; +} + +status_t WinampSkinThemesAddon::SetCLSkin(BString *from) +{ + status_t err; + BPath p; + err = CLSkinPath(&p); + if (err < B_OK) + return err; + p.Append(from->String()); + /* update the prefs file */ + BPath CLSPath; + + if (!from) + return EINVAL; + /* CL-Amp doesn't grok long names */ + if (strlen(p.Path()) >= B_FILE_NAME_LENGTH) + return B_NAME_TOO_LONG; + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &CLSPath) < B_OK) + return B_ERROR; + CLSPath.Append(CL_SETTINGS_NAME); + BFile CLSettings(CLSPath.Path(), B_WRITE_ONLY); + if (CLSettings.InitCheck() < B_OK) + return CLSettings.InitCheck(); + CLSettings.WriteAt(0x8LL, p.Path(), strlen(p.Path())+1); + + /* then tell the app */ + BMessenger msgr(CL_APP_SIG); + BMessage msg('skin'); + msg.AddString("name", p.Path()); + msg.PrintToStream(); + msgr.SendMessage(&msg, (BHandler *)NULL, 500000); + return B_OK; +} + +status_t WinampSkinThemesAddon::SetSPSkin(BString *from) +{ + status_t err; + BPath p; + err = SPSkinPath(&p); + if (err < B_OK) + return err; + p.Append(from->String()); + err = p.InitCheck(); + if (err < B_OK) + return err; + + /* update the prefs file */ + BPath SPSPath; + BMessage settings; + + if (!from) + return EINVAL; + if (from->Length() >= B_PATH_NAME_LENGTH) + return B_NAME_TOO_LONG; + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &SPSPath) < B_OK) + return B_ERROR; + BString leaf(SP_SETTINGS_NAME); + BString user(getenv("USER")); + user.RemoveFirst("USER="); + leaf.IReplaceFirst("$USER", user.String()); + SPSPath.Append(leaf.String()); + PRINT(("SPP %s\n", SPSPath.Path())); + BFile SPSettings(SPSPath.Path(), B_READ_WRITE); + PRINT(("SP:BFile\n")); + if (SPSettings.InitCheck() < B_OK) + return SPSettings.InitCheck(); + PRINT(("SP:BFile::InitCheck\n")); + //SPSettings.WriteAt(0x8LL, from->String(), from->Length()+1); + if (settings.Unflatten(&SPSettings) < B_OK) + return EIO; + PRINT(("SP:Unflatten\n")); + settings.ReplaceString("skinname", p.Path()); + PRINT(("SP:Replace\n")); + SPSettings.Seek(0LL, SEEK_SET); + if (settings.Flatten(&SPSettings) < B_OK) + return EIO; + PRINT(("SP:Flatten\n")); + + /* then tell the app */ + /* first make sure the native BeOS is shown (the 'sk!n' message toggles, wonder Why TF...) */ + bool beosIfaceHidden; + BMessenger msgr(SP_APP_SIG); + + BMessage command(B_GET_PROPERTY); + BMessage answer; + command.AddSpecifier("Hidden"); + command.AddSpecifier("Window", 0L); // TitleSpectrumAnalyzer does change the title from "SoundPlay"! + err = msgr.SendMessage(&command, &answer,(bigtime_t)2E6,(bigtime_t)2E6); + if(B_OK == err) { + if (answer.FindBool("result", &beosIfaceHidden) != B_OK) + beosIfaceHidden = false; + } else { + PRINT(("WinampSkinThemesAddon: couldn't talk to SoundPlay: error 0x%08lx\n", err)); + return EIO; + } + + BMessage msg('sk!n'); + msg.AddString("path", p.Path()); + msg.PrintToStream(); + if (!beosIfaceHidden) { // native GUI is active + // -> sending the message to the App will make ituse the skin for all tracks + PRINT(("SP:Sending to app\n")); + msgr.SendMessage(&msg, (BHandler *)NULL, 500000); + } else { // native GUI is hidden (= winamp GUI used) + int32 wincnt; + command.MakeEmpty(); + command.what = B_COUNT_PROPERTIES; + answer.MakeEmpty(); + command.AddSpecifier("Window"); + err = msgr.SendMessage(&command, &answer,(bigtime_t)2E6,(bigtime_t)2E6); + if(B_OK == err) { + if (answer.FindInt32("result", &wincnt) != B_OK) + wincnt = 1; + } else { + PRINT(("WinampSkinThemesAddon: couldn't talk to SoundPlay: (2) error 0x%08lx\n", err)); + return EIO; + } + // send to all windows but first one. + for (int32 i = 1; i < wincnt; i++) { + BMessage wmsg(msg); + PRINT(("SP:Sending to window %ld\n", i)); + wmsg.AddSpecifier("Window", i); + wmsg.PrintToStream(); + msgr.SendMessage(&wmsg, (BHandler *)NULL, 500000); + } + } + return B_OK; +} + +status_t WinampSkinThemesAddon::StripPath(BString *path) +{ + if (!path) + return EINVAL; + BPath p(path->String()); + *path = p.Leaf(); + return B_OK; +} + + + +ThemesAddon *instanciate_themes_addon() +{ + return (ThemesAddon *) new WinampSkinThemesAddon; +}