Add 12/24 hour and time formatting options to Deskbar.

* 12/24 hour settings come from and alter BLocale
* Time formats are short, medium, long. Short is default. Come from
  Locale kit.
* Don't delete fClock (now fTime) when hiding, just hide and show
  the view.
* BarView now has nothing to do with setting or keeping track of
  time settings. This is all handled in TTimeView. TReplicantTray
  is responsible for updating the replicant tray and doing showing
  and hiding. TTimeView is responsible for drawing according to the
  clock settings.
* Remove fShowInterval and fShowSeconds from BarView
* Remove ampmMode setting and replace it with timeFormat.
* Reset targets in DeskbarMenu.

Originally I was trying to solve a bug where the TTimeView
was relying on the Deskbar settings too much. The settings
should only by set on quit and accessed on startup or a crash can
cause Deskbar to be in an unusual state.

I realize that the timezone is not very helpful. I'd like to provide
the day of week in a short format instead, i.e. Wed for Wednesday or
similar based on your locale. Blame the Locale Kit for now allowing
me to be able to use a custom TimeFormat. Once a custom TimeFormats
becomes possible from the Locale Kit Deskbar can be updated to use
them.
This commit is contained in:
John Scipione 2012-04-09 06:39:11 -04:00
parent 40b6c14db7
commit 573f748c5f
13 changed files with 489 additions and 335 deletions

View File

@ -196,11 +196,12 @@ TBarApp::SaveSettings()
storedSettings.AddBool("vertical", fSettings.vertical);
storedSettings.AddBool("left", fSettings.left);
storedSettings.AddBool("top", fSettings.top);
storedSettings.AddBool("ampmMode", fSettings.ampmMode);
storedSettings.AddInt32("state", fSettings.state);
storedSettings.AddFloat("width", fSettings.width);
storedSettings.AddBool("showTime", fSettings.showTime);
storedSettings.AddBool("timeFormat", fSettings.timeFormat);
storedSettings.AddPoint("switcherLoc", fSettings.switcherLoc);
storedSettings.AddInt32("recentAppsCount", fSettings.recentAppsCount);
storedSettings.AddInt32("recentDocsCount", fSettings.recentDocsCount);
@ -237,8 +238,8 @@ TBarApp::InitSettings()
settings.vertical = true;
settings.left = false;
settings.top = true;
settings.ampmMode = true;
settings.showTime = true;
settings.timeFormat = B_SHORT_TIME_FORMAT;
settings.state = kExpandoState;
settings.width = 0;
settings.switcherLoc = BPoint(5000, 5000);
@ -287,10 +288,6 @@ TBarApp::InitSettings()
settings.left = false;
if (storedSettings.FindBool("top", &settings.top) != B_OK)
settings.top = true;
if (storedSettings.FindBool("ampmMode", &settings.ampmMode)
!= B_OK) {
settings.ampmMode = true;
}
if (storedSettings.FindInt32("state", (int32*)&settings.state)
!= B_OK) {
settings.state = kExpandoState;
@ -301,6 +298,10 @@ TBarApp::InitSettings()
!= B_OK) {
settings.showTime = true;
}
if (storedSettings.FindUInt32("timeFormat", &settings.timeFormat)
!= B_OK) {
settings.timeFormat = B_SHORT_TIME_FORMAT;
}
if (storedSettings.FindPoint("switcherLoc", &settings.switcherLoc)
!= B_OK) {
settings.switcherLoc = BPoint(5000, 5000);

View File

@ -102,8 +102,8 @@ struct desk_settings {
bool vertical;
bool left;
bool top;
bool ampmMode;
bool showTime;
uint32 timeFormat;
uint32 state;
float width;
BPoint switcherLoc;

View File

@ -70,13 +70,11 @@ const int32 kMenuTrackMargin = 20;
TBarView::TBarView(BRect frame, bool vertical, bool left, bool top,
bool showInterval, uint32 state, float, bool showClock)
uint32 state, float)
: BView(frame, "BarView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
fBarMenuBar(NULL),
fExpando(NULL),
fTrayLocation(1),
fShowInterval(showInterval),
fShowClock(showClock),
fVertical(vertical),
fTop(top),
fLeft(left),
@ -502,12 +500,10 @@ TBarView::SaveSettings()
settings->vertical = fVertical;
settings->left = fLeft;
settings->top = fTop;
settings->ampmMode = fShowInterval;
settings->state = (uint32)fState;
settings->width = 0;
settings->showTime = fShowClock;
fReplicantTray->RememberClockSettings();
fReplicantTray->SaveTimeSettings();
}

View File

@ -71,7 +71,7 @@ class TTeamMenuItem;
class TBarView : public BView {
public:
TBarView(BRect frame, bool vertical, bool left, bool top,
bool ampmMode, uint32 state, float width, bool showClock);
uint32 state, float width);
~TBarView();
virtual void AttachedToWindow();
@ -102,11 +102,7 @@ class TBarView : public BView {
bool MiniState() const { return fState == kMiniState; };
int32 State() const { return fState; };
// optional functionality methods
bool MilTime() const { return fShowInterval; };
void ShowClock(bool show) { fShowClock = show; };
bool ShowingClock() const { return fShowClock; };
// drag and drop methods
void CacheDragData(const BMessage* incoming);
status_t DragStart();
static bool MenuTrackingHook(BMenu* menu, void* castToThis);
@ -172,8 +168,6 @@ class TBarView : public BView {
TDragRegion* fDragRegion;
TReplicantTray* fReplicantTray;
bool fShowInterval : 1;
bool fShowClock : 1;
bool fVertical : 1;
bool fTop : 1;
bool fLeft : 1;

View File

@ -96,8 +96,7 @@ TBarWindow::TBarWindow()
if (settings->alwaysOnTop)
SetFeel(B_FLOATING_ALL_WINDOW_FEEL);
fBarView = new TBarView(Bounds(), settings->vertical, settings->left,
settings->top, settings->ampmMode, settings->state, settings->width,
settings->showTime);
settings->top, settings->state, settings->width);
AddChild(fBarView);
RemoveShortcut('H', B_COMMAND_KEY | B_CONTROL_KEY);

View File

@ -387,12 +387,22 @@ TDeskbarMenu::ResetTargets()
case kToggleDraggers:
case kConfigShow:
case kAlwaysTop:
case kShowSeconds:
case kExpandNewTeams:
case kHideLabels:
case kResizeTeamIcons:
case kSortRunningApps:
case kTrackerFirst:
case kRebootSystem:
case kSuspendSystem:
case kShutdownSystem:
item->SetTarget(be_app);
break;
case kShowHideTime:
case kTimeIntervalChanged:
case kTimeFormatChanged:
item->SetTarget(fBarView->fReplicantTray);
break;
}
}
}

