2 * Copyright 2007-2015 Haiku, Inc.
3 * Distributed under the terms of the MIT License.
6 * Ryan Leavengood <leavengood@gmail.com>
7 * John Scipione <jscipione@gmail.com>
8 * Joseph Groover <looncraz@looncraz.net>
12 #include <AboutWindow.h>
18 #include <AppFileInfo.h>
23 #include <GroupLayoutBuilder.h>
24 #include <GroupView.h>
25 #include <InterfaceDefs.h>
26 #include <LayoutBuilder.h>
28 #include <MessageFilter.h>
32 #include <ScrollView.h>
35 #include <StringView.h>
36 #include <SystemCatalog.h>
42 static const float kStripeWidth
= 30.0;
44 using BPrivate::gSystemCatalog
;
47 #undef B_TRANSLATION_CONTEXT
48 #define B_TRANSLATION_CONTEXT "AboutWindow"
53 class StripeView
: public BView
{
55 StripeView(BBitmap
* icon
);
56 virtual ~StripeView();
58 virtual void Draw(BRect updateRect
);
60 BBitmap
* Icon() const { return fIcon
; };
61 void SetIcon(BBitmap
* icon
);
68 class AboutView
: public BGroupView
{
70 AboutView(const char* name
,
71 const char* signature
);
74 virtual void AllAttached();
76 BTextView
* InfoView() const { return fInfoView
; };
79 status_t
SetIcon(BBitmap
* icon
);
82 status_t
SetName(const char* name
);
84 const char* Version();
85 status_t
SetVersion(const char* version
);
88 const char* _GetVersionFromSignature(const char* signature
);
89 BBitmap
* _GetIconFromSignature(const char* signature
);
92 BStringView
* fNameView
;
93 BStringView
* fVersionView
;
95 StripeView
* fStripeView
;
99 // #pragma mark - StripeView
102 StripeView::StripeView(BBitmap
* icon
)
104 BView("StripeView", B_WILL_DRAW
),
107 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
111 width
+= icon
->Bounds().Width() + 32.0f
;
113 SetExplicitMinSize(BSize(width
, B_SIZE_UNSET
));
114 SetExplicitPreferredSize(BSize(width
, B_SIZE_UNLIMITED
));
118 StripeView::~StripeView()
124 StripeView::Draw(BRect updateRect
)
129 SetHighColor(ViewColor());
130 FillRect(updateRect
);
132 BRect stripeRect
= Bounds();
133 stripeRect
.right
= kStripeWidth
;
134 SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT
));
135 FillRect(stripeRect
);
137 SetDrawingMode(B_OP_ALPHA
);
138 SetBlendingMode(B_PIXEL_ALPHA
, B_ALPHA_OVERLAY
);
139 DrawBitmapAsync(fIcon
, BPoint(15.0f
, 10.0f
));
144 StripeView::SetIcon(BBitmap
* icon
)
153 width
+= icon
->Bounds().Width() + 32.0f
;
155 SetExplicitMinSize(BSize(width
, B_SIZE_UNSET
));
156 SetExplicitPreferredSize(BSize(width
, B_SIZE_UNLIMITED
));
160 // #pragma mark - AboutView
163 AboutView::AboutView(const char* appName
, const char* signature
)
165 BGroupView("AboutView", B_VERTICAL
)
167 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
168 fNameView
= new BStringView("name", appName
);
170 fNameView
->GetFont(&font
);
171 font
.SetFace(B_BOLD_FACE
);
172 font
.SetSize(font
.Size() * 2.0);
173 fNameView
->SetFont(&font
, B_FONT_FAMILY_AND_STYLE
| B_FONT_SIZE
176 fVersionView
= new BStringView("version",
177 _GetVersionFromSignature(signature
));
179 rgb_color documentColor
= ui_color(B_DOCUMENT_TEXT_COLOR
);
180 fInfoView
= new BTextView("info", NULL
, &documentColor
, B_WILL_DRAW
);
181 fInfoView
->SetExplicitMinSize(BSize(210.0, 160.0));
182 fInfoView
->MakeEditable(false);
183 fInfoView
->SetWordWrap(true);
184 fInfoView
->SetInsets(5.0, 5.0, 5.0, 5.0);
185 fInfoView
->SetStylable(true);
187 BScrollView
* infoViewScroller
= new BScrollView(
188 "infoViewScroller", fInfoView
, B_WILL_DRAW
| B_FRAME_EVENTS
,
189 false, true, B_PLAIN_BORDER
);
191 fStripeView
= new StripeView(_GetIconFromSignature(signature
));
193 const char* ok
= B_TRANSLATE_MARK("OK");
194 BButton
* closeButton
= new BButton("ok",
195 gSystemCatalog
.GetString(ok
, "AboutWindow"),
196 new BMessage(B_QUIT_REQUESTED
));
198 GroupLayout()->SetSpacing(0);
199 BLayoutBuilder::Group
<>(this, B_HORIZONTAL
, 0)
201 .AddGroup(B_VERTICAL
, B_USE_SMALL_SPACING
)
202 .SetInsets(0, B_USE_DEFAULT_SPACING
,
203 B_USE_DEFAULT_SPACING
, B_USE_DEFAULT_SPACING
)
206 .Add(infoViewScroller
)
207 .AddGroup(B_HORIZONTAL
, 0)
213 .View()->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
218 AboutView::~AboutView()
224 AboutView::AllAttached()
226 fNameView
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
227 fInfoView
->SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR
);
228 fVersionView
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
232 // #pragma mark - AboutView private methods
236 AboutView::_GetVersionFromSignature(const char* signature
)
238 if (signature
== NULL
)
242 if (be_roster
->FindApp(signature
, &ref
) != B_OK
)
245 BFile
file(&ref
, B_READ_ONLY
);
246 BAppFileInfo
appMime(&file
);
247 if (appMime
.InitCheck() != B_OK
)
250 version_info versionInfo
;
251 if (appMime
.GetVersionInfo(&versionInfo
, B_APP_VERSION_KIND
) == B_OK
) {
252 if (versionInfo
.major
== 0 && versionInfo
.middle
== 0
253 && versionInfo
.minor
== 0) {
257 const char* version
= B_TRANSLATE_MARK("Version");
258 version
= gSystemCatalog
.GetString(version
, "AboutWindow");
259 BString
appVersion(version
);
260 appVersion
<< " " << versionInfo
.major
<< "." << versionInfo
.middle
;
261 if (versionInfo
.minor
> 0)
262 appVersion
<< "." << versionInfo
.minor
;
264 // Add the version variety
265 const char* variety
= NULL
;
266 switch (versionInfo
.variety
) {
267 case B_DEVELOPMENT_VERSION
:
268 variety
= B_TRANSLATE_MARK("development");
270 case B_ALPHA_VERSION
:
271 variety
= B_TRANSLATE_MARK("alpha");
274 variety
= B_TRANSLATE_MARK("beta");
276 case B_GAMMA_VERSION
:
277 variety
= B_TRANSLATE_MARK("gamma");
279 case B_GOLDEN_MASTER_VERSION
:
280 variety
= B_TRANSLATE_MARK("gold master");
284 if (variety
!= NULL
) {
285 variety
= gSystemCatalog
.GetString(variety
, "AboutWindow");
286 appVersion
<< "-" << variety
;
289 return appVersion
.String();
297 AboutView::_GetIconFromSignature(const char* signature
)
299 if (signature
== NULL
)
303 if (be_roster
->FindApp(signature
, &ref
) != B_OK
)
306 BFile
file(&ref
, B_READ_ONLY
);
307 BAppFileInfo
appMime(&file
);
308 if (appMime
.InitCheck() != B_OK
)
311 BBitmap
* icon
= new BBitmap(BRect(0.0, 0.0, 127.0, 127.0), B_RGBA32
);
312 if (appMime
.GetIcon(icon
, (icon_size
)128) == B_OK
)
320 // #pragma mark - AboutView public methods
326 if (fStripeView
== NULL
)
329 return fStripeView
->Icon();
334 AboutView::SetIcon(BBitmap
* icon
)
336 if (fStripeView
== NULL
)
339 fStripeView
->SetIcon(icon
);
348 return fNameView
->Text();
353 AboutView::SetName(const char* name
)
355 fNameView
->SetText(name
);
364 return fVersionView
->Text();
369 AboutView::SetVersion(const char* version
)
371 fVersionView
->SetText(version
);
376 } // namespace BPrivate
379 // #pragma mark - BAboutWindow
382 BAboutWindow::BAboutWindow(const char* appName
, const char* signature
)
384 BWindow(BRect(0.0, 0.0, 200.0, 200.0), appName
, B_MODAL_WINDOW
,
385 B_ASYNCHRONOUS_CONTROLS
| B_NOT_ZOOMABLE
| B_NOT_RESIZABLE
386 | B_AUTO_UPDATE_SIZE_LIMITS
| B_CLOSE_ON_ESCAPE
)
388 SetLayout(new BGroupLayout(B_VERTICAL
));
390 const char* about
= B_TRANSLATE_MARK("About %app%");
391 about
= gSystemCatalog
.GetString(about
, "AboutWindow");
393 BString
title(about
);
394 title
.ReplaceFirst("%app%", appName
);
395 SetTitle(title
.String());
397 fAboutView
= new BPrivate::AboutView(appName
, signature
);
398 AddChild(fAboutView
);
400 MoveTo(AboutPosition(Frame().Width(), Frame().Height()));
404 BAboutWindow::~BAboutWindow()
406 fAboutView
->RemoveSelf();
412 // #pragma mark - BAboutWindow virtual methods
419 // move to current workspace
420 SetWorkspaces(B_CURRENT_WORKSPACE
);
427 // #pragma mark - BAboutWindow public methods
431 BAboutWindow::AboutPosition(float width
, float height
)
433 BPoint
result(100, 100);
436 dynamic_cast<BWindow
*>(BLooper::LooperForThread(find_thread(NULL
)));
438 BScreen
screen(window
);
439 BRect
screenFrame(0, 0, 640, 480);
440 if (screen
.IsValid())
441 screenFrame
= screen
.Frame();
443 // Horizontally, we're smack in the middle
444 result
.x
= screenFrame
.left
+ (screenFrame
.Width() / 2.0) - (width
/ 2.0);
446 // This is probably sooo wrong, but it looks right on 1024 x 768
447 result
.y
= screenFrame
.top
+ (screenFrame
.Height() / 4.0)
448 - ceil(height
/ 3.0);
455 BAboutWindow::AddDescription(const char* description
)
457 if (description
== NULL
)
460 AddText(description
);
465 BAboutWindow::AddCopyright(int32 firstCopyrightYear
,
466 const char* copyrightHolder
, const char** extraCopyrights
)
468 BString
copyright(B_UTF8_COPYRIGHT
" %years% %holder%");
474 strftime(currentYear
, 5, "%Y", localtime(&tp
));
475 BString copyrightYears
;
476 copyrightYears
<< firstCopyrightYear
;
477 if (copyrightYears
!= currentYear
)
478 copyrightYears
<< "-" << currentYear
;
481 if (fAboutView
->InfoView()->TextLength() > 0)
486 // Fill out the copyright year placeholder
487 text
.ReplaceAll("%years%", copyrightYears
.String());
489 // Fill in the copyright holder placeholder
490 text
.ReplaceAll("%holder%", copyrightHolder
);
492 // Add extra copyright strings
493 if (extraCopyrights
!= NULL
) {
494 // Add optional extra copyright information
495 for (int32 i
= 0; extraCopyrights
[i
]; i
++)
496 text
<< "\n" << B_UTF8_COPYRIGHT
<< " " << extraCopyrights
[i
];
499 const char* allRightsReserved
= B_TRANSLATE_MARK("All Rights Reserved.");
500 allRightsReserved
= gSystemCatalog
.GetString(allRightsReserved
,
502 text
<< "\n " << allRightsReserved
;
504 fAboutView
->InfoView()->Insert(text
.String());
509 BAboutWindow::AddAuthors(const char** authors
)
514 const char* writtenBy
= B_TRANSLATE_MARK("Written by:");
515 writtenBy
= gSystemCatalog
.GetString(writtenBy
, "AboutWindow");
517 AddText(writtenBy
, authors
);
522 BAboutWindow::AddSpecialThanks(const char** thanks
)
527 const char* specialThanks
= B_TRANSLATE_MARK("Special Thanks:");
528 specialThanks
= gSystemCatalog
.GetString(specialThanks
, "AboutWindow");
530 AddText(specialThanks
, thanks
);
535 BAboutWindow::AddVersionHistory(const char** history
)
540 const char* versionHistory
= B_TRANSLATE_MARK("Version history:");
541 versionHistory
= gSystemCatalog
.GetString(versionHistory
, "AboutWindow");
543 AddText(versionHistory
, history
);
548 BAboutWindow::AddExtraInfo(const char* extraInfo
)
550 if (extraInfo
== NULL
)
553 const char* appExtraInfo
= B_TRANSLATE_MARK(extraInfo
);
554 appExtraInfo
= gSystemCatalog
.GetString(extraInfo
, "AboutWindow");
557 if (fAboutView
->InfoView()->TextLength() > 0)
560 extra
<< appExtraInfo
;
562 fAboutView
->InfoView()->Insert(extra
.String());
567 BAboutWindow::AddText(const char* header
, const char** contents
)
569 BTextView
* infoView
= fAboutView
->InfoView();
570 int32 textLength
= infoView
->TextLength();
573 if (textLength
> 0) {
578 const char* indent
= "";
579 if (header
!= NULL
) {
584 if (contents
!= NULL
) {
586 for (int32 i
= 0; contents
[i
]; i
++)
587 text
<< indent
<< contents
[i
] << "\n";
590 infoView
->Insert(text
.String());
592 if (contents
!= NULL
&& header
!= NULL
) {
593 infoView
->SetFontAndColor(textLength
, textLength
+ strlen(header
),
602 return fAboutView
->Icon();
607 BAboutWindow::SetIcon(BBitmap
* icon
)
609 fAboutView
->SetIcon(icon
);
616 return fAboutView
->Name();
621 BAboutWindow::SetName(const char* name
)
623 fAboutView
->SetName(name
);
628 BAboutWindow::Version()
630 return fAboutView
->Version();
635 BAboutWindow::SetVersion(const char* version
)
637 fAboutView
->SetVersion(version
);
643 void BAboutWindow::_ReservedAboutWindow20() {}
644 void BAboutWindow::_ReservedAboutWindow19() {}
645 void BAboutWindow::_ReservedAboutWindow18() {}
646 void BAboutWindow::_ReservedAboutWindow17() {}
647 void BAboutWindow::_ReservedAboutWindow16() {}
648 void BAboutWindow::_ReservedAboutWindow15() {}
649 void BAboutWindow::_ReservedAboutWindow14() {}
650 void BAboutWindow::_ReservedAboutWindow13() {}
651 void BAboutWindow::_ReservedAboutWindow12() {}
652 void BAboutWindow::_ReservedAboutWindow11() {}
653 void BAboutWindow::_ReservedAboutWindow10() {}
654 void BAboutWindow::_ReservedAboutWindow9() {}
655 void BAboutWindow::_ReservedAboutWindow8() {}
656 void BAboutWindow::_ReservedAboutWindow7() {}
657 void BAboutWindow::_ReservedAboutWindow6() {}
658 void BAboutWindow::_ReservedAboutWindow5() {}
659 void BAboutWindow::_ReservedAboutWindow4() {}
660 void BAboutWindow::_ReservedAboutWindow3() {}
661 void BAboutWindow::_ReservedAboutWindow2() {}
662 void BAboutWindow::_ReservedAboutWindow1() {}