From 0046f4443675694b16fda4829e6f838954bf23fa Mon Sep 17 00:00:00 2001 From: John Scipione Date: Wed, 1 Aug 2012 07:25:56 -0400 Subject: [PATCH] Modify about window to take an app signature. * Grabs the app icon and version from the resource file. * Allow you to specify the copyright holder instead of hardcoding "Haiku, Inc." * Support multiple extra copyright fields. * Modify BAlert to take a custom icon. * Set the custom icon of the BAlert to the app icon. * Also set the app version. * Convert BAboutWindow to derive from BWindow * Place a 128x128 icon and fill out a scrolling BTextView with options such as authors, version history, copyright, license, etc. Still needs some work but is coming along. * Add the word Version to the version line, i8n'ed of course, and tweak the info box and default sizes. --- headers/private/shared/AboutWindow.h | 45 ++- src/apps/deskcalc/CalcApplication.cpp | 1 + src/apps/deskcalc/CalcApplication.h | 1 + src/apps/deskcalc/CalcView.cpp | 18 +- src/apps/deskcalc/CalcView.h | 1 + src/apps/deskcalc/CalcWindow.cpp | 5 +- src/apps/deskcalc/DeskCalc.rdef | 5 +- src/kits/shared/AboutWindow.cpp | 435 +++++++++++++++++++++++--- 8 files changed, 439 insertions(+), 72 deletions(-) diff --git a/headers/private/shared/AboutWindow.h b/headers/private/shared/AboutWindow.h index da7d5c8e37..d6ac30e6ef 100644 --- a/headers/private/shared/AboutWindow.h +++ b/headers/private/shared/AboutWindow.h @@ -1,28 +1,45 @@ /* - * Copyright 2007-2009 Haiku, Inc. + * Copyright 2007-2012 Haiku, Inc. * Distributed under the terms of the MIT License. - * - * Authors: - * Ryan Leavengood, leavengood@gmail.com */ #ifndef B_ABOUT_WINDOW_H #define B_ABOUT_WINDOW_H -#include +#include +#include +#include -class BAboutWindow { - public: - BAboutWindow(const char *appName, int32 firstCopyrightYear, - const char **authors, const char *extraInfo = NULL); - virtual ~BAboutWindow(); +class AboutView; +class BPoint; - void Show(); +class BAboutWindow : public BWindow { + public: + BAboutWindow(const char* appName, + int32 firstCopyrightYear, + const char** authors = NULL, + const char* extraInfo = NULL); + BAboutWindow(const char* appName, + const char* signature); + virtual ~BAboutWindow(); - private: - BString* fAppName; - BString* fText; + void AddDescription(const char* description); + void AddCopyright(int32 firstCopyrightYear, + const char* copyrightHolder, + const char** extraCopyrights = NULL); + void AddAuthors(const char** authors); + void AddSpecialThanks(const char** thanks); + void AddVersionHistory(const char** history); + void AddExtraInfo(const char* extraInfo); + + BPoint AboutPosition(float width, float height); + + protected: + void _Init(const char* appName, const char* signature); + + private: + AboutView* fAboutView; }; #endif // B_ABOUT_WINDOW_H diff --git a/src/apps/deskcalc/CalcApplication.cpp b/src/apps/deskcalc/CalcApplication.cpp index 2e32e6266d..d91002ce90 100644 --- a/src/apps/deskcalc/CalcApplication.cpp +++ b/src/apps/deskcalc/CalcApplication.cpp @@ -30,6 +30,7 @@ static const char* kSettingsFileName = "DeskCalc_settings"; +const char* kAppName = B_TRANSLATE_SYSTEM_NAME("DeskCalc"); const char* kAppSig = "application/x-vnd.Haiku-DeskCalc"; static const float kDefaultWindowWidth = 220.0; diff --git a/src/apps/deskcalc/CalcApplication.h b/src/apps/deskcalc/CalcApplication.h index d47f445cec..9707daf4be 100644 --- a/src/apps/deskcalc/CalcApplication.h +++ b/src/apps/deskcalc/CalcApplication.h @@ -15,6 +15,7 @@ #include +extern const char* kAppName; extern const char* kAppSig; class BFile; diff --git a/src/apps/deskcalc/CalcView.cpp b/src/apps/deskcalc/CalcView.cpp index 73e2d7925e..d0b53d6c4e 100644 --- a/src/apps/deskcalc/CalcView.cpp +++ b/src/apps/deskcalc/CalcView.cpp @@ -712,15 +712,14 @@ CalcView::FrameResized(float width, float height) void CalcView::AboutRequested() { - const char* authors[] = { - "Timothy Wayper", - "Stephan Aßmus", - "Ingo Weinhold", + const char* extraCopyrights[] = { + "1997, 1998 R3 Software Ltd.", NULL }; - BAboutWindow about(B_TRANSLATE_SYSTEM_NAME("DeskCalc"), 2006, authors, - B_UTF8_COPYRIGHT "1997, 1998 R3 Software Ltd."); - about.Show(); + + BAboutWindow* about = new BAboutWindow(kAppName, kAppSig); + about->AddCopyright(2006, "Haiku, Inc.", extraCopyrights); + about->Show(); } @@ -1289,6 +1288,9 @@ CalcView::_CreatePopUpMenu(bool addKeypadModeMenuItems) fKeypadModeScientificItem = new BMenuItem(B_TRANSLATE("Scientific"), new BMessage(MSG_OPTIONS_KEYPAD_MODE_SCIENTIFIC), '2'); } + BMenuItem* aboutItem + = new BMenuItem(B_TRANSLATE("About DeskCalc" B_UTF8_ELLIPSIS), + new BMessage(B_ABOUT_REQUESTED)); // apply current settings fAutoNumlockItem->SetMarked(fOptions->auto_num_lock); @@ -1313,6 +1315,8 @@ CalcView::_CreatePopUpMenu(bool addKeypadModeMenuItems) fPopUpMenu->AddItem(fKeypadModeScientificItem); _MarkKeypadItems(fOptions->keypad_mode); } + fPopUpMenu->AddSeparatorItem(); + fPopUpMenu->AddItem(aboutItem); } diff --git a/src/apps/deskcalc/CalcView.h b/src/apps/deskcalc/CalcView.h index c004f668fb..93bc594f2a 100644 --- a/src/apps/deskcalc/CalcView.h +++ b/src/apps/deskcalc/CalcView.h @@ -31,6 +31,7 @@ static const float kMaximumWidthBasic = 400.0f; static const float kMinimumHeightBasic = 130.0f; static const float kMaximumHeightBasic = 400.0f; +class BAboutWindow; class BString; class BMenuItem; class BPopUpMenu; diff --git a/src/apps/deskcalc/CalcWindow.cpp b/src/apps/deskcalc/CalcWindow.cpp index 4a3740edb3..ae6e337c42 100644 --- a/src/apps/deskcalc/CalcWindow.cpp +++ b/src/apps/deskcalc/CalcWindow.cpp @@ -21,6 +21,7 @@ #include #include +#include "CalcApplication.h" #include "CalcOptions.h" #include "CalcView.h" @@ -31,8 +32,8 @@ CalcWindow::CalcWindow(BRect frame, BMessage* settings) : - BWindow(frame, B_TRANSLATE_SYSTEM_NAME("DeskCalc"), B_TITLED_WINDOW, - B_ASYNCHRONOUS_CONTROLS | B_NOT_ANCHORED_ON_ACTIVATE) + BWindow(frame, kAppName, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS + | B_NOT_ANCHORED_ON_ACTIVATE) { // create calculator view with calculator description and // desktop background color diff --git a/src/apps/deskcalc/DeskCalc.rdef b/src/apps/deskcalc/DeskCalc.rdef index eb159ece92..7cfe95e212 100644 --- a/src/apps/deskcalc/DeskCalc.rdef +++ b/src/apps/deskcalc/DeskCalc.rdef @@ -5,14 +5,14 @@ resource app_name_catalog_entry "x-vnd.Haiku-DeskCalc:System name:DeskCalc"; resource app_version { major = 2, - middle = 2, + middle = 4, minor = 0, variety = B_APPV_ALPHA, internal = 1, short_info = "DeskCalc", - long_info = "DeskCalc ©2006-2012 Haiku, Inc." + long_info = "DeskCalc ©1997, 1998 R3 Software Ltd. ©2006-2012 Haiku, Inc." }; resource app_flags B_SINGLE_LAUNCH; @@ -31,4 +31,3 @@ resource vector_icon { $"011001178400040A010102000A050105000A06030806071001178122040A0201" $"03000A030104000A0706090A0B0D0E0C100117810004" }; - diff --git a/src/kits/shared/AboutWindow.cpp b/src/kits/shared/AboutWindow.cpp index e8fbe72bf0..e7d968277e 100644 --- a/src/kits/shared/AboutWindow.cpp +++ b/src/kits/shared/AboutWindow.cpp @@ -1,39 +1,292 @@ /* - * Copyright 2007-2009 Haiku, Inc. + * Copyright 2007-2012 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Ryan Leavengood, leavengood@gmail.com + * John Scipione, jscipione@gmail.com */ + #include #include #include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include +#include + + +static const float kStripeWidth = 30.0; using BPrivate::gSystemCatalog; - #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "AboutWindow" -BAboutWindow::BAboutWindow(const char *appName, int32 firstCopyrightYear, - const char **authors, const char *extraInfo) -{ - fAppName = new BString(appName); +class StripeView : public BView { + public: + StripeView(BBitmap* icon); + virtual ~StripeView(); - const char* copyright = gSystemCatalog.GetString( - B_TRANSLATE_MARK("Copyright " B_UTF8_COPYRIGHT " %years% Haiku, Inc."), - "AboutWindow"); - const char* writtenBy = gSystemCatalog.GetString( - B_TRANSLATE_MARK("Written by:"), "AboutWindow"); + virtual void Draw(BRect updateRect); + + private: + BBitmap* fIcon; +}; + + +class AboutView : public BGroupView { + public: + AboutView(const char* name, + const char* signature); + virtual ~AboutView(); + + BTextView* InfoView() const { return fInfoView; }; + + protected: + const char* AppVersion(const char* signature); + BBitmap* AppIcon(const char* signature); + + private: + BStringView* fNameView; + BStringView* fVersionView; + BTextView* fInfoView; +}; + + +// #pragma mark - + + +StripeView::StripeView(BBitmap* icon) + : + BView("StripeView", B_WILL_DRAW), + fIcon(icon) +{ + SetExplicitMinSize(BSize(160.0, B_SIZE_UNSET)); + SetExplicitPreferredSize(BSize(160.0, B_SIZE_UNLIMITED)); + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); +} + + +StripeView::~StripeView() +{ +} + + +void +StripeView::Draw(BRect updateRect) +{ + SetHighColor(ViewColor()); + FillRect(updateRect); + + BRect stripeRect = Bounds(); + stripeRect.right = kStripeWidth; + SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); + FillRect(stripeRect); + + if (fIcon == NULL) + return; + + SetDrawingMode(B_OP_ALPHA); + SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); + DrawBitmapAsync(fIcon, BPoint(15.0, 5.0)); +} + + +// #pragma mark - + + +AboutView::AboutView(const char* appName, const char* signature) + : + BGroupView("AboutView", B_VERTICAL) +{ + fNameView = new BStringView("name", appName); + BFont font; + fNameView->GetFont(&font); + font.SetFace(B_BOLD_FACE); + font.SetSize(font.Size() * 2.0); + fNameView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE + | B_FONT_FLAGS); + + fVersionView = new BStringView("version", AppVersion(signature)); + + fInfoView = new BTextView("info", B_WILL_DRAW); + fInfoView->SetExplicitMinSize(BSize(210.0, 100.0)); + fInfoView->MakeEditable(false); + fInfoView->SetWordWrap(true); + fInfoView->SetInsets(5.0, 5.0, 5.0, 5.0); + fInfoView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + fInfoView->SetHighColor(ui_color(B_DOCUMENT_TEXT_COLOR)); + + BScrollView* infoViewScroller = new BScrollView( + "infoViewScroller", fInfoView, B_WILL_DRAW | B_FRAME_EVENTS, + false, true, B_PLAIN_BORDER); + + GroupLayout()->SetSpacing(0); + BLayoutBuilder::Group<>(this) + .AddGroup(B_HORIZONTAL, 0) + .Add(new StripeView(AppIcon(signature))) + .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING) + .SetInsets(0, B_USE_DEFAULT_SPACING, + B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) + .Add(fNameView) + .Add(fVersionView) + .Add(infoViewScroller) + .End() + .AddGlue() + .End(); +} + + +AboutView::~AboutView() +{ +} + + +const char* +AboutView::AppVersion(const char* signature) +{ + if (signature == NULL) + return NULL; + + app_info appInfo; + if (be_roster->GetAppInfo(signature, &appInfo) != B_OK) + return NULL; + + BFile file(&appInfo.ref, B_READ_ONLY); + BAppFileInfo appMime(&file); + if (appMime.InitCheck() != B_OK) + return NULL; + + version_info versionInfo; + if (appMime.GetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK) { + if (versionInfo.major == 0 && versionInfo.middle == 0 + && versionInfo.minor == 0) { + return NULL; + } + + const char* version = B_TRANSLATE_MARK("Version"); + version = gSystemCatalog.GetString(version, "AboutWindow"); + BString appVersion(version); + appVersion << " " << versionInfo.major << "." << versionInfo.middle; + if (versionInfo.minor > 0) + appVersion << "." << versionInfo.minor; + + return appVersion.String(); + } + + return NULL; +} + + +BBitmap* +AboutView::AppIcon(const char* signature) +{ + if (signature == NULL) + return NULL; + + app_info appInfo; + if (be_roster->GetAppInfo(signature, &appInfo) != B_OK) + return NULL; + + BFile file(&appInfo.ref, B_READ_ONLY); + BAppFileInfo appMime(&file); + if (appMime.InitCheck() != B_OK) + return NULL; + + // fetch the app icon + BBitmap* icon = new BBitmap(BRect(0.0, 0.0, 127.0, 127.0), B_RGBA32); + if (appMime.GetIcon(icon, B_LARGE_ICON) == B_OK) + return icon; + + // couldn't find the app icon + // fetch the generic 3 boxes icon + BMimeType defaultAppMime; + defaultAppMime.SetTo(B_APP_MIME_TYPE); + if (defaultAppMime.GetIcon(icon, B_LARGE_ICON) == B_OK) + return icon; + + return NULL; +} + + +// #pragma mark - + + +BAboutWindow::BAboutWindow(const char* appName, int32 firstCopyrightYear, + const char** authors, const char* extraInfo) + : BWindow(BRect(0.0, 0.0, 300.0, 140.0), appName, B_TITLED_WINDOW, + B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE + | B_AUTO_UPDATE_SIZE_LIMITS) +{ + _Init(appName, NULL); + AddCopyright(firstCopyrightYear, "Haiku, Inc.", NULL); + AddAuthors(authors); + AddExtraInfo(extraInfo); +} + + +BAboutWindow::BAboutWindow(const char* appName, const char* signature) + : BWindow(BRect(0.0, 0.0, 310.0, 140.0), appName, B_TITLED_WINDOW, + B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE + | B_AUTO_UPDATE_SIZE_LIMITS) +{ + _Init(appName, signature); +} + + +BAboutWindow::~BAboutWindow() +{ + fAboutView->RemoveSelf(); + delete fAboutView; + fAboutView = NULL; +} + + +void +BAboutWindow::AddDescription(const char* description) +{ + if (description == NULL) + return; + + const char* appDesc = B_TRANSLATE_MARK(description); + appDesc = gSystemCatalog.GetString(appDesc, "AboutWindow"); + + BString desc(appDesc); + desc << "\n\n"; + + fAboutView->InfoView()->Insert(desc.String()); +} + + +void +BAboutWindow::AddCopyright(int32 firstCopyrightYear, + const char* copyrightHolder, const char** extraCopyrights) +{ + BString copyright(B_UTF8_COPYRIGHT " %years%"); + if (copyrightHolder != NULL) + copyright << " " << copyrightHolder; + + const char* firstCopyright = B_TRANSLATE_MARK(copyright.String()); + firstCopyright = gSystemCatalog.GetString(copyright, "AboutWindow"); // Get current year time_t tp; @@ -45,50 +298,140 @@ BAboutWindow::BAboutWindow(const char *appName, int32 firstCopyrightYear, if (copyrightYears != currentYear) copyrightYears << "-" << currentYear; - // Build the text to display - BString text(appName); - text << "\n\n"; - text << copyright; - text << "\n\n"; + BString text(firstCopyright); + + // Replace the copyright year with the current year text.ReplaceAll("%years%", copyrightYears.String()); - text << writtenBy << "\n"; - for (int32 i = 0; authors[i]; i++) { - text << " " << authors[i] << "\n"; + + // Add extra copyright strings + if (extraCopyrights != NULL) { + // Add optional extra copyright information + for (int32 i = 0; extraCopyrights[i]; i++) + text << "\n" << B_UTF8_COPYRIGHT << " " << extraCopyrights[i]; } + text << "\n"; - // The extra information is optional - if (extraInfo != NULL) { - text << "\n" << extraInfo << "\n"; - } + const char* allRightsReserved = B_TRANSLATE_MARK("All Rights Reserved."); + allRightsReserved = gSystemCatalog.GetString(allRightsReserved, + "AboutWindow"); + text << " " << allRightsReserved << "\n\n"; - fText = new BString(text); -} - - -BAboutWindow::~BAboutWindow() -{ - delete fText; - delete fAppName; + fAboutView->InfoView()->Insert(text.String()); } void -BAboutWindow::Show() +BAboutWindow::AddAuthors(const char** authors) { - const char* aboutTitle = gSystemCatalog.GetString( - B_TRANSLATE_MARK("About" B_UTF8_ELLIPSIS), "AboutWindow"); - const char* closeLabel = gSystemCatalog.GetString( - B_TRANSLATE_MARK("Close"), "AboutWindow"); + if (authors == NULL) + return; - BAlert *alert = new BAlert(aboutTitle, fText->String(), closeLabel); - BTextView *view = alert->TextView(); - BFont font; - view->SetStylable(true); - view->GetFont(&font); - font.SetFace(B_BOLD_FACE); - font.SetSize(font.Size() * 1.7); - view->SetFontAndColor(0, fAppName->Length(), &font); - alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); - alert->Go(); + const char* writtenBy = B_TRANSLATE_MARK("Written by:"); + writtenBy = gSystemCatalog.GetString(writtenBy, "AboutWindow"); + + BString text(writtenBy); + text << "\n"; + for (int32 i = 0; authors[i]; i++) + text << " " << authors[i] << "\n"; + text << "\n"; + + fAboutView->InfoView()->Insert(text.String()); } + +void +BAboutWindow::AddSpecialThanks(const char** thanks) +{ + if (thanks == NULL) + return; + + const char* specialThanks = B_TRANSLATE_MARK("Special Thanks:"); + specialThanks = gSystemCatalog.GetString(specialThanks, "AboutWindow"); + + BString text(specialThanks); + text << "\n"; + for (int32 i = 0; thanks[i]; i++) + text << " " << thanks[i] << "\n"; + text << "\n"; + + fAboutView->InfoView()->Insert(text.String()); +} + + +void +BAboutWindow::AddVersionHistory(const char** history) +{ + if (history == NULL) + return; + + const char* versionHistory = B_TRANSLATE_MARK("Version history:"); + versionHistory = gSystemCatalog.GetString(versionHistory, "AboutWindow"); + BString text(versionHistory); + text << "\n"; + for (int32 i = 0; history[i]; i++) + text << " " << history[i] << "\n"; + text << "\n"; + + fAboutView->InfoView()->Insert(text.String()); +} + + +void +BAboutWindow::AddExtraInfo(const char* extraInfo) +{ + if (extraInfo == NULL) + return; + + const char* appExtraInfo = B_TRANSLATE_MARK(extraInfo); + appExtraInfo = gSystemCatalog.GetString(extraInfo, "AboutWindow"); + + BString extra(appExtraInfo); + extra << "\n"; + + fAboutView->InfoView()->Insert(extra.String()); +} + + +BPoint +BAboutWindow::AboutPosition(float width, float height) +{ + BPoint result(100, 100); + + BWindow* window = + dynamic_cast(BLooper::LooperForThread(find_thread(NULL))); + + BScreen screen(window); + BRect screenFrame(0, 0, 640, 480); + if (screen.IsValid()) + screenFrame = screen.Frame(); + + // Horizontally, we're smack in the middle + result.x = screenFrame.left + (screenFrame.Width() / 2.0) - (width / 2.0); + + // This is probably sooo wrong, but it looks right on 1024 x 768 + result.y = screenFrame.top + (screenFrame.Height() / 4.0) - ceil(height / 3.0); + + return result; +} + + +// #pragma mark - + + +void +BAboutWindow::_Init(const char* appName, const char* signature) +{ + SetLayout(new BGroupLayout(B_VERTICAL)); + + const char* about = B_TRANSLATE_MARK("About"); + about = gSystemCatalog.GetString(about, "AboutWindow"); + + BString title(about); + title << " " << appName; + SetTitle(title.String()); + + fAboutView = new AboutView(appName, signature); + AddChild(fAboutView); + + MoveTo(AboutPosition(Frame().Width(), Frame().Height())); +}