View File

@ -1,6 +1,6 @@
SubDir HAIKU_TOP src apps deskbar ;
UsePrivateHeaders app interface shared tracker ;
UsePrivateHeaders app interface locale shared tracker ;
UsePrivateHeaders private shared ;
SubDirHdrs $(HAIKU_TOP) src kits tracker ;

View File

@ -9,8 +9,11 @@
#include "PreferencesWindow.h"
#include <ctype.h>
#include <Catalog.h>
#include <CheckBox.h>
#include <FormattingConventions.h>
#include <GroupLayout.h>
#include <Locale.h>
#include <LayoutBuilder.h>
@ -18,8 +21,8 @@
#include <RadioButton.h>
#include <SeparatorView.h>
#include <Slider.h>
#include <ctype.h>
#include <StringView.h>
#include <View.h>
#include "BarApp.h"
#include "StatusView.h"
@ -33,7 +36,7 @@ PreferencesWindow::PreferencesWindow(BRect frame)
BWindow(frame, B_TRANSLATE("Deskbar preferences"), B_TITLED_WINDOW,
B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE)
{
// Controls
// Menu controls
fMenuRecentDocuments = new BCheckBox(B_TRANSLATE("Recent documents:"),
new BMessage(kUpdateRecentCounts));
fMenuRecentApplications = new BCheckBox(B_TRANSLATE("Recent applications:"),
@ -48,6 +51,7 @@ PreferencesWindow::PreferencesWindow(BRect frame)
fMenuRecentFolderCount = new BTextControl(NULL, NULL,
new BMessage(kUpdateRecentCounts));
// Applications controls
fAppsSort = new BCheckBox(B_TRANSLATE("Sort running applications"),
new BMessage(kSortRunningApps));
fAppsSortTrackerFirst = new BCheckBox(B_TRANSLATE("Tracker always first"),
@ -68,8 +72,7 @@ PreferencesWindow::PreferencesWindow(BRect frame)
B_TRANSLATE("Large"));
fAppsIconSizeSlider->SetModificationMessage(new BMessage(kResizeTeamIcons));
fClockSeconds = new BCheckBox(B_TRANSLATE("Show seconds"),
new BMessage(kShowSeconds));
// Window controls
fWindowAlwaysOnTop = new BCheckBox(B_TRANSLATE("Always on top"),
new BMessage(kAlwaysTop));
fWindowAutoRaise = new BCheckBox(B_TRANSLATE("Auto-raise"),
@ -77,6 +80,39 @@ PreferencesWindow::PreferencesWindow(BRect frame)
fWindowAutoHide = new BCheckBox(B_TRANSLATE("Auto-hide"),
new BMessage(kAutoHide));
// Clock controls
BMessage* timeInterval12HoursMessage = new BMessage(kTimeIntervalChanged);
timeInterval12HoursMessage->AddBool("use24HourClock", false);
fTimeInterval12HourRadioButton = new BRadioButton("time inteval",
B_TRANSLATE("12 hour"), timeInterval12HoursMessage);
BMessage* timeInterval24HoursMessage = new BMessage(kTimeIntervalChanged);
timeInterval24HoursMessage->AddBool("use24HourClock", true);
fTimeInterval24HourRadioButton = new BRadioButton("time inteval",
B_TRANSLATE("24 hour"), timeInterval24HoursMessage);
BMessage* timeFormatShortMessage = new BMessage(kTimeFormatChanged);
timeFormatShortMessage->AddUInt32("time format", B_SHORT_TIME_FORMAT);
fTimeFormatShortRadioButton = new BRadioButton("time format",
"Short", timeFormatShortMessage);
BMessage* timeFormatMediumMessage = new BMessage(kTimeFormatChanged);
timeFormatMediumMessage->AddUInt32("time format", B_MEDIUM_TIME_FORMAT);
fTimeFormatMediumRadioButton = new BRadioButton("time format",
"Medium", timeFormatMediumMessage);
BMessage* timeFormatLongMessage = new BMessage(kTimeFormatChanged);
timeFormatLongMessage->AddUInt32("time format", B_LONG_TIME_FORMAT);
fTimeFormatLongRadioButton = new BRadioButton("time format",
"Long", timeFormatLongMessage);
_UpdateTimeFormatRadioButtonLabels();
// Get settings from BarApp
TBarApp* barApp = static_cast<TBarApp*>(be_app);
desk_settings* settings = barApp->Settings();
// Menu settings
BTextView* docTextView = fMenuRecentDocumentCount->TextView();
BTextView* appTextView = fMenuRecentApplicationCount->TextView();
BTextView* folderTextView = fMenuRecentFolderCount->TextView();
@ -93,29 +129,18 @@ PreferencesWindow::PreferencesWindow(BRect frame)
appTextView->SetMaxBytes(4);
folderTextView->SetMaxBytes(4);
// Values
TBarApp* barApp = static_cast<TBarApp*>(be_app);
desk_settings* appSettings = barApp->Settings();
int32 docCount = settings->recentDocsCount;
int32 appCount = settings->recentAppsCount;
int32 folderCount = settings->recentFoldersCount;
fAppsSort->SetValue(appSettings->sortRunningApps);
fAppsSortTrackerFirst->SetValue(appSettings->trackerAlwaysFirst);
fAppsShowExpanders->SetValue(appSettings->superExpando);
fAppsExpandNew->SetValue(appSettings->expandNewTeams);
fAppsHideLabels->SetValue(appSettings->hideLabels);
fAppsIconSizeSlider->SetValue(appSettings->iconSize / kIconSizeInterval);
fMenuRecentDocuments->SetValue(settings->recentDocsEnabled);
fMenuRecentDocumentCount->SetEnabled(settings->recentDocsEnabled);
int32 docCount = appSettings->recentDocsCount;
int32 appCount = appSettings->recentAppsCount;
int32 folderCount = appSettings->recentFoldersCount;
fMenuRecentApplications->SetValue(settings->recentAppsEnabled);
fMenuRecentApplicationCount->SetEnabled(settings->recentAppsEnabled);
fMenuRecentDocuments->SetValue(appSettings->recentDocsEnabled);
fMenuRecentDocumentCount->SetEnabled(appSettings->recentDocsEnabled);
fMenuRecentApplications->SetValue(appSettings->recentAppsEnabled);
fMenuRecentApplicationCount->SetEnabled(appSettings->recentAppsEnabled);
fMenuRecentFolders->SetValue(appSettings->recentFoldersEnabled);
fMenuRecentFolderCount->SetEnabled(appSettings->recentFoldersEnabled);
fMenuRecentFolders->SetValue(settings->recentFoldersEnabled);
fMenuRecentFolderCount->SetEnabled(settings->recentFoldersEnabled);
BString docString;
BString appString;
@ -129,16 +154,37 @@ PreferencesWindow::PreferencesWindow(BRect frame)
fMenuRecentApplicationCount->SetText(appString.String());
fMenuRecentFolderCount->SetText(folderString.String());
TReplicantTray* replicantTray = barApp->BarView()->fReplicantTray;
// Applications settings
fAppsSort->SetValue(settings->sortRunningApps);
fAppsSortTrackerFirst->SetValue(settings->trackerAlwaysFirst);
fAppsShowExpanders->SetValue(settings->superExpando);
fAppsExpandNew->SetValue(settings->expandNewTeams);
fAppsHideLabels->SetValue(settings->hideLabels);
fAppsIconSizeSlider->SetValue(settings->iconSize / kIconSizeInterval);
fClockSeconds->SetValue(replicantTray->ShowingSeconds());
// Window settings
fWindowAlwaysOnTop->SetValue(settings->alwaysOnTop);
fWindowAutoRaise->SetValue(settings->autoRaise);
fWindowAutoHide->SetValue(settings->autoHide);
bool showingClock = barApp->BarView()->ShowingClock();
fClockSeconds->SetEnabled(showingClock);
// Clock settings
BFormattingConventions conventions;
BLocale::Default()->GetFormattingConventions(&conventions);
if (conventions.Use24HourClock())
fTimeInterval24HourRadioButton->SetValue(B_CONTROL_ON);
else
fTimeInterval12HourRadioButton->SetValue(B_CONTROL_ON);
fWindowAlwaysOnTop->SetValue(appSettings->alwaysOnTop);
fWindowAutoRaise->SetValue(appSettings->autoRaise);
fWindowAutoHide->SetValue(appSettings->autoHide);
switch (settings->timeFormat) {
case B_LONG_TIME_FORMAT:
fTimeFormatLongRadioButton->SetValue(B_CONTROL_ON);
break;
case B_MEDIUM_TIME_FORMAT:
fTimeFormatMediumRadioButton->SetValue(B_CONTROL_ON);
break;
default:
fTimeFormatShortRadioButton->SetValue(B_CONTROL_ON);
}
_EnableDisableDependentItems();
@ -149,22 +195,27 @@ PreferencesWindow::PreferencesWindow(BRect frame)
fAppsHideLabels->SetTarget(be_app);
fAppsIconSizeSlider->SetTarget(be_app);
fClockSeconds->SetTarget(replicantTray);
fWindowAlwaysOnTop->SetTarget(be_app);
fWindowAutoRaise->SetTarget(be_app);
fWindowAutoHide->SetTarget(be_app);
TReplicantTray* replicantTray = barApp->BarView()->fReplicantTray;
fTimeInterval12HourRadioButton->SetTarget(replicantTray);
fTimeInterval24HourRadioButton->SetTarget(replicantTray);
fTimeFormatShortRadioButton->SetTarget(replicantTray);
fTimeFormatMediumRadioButton->SetTarget(replicantTray);
fTimeFormatLongRadioButton->SetTarget(replicantTray);
// Layout
fMenuBox = new BBox("fMenuBox");
fAppsBox = new BBox("fAppsBox");
fClockBox = new BBox("fClockBox");
fWindowBox = new BBox("fWindowBox");
fClockBox = new BBox("fClockBox");
fMenuBox->SetLabel(B_TRANSLATE("Menu"));
fAppsBox->SetLabel(B_TRANSLATE("Applications"));
fClockBox->SetLabel(B_TRANSLATE("Clock"));
fWindowBox->SetLabel(B_TRANSLATE("Window"));
fClockBox->SetLabel(B_TRANSLATE("Clock"));
BView* view;
view = BLayoutBuilder::Group<>()
@ -205,15 +256,6 @@ PreferencesWindow::PreferencesWindow(BRect frame)
.View();
fAppsBox->AddChild(view);
view = BLayoutBuilder::Group<>()
.AddGroup(B_VERTICAL, 1)
.Add(fClockSeconds)
.AddGlue()
.SetInsets(10, 10, 10, 10)
.End()
.View();
fClockBox->AddChild(view);
view = BLayoutBuilder::Group<>()
.AddGroup(B_VERTICAL, 1)
.Add(fWindowAlwaysOnTop)
@ -225,6 +267,51 @@ PreferencesWindow::PreferencesWindow(BRect frame)
.View();
fWindowBox->AddChild(view);
BStringView* timeIntervalLabel = new BStringView("interval",
B_TRANSLATE("Interval:"));
timeIntervalLabel->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
B_SIZE_UNSET));
timeIntervalLabel->SetLowColor((rgb_color){255, 255, 255, 255});
BGroupLayout* timeIntervalLayout = new BGroupLayout(B_VERTICAL, 0);
timeIntervalLayout->SetInsets(10, 0, 0, 0);
BView* timeIntervalView = new BView("interval", 0, timeIntervalLayout);
timeIntervalView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
timeIntervalView->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
timeIntervalView->AddChild(fTimeInterval12HourRadioButton);
timeIntervalView->AddChild(fTimeInterval24HourRadioButton);
BStringView* timeFormatLabel = new BStringView("format",
B_TRANSLATE("Format:"));
timeFormatLabel->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
B_SIZE_UNSET));
timeFormatLabel->SetLowColor((rgb_color){255, 255, 255, 255});
BGroupLayout* timeFormatLayout = new BGroupLayout(B_VERTICAL, 0);
timeFormatLayout->SetInsets(10, 0, 0, 0);
BView* timeFormatView = new BView("format", 0, timeFormatLayout);
timeFormatView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
timeFormatView->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
timeFormatView->AddChild(fTimeFormatShortRadioButton);
timeFormatView->AddChild(fTimeFormatMediumRadioButton);
timeFormatView->AddChild(fTimeFormatLongRadioButton);
view = BLayoutBuilder::Group<>()
.AddGroup(B_VERTICAL, 10)
.AddGroup(B_VERTICAL, 0)
.Add(timeIntervalLabel)
.Add(timeIntervalView)
.End()
.AddGroup(B_VERTICAL, 0)
.Add(timeFormatLabel)
.Add(timeFormatView)
.End()
.AddGlue()
.SetInsets(10, 10, 10, 10)
.End()
.View();
fClockBox->AddChild(view);
BLayoutBuilder::Group<>(this)
.AddGrid(5, 5)
.Add(fMenuBox, 0, 0)
@ -274,6 +361,14 @@ PreferencesWindow::MessageReceived(BMessage* message)
}
void
PreferencesWindow::WindowActivated(bool active)
{
if (!active && IsMinimized())
PostMessage(B_QUIT_REQUESTED);
}
void
PreferencesWindow::_UpdateRecentCounts()
{
@ -323,8 +418,17 @@ PreferencesWindow::_EnableDisableDependentItems()
void
PreferencesWindow::WindowActivated(bool active)
PreferencesWindow::_UpdateTimeFormatRadioButtonLabels()
{
if (!active && IsMinimized())
PostMessage(B_QUIT_REQUESTED);
time_t timeValue = (time_t)time(NULL);
BString result;
BLocale::Default()->FormatTime(&result, timeValue, B_SHORT_TIME_FORMAT);
fTimeFormatShortRadioButton->SetLabel(result);
BLocale::Default()->FormatTime(&result, timeValue, B_MEDIUM_TIME_FORMAT);
fTimeFormatMediumRadioButton->SetLabel(result);
BLocale::Default()->FormatTime(&result, timeValue, B_LONG_TIME_FORMAT);
fTimeFormatLongRadioButton->SetLabel(result);
}

View File

@ -35,6 +35,7 @@ public:
private:
void _UpdateRecentCounts();
void _EnableDisableDependentItems();
void _UpdateTimeFormatRadioButtonLabels();
BBox* fMenuBox;
BBox* fAppsBox;
@ -56,11 +57,17 @@ private:
BCheckBox* fAppsHideLabels;
BSlider* fAppsIconSizeSlider;
BCheckBox* fClockSeconds;
BCheckBox* fWindowAlwaysOnTop;
BCheckBox* fWindowAutoRaise;
BCheckBox* fWindowAutoHide;
BCheckBox* fShowTime;
BRadioButton* fTimeInterval24HourRadioButton;
BRadioButton* fTimeInterval12HourRadioButton;
BRadioButton* fTimeFormatLongRadioButton;
BRadioButton* fTimeFormatMediumRadioButton;
BRadioButton* fTimeFormatShortRadioButton;
};
#endif // _PREFERENCES_WINDOW_H

