2 * Copyright 2007-2012 Haiku, Inc.
3 * Distributed under the terms of the MIT License.
6 * Ryan Leavengood <leavengood@gmail.com>
7 * John Scipione <jscipione@gmail.com>
11 #include <AboutWindow.h>
17 #include <AppFileInfo.h>
22 #include <GroupLayoutBuilder.h>
23 #include <GroupView.h>
24 #include <InterfaceDefs.h>
25 #include <LayoutBuilder.h>
27 #include <MessageFilter.h>
31 #include <ScrollView.h>
34 #include <StringView.h>
35 #include <SystemCatalog.h>
41 static const float kStripeWidth
= 30.0;
43 using BPrivate::gSystemCatalog
;
46 #undef B_TRANSLATION_CONTEXT
47 #define B_TRANSLATION_CONTEXT "AboutWindow"
50 class StripeView
: public BView
{
52 StripeView(BBitmap
* icon
);
53 virtual ~StripeView();
55 virtual void Draw(BRect updateRect
);
57 BBitmap
* Icon() const { return fIcon
; };
58 void SetIcon(BBitmap
* icon
);
65 class AboutView
: public BGroupView
{
67 AboutView(const char* name
,
68 const char* signature
);
71 BTextView
* InfoView() const { return fInfoView
; };
74 status_t
SetIcon(BBitmap
* icon
);
77 status_t
SetName(const char* name
);
79 const char* Version();
80 status_t
SetVersion(const char* version
);
83 const char* _GetVersionFromSignature(const char* signature
);
84 BBitmap
* _GetIconFromSignature(const char* signature
);
87 BStringView
* fNameView
;
88 BStringView
* fVersionView
;
90 StripeView
* fStripeView
;
94 // #pragma mark - StripeView
97 StripeView::StripeView(BBitmap
* icon
)
99 BView("StripeView", B_WILL_DRAW
),
102 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
106 width
+= icon
->Bounds().Width() + 32.0f
;
108 SetExplicitMinSize(BSize(width
, B_SIZE_UNSET
));
109 SetExplicitPreferredSize(BSize(width
, B_SIZE_UNLIMITED
));
113 StripeView::~StripeView()
119 StripeView::Draw(BRect updateRect
)
124 SetHighColor(ViewColor());
125 FillRect(updateRect
);
127 BRect stripeRect
= Bounds();
128 stripeRect
.right
= kStripeWidth
;
129 SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT
));
130 FillRect(stripeRect
);
132 SetDrawingMode(B_OP_ALPHA
);
133 SetBlendingMode(B_PIXEL_ALPHA
, B_ALPHA_OVERLAY
);
134 DrawBitmapAsync(fIcon
, BPoint(15.0f
, 10.0f
));
139 StripeView::SetIcon(BBitmap
* icon
)
148 width
+= icon
->Bounds().Width() + 32.0f
;
150 SetExplicitMinSize(BSize(width
, B_SIZE_UNSET
));
151 SetExplicitPreferredSize(BSize(width
, B_SIZE_UNLIMITED
));
155 // #pragma mark - AboutView
158 AboutView::AboutView(const char* appName
, const char* signature
)
160 BGroupView("AboutView", B_VERTICAL
)
162 fNameView
= new BStringView("name", appName
);
164 fNameView
->GetFont(&font
);
165 font
.SetFace(B_BOLD_FACE
);
166 font
.SetSize(font
.Size() * 2.0);
167 fNameView
->SetFont(&font
, B_FONT_FAMILY_AND_STYLE
| B_FONT_SIZE
170 fVersionView
= new BStringView("version",
171 _GetVersionFromSignature(signature
));
173 rgb_color documentColor
= ui_color(B_DOCUMENT_TEXT_COLOR
);
174 fInfoView
= new BTextView("info", NULL
, &documentColor
, B_WILL_DRAW
);
175 fInfoView
->SetExplicitMinSize(BSize(210.0, 160.0));
176 fInfoView
->MakeEditable(false);
177 fInfoView
->SetWordWrap(true);
178 fInfoView
->SetInsets(5.0, 5.0, 5.0, 5.0);
179 fInfoView
->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR
));
180 fInfoView
->SetStylable(true);
182 BScrollView
* infoViewScroller
= new BScrollView(
183 "infoViewScroller", fInfoView
, B_WILL_DRAW
| B_FRAME_EVENTS
,
184 false, true, B_PLAIN_BORDER
);
186 fStripeView
= new StripeView(_GetIconFromSignature(signature
));
188 const char* ok
= B_TRANSLATE_MARK("OK");
189 BButton
* closeButton
= new BButton("ok",
190 gSystemCatalog
.GetString(ok
, "AboutWindow"),
191 new BMessage(B_QUIT_REQUESTED
));
193 GroupLayout()->SetSpacing(0);
194 BLayoutBuilder::Group
<>(this, B_HORIZONTAL
, 0)
196 .AddGroup(B_VERTICAL
, B_USE_SMALL_SPACING
)
197 .SetInsets(0, B_USE_DEFAULT_SPACING
,
198 B_USE_DEFAULT_SPACING
, B_USE_DEFAULT_SPACING
)
201 .Add(infoViewScroller
)
202 .AddGroup(B_HORIZONTAL
, 0)
212 AboutView::~AboutView()
217 // #pragma mark - AboutView private methods
221 AboutView::_GetVersionFromSignature(const char* signature
)
223 if (signature
== NULL
)
227 if (be_roster
->FindApp(signature
, &ref
) != B_OK
)
230 BFile
file(&ref
, B_READ_ONLY
);
231 BAppFileInfo
appMime(&file
);
232 if (appMime
.InitCheck() != B_OK
)
235 version_info versionInfo
;
236 if (appMime
.GetVersionInfo(&versionInfo
, B_APP_VERSION_KIND
) == B_OK
) {
237 if (versionInfo
.major
== 0 && versionInfo
.middle
== 0
238 && versionInfo
.minor
== 0) {
242 const char* version
= B_TRANSLATE_MARK("Version");
243 version
= gSystemCatalog
.GetString(version
, "AboutWindow");
244 BString
appVersion(version
);
245 appVersion
<< " " << versionInfo
.major
<< "." << versionInfo
.middle
;
246 if (versionInfo
.minor
> 0)
247 appVersion
<< "." << versionInfo
.minor
;
249 // Add the version variety
250 const char* variety
= NULL
;
251 switch (versionInfo
.variety
) {
252 case B_DEVELOPMENT_VERSION
:
253 variety
= B_TRANSLATE_MARK("development");
255 case B_ALPHA_VERSION
:
256 variety
= B_TRANSLATE_MARK("alpha");
259 variety
= B_TRANSLATE_MARK("beta");
261 case B_GAMMA_VERSION
:
262 variety
= B_TRANSLATE_MARK("gamma");
264 case B_GOLDEN_MASTER_VERSION
:
265 variety
= B_TRANSLATE_MARK("gold master");
269 if (variety
!= NULL
) {
270 variety
= gSystemCatalog
.GetString(variety
, "AboutWindow");
271 appVersion
<< "-" << variety
;
274 return appVersion
.String();
282 AboutView::_GetIconFromSignature(const char* signature
)
284 if (signature
== NULL
)
288 if (be_roster
->FindApp(signature
, &ref
) != B_OK
)
291 BFile
file(&ref
, B_READ_ONLY
);
292 BAppFileInfo
appMime(&file
);
293 if (appMime
.InitCheck() != B_OK
)
296 BBitmap
* icon
= new BBitmap(BRect(0.0, 0.0, 127.0, 127.0), B_RGBA32
);
297 if (appMime
.GetIcon(icon
, (icon_size
)128) == B_OK
)
305 // #pragma mark - AboutView public methods
311 if (fStripeView
== NULL
)
314 return fStripeView
->Icon();
319 AboutView::SetIcon(BBitmap
* icon
)
321 if (fStripeView
== NULL
)
324 fStripeView
->SetIcon(icon
);
333 return fNameView
->Text();
338 AboutView::SetName(const char* name
)
340 fNameView
->SetText(name
);
349 return fVersionView
->Text();
354 AboutView::SetVersion(const char* version
)
356 fVersionView
->SetText(version
);
362 // #pragma mark - BAboutWindow
365 BAboutWindow::BAboutWindow(const char* appName
, const char* signature
)
367 BWindow(BRect(0.0, 0.0, 200.0, 200.0), appName
, B_MODAL_WINDOW
,
368 B_ASYNCHRONOUS_CONTROLS
| B_NOT_ZOOMABLE
| B_NOT_RESIZABLE
369 | B_AUTO_UPDATE_SIZE_LIMITS
| B_CLOSE_ON_ESCAPE
)
371 SetLayout(new BGroupLayout(B_VERTICAL
));
373 const char* about
= B_TRANSLATE_MARK("About %app%");
374 about
= gSystemCatalog
.GetString(about
, "AboutWindow");
376 BString
title(about
);
377 title
.ReplaceFirst("%app%", appName
);
378 SetTitle(title
.String());
380 fAboutView
= new AboutView(appName
, signature
);
381 AddChild(fAboutView
);
383 MoveTo(AboutPosition(Frame().Width(), Frame().Height()));
387 BAboutWindow::~BAboutWindow()
389 fAboutView
->RemoveSelf();
395 // #pragma mark - BAboutWindow virtual methods
402 // move to current workspace
403 SetWorkspaces(B_CURRENT_WORKSPACE
);
410 // #pragma mark - BAboutWindow public methods
414 BAboutWindow::AboutPosition(float width
, float height
)
416 BPoint
result(100, 100);
419 dynamic_cast<BWindow
*>(BLooper::LooperForThread(find_thread(NULL
)));
421 BScreen
screen(window
);
422 BRect
screenFrame(0, 0, 640, 480);
423 if (screen
.IsValid())
424 screenFrame
= screen
.Frame();
426 // Horizontally, we're smack in the middle
427 result
.x
= screenFrame
.left
+ (screenFrame
.Width() / 2.0) - (width
/ 2.0);
429 // This is probably sooo wrong, but it looks right on 1024 x 768
430 result
.y
= screenFrame
.top
+ (screenFrame
.Height() / 4.0)
431 - ceil(height
/ 3.0);
438 BAboutWindow::AddDescription(const char* description
)
440 if (description
== NULL
)
443 AddText(description
);
448 BAboutWindow::AddCopyright(int32 firstCopyrightYear
,
449 const char* copyrightHolder
, const char** extraCopyrights
)
451 BString
copyright(B_UTF8_COPYRIGHT
" %years% %holder%");
457 strftime(currentYear
, 5, "%Y", localtime(&tp
));
458 BString copyrightYears
;
459 copyrightYears
<< firstCopyrightYear
;
460 if (copyrightYears
!= currentYear
)
461 copyrightYears
<< "-" << currentYear
;
464 if (fAboutView
->InfoView()->TextLength() > 0)
469 // Fill out the copyright year placeholder
470 text
.ReplaceAll("%years%", copyrightYears
.String());
472 // Fill in the copyright holder placeholder
473 text
.ReplaceAll("%holder%", copyrightHolder
);
475 // Add extra copyright strings
476 if (extraCopyrights
!= NULL
) {
477 // Add optional extra copyright information
478 for (int32 i
= 0; extraCopyrights
[i
]; i
++)
479 text
<< "\n" << B_UTF8_COPYRIGHT
<< " " << extraCopyrights
[i
];
482 const char* allRightsReserved
= B_TRANSLATE_MARK("All Rights Reserved.");
483 allRightsReserved
= gSystemCatalog
.GetString(allRightsReserved
,
485 text
<< "\n " << allRightsReserved
;
487 fAboutView
->InfoView()->Insert(text
.String());
492 BAboutWindow::AddAuthors(const char** authors
)
497 const char* writtenBy
= B_TRANSLATE_MARK("Written by:");
498 writtenBy
= gSystemCatalog
.GetString(writtenBy
, "AboutWindow");
500 AddText(writtenBy
, authors
);
505 BAboutWindow::AddSpecialThanks(const char** thanks
)
510 const char* specialThanks
= B_TRANSLATE_MARK("Special Thanks:");
511 specialThanks
= gSystemCatalog
.GetString(specialThanks
, "AboutWindow");
513 AddText(specialThanks
, thanks
);
518 BAboutWindow::AddVersionHistory(const char** history
)
523 const char* versionHistory
= B_TRANSLATE_MARK("Version history:");
524 versionHistory
= gSystemCatalog
.GetString(versionHistory
, "AboutWindow");
526 AddText(versionHistory
, history
);
531 BAboutWindow::AddExtraInfo(const char* extraInfo
)
533 if (extraInfo
== NULL
)
536 const char* appExtraInfo
= B_TRANSLATE_MARK(extraInfo
);
537 appExtraInfo
= gSystemCatalog
.GetString(extraInfo
, "AboutWindow");
540 if (fAboutView
->InfoView()->TextLength() > 0)
543 extra
<< appExtraInfo
;
545 fAboutView
->InfoView()->Insert(extra
.String());
550 BAboutWindow::AddText(const char* header
, const char** contents
)
552 BTextView
* infoView
= fAboutView
->InfoView();
553 int32 textLength
= infoView
->TextLength();
556 if (textLength
> 0) {
561 const char* indent
= "";
562 if (header
!= NULL
) {
567 if (contents
!= NULL
) {
569 for (int32 i
= 0; contents
[i
]; i
++)
570 text
<< indent
<< contents
[i
] << "\n";
573 infoView
->Insert(text
.String());
575 if (contents
!= NULL
&& header
!= NULL
) {
576 infoView
->SetFontAndColor(textLength
, textLength
+ strlen(header
),
585 return fAboutView
->Icon();
590 BAboutWindow::SetIcon(BBitmap
* icon
)
592 fAboutView
->SetIcon(icon
);
599 return fAboutView
->Name();
604 BAboutWindow::SetName(const char* name
)
606 fAboutView
->SetName(name
);
611 BAboutWindow::Version()
613 return fAboutView
->Version();
618 BAboutWindow::SetVersion(const char* version
)
620 fAboutView
->SetVersion(version
);
626 void BAboutWindow::_ReservedAboutWindow20() {}
627 void BAboutWindow::_ReservedAboutWindow19() {}
628 void BAboutWindow::_ReservedAboutWindow18() {}
629 void BAboutWindow::_ReservedAboutWindow17() {}
630 void BAboutWindow::_ReservedAboutWindow16() {}
631 void BAboutWindow::_ReservedAboutWindow15() {}
632 void BAboutWindow::_ReservedAboutWindow14() {}
633 void BAboutWindow::_ReservedAboutWindow13() {}
634 void BAboutWindow::_ReservedAboutWindow12() {}
635 void BAboutWindow::_ReservedAboutWindow11() {}
636 void BAboutWindow::_ReservedAboutWindow10() {}
637 void BAboutWindow::_ReservedAboutWindow9() {}
638 void BAboutWindow::_ReservedAboutWindow8() {}
639 void BAboutWindow::_ReservedAboutWindow7() {}
640 void BAboutWindow::_ReservedAboutWindow6() {}
641 void BAboutWindow::_ReservedAboutWindow5() {}
642 void BAboutWindow::_ReservedAboutWindow4() {}
643 void BAboutWindow::_ReservedAboutWindow3() {}
644 void BAboutWindow::_ReservedAboutWindow2() {}
645 void BAboutWindow::_ReservedAboutWindow1() {}