Show localized app names. Show reboot count-down in bold type. Layout changes to support multiline strings, and for this purpose adding a BTextView derivate which enforces its height. (I did look at BTextView itself, but it wasn't obvious to me how approach it.) Making use of the IconView class.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41250 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jonas Sundström
2011-04-14 17:48:52 +00:00
parent eb88c867c1
commit 95bd470555
4 changed files with 202 additions and 141 deletions
@@ -11,35 +11,40 @@
#include <string.h> #include <string.h>
#include <FindDirectory.h> #include <FindDirectory.h>
#include <LocaleRoster.h>
#include <NodeInfo.h> #include <NodeInfo.h>
#include <Path.h> #include <Path.h>
#include <Roster.h>
#include <View.h> #include <View.h>
static const int32 kItemMargin = 2; static const int32 kItemMargin = 2;
TeamListItem::TeamListItem(team_info &tinfo) bool gLocalizedNamePreferred;
TeamListItem::TeamListItem(team_info &teamInfo)
: :
fInfo(tinfo), fTeamInfo(teamInfo),
fIcon(BRect(0, 0, 15, 15), B_RGBA32), fAppInfo(),
fMiniIcon(BRect(0, 0, 15, 15), B_RGBA32),
fLargeIcon(BRect(0, 0, 31, 31), B_RGBA32), fLargeIcon(BRect(0, 0, 31, 31), B_RGBA32),
fFound(false) fFound(false)
{ {
int32 cookie = 0; int32 cookie = 0;
image_info info; image_info info;
if (get_next_image_info(tinfo.team, &cookie, &info) == B_OK) { if (get_next_image_info(teamInfo.team, &cookie, &info) == B_OK) {
fPath = BPath(info.name); fPath = BPath(info.name);
BNode node(info.name); BNode node(info.name);
BNodeInfo nodeInfo(&node); BNodeInfo nodeInfo(&node);
nodeInfo.GetTrackerIcon(&fIcon, B_MINI_ICON); nodeInfo.GetTrackerIcon(&fMiniIcon, B_MINI_ICON);
nodeInfo.GetTrackerIcon(&fLargeIcon, B_LARGE_ICON); nodeInfo.GetTrackerIcon(&fLargeIcon, B_LARGE_ICON);
} }
app_info appInfo; if (be_roster->GetRunningAppInfo(fTeamInfo.team, &fAppInfo) != B_OK)
if (be_roster->GetRunningAppInfo(fInfo.team, &appInfo) == B_OK) fAppInfo.signature[0] = '\0';
fAppSignature = appInfo.signature;
CacheLocalizedName();
} }
@@ -48,6 +53,15 @@ TeamListItem::~TeamListItem()
} }
void
TeamListItem::CacheLocalizedName()
{
if (BLocaleRoster::Default()->GetLocalizedFileName(fLocalizedName,
fAppInfo.ref, true) != B_OK)
fLocalizedName = fPath.Leaf();
}
void void
TeamListItem::DrawItem(BView* owner, BRect frame, bool complete) TeamListItem::DrawItem(BView* owner, BRect frame, bool complete)
{ {
@@ -78,7 +92,7 @@ TeamListItem::DrawItem(BView* owner, BRect frame, bool complete)
iconFrame.top + 16); iconFrame.top + 16);
owner->SetDrawingMode(B_OP_ALPHA); owner->SetDrawingMode(B_OP_ALPHA);
owner->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); owner->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
owner->DrawBitmap(&fIcon, iconFrame); owner->DrawBitmap(&fMiniIcon, iconFrame);
owner->SetDrawingMode(B_OP_COPY); owner->SetDrawingMode(B_OP_COPY);
frame.left += 16; frame.left += 16;
@@ -91,7 +105,11 @@ TeamListItem::DrawItem(BView* owner, BRect frame, bool complete)
owner->MovePenTo(frame.left + 8, frame.top + ((frame.Height() owner->MovePenTo(frame.left + 8, frame.top + ((frame.Height()
- (finfo.ascent + finfo.descent + finfo.leading)) / 2) - (finfo.ascent + finfo.descent + finfo.leading)) / 2)
+ finfo.ascent); + finfo.ascent);
owner->DrawString(fPath.Leaf());
if (gLocalizedNamePreferred)
owner->DrawString(fLocalizedName.String());
else
owner->DrawString(fPath.Leaf());
} }
@@ -116,7 +134,7 @@ TeamListItem::Update(BView* owner, const BFont* font)
const team_info* const team_info*
TeamListItem::GetInfo() TeamListItem::GetInfo()
{ {
return &fInfo; return &fTeamInfo;
} }
@@ -140,14 +158,16 @@ TeamListItem::IsSystemServer()
firstCall = false; firstCall = false;
} }
if (strncmp(systemServersPath.Path(), fInfo.args, if (strncmp(systemServersPath.Path(), fTeamInfo.args,
strlen(systemServersPath.Path())) == 0) strlen(systemServersPath.Path())) == 0)
return true; return true;
if (strncmp(trackerPath.Path(), fInfo.args, strlen(trackerPath.Path())) == 0) if (strncmp(trackerPath.Path(), fTeamInfo.args,
strlen(trackerPath.Path())) == 0)
return true; return true;
if (strncmp(deskbarPath.Path(), fInfo.args, strlen(deskbarPath.Path())) == 0) if (strncmp(deskbarPath.Path(), fTeamInfo.args,
strlen(deskbarPath.Path())) == 0)
return true; return true;
return false; return false;
@@ -157,5 +177,5 @@ TeamListItem::IsSystemServer()
bool bool
TeamListItem::IsApplication() TeamListItem::IsApplication()
{ {
return !fAppSignature.IsEmpty(); return fAppInfo.signature[0] != '\0';
} }
@@ -12,9 +12,13 @@
#include <Bitmap.h> #include <Bitmap.h>
#include <ListItem.h> #include <ListItem.h>
#include <Path.h> #include <Path.h>
#include <Roster.h>
#include <String.h> #include <String.h>
extern bool gLocalizedNamePreferred;
class TeamListItem : public BListItem { class TeamListItem : public BListItem {
public: public:
TeamListItem(team_info& info); TeamListItem(team_info& info);
@@ -24,10 +28,12 @@ public:
bool complete = false); bool complete = false);
virtual void Update(BView* owner, const BFont* font); virtual void Update(BView* owner, const BFont* font);
void CacheLocalizedName();
const team_info* GetInfo(); const team_info* GetInfo();
const BBitmap* LargeIcon() { return &fLargeIcon; }; const BBitmap* LargeIcon() { return &fLargeIcon; };
const BPath* Path() { return &fPath; }; const BPath* Path() { return &fPath; };
const BString* AppSignature() { return &fAppSignature; }; const char* AppSignature() { return fAppInfo.signature; };
bool IsSystemServer(); bool IsSystemServer();
bool IsApplication(); bool IsApplication();
@@ -38,10 +44,12 @@ public:
static int32 MinimalHeight(); static int32 MinimalHeight();
private: private:
team_info fInfo; team_info fTeamInfo;
BBitmap fIcon, fLargeIcon; app_info fAppInfo;
BBitmap fMiniIcon;
BBitmap fLargeIcon;
BPath fPath; BPath fPath;
BString fAppSignature; BString fLocalizedName;
bool fFound; bool fFound;
}; };
@@ -13,10 +13,12 @@
#include <stdio.h> #include <stdio.h>
#include <Application.h>
#include <CardLayout.h> #include <CardLayout.h>
#include <Catalog.h> #include <Catalog.h>
#include <GroupLayout.h> #include <GroupLayoutBuilder.h>
#include <GroupView.h> #include <IconView.h>
#include <LocaleRoster.h>
#include <Message.h> #include <Message.h>
#include <MessageRunner.h> #include <MessageRunner.h>
#include <Roster.h> #include <Roster.h>
@@ -37,14 +39,32 @@
#define B_TRANSLATE_CONTEXT "Team Monitor" #define B_TRANSLATE_CONTEXT "Team Monitor"
class TeamDescriptionView : public BBox { TeamMonitorWindow* gTeamMonitorWindow = NULL;
filter_result
FilterLocaleChanged(BMessage* message, BHandler** target, BMessageFilter *filter)
{
if (message->what == B_LOCALE_CHANGED && gTeamMonitorWindow != NULL)
gTeamMonitorWindow->LocaleChanged();
return B_DISPATCH_MESSAGE;
}
class AllShowingTextView : public BTextView {
public:
AllShowingTextView(const char* name);
virtual void FrameResized(float width, float height);
};
class TeamDescriptionView : public BView {
public: public:
TeamDescriptionView(); TeamDescriptionView();
virtual ~TeamDescriptionView(); virtual ~TeamDescriptionView();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual void Draw(BRect bounds);
virtual void GetPreferredSize(float* _width, float* _height);
void CtrlAltDelPressed(bool keyDown); void CtrlAltDelPressed(bool keyDown);
@@ -52,10 +72,15 @@ public:
TeamListItem* Item() { return fItem; } TeamListItem* Item() { return fItem; }
private: private:
const char* fText[3];
TeamListItem* fItem; TeamListItem* fItem;
int32 fSeconds; int32 fSeconds;
BMessageRunner* fRebootRunner; BMessageRunner* fRebootRunner;
IconView* fIconView;
const char* fInfoString;
const char* fSysComponentString;
BCardLayout* fLayout;
AllShowingTextView* fIconTextView;
AllShowingTextView* fInfoTextView;
}; };
@@ -73,10 +98,10 @@ static const uint32 kMsgRebootTick = 'TMrt';
TeamMonitorWindow::TeamMonitorWindow() TeamMonitorWindow::TeamMonitorWindow()
: :
BWindow(BRect(0, 0, 350, 300), B_TRANSLATE("Team Monitor"), BWindow(BRect(0, 0, 350, 400), B_TRANSLATE("Team Monitor"),
B_TITLED_WINDOW_LOOK, B_MODAL_ALL_WINDOW_FEEL, B_TITLED_WINDOW_LOOK, B_MODAL_ALL_WINDOW_FEEL,
B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
| B_CLOSE_ON_ESCAPE, | B_CLOSE_ON_ESCAPE | B_AUTO_UPDATE_SIZE_LIMITS,
B_ALL_WORKSPACES), B_ALL_WORKSPACES),
fQuitting(false), fQuitting(false),
fUpdateRunner(NULL) fUpdateRunner(NULL)
@@ -161,6 +186,17 @@ TeamMonitorWindow::TeamMonitorWindow()
AddShortcut('T', B_COMMAND_KEY | B_OPTION_KEY, AddShortcut('T', B_COMMAND_KEY | B_OPTION_KEY,
new BMessage(kMsgLaunchTerminal)); new BMessage(kMsgLaunchTerminal));
AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED)); AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED));
gLocalizedNamePreferred
= BLocaleRoster::Default()->IsFilesystemTranslationPreferred();
gTeamMonitorWindow = this;
if (be_app->Lock()) {
be_app->AddCommonFilter(new BMessageFilter(B_ANY_DELIVERY,
B_ANY_SOURCE, B_LOCALE_CHANGED, FilterLocaleChanged));
be_app->Unlock();
}
} }
@@ -189,6 +225,10 @@ TeamMonitorWindow::MessageReceived(BMessage* msg)
fDescriptionView->CtrlAltDelPressed(keyDown); fDescriptionView->CtrlAltDelPressed(keyDown);
break; break;
case kMsgDeselectAll:
fListView->DeselectAll();
break;
case kMsgLaunchTerminal: case kMsgLaunchTerminal:
be_roster->Launch("application/x-vnd.Haiku-Terminal"); be_roster->Launch("application/x-vnd.Haiku-Terminal");
break; break;
@@ -212,7 +252,7 @@ TeamMonitorWindow::MessageReceived(BMessage* msg)
TeamListItem* item = dynamic_cast<TeamListItem*>(fListView->ItemAt( TeamListItem* item = dynamic_cast<TeamListItem*>(fListView->ItemAt(
fListView->CurrentSelection())); fListView->CurrentSelection()));
if (item != NULL) { if (item != NULL) {
BMessenger messenger(item->AppSignature()->String(), BMessenger messenger(item->AppSignature(),
item->GetInfo()->team); item->GetInfo()->team);
messenger.SendMessage(B_QUIT_REQUESTED); messenger.SendMessage(B_QUIT_REQUESTED);
} }
@@ -348,40 +388,61 @@ TeamMonitorWindow::Disable()
} }
void
TeamMonitorWindow::LocaleChanged()
{
BLocaleRoster::Default()->Refresh();
gLocalizedNamePreferred
= BLocaleRoster::Default()->IsFilesystemTranslationPreferred();
for (int32 i = 0; i < fListView->CountItems(); i++) {
TeamListItem* item
= dynamic_cast<TeamListItem*>(fListView->ItemAt(i));
if (item != NULL)
item->CacheLocalizedName();
}
}
// #pragma mark - // #pragma mark -
TeamDescriptionView::TeamDescriptionView() TeamDescriptionView::TeamDescriptionView()
: :
BBox("description view", B_WILL_DRAW | B_PULSE_NEEDED, B_NO_BORDER), BView("description view", B_WILL_DRAW),
fItem(NULL), fItem(NULL),
fSeconds(4), fSeconds(4),
fRebootRunner(NULL) fRebootRunner(NULL)
{ {
/* fInfoString = B_TRANSLATE(
BTextView* textView = new BTextView("description"); "Select an application from the list above and click one of "
textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); "the buttons 'Kill Application' and 'Quit Application' "
textView->MakeEditable(false); "in order to close it.\n\n"
textView->SetText("Select an application from the list above and click "
"the \"Kill Application\" button in order to close it.\n\n"
"Hold CONTROL+ALT+DELETE for %ld seconds to reboot.");
view->AddChild(textView);
((BCardLayout*)view->GetLayout())->SetVisibleItem((int32)0);
*/
SetFont(be_plain_font);
fText[0] = B_TRANSLATE(
"Select an application from the list above and click the");
fText[1] = B_TRANSLATE(
"\"Kill Application\" button in order to close it.");
fText[2] = B_TRANSLATE(
"Hold CONTROL+ALT+DELETE for %ld seconds to reboot."); "Hold CONTROL+ALT+DELETE for %ld seconds to reboot.");
float width, height; fSysComponentString = B_TRANSLATE("(This team is a system component)");
GetPreferredSize(&width, &height);
SetExplicitMinSize(BSize(width, -1)); fInfoTextView = new AllShowingTextView("info text");
SetExplicitPreferredSize(BSize(width, height)); fIconTextView = new AllShowingTextView("icon text");
SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, height));
fIconView = new IconView();
fIconView->SetExplicitAlignment(
BAlignment(B_ALIGN_HORIZONTAL_UNSET, B_ALIGN_TOP));
BView* teamPropertiesView = new BView("team properties", B_WILL_DRAW);
teamPropertiesView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL);
teamPropertiesView->SetLayout(layout);
BGroupLayoutBuilder(layout)
.Add(fIconView)
.Add(fIconTextView);
fLayout = new BCardLayout();
SetLayout(fLayout);
fLayout->AddView(fInfoTextView);
fLayout->AddView(teamPropertiesView);
SetItem(NULL);
} }
@@ -400,11 +461,11 @@ TeamDescriptionView::MessageReceived(BMessage* message)
if (fSeconds == 0) if (fSeconds == 0)
Window()->PostMessage(TM_FORCE_REBOOT); Window()->PostMessage(TM_FORCE_REBOOT);
else else
Invalidate(); SetItem(fItem);
break; break;
default: default:
BBox::MessageReceived(message); BView::MessageReceived(message);
} }
} }
@@ -420,96 +481,12 @@ TeamDescriptionView::CtrlAltDelPressed(bool keyDown)
fSeconds = 4; fSeconds = 4;
if (keyDown) { if (keyDown) {
Window()->PostMessage(kMsgDeselectAll);
BMessage tick(kMsgRebootTick); BMessage tick(kMsgRebootTick);
fRebootRunner = new BMessageRunner(this, &tick, 1000000LL); fRebootRunner = new BMessageRunner(this, &tick, 1000000LL);
} else
Invalidate();
}
void
TeamDescriptionView::Draw(BRect rect)
{
rect = Bounds();
font_height fontInfo;
GetFontHeight(&fontInfo);
float height
= ceil(fontInfo.ascent + fontInfo.descent + fontInfo.leading + 2);
if (fItem) {
// draw icon and application path
BRect frame(rect);
frame.Set(frame.left, frame.top, frame.left + 31, frame.top + 31);
SetDrawingMode(B_OP_ALPHA);
SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
DrawBitmap(fItem->LargeIcon(), frame);
SetDrawingMode(B_OP_COPY);
BPoint line(frame.right + 9, frame.top + fontInfo.ascent);
if (!fItem->IsSystemServer())
line.y += (frame.Height() - height) / 2;
else
line.y += (frame.Height() - 2 * height) / 2;
BString path = fItem->Path()->Path();
TruncateString(&path, B_TRUNCATE_MIDDLE, rect.right - line.x);
DrawString(path.String(), line);
if (fItem->IsSystemServer()) {
line.y += height;
//SetFont(be_bold_font);
DrawString(B_TRANSLATE("(This team is a system component)"), line);
//SetFont(be_plain_font);
}
} else {
BPoint line(rect.left, rect.top + fontInfo.ascent);
for (int32 i = 0; i < 2; i++) {
DrawString(fText[i], line);
line.y += height;
}
char text[256];
if (fSeconds >= 0)
snprintf(text, sizeof(text), fText[2], fSeconds);
else
strlcpy(text, B_TRANSLATE("Booom!"), sizeof(text));
line.y += height;
DrawString(text, line);
}
}
void
TeamDescriptionView::GetPreferredSize(float* _width, float* _height)
{
if (_width != NULL) {
float width = 0;
for (int32 i = 0; i < 3; i++) {
float stringWidth = ceilf(StringWidth(fText[i]));
if (stringWidth > width)
width = stringWidth;
}
if (width < 330)
width = 330;
*_width = width;
} }
if (_height != NULL) { SetItem(NULL);
font_height fontInfo;
GetFontHeight(&fontInfo);
float height = 4 * ceil(fontInfo.ascent + fontInfo.descent
+ fontInfo.leading + 2);
if (height < 32)
height = 32;
*_height = height;
}
} }
@@ -517,5 +494,57 @@ void
TeamDescriptionView::SetItem(TeamListItem* item) TeamDescriptionView::SetItem(TeamListItem* item)
{ {
fItem = item; fItem = item;
if (item == NULL) {
BString text;
text.SetToFormat(fInfoString, fSeconds);
fInfoTextView->SetText(text);
if (fRebootRunner != NULL && fSeconds < 4) {
BFont font;
fInfoTextView->GetFont(&font);
font.SetFace(B_BOLD_FACE);
fInfoTextView->SetStylable(true);
fInfoTextView->SetFontAndColor(text.FindLast('\n'),
text.Length() - 1, &font);
}
} else {
BString text = item->Path()->Path();
if (item->IsSystemServer())
text << "\n" << fSysComponentString;
fIconTextView->SetText(text);
fIconView->SetIcon(item->Path()->Path());
}
if (fLayout == NULL)
return;
if (item == NULL)
fLayout->SetVisibleItem((int32)0);
else
fLayout->SetVisibleItem((int32)1);
Invalidate(); Invalidate();
} }
// #pragma mark -
AllShowingTextView::AllShowingTextView(const char* name)
:
BTextView(name, B_WILL_DRAW)
{
MakeEditable(false);
MakeSelectable(false);
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
void
AllShowingTextView::FrameResized(float width, float height)
{
float minHeight = TextHeight(0, CountLines() - 1);
SetExplicitMinSize(BSize(B_SIZE_UNSET, minHeight));
BTextView::FrameResized(width, minHeight);
}
@@ -13,6 +13,7 @@
#include <Box.h> #include <Box.h>
#include <Button.h> #include <Button.h>
#include <ListView.h> #include <ListView.h>
#include <MessageFilter.h>
#include <Window.h> #include <Window.h>
#include "TeamListItem.h" #include "TeamListItem.h"
@@ -30,6 +31,8 @@ public:
void Enable(); void Enable();
void Disable(); void Disable();
void DeselectAll();
void LocaleChanged();
private: private:
void UpdateList(); void UpdateList();
@@ -41,9 +44,10 @@ private:
BButton* fKillButton; BButton* fKillButton;
BButton* fQuitButton; BButton* fQuitButton;
BButton* fRestartButton; BButton* fRestartButton;
TeamDescriptionView* fDescriptionView; TeamDescriptionView* fDescriptionView;
}; };
static const uint32 kMsgCtrlAltDelPressed = 'TMcp'; static const uint32 kMsgCtrlAltDelPressed = 'TMcp';
static const uint32 kMsgDeselectAll = 'TMds';
#endif // TEAM_MONITOR_WINDOW_H #endif // TEAM_MONITOR_WINDOW_H