View File

@ -54,6 +54,7 @@ All rights reserved.
#include <FindDirectory.h>
#include <Locale.h>
#include <MenuItem.h>
#include <MutableLocaleRoster.h>
#include <NodeInfo.h>
#include <NodeMonitor.h>
#include <Path.h>
@ -126,7 +127,7 @@ DumpList(BList* itemlist)
TReplicantTray::TReplicantTray(TBarView* parent, bool vertical)
: BView(BRect(0, 0, 1, 1), "Status", B_FOLLOW_LEFT | B_FOLLOW_TOP,
B_WILL_DRAW | B_FRAME_EVENTS),
fClock(NULL),
fTime(NULL),
fBarView(parent),
fShelf(new TReplicantShelf(this)),
fMultiRowMode(vertical),
@ -141,12 +142,17 @@ TReplicantTray::TReplicantTray(TBarView* parent, bool vertical)
2 * (logoBitmap->Bounds().Width() + 8));
fMinimumTrayWidth = sMinimumWindowWidth - kGutter - kDragRegionWidth;
}
// Create the time view
fTime = new TTimeView(fMinimumTrayWidth, kMaxReplicantHeight - 1.0,
((TBarApp*)be_app)->Settings()->timeFormat);
}
TReplicantTray::~TReplicantTray()
{
delete fShelf;
delete fTime;
}
@ -164,8 +170,14 @@ TReplicantTray::AttachedToWindow()
SetDrawingMode(B_OP_COPY);
Window()->SetPulseRate(1000000);
DealWithClock(fBarView->ShowingClock());
AddChild(fTime);
fTime->MoveTo(Bounds().right - fTime->Bounds().Width() - 1, 2);
if (!((TBarApp*)be_app)->Settings()->showTime) {
fTime->Hide();
RealignReplicants();
AdjustPlacement();
}
#ifdef DB_ADDONS
// load addons and rehydrate archives
@ -191,50 +203,43 @@ TReplicantTray::DetachedFromWindow()
void
TReplicantTray::RememberClockSettings()
TReplicantTray::SaveTimeSettings()
{
if (fClock) {
desk_settings* settings = ((TBarApp*)be_app)->Settings();
if (fTime == NULL)
return;
settings->timeShowSeconds = fClock->ShowingSeconds();
}
}
bool
TReplicantTray::ShowingSeconds()
{
if (fClock)
return fClock->ShowingSeconds();
return false;
desk_settings* settings = ((TBarApp*)be_app)->Settings();
settings->showTime = !fTime->IsHidden();
settings->timeFormat = fTime->TimeFormat();
}
void
TReplicantTray::DealWithClock(bool showClock)
TReplicantTray::ShowHideTime()
{
fBarView->ShowClock(showClock);
if (fTime == NULL)
return;
if (showClock) {
if (!fClock) {
desk_settings* settings = ((TBarApp*)be_app)->Settings();
if (fTime->IsHidden())
fTime->Show();
else
fTime->Hide();
fClock = new TTimeView(fMinimumTrayWidth, kMaxReplicantHeight - 1.0,
settings->timeShowSeconds,
false);
AddChild(fClock);
RealignReplicants();
AdjustPlacement();
}
fClock->MoveTo(Bounds().right - fClock->Bounds().Width() - 1, 2);
}
} else {
if (fClock) {
RememberClockSettings();
fClock->RemoveSelf();
delete fClock;
fClock = NULL;
}
}
void
TReplicantTray::UpdateTimeFormat(uint32 timeFormat)
{
if (fTime == NULL)
return;
fTime->SetTimeFormat(timeFormat);
RealignReplicants();
AdjustPlacement();
}
@ -261,10 +266,10 @@ TReplicantTray::GetPreferredSize(float* preferredWidth, float* preferredHeight)
} else {
// if last replicant overruns clock then resize to accomodate
if (fShelf->CountReplicants() > 0) {
if (fBarView->ShowingClock() && fRightBottomReplicant.right + 6
>= fClock->Frame().left) {
if (!fTime->IsHidden() && fTime->Frame().left
< fRightBottomReplicant.right + 6) {
width = fRightBottomReplicant.right + 6
+ fClock->Frame().Width();
+ fTime->Frame().Width();
} else
width = fRightBottomReplicant.right + 3;
}
@ -306,25 +311,44 @@ void
TReplicantTray::MessageReceived(BMessage* message)
{
switch (message->what) {
case 'time':
case kShowHideTime:
// from context menu in clock and in this view
DealWithClock(!fBarView->ShowingClock());
RealignReplicants();
AdjustPlacement();
ShowHideTime();
break;
case 'Trfm':
// time string reformat -> realign
DealWithClock(fBarView->ShowingClock());
RealignReplicants();
AdjustPlacement();
break;
case kTimeIntervalChanged:
{
if (fTime == NULL)
return;
bool use24HourClock;
if (message->FindBool("use24HourClock", &use24HourClock)
== B_OK) {
BFormattingConventions conventions;
BLocale::Default()->GetFormattingConventions(&conventions);
conventions.SetExplicitUse24HourClock(use24HourClock);
BPrivate::MutableLocaleRoster::Default()->
SetDefaultFormattingConventions(conventions);
fTime->Update();
// time string reformat -> realign
RealignReplicants();
AdjustPlacement();
}
case kShowSeconds:
case kFullDate:
if (fClock != NULL)
Window()->PostMessage(message, fClock);
break;
}
case kTimeFormatChanged:
{
if (fTime == NULL)
return;
uint32 timeFormat;
if (message->FindUInt32("time format", &timeFormat) == B_OK)
UpdateTimeFormat(timeFormat);
break;
}
#ifdef DB_ADDONS
case B_NODE_MONITOR:
@ -347,11 +371,11 @@ TReplicantTray::ShowReplicantMenu(BPoint point)
// If clock is visible show the extended menu, otherwise show "Show Time"
if (fBarView->ShowingClock())
fClock->ShowClockOptions(ConvertToScreen(point));
if (fTime != NULL)
fTime->ShowTimeOptions(ConvertToScreen(point));
else {
BMenuItem* item = new BMenuItem(B_TRANSLATE("Show Time"),
new BMessage('time'));
new BMessage(kShowHideTime));
menu->AddItem(item);
menu->SetTargetForItems(this);
BPoint where = ConvertToScreen(point);
@ -1097,8 +1121,8 @@ TReplicantTray::LocationForReplicant(int32 index, float width)
// determine free space in this row
BRect rect(loc.x, loc.y, loc.x + fMinimumTrayWidth - kIconGap
- 2.0, loc.y + kMaxReplicantHeight);
if (row == 0 && fBarView->ShowingClock())
rect.right -= fClock->Frame().Width() + kIconGap;
if (row == 0 && !fTime->IsHidden())
rect.right -= fTime->Frame().Width() + kIconGap;
for (int32 i = 0; i < index; i++) {
BView* view = NULL;

View File

@ -45,6 +45,7 @@ All rights reserved.
#include "BarView.h"
#include "TimeView.h"
const float kMaxReplicantHeight = 16.0f;
const float kMaxReplicantWidth = 16.0f;
const int32 kMinimumReplicantCount = 6;
@ -111,11 +112,7 @@ public:
bool AcceptAddon(BRect frame, BMessage* message);
void RealignReplicants(int32 startIndex = -1);
bool ShowingSeconds(void);
bool ShowingMiltime(void);
void RememberClockSettings();
void DealWithClock(bool);
void SaveTimeSettings();
#ifdef DB_ADDONS
status_t LoadAddOn(BEntry* entry, int32* id, bool addToSettings = true);
@ -147,11 +144,14 @@ private:
BPoint LocationForReplicant(int32 index, float width);
BShelf* Shelf() const;
void ShowHideTime();
void UpdateTimeFormat(uint32 timeFormat);
status_t _SaveSettings();
friend class TReplicantShelf;
TTimeView* fClock;
TTimeView* fTime;
TBarView* fBarView;
TReplicantShelf* fShelf;
BRect fRightBottomReplicant;

View File

@ -56,8 +56,8 @@ static const float kHMargin = 2.0;
enum {
kShowClock,
kChangeClock,
kShowTime,
kChangeTime,
kHide,
kShowCalendar
};
@ -66,23 +66,21 @@ enum {
#undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "TimeView"
TTimeView::TTimeView(float maxWidth, float height, bool showSeconds,
bool)
TTimeView::TTimeView(float maxWidth, float height, uint32 timeFormat)
:
BView(BRect(-100, -100, -90, -90), "_deskbar_tv_",
B_FOLLOW_RIGHT | B_FOLLOW_TOP,
B_WILL_DRAW | B_PULSE_NEEDED | B_FRAME_EVENTS),
fParent(NULL),
fShowInterval(true), // ToDo: defaulting this to true until UI is in place
fShowSeconds(showSeconds),
fMaxWidth(maxWidth),
fHeight(height),
fOrientation(true)
fOrientation(true),
fTimeFormat(timeFormat)
{
fTime = fLastTime = time(NULL);
fCurrentTime = fLastTime = time(NULL);
fSeconds = fMinute = fHour = 0;
fTimeStr[0] = 0;
fDateStr[0] = 0;
fCurrentTimeStr[0] = 0;
fCurrentDateStr[0] = 0;
fLastTimeStr[0] = 0;
fLastDateStr[0] = 0;
fNeedToUpdate = true;
@ -95,7 +93,7 @@ TTimeView::TTimeView(float maxWidth, float height, bool showSeconds,
TTimeView::TTimeView(BMessage* data)
: BView(data)
{
fTime = fLastTime = time(NULL);
fCurrentTime = fLastTime = time(NULL);
data->FindBool("seconds", &fShowSeconds);
fLocale = *BLocale::Default();
@ -134,7 +132,7 @@ TTimeView::Archive(BMessage* data, bool deep) const
void
TTimeView::AttachedToWindow()
{
fTime = time(NULL);
fCurrentTime = time(NULL);
SetFont(be_plain_font);
if (Parent()) {
@ -148,6 +146,29 @@ TTimeView::AttachedToWindow()
}
void
TTimeView::Draw(BRect /*updateRect*/)
{
PushState();
SetHighColor(ViewColor());
SetLowColor(ViewColor());
FillRect(Bounds());
SetHighColor(0, 0, 0, 255);
DrawString(fCurrentTimeStr, fTimeLocation);
PopState();
}
void
TTimeView::FrameMoved(BPoint)
{
Update();
}
void
TTimeView::GetPreferredSize(float* width, float* height)
{
@ -159,8 +180,103 @@ TTimeView::GetPreferredSize(float* width, float* height)
// we want to limit the width so that it can't overlap the bevels in the
// parent view.
*width = fOrientation ?
min_c(fMaxWidth - kHMargin, kHMargin + StringWidth(fTimeStr))
: kHMargin + StringWidth(fTimeStr);
min_c(fMaxWidth - kHMargin, kHMargin + StringWidth(fCurrentTimeStr))
: kHMargin + StringWidth(fCurrentTimeStr);
}
void
TTimeView::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_LOCALE_CHANGED:
Update();
break;
case kChangeTime:
// launch the time prefs app
be_roster->Launch("application/x-vnd.Haiku-Time");
break;
case kShowHideTime:
Window()->PostMessage(message, Parent());
break;
case kShowCalendar:
{
BRect bounds(Bounds());
BPoint center(bounds.LeftTop());
center += BPoint(bounds.Width() / 2, bounds.Height() / 2);
ShowCalendar(center);
break;
}
default:
BView::MessageReceived(message);
break;
}
}
void
TTimeView::MouseDown(BPoint point)
{
uint32 buttons;
Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons);
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
ShowTimeOptions(ConvertToScreen(point));
return;
} else if (buttons == B_PRIMARY_MOUSE_BUTTON)
ShowCalendar(point);
// invalidate last time/date strings and call the pulse
// method directly to change the display instantly
fLastDateStr[0] = '\0';
fLastTimeStr[0] = '\0';
Pulse();
}
void
TTimeView::Pulse()
{
time_t curTime = time(NULL);
tm* ct = localtime(&curTime);
if (ct == NULL)
return;
fCurrentTime = curTime;
GetCurrentTime();
GetCurrentDate();
if (strcmp(fCurrentTimeStr, fLastTimeStr) != 0) {
// Update bounds when the size of the strings has changed
// For dates, Update() could be called two times in a row,
// but that should only happen very rarely
if ((fLastTimeStr[1] != fCurrentTimeStr[1]
&& (fLastTimeStr[1] == ':' || fCurrentTimeStr[1] == ':'))
|| !fLastTimeStr[0])
Update();
strlcpy(fLastTimeStr, fCurrentTimeStr, sizeof(fLastTimeStr));
fNeedToUpdate = true;
}
// Update the tooltip if the date has changed
if (strcmp(fCurrentDateStr, fLastDateStr) != 0) {
strlcpy(fLastDateStr, fCurrentDateStr, sizeof(fLastDateStr));
SetToolTip(fCurrentDateStr);
}
if (fNeedToUpdate) {
fSeconds = ct->tm_sec;
fMinute = ct->tm_min;
fHour = ct->tm_hour;
Draw(Bounds());
fNeedToUpdate = false;
}
}
@ -179,47 +295,23 @@ TTimeView::ResizeToPreferred()
}
// # pragma mark - Public methods
void
TTimeView::FrameMoved(BPoint)
TTimeView::SetOrientation(bool orientation)
{
Update();
fOrientation = orientation;
CalculateTextPlacement();
Invalidate();
}
void
TTimeView::MessageReceived(BMessage* message)
TTimeView::SetTimeFormat(uint32 timeFormat)
{
switch (message->what) {
case kShowSeconds:
ShowSeconds(!ShowingSeconds());
break;
case B_LOCALE_CHANGED:
Update();
break;
case kChangeClock:
// launch the time prefs app
be_roster->Launch("application/x-vnd.Haiku-Time");
break;
case 'time':
Window()->PostMessage(message, Parent());
break;
case kShowCalendar:
{
BRect bounds(Bounds());
BPoint center(bounds.LeftTop());
center += BPoint(bounds.Width() / 2, bounds.Height() / 2);
ShowCalendar(center);
break;
}
default:
BView::MessageReceived(message);
break;
}
fTimeFormat = timeFormat;
Update();
}
@ -249,11 +341,26 @@ TTimeView::ShowCalendar(BPoint where)
}
// # pragma mark - Private methods
void
TTimeView::GetCurrentTime()
{
fLocale.FormatTime(fTimeStr, 64, fTime,
fShowSeconds ? B_MEDIUM_TIME_FORMAT : B_SHORT_TIME_FORMAT);
switch (fTimeFormat) {
case B_LONG_TIME_FORMAT:
fLocale.FormatTime(fCurrentTimeStr, 64, fCurrentTime,
B_LONG_TIME_FORMAT);
break;
case B_MEDIUM_TIME_FORMAT:
fLocale.FormatTime(fCurrentTimeStr, 64, fCurrentTime,
B_MEDIUM_TIME_FORMAT);
break;
default:
fLocale.FormatTime(fCurrentTimeStr, 64, fCurrentTime,
B_SHORT_TIME_FORMAT);
}
}
@ -262,7 +369,7 @@ TTimeView::GetCurrentDate()
{
char tmp[64];
fLocale.FormatDate(tmp, 64, fTime, B_FULL_DATE_FORMAT);
fLocale.FormatDate(tmp, 64, fCurrentTime, B_FULL_DATE_FORMAT);
// remove leading 0 from date when month is less than 10 (MM/DD/YY)
// or remove leading 0 from date when day is less than 10 (DD/MM/YY)
@ -270,123 +377,7 @@ TTimeView::GetCurrentDate()
if (str[0] == '0')
str++;
strlcpy(fDateStr, str, sizeof(fDateStr));
}
void
TTimeView::Draw(BRect /*updateRect*/)
{
PushState();
SetHighColor(ViewColor());
SetLowColor(ViewColor());
FillRect(Bounds());
SetHighColor(0, 0, 0, 255);
DrawString(fTimeStr, fTimeLocation);
PopState();
}
void
TTimeView::MouseDown(BPoint point)
{
uint32 buttons;
Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons);
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
ShowClockOptions(ConvertToScreen(point));
return;
} else if (buttons == B_PRIMARY_MOUSE_BUTTON)
ShowCalendar(point);
// invalidate last time/date strings and call the pulse
// method directly to change the display instantly
fLastDateStr[0] = '\0';
fLastTimeStr[0] = '\0';
Pulse();
}
void
TTimeView::Pulse()
{
time_t curTime = time(NULL);
tm* ct = localtime(&curTime);
if (ct == NULL)
return;
fTime = curTime;
GetCurrentTime();
GetCurrentDate();
if (strcmp(fTimeStr, fLastTimeStr) != 0) {
// Update bounds when the size of the strings has changed
// For dates, Update() could be called two times in a row,
// but that should only happen very rarely
if ((fLastTimeStr[1] != fTimeStr[1]
&& (fLastTimeStr[1] == ':' || fTimeStr[1] == ':'))
|| !fLastTimeStr[0])
Update();
strlcpy(fLastTimeStr, fTimeStr, sizeof(fLastTimeStr));
fNeedToUpdate = true;
}
// Update the tooltip if the date has changed
if (strcmp(fDateStr, fLastDateStr) != 0) {
strlcpy(fLastDateStr, fDateStr, sizeof(fLastDateStr));
SetToolTip(fDateStr);
}
if (fNeedToUpdate) {
fSeconds = ct->tm_sec;
fMinute = ct->tm_min;
fHour = ct->tm_hour;
Draw(Bounds());
fNeedToUpdate = false;
}
}
void
TTimeView::ShowSeconds(bool on)
{
fShowSeconds = on;
Update();
}
void
TTimeView::Update()
{
fLocale = *BLocale::Default();
GetCurrentTime();
GetCurrentDate();
SetToolTip(fDateStr);
ResizeToPreferred();
CalculateTextPlacement();
if (fParent) {
BMessage reformat('Trfm');
fParent->MessageReceived(&reformat);
// time string format realign
fParent->Invalidate();
}
}
void
TTimeView::SetOrientation(bool o)
{
fOrientation = o;
CalculateTextPlacement();
Invalidate();
strlcpy(fCurrentDateStr, str, sizeof(fCurrentDateStr));
}
@ -401,7 +392,7 @@ TTimeView::CalculateTextPlacement()
BFont font;
GetFont(&font);
const char* stringArray[1];
stringArray[0] = fTimeStr;
stringArray[0] = fCurrentTimeStr;
BRect rectArray[1];
escapement_delta delta = { 0.0, 0.0 };
font.GetBoundingBoxesForStrings(stringArray, 1, B_SCREEN_METRIC, &delta,
@ -413,22 +404,29 @@ TTimeView::CalculateTextPlacement()
void
TTimeView::ShowClockOptions(BPoint point)
TTimeView::ShowTimeOptions(BPoint point)
{
BPopUpMenu* menu = new BPopUpMenu("", false, false);
menu->SetFont(be_plain_font);
BMenuItem* item;
item = new BMenuItem(B_TRANSLATE("Change time" B_UTF8_ELLIPSIS),
new BMessage(kChangeClock));
menu->AddItem(item);
if (IsHidden()) {
item = new BMenuItem(B_TRANSLATE("Show time"),
new BMessage(kShowHideTime));
menu->AddItem(item);
} else {
item = new BMenuItem(B_TRANSLATE("Change time" B_UTF8_ELLIPSIS),
new BMessage(kChangeTime));
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Hide time"), new BMessage('time'));
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Hide time"),
new BMessage(kShowHideTime));
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Show calendar" B_UTF8_ELLIPSIS),
new BMessage(kShowCalendar));
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Show calendar" B_UTF8_ELLIPSIS),
new BMessage(kShowCalendar));
menu->AddItem(item);
}
menu->SetTargetForItems(this);
// Changed to accept screen coord system point;
@ -437,3 +435,18 @@ TTimeView::ShowClockOptions(BPoint point)
point.x + 4, point.y +4), true);
}
void
TTimeView::Update()
{
fLocale = *BLocale::Default();
GetCurrentTime();
GetCurrentDate();
SetToolTip(fCurrentDateStr);
ResizeToPreferred();
CalculateTextPlacement();
if (fParent)
fParent->Invalidate();
}

View File

@ -42,8 +42,9 @@ All rights reserved.
#include <View.h>
const uint32 kShowSeconds = 'ShSc';
const uint32 kFullDate = 'FDat';
const uint32 kShowHideTime = 'shtm';
const uint32 kTimeIntervalChanged = 'tivc';
const uint32 kTimeFormatChanged = 'tfmc';
class BCountry;
class BMessageRunner;
@ -55,8 +56,7 @@ class _EXPORT TTimeView;
class TTimeView : public BView {
public:
TTimeView(float maxWidth, float height, bool showSeconds = false,
bool showInterval = false);
TTimeView(float maxWidth, float height, uint32 timeFormat);
TTimeView(BMessage* data);
~TTimeView();
@ -67,50 +67,49 @@ class TTimeView : public BView {
void AttachedToWindow();
void Draw(BRect update);
void GetPreferredSize(float* width, float* height);
void ResizeToPreferred();
void FrameMoved(BPoint);
void GetPreferredSize(float* width, float* height);
void MessageReceived(BMessage*);
void MouseDown(BPoint where);
void Pulse();
bool ShowingSeconds() { return fShowSeconds; }
void ShowSeconds(bool);
void ShowCalendar(BPoint where);
void ResizeToPreferred();
bool Orientation() const;
void SetOrientation(bool o);
uint32 TimeFormat() const;
void SetTimeFormat(uint32 timeFormat);
void ShowCalendar(BPoint where);
private:
friend class TReplicantTray;
void Update();
void GetCurrentTime();
void GetCurrentDate();
void CalculateTextPlacement();
void ShowClockOptions(BPoint);
void ShowTimeOptions(BPoint);
void Update();
BView *fParent;
bool fNeedToUpdate;
time_t fTime;
time_t fCurrentTime;
time_t fLastTime;
char fTimeStr[64];
char fCurrentTimeStr[64];
char fLastTimeStr[64];
char fDateStr[64];
char fCurrentDateStr[64];
char fLastDateStr[64];
int fSeconds;
int fMinute;
int fHour;
bool fShowInterval;
bool fShowSeconds;
float fMaxWidth;
float fHeight;
bool fOrientation; // vertical = true
uint32 fTimeFormat;
BPoint fTimeLocation;
BPoint fDateLocation;
@ -127,5 +126,12 @@ TTimeView::Orientation() const
}
inline uint32
TTimeView::TimeFormat() const
{
return fTimeFormat;
}
#endif /* TIME_VIEW_H */