diff --git a/src/prefs/time/AnalogClock.cpp b/src/prefs/time/AnalogClock.cpp index e82ec3e3fb..524216c5e5 100644 --- a/src/prefs/time/AnalogClock.cpp +++ b/src/prefs/time/AnalogClock.cpp @@ -1,6 +1,16 @@ +/* + AnalogClock.cpp + by Mike Berg (inseculous) + + Notes: + TOffscreen borrows heavily from the clock source. + +*/ + #include #include #include +#include #include #include "AnalogClock.h" @@ -11,6 +21,10 @@ const BRect kClockRect(0, 0, kClockFaceWidth -1, kClockFaceHeight -1); const BRect kCenterRect(0, 0, kCenterWidth -1, kCenterHeight -1); const BRect kCapRect(0, 0, kCapWidth -1, kCapHeight -1); +/* + TOffscreen + Analog Clock face rendering view. +*/ TOffscreen::TOffscreen(BRect frame, const char *name) : BView(frame, name, B_NOT_RESIZABLE, B_WILL_DRAW) @@ -69,6 +83,8 @@ TOffscreen::TOffscreen(BRect frame, const char *name) TOffscreen::~TOffscreen() { delete f_bitmap; + delete f_centerbmp; + delete f_capbmp; } @@ -110,7 +126,10 @@ TOffscreen::DrawX() -/*=====> TAnalogClock <=====*/ +/* + TAnalogClock + BView to display clock face of current time. +*/ TAnalogClock::TAnalogClock(BRect frame, const char *name, uint32 resizingmode, uint32 flags) : BView(frame, name, resizingmode, flags|B_DRAW_ON_CHILDREN) @@ -122,6 +141,7 @@ TAnalogClock::TAnalogClock(BRect frame, const char *name, uint32 resizingmode, u TAnalogClock::~TAnalogClock() { delete f_bitmap; + delete f_offscreen; } @@ -162,7 +182,7 @@ TAnalogClock::MessageReceived(BMessage *message) case B_OBSERVER_NOTICE_CHANGE: message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change); switch (change) { - case OB_TM_CHANGED: + case H_TM_CHANGED: { int32 hour = 0; int32 minute = 0; diff --git a/src/prefs/time/AnalogClock.h b/src/prefs/time/AnalogClock.h index f02b48e77d..6782cc98f4 100644 --- a/src/prefs/time/AnalogClock.h +++ b/src/prefs/time/AnalogClock.h @@ -8,7 +8,7 @@ class TOffscreen: public BView { public: TOffscreen(BRect frame, const char *name); virtual ~TOffscreen(); - + virtual void DrawX(); BPoint Position(); @@ -29,8 +29,8 @@ class TAnalogClock: public BView { TAnalogClock(BRect frame, const char *name, uint32 resizingmode, uint32 flags); virtual ~TAnalogClock(); - virtual void AttachedToWindow(); - virtual void Draw(BRect updaterect); + virtual void AttachedToWindow(); + virtual void Draw(BRect updaterect); virtual void MessageReceived(BMessage *); void InitView(BRect frame); diff --git a/src/prefs/time/BaseView.cpp b/src/prefs/time/BaseView.cpp index bdaa8b2f30..d0eb075e57 100644 --- a/src/prefs/time/BaseView.cpp +++ b/src/prefs/time/BaseView.cpp @@ -1,13 +1,20 @@ +/* + BaseView.cpp + by Mike Berg (inseculous) +*/ + +#include #include #include #include "BaseView.h" +#include "TimeMessages.h" TTimeBaseView::TTimeBaseView(BRect frame, const char *name) : BView(frame, name, B_FOLLOW_ALL_SIDES, B_PULSE_NEEDED) { - f_message = new BMessage(OB_TIME_UPDATE); + InitView(); } @@ -16,6 +23,14 @@ TTimeBaseView::~TTimeBaseView() } + +void +TTimeBaseView::InitView() +{ + f_message = new BMessage(H_TIME_UPDATE); +} + + void TTimeBaseView::Pulse() { @@ -59,7 +74,7 @@ TTimeBaseView::DispatchMessage() f_message->AddInt32("minute", minute); f_message->AddInt32("second", second); - SendNotices(OB_TM_CHANGED, f_message); + SendNotices(H_TM_CHANGED, f_message); } @@ -73,6 +88,7 @@ TTimeBaseView::ChangeTime(BMessage *message) time_t atime; struct tm *_tm; + atime = time(0); _tm = localtime(&atime); @@ -82,6 +98,7 @@ TTimeBaseView::ChangeTime(BMessage *message) int32 month = 0; int32 day = 0; int32 year = 0; + bool isam = false; if (istime) { if (message->FindInt32("hour", &hour) == B_OK) _tm->tm_hour = hour; @@ -89,6 +106,10 @@ TTimeBaseView::ChangeTime(BMessage *message) _tm->tm_min = minute; if (message->FindInt32("second", &second) == B_OK) _tm->tm_sec = second; + if (message->FindBool("isam", &isam) == B_OK) { + if (!isam) + _tm->tm_hour += 12; + } } else { if (message->FindInt32("month", &month) == B_OK) _tm->tm_mon = month; @@ -102,3 +123,4 @@ TTimeBaseView::ChangeTime(BMessage *message) set_real_time_clock(atime2); DispatchMessage(); } + diff --git a/src/prefs/time/BaseView.h b/src/prefs/time/BaseView.h index 9750ebb064..ea83b246ab 100644 --- a/src/prefs/time/BaseView.h +++ b/src/prefs/time/BaseView.h @@ -4,7 +4,6 @@ #include #include -#include "TimeMessages.h" class TTimeBaseView: public BView { public: @@ -13,9 +12,10 @@ class TTimeBaseView: public BView { virtual void Pulse(); - void ChangeTime(BMessage *message); + void ChangeTime(BMessage *); void SetGMTime(bool); protected: + virtual void InitView(); virtual void DispatchMessage(); private: BMessage *f_message; diff --git a/src/prefs/time/CalendarView.cpp b/src/prefs/time/CalendarView.cpp index f2e21a681b..193e266a1e 100644 --- a/src/prefs/time/CalendarView.cpp +++ b/src/prefs/time/CalendarView.cpp @@ -5,6 +5,7 @@ #include "DateUtils.h" #include "TimeMessages.h" +#include #define SEGMENT_CHANGE 'ostd' @@ -46,6 +47,14 @@ TDay::MouseDown(BPoint where) } +void +TDay::KeyDown(const char *bytes, int32 numbytes) +{ + BControl::KeyDown(bytes, numbytes); + Parent()->KeyDown(bytes, numbytes); +} + + void TDay::MakeFocus(bool focused) { @@ -189,15 +198,25 @@ TCalendarView::TCalendarView(BRect frame, const char *name, InitView(); } + TCalendarView::~TCalendarView() { } + +void +TCalendarView::AttachedToWindow() +{ + if (Parent()) + SetViewColor(Parent()->ViewColor()); +} + + void TCalendarView::MessageReceived(BMessage *message) { switch(message->what) { - case OB_DAY_CHANGED: + case H_DAY_CHANGED: { TDay *day; message->FindPointer("source", (void **)&day); @@ -217,15 +236,86 @@ TCalendarView::MessageReceived(BMessage *message) void -TCalendarView::AttachedToWindow() +TCalendarView::KeyDown(const char *bytes, int32 numbytes) { - if (Parent()) - SetViewColor(Parent()->ViewColor()); + if (f_focused == NULL) + f_focused = f_cday; + + switch(bytes[0]) { + case B_LEFT_ARROW: { + TDay *newfocus = dynamic_cast(f_focused->PreviousSibling()); + if (newfocus == NULL || newfocus->Day() == 0) + break; + f_focused->MakeFocus(false); + f_focused = newfocus; + f_focused->MakeFocus(true); + } + break; + + case B_RIGHT_ARROW: { + TDay *newfocus = dynamic_cast(f_focused->NextSibling()); + if (newfocus == NULL || newfocus->Day() == 0) + break; + f_focused->MakeFocus(false); + f_focused = newfocus; + f_focused->MakeFocus(true); + } + break; + + case B_UP_ARROW: { + int32 idx = IndexOf(f_focused) -7; + if (idx> f_daybound.x -1 ) { + f_focused->MakeFocus(false); + f_focused = dynamic_cast(ChildAt(idx)); + f_focused->MakeFocus(true); + } + } + break; + + case B_DOWN_ARROW: { + int32 idx = IndexOf(f_focused) +7; + if (idx < f_daybound.y +1) { + f_focused->MakeFocus(false); + f_focused = dynamic_cast(ChildAt(idx)); + f_focused->MakeFocus(true); + } + } + break; + + default: + break; + } +} + + + +int32 +TCalendarView::IndexOf(BView *child) const +{ + BView *test; + for (int32 idx = 0; idx < CountChildren(); idx++) { + test = ChildAt(idx); + if (test == child) + return idx; + } } static const char days[7] = { 'S', 'M', 'T', 'W', 'T', 'F', 'S' }; +static float +FontHeight(BView* target, bool full) +{ + font_height finfo; + target->GetFontHeight(&finfo); + float h = ceil(finfo.ascent) + ceil(finfo.descent); + + if (full) + h += ceil(finfo.leading); + + return h; +} + void TCalendarView::Draw(BRect updaterect) { @@ -237,11 +327,14 @@ TCalendarView::Draw(BRect updaterect) BString day; SetLowColor(ViewColor()); SetHighColor(0, 0, 0); + + float offset = FontHeight(this, true); + for (int i = 0; i < 7; i++) { day = days[i]; width = be_plain_font->StringWidth(day.String()); drawpt.x = bounds.left +(x -width/2.0 +2); - drawpt.y = bounds.bottom; + drawpt.y = bounds.bottom -offset/2.0; DrawString(day.String(), drawpt); bounds.OffsetBy(bounds.Width() +1, 0); } @@ -298,11 +391,15 @@ TCalendarView::InitDates() day->SetTo(label, cday); if (label> 0) { - BMessage *message = new BMessage(OB_DAY_CHANGED); + BMessage *message = new BMessage(H_DAY_CHANGED); message->AddInt32("Day", label); day->SetTarget(this); day->SetMessage(message); + if (label == 1) + f_daybound.x = row *7 +col; + if (label == daycnt) + f_daybound.y = row *7 +col; } if (cday) { @@ -311,6 +408,8 @@ TCalendarView::InitDates() cday = false; } } + if (f_focused == NULL) + f_focused = f_cday; } @@ -337,7 +436,7 @@ void TCalendarView::DispatchMessage() { // send message to update timedate - BMessage *msg = new BMessage(OB_USER_CHANGE); + BMessage *msg = new BMessage(H_USER_CHANGE); msg->AddBool("time", false); msg->AddInt32("month", f_month); if (f_cday != NULL) diff --git a/src/prefs/time/CalendarView.h b/src/prefs/time/CalendarView.h index 6f3c83465a..7722c6e965 100644 --- a/src/prefs/time/CalendarView.h +++ b/src/prefs/time/CalendarView.h @@ -8,11 +8,12 @@ class TDay: public BControl { public: TDay(BRect frame, int day); virtual ~TDay(); - virtual void Draw(BRect updaterect); virtual void AttachedToWindow(); + virtual void Draw(BRect updaterect); + virtual void KeyDown(const char *bytes, int32 numbytes); + virtual void MakeFocus(bool focused); virtual void MouseDown(BPoint where); virtual void SetValue(int32 value); - virtual void MakeFocus(bool focused); void SetTo(BRect frame, int day); void SetTo(int day, bool selected = false); @@ -31,6 +32,7 @@ class TCalendarView: public BView { virtual ~TCalendarView(); virtual void AttachedToWindow(); virtual void Draw(BRect bounds); + void KeyDown(const char *bytes, int32 numbytes); virtual void MessageReceived(BMessage *message); void SetTo(int32, int32, int32); @@ -40,9 +42,13 @@ class TCalendarView: public BView { private: void InitDates(); void CalcFlags(); + int32 IndexOf(BView *) const; TDay *f_cday; + TDay *f_focused; BRect f_dayrect; + // x = index of first day; y = index of last; + BPoint f_daybound; int f_firstday; int f_month; int f_day; diff --git a/src/prefs/time/DateTimeEdit.cpp b/src/prefs/time/DateTimeEdit.cpp index f3f0e7fba7..5d19f64b6f 100644 --- a/src/prefs/time/DateTimeEdit.cpp +++ b/src/prefs/time/DateTimeEdit.cpp @@ -1,466 +1,342 @@ -#include -#include -#include - -#include "Bitmaps.h" #include "DateTimeEdit.h" #include "DateUtils.h" -#include "TimeMessages.h" -const int32 kArrowAreaWidth = 16; +#include +#include -// number of years after 1900 to loop should be system setting -#define YEAR_DELTA 110 +#define YEAR_DELTA_MAX 110 +#define YEAR_DELTA_MIN 64 -/*=====> TDateTimeEdit <=====*/ -TDateTimeEdit::TDateTimeEdit(BRect frame, const char *name) - : BControl(frame, name, NULL, NULL, B_FOLLOW_NONE, B_NAVIGABLE|B_WILL_DRAW) - , f_holdvalue(0) -{ - f_up = new BBitmap(BRect(0, 0, kUpArrowWidth -1, kUpArrowHeight -1), kUpArrowColorSpace); - f_up->SetBits(kUpArrowBits, (kUpArrowWidth) *(kUpArrowHeight+1), 0, kUpArrowColorSpace); - - f_down = new BBitmap(BRect(0, 0, kDownArrowWidth -1, kDownArrowHeight -2), kDownArrowColorSpace); - f_down->SetBits(kDownArrowBits, (kDownArrowWidth) *(kDownArrowHeight), 0, kDownArrowColorSpace); - +TDateTimeSection::TDateTimeSection(BRect frame, uint32 data = 0) + : TSection(frame) + , f_data(data) +{ } -TDateTimeEdit::~TDateTimeEdit() +TDateTimeSection::~TDateTimeSection() { } +uint32 +TDateTimeSection::Data() const +{ + return f_data; +} + + void -TDateTimeEdit::AttachedToWindow() +TDateTimeSection::SetData(uint32 data) { - if (Parent()) { - SetViewColor(Parent()->ViewColor()); - ReplaceTransparentColor(f_up, ViewColor()); - ReplaceTransparentColor(f_down, ViewColor()); - } + f_data = data; } -void -TDateTimeEdit::MessageReceived(BMessage *message) + + +TTimeEdit::TTimeEdit(BRect frame, const char *name, uint32 sections) + : TSectionEdit(frame, name, sections) { - switch(message->what) { - default: - BView::MessageReceived(message); - break; - } -} - - -void -TDateTimeEdit::MouseDown(BPoint where) -{ - MakeFocus(true); - if (f_uprect.Contains(where)) - UpPress(); - else if (f_downrect.Contains(where)) - DownPress(); -} - - -void -TDateTimeEdit::Draw(BRect updaterect) -{ - rgb_color bgcolor = ViewColor(); - rgb_color light = tint_color(bgcolor, B_LIGHTEN_MAX_TINT); - rgb_color dark = tint_color(bgcolor, B_DARKEN_1_TINT); - rgb_color darker = tint_color(bgcolor, B_DARKEN_3_TINT); - - // draw 3d border - BRect bounds(Bounds()); - SetHighColor(light); - SetLowColor(dark); - Draw3dFrame(bounds, true); - StrokeLine(bounds.LeftBottom(), bounds.LeftBottom(), B_SOLID_LOW); - - bounds.InsetBy(1, 1); - bounds.right -= kArrowAreaWidth; - - if ( (IsFocus() && Window() && Window()->IsActive())) { - rgb_color navcolor = keyboard_navigation_color(); - - SetHighColor(navcolor); - StrokeRect(bounds); - } else { - // draw border thickening (erase focus) - SetHighColor(darker); - SetLowColor(bgcolor); - Draw3dFrame(bounds, false); - } - - // draw up/down control - SetHighColor(light); - bounds.left = bounds.right +1;// -kArrowAreaWidth; - bounds.right = Bounds().right -1; - f_uprect.Set(bounds.left +3, bounds.top +2, bounds.right, bounds.bottom /2.0); - f_downrect = f_uprect.OffsetByCopy(0, f_uprect.Height()+2); - - DrawBitmap(f_up, f_uprect.LeftTop()); - DrawBitmap(f_down, f_downrect.LeftTop()); - - Draw3dFrame(bounds, false); - SetHighColor(dark); - StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); - StrokeLine(bounds.RightBottom(), bounds.RightTop()); - SetHighColor(light); - StrokeLine(bounds.RightTop(), bounds.RightTop()); -} - - -void -TDateTimeEdit::Draw3dFrame(BRect frame, bool inset) -{ - rgb_color color1, color2; - - if (inset) { - color1 = HighColor(); - color2 = LowColor(); - } else { - color1 = LowColor(); - color2 = HighColor(); - } - - BeginLineArray(4); - // left side - AddLine(frame.LeftBottom(), frame.LeftTop(), color2); - // right side - AddLine(frame.RightTop(), frame.RightBottom(), color1); - // bottom side - AddLine(frame.RightBottom(), frame.LeftBottom(), color1); - // top side - AddLine(frame.LeftTop(), frame.RightTop(), color2); - EndLineArray(); -} - - -void -TDateTimeEdit::DispatchMessage() -{ - // send message to update timedate - BMessage *msg = new BMessage(OB_USER_CHANGE); - BuildDispatch(msg); - Window()->PostMessage(msg); -} - - -/*=====> TTimeEdit <=====*/ - -TTimeEdit::TTimeEdit(BRect frame, const char *name) - : TDateTimeEdit(frame, name) -{ - BRect bounds(Bounds().InsetByCopy(1, 2)); - - // all areas same width :) - float width = be_plain_font->StringWidth("00") +6; - - // AM/PM rect - bounds.right = Bounds().right -(kArrowAreaWidth +3); - bounds.left = bounds.right -(width +5); - f_aprect = bounds; - - // seconds rect - bounds.right = bounds.left; - bounds.left = bounds.right -width; - f_secrect = bounds; - - float sep_width = 9; - - //minutes rect - bounds.right = bounds.left -sep_width; - bounds.left = bounds.right -width; - f_minrect = bounds; - - //hour rect - bounds.right = bounds.left -sep_width; - bounds.left = Bounds().left +2; - f_hourrect = bounds; + InitView(); } TTimeEdit::~TTimeEdit() { + TSection *section; + if (f_sections->CountItems() > 0) + for (int32 idx = 0; (section = (TSection *)f_sections->ItemAt(idx)); idx++) + delete section; + delete f_sections; } void -TTimeEdit::Draw(BRect updaterect) +TTimeEdit::InitView() { - TDateTimeEdit::Draw(Bounds()); + TSectionEdit::InitView(); + SetSections(f_sectionsarea); +} + + +void +TTimeEdit::DrawSection(uint32 index, bool isfocus) +{ + if (f_sections->CountItems() == 0) + printf("No Sections!!!\n"); + + // user defined section drawing + TDateTimeSection *section; + section = (TDateTimeSection *)f_sections->ItemAt(index); - SetHighColor(0, 0, 0, 255); + BRect bounds = section->Frame(); + + + // format value to display + + uint32 value; + + if (isfocus) { + SetLowColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); + value = f_holdvalue; + } else { + SetLowColor(ViewColor()); + value = section->Data(); + } BString text; - BPoint drawpt; - BPoint offset(0, f_hourrect.Height()/2.0 -6); - int value; - - // seperator - BString septext(":"); - - float width; - rgb_color dark = tint_color(ViewColor(), B_DARKEN_1_TINT); - - //draw hour - if (updaterect.Contains(f_hourrect)) { + // format value (new method?) + switch (index) { + case 0: // hour + if (value> 12) { + if (value < 22) text << "0"; + text << value -12; + } else if (value == 0) { + text << "12"; + } else { + if (value <10) text << "0"; + text << value; + } + break; - if (f_focus == FOCUS_HOUR && IsFocus()) { - SetLowColor(dark); - value = f_holdvalue; - } else { - SetLowColor(ViewColor()); - value = f_hour; - } - - if (value> 12) { - if (value < 22) text << "0"; - text << value -12; - } else { - if (value < 10) text << "0"; + case 1: // minute + case 2: // second + if (value <10) text << "0"; text << value; - } - width = be_plain_font->StringWidth(text.String()); - offset.x = -(f_hourrect.Width()/2.0 -width/2.0) -1; - drawpt = f_hourrect.LeftBottom() -offset; - - FillRect(f_hourrect, B_SOLID_LOW); - DrawString(text.String(), drawpt); - - SetLowColor(ViewColor()); - DrawString(septext.String(), f_hourrect.RightBottom() -offset); - } - - //draw min - if (updaterect.Contains(f_minrect)) { - if (f_focus == FOCUS_MINUTE && IsFocus()) { - SetLowColor(dark); - value = f_holdvalue; - } else { - SetLowColor(ViewColor()); - value = f_minute; - } - - text = ""; - if (value < 10) text << "0"; - text << value; - - width = be_plain_font->StringWidth(text.String()); - offset.x = -(f_minrect.Width()/2.0 -width/2.0) -1; - drawpt = f_minrect.LeftBottom() -offset; + break; - FillRect(f_minrect, B_SOLID_LOW); - DrawString(text.String(), drawpt); + case 3: //am/pm + value = ((TDateTimeSection *)f_sections->ItemAt(0))->Data(); + if (value >12 || value == 0) + text << "PM"; + else + text << "AM"; + break; - offset.x = -3; - SetLowColor(ViewColor()); - DrawString(septext.String(), f_minrect.RightBottom() -offset); + default: + return; + break; } - - //draw sec - if (updaterect.Contains(f_secrect)) { - if (f_focus == FOCUS_SECOND && IsFocus()) { - SetLowColor(dark); - value = f_holdvalue; - } else { - SetLowColor(ViewColor()); - value = f_second; - } - - text = ""; - if (value < 10) text << "0"; - text << value; - - width = be_plain_font->StringWidth(text.String()); - offset.x = -(f_secrect.Width()/2.0 -width/2.0) -1; - drawpt = f_secrect.LeftBottom() -offset; - FillRect(f_secrect, B_SOLID_LOW); - DrawString(text.String(), drawpt); - } - - //draw AM/PM - if (updaterect.Contains(f_aprect)) { - text = ""; - if (f_isam) - text << "AM"; - else - text << "PM"; - - width = be_plain_font->StringWidth(text.String()); - offset.x = -(f_aprect.Width()/2.0 -width/2.0) -1; - drawpt = f_aprect.LeftBottom() -offset; + // calc and center text in section rect - if (f_focus == FOCUS_AMPM && IsFocus()) - SetLowColor(dark); - else - SetLowColor(ViewColor()); + float width = be_plain_font->StringWidth(text.String()); - FillRect(f_aprect, B_SOLID_LOW); - DrawString(text.String(), drawpt); + BPoint offset(-(bounds.Width()/2.0 -width/2.0) -1.0, bounds.Height()/2.0 -6.0); + + BPoint drawpt(bounds.LeftBottom() -offset); + + SetHighColor(0, 0, 0, 255); + FillRect(bounds, B_SOLID_LOW); + DrawString(text.String(), drawpt); +} + + +void +TTimeEdit::DrawSeperator(uint32 index) +{ + /* user drawn seperator. section is the index of the section + in f_sections or the section to the seps left + */ + + if (index == 3) return; // no seperator for am/pm + BString text(":"); + uint32 sep; + GetSeperatorWidth(&sep); + + TDateTimeSection *section = (TDateTimeSection *)f_sections->ItemAt(index); + BRect bounds = section->Frame(); + + float width = be_plain_font->StringWidth(text.String()); + BPoint offset(-(sep/2.0 -width/2.0) -1.0, bounds.Height()/2.0 -6.0); + BPoint drawpt(bounds.RightBottom() -offset); + + DrawString(text.String(), drawpt); +} + + +void +TTimeEdit::SetSections(BRect area) +{ + // by default divie up the sections evenly + BRect bounds(area); + // no comp for sep width + + uint32 sep_width; + GetSeperatorWidth(&sep_width); + + float sep_2 = ceil(sep_width/f_sectioncount +1); + float width = bounds.Width()/f_sectioncount -sep_2; + bounds.right = bounds.left +(width -sep_width/f_sectioncount); + + TDateTimeSection *section; + + for (uint32 idx = 0; idx < f_sectioncount; idx++) { + section = new TDateTimeSection(bounds); + f_sections->AddItem(section); + + bounds.left = bounds.right +sep_width; + if (idx == f_sectioncount -2) + bounds.right = area.right -1; + else + bounds.right = bounds.left +(width -sep_2); } } void -TTimeEdit::MouseDown(BPoint where) +TTimeEdit::GetSeperatorWidth(uint32 *width) { - TDateTimeEdit::MouseDown(where); + *width = 8; +} + + +void +TTimeEdit::SectionFocus(uint32 index) +{ + f_focus = index; + + // update hold value + f_holdvalue = ((TDateTimeSection *)f_sections->ItemAt(f_focus))->Data(); - if (f_hourrect.Contains(where)) { - f_focus = FOCUS_HOUR; - f_holdvalue = f_hour; - } else if (f_minrect.Contains(where)) { - f_focus = FOCUS_MINUTE; - f_holdvalue = f_minute; - } else if (f_secrect.Contains(where)) { - f_focus = FOCUS_SECOND; - f_holdvalue = f_second; - } else if (f_aprect.Contains(where)) { - f_focus = FOCUS_AMPM; - } Draw(Bounds()); } void -TTimeEdit::SetFocus(bool forward) +TTimeEdit::SetTo(uint32 hour, uint32 minute, uint32 second) { - switch(f_focus) { - case FOCUS_HOUR: - (forward)?f_focus = FOCUS_MINUTE: f_focus = FOCUS_AMPM; - break; - case FOCUS_MINUTE: - (forward)?f_focus = FOCUS_SECOND: f_focus = FOCUS_HOUR; - break; - case FOCUS_SECOND: - (forward)?f_focus = FOCUS_AMPM: f_focus = FOCUS_MINUTE; - break; - case FOCUS_AMPM: - (forward)?f_focus = FOCUS_HOUR: f_focus = FOCUS_SECOND; - break; - default: - break; - } - - UpdateFocus(); -} - - -void -TTimeEdit::UpdateFocus() -{ - switch(f_focus) { - case FOCUS_HOUR: - f_hour = f_holdvalue; - Draw(f_hourrect); - break; - case FOCUS_MINUTE: - f_minute = f_holdvalue; - Draw(f_minrect); - break; - case FOCUS_SECOND: - f_second = f_holdvalue; - Draw(f_secrect); - break; - case FOCUS_AMPM: - f_isam = !f_isam; - Draw(f_aprect); - break; - default: - break; + if (f_sections->CountItems()> 0) + { + bool update = false; + + TDateTimeSection *section = (TDateTimeSection *)f_sections->ItemAt(0); + if (section->Data() != hour) { + section->SetData(hour); + update = true; + } + + section = (TDateTimeSection *)f_sections->ItemAt(1); + if (section->Data() != minute) { + section->SetData(minute); + update = true; + } + + section = (TDateTimeSection *)f_sections->ItemAt(2); + if (section->Data() != second) { + section->SetData(second); + update = true; + } + + if (update) + Draw(Bounds()); } } void -TTimeEdit::KeyDown(const char *bytes, int32 numbytes) -{ - switch(bytes[0]) { - case B_LEFT_ARROW: - SetFocus(false); - break; - - case B_RIGHT_ARROW: - SetFocus(true); - break; - - case B_UP_ARROW: - UpPress(); - break; - - case B_DOWN_ARROW: - DownPress(); - break; - - default: - BView::KeyDown(bytes, numbytes); - break; - } -} - - -void -TTimeEdit::UpPress() +TTimeEdit::DoUpPress() { + // update displayed value f_holdvalue += 1; - if (f_focus == FOCUS_AMPM) - f_isam = !f_isam; - - UpdateFocus(); - - // notify of change + + CheckRange(); + + // send message to change time DispatchMessage(); } - + void -TTimeEdit::DownPress() +TTimeEdit::DoDownPress() { + // update display value f_holdvalue -= 1; - if (f_focus == FOCUS_AMPM) - f_isam = !f_isam; - - UpdateFocus(); - - // notify of change + CheckRange(); + + // send message to change time DispatchMessage(); } - - -void -TTimeEdit::SetTo(int32 hour, int32 minute, int32 second) -{ - if (f_hour != hour - ||f_minute != minute - ||f_second != second) { - f_hour = hour; - f_minute = minute; - f_second = second; - f_isam = f_hour <= 12; - Draw(Bounds()); - } -} - - + + void TTimeEdit::BuildDispatch(BMessage *message) { + static const char *fields[4] = {"hour", "minute", "second", "isam"}; + message->AddBool("time", true); - message->AddInt32("hour", f_hour); - message->AddInt32("minute", f_minute); - message->AddInt32("second", f_second); + + for (int32 idx = 0; idx < f_sections->CountItems() -1; idx++) { + uint32 data; + + if (f_focus == idx) + data = f_holdvalue; + else + data = ((TDateTimeSection *)f_sections->ItemAt(idx))->Data(); + + if (idx == 3) // isam + message->AddBool("isam", data == 1); + else + message->AddInt32(fields[idx], data); + } +} + + +void +TTimeEdit::CheckRange() +{ + int32 value = f_holdvalue; + switch (f_focus) { + case 0: //hour + if (value> 23) + value = 0; + else if (value < 0) + value = 23; + break; + + case 1: //minute + if (value> 59) + value = 0; + else if (value < 0) + value = 59; + break; + + case 2: //second + if (value > 59) + value = 0; + else if (value < 0) + value = 59; + + break; + + case 3: + // modify hour value to reflect change in am/pm + value = ((TDateTimeSection *)f_sections->ItemAt(0))->Data(); + if (value < 13) + value += 12; + else + value -= 12; + if (value == 24) value = 0; + ((TDateTimeSection *)f_sections->ItemAt(0))->SetData(value); + break; + + default: + break; + } + + ((TDateTimeSection *)f_sections->ItemAt(f_focus))->SetData(value); + f_holdvalue = value; + + Draw(Bounds()); } -/*=====> TDateEdit <=====*/ +/* DATE TSECTIONEDIT */ + const char *months[] = { "January", "Febuary", "March", "April", "May", "June", @@ -468,291 +344,292 @@ const char *months[] = }; -TDateEdit::TDateEdit(BRect frame, const char *name) - : TDateTimeEdit(frame, name) -{ - BRect bounds(Bounds().InsetByCopy(1, 2)); - float width; - - // year rect - width = be_plain_font->StringWidth("0000") +6; - bounds.right = Bounds().right -(kArrowAreaWidth +2); - bounds.left = bounds.right -width; - f_yearrect = bounds; - - // don't know how to determine system date sep char - float sep_width = be_plain_font->StringWidth("/") +6; - - // day rect - //day is 2 digits 0 usually widest - width = be_plain_font->StringWidth("00") +6; - bounds.right = bounds.left -sep_width; - bounds.left = bounds.right -width; - f_dayrect = bounds; - - bounds.right = bounds.left -sep_width; - bounds.left = Bounds().left +2; - - f_monthrect = bounds; +TDateEdit::TDateEdit(BRect frame, const char *name, uint32 sections) + : TSectionEdit(frame, name, sections) +{ + InitView(); } TDateEdit::~TDateEdit() { + TSection *section; + if (f_sections->CountItems() > 0) + for (int32 idx = 0; (section = (TSection *)f_sections->ItemAt(idx)); idx++) + delete section; + delete f_sections; } void -TDateEdit::MouseDown(BPoint where) +TDateEdit::InitView() { - TDateTimeEdit::MouseDown(where); + TSectionEdit::InitView(); + SetSections(f_sectionsarea); +} + + +void +TDateEdit::DrawSection(uint32 index, bool isfocus) +{ + if (f_sections->CountItems() == 0) + printf("No Sections!!!\n"); + + // user defined section drawing + TDateTimeSection *section; + section = (TDateTimeSection *)f_sections->ItemAt(index); - if (f_monthrect.Contains(where)) { - f_focus = FOCUS_MONTH; - f_holdvalue = f_month; - } else if (f_dayrect.Contains(where)) { - f_focus = FOCUS_DAY; - f_holdvalue = f_day; - } else if (f_yearrect.Contains(where)) { - f_focus = FOCUS_YEAR; - f_holdvalue = f_year; + BRect bounds = section->Frame(); + + + // format value to display + + uint32 value; + + if (isfocus) { + SetLowColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); + value = f_holdvalue; + } else { + SetLowColor(ViewColor()); + value = section->Data(); } + + BString text; + // format value (new method?) + switch (index) { + case 0: // month + text << months[value]; + break; + + case 1: // day + text << value; + break; + + case 2: // year + text << value +1900; + break; + + default: + return; + break; + } + // calc and center text in section rect + + float width = be_plain_font->StringWidth(text.String()); + + BPoint offset(-(bounds.Width()/2.0 -width/2.0) -1.0, (bounds.Height()/2.0 -6.0)); + + if (index == 0) + offset.x = -(bounds.Width() -width) ; + + BPoint drawpt(bounds.LeftBottom() -offset); + + SetHighColor(0, 0, 0, 255); + FillRect(bounds, B_SOLID_LOW); + DrawString(text.String(), drawpt); +} + + +void +TDateEdit::DrawSeperator(uint32 index) +{ + /* user drawn seperator. section is the index of the section + in f_sections or the section to the seps left + */ + + if (index == 3) return; // no seperator for am/pm + BString text("/"); + uint32 sep; + GetSeperatorWidth(&sep); + + TDateTimeSection *section = (TDateTimeSection *)f_sections->ItemAt(index); + BRect bounds = section->Frame(); + + float width = be_plain_font->StringWidth(text.String()); + BPoint offset(-(sep/2.0 -width/2.0) -1.0, bounds.Height()/2.0 -6.0); + BPoint drawpt(bounds.RightBottom() -offset); + + DrawString(text.String(), drawpt); +} + + +void +TDateEdit::SetSections(BRect area) +{ + TDateTimeSection *section; + // create sections + for (uint32 idx = 0; idx < f_sectioncount; idx++) { + section = new TDateTimeSection(area); + f_sections->AddItem(section); + } + + BRect bounds(area); + float width; + + // year + width = be_plain_font->StringWidth("0000") +6; + bounds.right = area.right; + bounds.left = bounds.right -width; + ((TDateTimeSection *)f_sections->ItemAt(2))->SetBounds(bounds); + + uint32 sep; + GetSeperatorWidth(&sep); + + // day + width = be_plain_font->StringWidth("00") +6; + bounds.right = bounds.left -sep; + bounds.left = bounds.right -width; + ((TDateTimeSection *)f_sections->ItemAt(1))->SetBounds(bounds); + + // month + bounds.right = bounds.left -sep; + bounds.left = area.left; + ((TDateTimeSection *)f_sections->ItemAt(0))->SetBounds(bounds); +} + + +void +TDateEdit::GetSeperatorWidth(uint32 *width) +{ + *width = 8; +} + + +void +TDateEdit::SectionFocus(uint32 index) +{ + f_focus = index; + + // update hold value + f_holdvalue = ((TDateTimeSection *)f_sections->ItemAt(f_focus))->Data(); + Draw(Bounds()); } void -TDateEdit::Draw(BRect updaterect) +TDateEdit::SetTo(uint32 year, uint32 month, uint32 day) { - TDateTimeEdit::Draw(Bounds()); - - SetHighColor(0, 0, 0, 255); - - BString text; - BPoint drawpt; - BPoint offset(0, f_monthrect.Height()/2.0 -6); - int value; - - // seperator - BString septext("/"); - - float width; - rgb_color dark = tint_color(ViewColor(), B_DARKEN_1_TINT); - - //draw month - if (updaterect.Contains(f_monthrect)) { - if (f_focus == FOCUS_MONTH && IsFocus()) { - SetLowColor(dark); - value = f_holdvalue; - } else { - SetLowColor(ViewColor()); - value = f_month; - } - - text << months[value]; - width = be_plain_font->StringWidth(text.String()); - offset.x = width +3; - drawpt = f_monthrect.RightBottom() -offset; - - FillRect(f_monthrect, B_SOLID_LOW); - DrawString(text.String(), drawpt); - - offset.x = -3; - SetLowColor(ViewColor()); - DrawString(septext.String(), f_monthrect.RightBottom() -offset); - } - - //draw day - if (updaterect.Contains(f_dayrect)) { - if (f_focus == FOCUS_DAY && IsFocus()) { - SetLowColor(dark); - value = f_holdvalue; - } else { - SetLowColor(ViewColor()); - value = f_day; - } - - text = ""; - text << value; - width = be_plain_font->StringWidth(text.String()); - offset.x = -(f_dayrect.Width()/2.0 -width/2.0) -1; - - drawpt = f_dayrect.LeftBottom() -offset; - FillRect(f_dayrect, B_SOLID_LOW); - DrawString(text.String(), drawpt); - - offset.x = -3; - SetLowColor(ViewColor()); - DrawString(septext.String(), f_dayrect.RightBottom() -offset); - } - - //draw year - if (updaterect.Contains(f_yearrect)) { - if (f_focus == FOCUS_YEAR && IsFocus()) { - SetLowColor(dark); - value = f_holdvalue; - } else { - SetLowColor(ViewColor()); - value = f_year; - } - - text = ""; - text << value +1900; - width = be_plain_font->StringWidth(text.String()); - offset.x = -(f_yearrect.Width()/2.0 -width/2.0); - drawpt = f_yearrect.LeftBottom() -offset; - - FillRect(f_yearrect, B_SOLID_LOW); - DrawString(text.String(), drawpt); - } -} - - -void -TDateEdit::SetFocus(bool forward) -{ - switch(f_focus) { - case FOCUS_MONTH: - (forward)?f_focus = FOCUS_DAY: f_focus = FOCUS_YEAR; - break; - case FOCUS_DAY: - (forward)?f_focus = FOCUS_YEAR: f_focus = FOCUS_MONTH; - break; - case FOCUS_YEAR: - (forward)?f_focus = FOCUS_MONTH: f_focus = FOCUS_DAY; - break; - default: - break; - } - - UpdateFocus(); -} - - -void -TDateEdit::UpdateFocus(bool sethold = false) -{ - switch(f_focus) { - case FOCUS_MONTH: - { - if (sethold) - f_holdvalue = f_month; - else - { - if (f_holdvalue> 11) - f_holdvalue = 0; - else - if (f_holdvalue < 0) - f_holdvalue = 11; - - f_month = f_holdvalue; - } - Draw(f_monthrect); - } - break; - case FOCUS_DAY: - { - if (sethold) - f_holdvalue = f_day; - else - { - int daycnt = getDaysInMonth(f_month, f_year); - if (f_holdvalue> daycnt) - f_holdvalue = 1; - else - if (f_holdvalue < 0) - f_holdvalue = daycnt; - f_day = f_holdvalue; - } - Draw(f_dayrect); - } - break; - case FOCUS_YEAR: - { - if (sethold) - f_holdvalue = f_year; - else - { - if (f_holdvalue> YEAR_DELTA) - f_holdvalue = 65; - else - if (f_holdvalue < 65) - f_holdvalue = YEAR_DELTA; - f_year = f_holdvalue; - } - Draw(f_yearrect); - } - break; - default: - break; - } -} - - -void -TDateEdit::KeyDown(const char *bytes, int32 numbytes) -{ - switch(bytes[0]) { - case B_LEFT_ARROW: - SetFocus(false); - break; - - case B_RIGHT_ARROW: - SetFocus(true); - break; - - case B_UP_ARROW: - UpPress(); - break; - - case B_DOWN_ARROW: - DownPress(); - break; - - default: - BView::KeyDown(bytes, numbytes); - break; - } -} - - -void -TDateEdit::UpPress() -{ - f_holdvalue += 1; - UpdateFocus(); - DispatchMessage(); -} - - -void -TDateEdit::DownPress() -{ - f_holdvalue -= 1; - UpdateFocus(); - DispatchMessage(); -} - - -void -TDateEdit::SetTo(int32 year, int32 month, int32 day) -{ - if (f_month != month - || f_day != day - || f_year != year) + if (f_sections->CountItems()> 0) { - f_month = month; - f_day = day; - f_year = year; - Draw(Bounds()); + bool update = false; + + TDateTimeSection *section = (TDateTimeSection *)f_sections->ItemAt(0); + if (section->Data() != month) { + section->SetData(month); + update = true; + } + + section = (TDateTimeSection *)f_sections->ItemAt(1); + if (section->Data() != day) { + section->SetData(day); + update = true; + } + + section = (TDateTimeSection *)f_sections->ItemAt(2); + if (section->Data() != year) { + section->SetData(year); + update = true; + } + + if (update) + Draw(Bounds()); } } + +void +TDateEdit::DoUpPress() +{ + // update displayed value + f_holdvalue += 1; + + CheckRange(); + + // send message to change Date + DispatchMessage(); +} + + +void +TDateEdit::DoDownPress() +{ + // update display value + f_holdvalue -= 1; + + CheckRange(); + + // send message to change Date + DispatchMessage(); +} + + void TDateEdit::BuildDispatch(BMessage *message) { + static const char *fields[3] = {"month", "day", "year"}; + message->AddBool("time", false); - message->AddInt32("month", f_month); - message->AddInt32("day", f_day); - message->AddInt32("year", f_year); + + for (int32 idx = 0; idx < f_sections->CountItems(); idx++) { + uint32 data; + + if (f_focus == idx) + data = f_holdvalue; + else + data = ((TDateTimeSection *)f_sections->ItemAt(idx))->Data(); + + message->AddInt32(fields[idx], data); + } } + + +void +TDateEdit::CheckRange() +{ + int32 value = f_holdvalue; + + switch (f_focus) { + case 0: // month + { + if (value > 11) + value = 0; + else if (value < 0) + value = 11; + } + break; + + case 1: //day + { + uint32 month = ((TDateTimeSection *)f_sections->ItemAt(0))->Data(); + uint32 year = ((TDateTimeSection *)f_sections->ItemAt(2))->Data(); + + int daycnt = getDaysInMonth(month, year); + if (value > daycnt) + value = 1; + else if (value < 1) + value = daycnt; + } + break; + + case 2: //year + { + if (value > YEAR_DELTA_MAX) + value = YEAR_DELTA_MIN; + else if (value < YEAR_DELTA_MIN) + value = YEAR_DELTA_MAX; + } + break; + + default: + break; + } + + ((TDateTimeSection *)f_sections->ItemAt(f_focus))->SetData(value); + f_holdvalue = value; + + Draw(Bounds()); +} + + +//---// diff --git a/src/prefs/time/DateTimeEdit.h b/src/prefs/time/DateTimeEdit.h index 34747b4ce6..a0a56cd811 100644 --- a/src/prefs/time/DateTimeEdit.h +++ b/src/prefs/time/DateTimeEdit.h @@ -1,101 +1,70 @@ -#ifndef DATETIME_EDIT_H -#define DATETIME_EDIT_H +#ifndef DATETIME_H +#define DATETIME_H -#include -#include +#include "SectionEdit.h" -#define OB_UP_PRESS 'obUP' -#define OB_DOWN_PRESS 'obDN' - -enum FieldFocus { - FOCUS_NONE = 0, - FOCUS_MONTH, - FOCUS_DAY, - FOCUS_YEAR, - FOCUS_HOUR, - FOCUS_MINUTE, - FOCUS_SECOND, - FOCUS_AMPM -}; - -class TDateTimeEdit: public BControl { +// TSection descendent to hold uint32 value +class TDateTimeSection: public TSection { public: - TDateTimeEdit(BRect frame, const char *name); - virtual ~TDateTimeEdit(); + TDateTimeSection(BRect frame, uint32 data = 0); + ~TDateTimeSection(); - virtual void AttachedToWindow(); - virtual void Draw(BRect updaterect); - virtual void MouseDown(BPoint where); - virtual void MessageReceived(BMessage *message); - - virtual void UpPress()=0; - virtual void DownPress()=0; - protected: - virtual void DispatchMessage(); - virtual void BuildDispatch(BMessage *message)=0; - - virtual void Draw3dFrame(BRect frame, bool inset); - - BBitmap *f_up; - BBitmap *f_down; - BRect f_uprect; - BRect f_downrect; - - FieldFocus f_focus; - int f_holdvalue; -}; - -class TTimeEdit: public TDateTimeEdit { - public: - TTimeEdit(BRect frame, const char *name); - virtual ~TTimeEdit(); - - virtual void Draw(BRect updaterect); - virtual void MouseDown(BPoint where); - virtual void KeyDown(const char *bytes, int32 numbytes); - virtual void UpPress(); - virtual void DownPress(); - - virtual void SetTo(int32, int32, int32); + uint32 Data() const; + void SetData(uint32 data); private: - void BuildDispatch(BMessage *message); - void SetFocus(bool forward); - void UpdateFocus(); - - BRect f_hourrect; - BRect f_minrect; - BRect f_secrect; - BRect f_aprect; - - int f_hour; - int f_minute; - int f_second; - bool f_isam; + uint32 f_data; }; -class TDateEdit: public TDateTimeEdit { +// TSectionEdit descendent to edit time +class TTimeEdit: public TSectionEdit { public: - TDateEdit(BRect frame, const char *name); - virtual ~TDateEdit(); + TTimeEdit(BRect frame, const char *name, uint32 sections); + ~TTimeEdit(); - virtual void Draw(BRect updaterect); - virtual void MouseDown(BPoint where); - virtual void KeyDown(const char *bytes, int32 numbytes); - virtual void UpPress(); - virtual void DownPress(); + virtual void InitView(); + virtual void DrawSection(uint32 index, bool isfocus); + virtual void DrawSeperator(uint32 index); - virtual void SetTo(int32, int32, int32); - private: - void BuildDispatch(BMessage *message); - void SetFocus(bool forward); - void UpdateFocus(bool = false); + virtual void SetSections(BRect area); + virtual void SectionFocus(uint32 index); + virtual void GetSeperatorWidth(uint32 *width); - BRect f_monthrect; - BRect f_dayrect; - BRect f_yearrect; - int f_month; - int f_day; - int f_year; + void CheckRange(); + + virtual void DoUpPress(); + virtual void DoDownPress(); + + virtual void BuildDispatch(BMessage *message); + + void SetTo(uint32 hour, uint32 minute, uint32 second); }; -#endif //DATETIME_EDIT_H + +/* DATE TSECTIONEDIT */ + +// TSectionEdit descendent to edit Date +class TDateEdit: public TSectionEdit { + public: + TDateEdit(BRect frame, const char *name, uint32 sections); + ~TDateEdit(); + + virtual void InitView(); + virtual void DrawSection(uint32 index, bool isfocus); + virtual void DrawSeperator(uint32 index); + + virtual void SetSections(BRect area); + virtual void SectionFocus(uint32 index); + virtual void GetSeperatorWidth(uint32 *width); + + void CheckRange(); + + virtual void DoUpPress(); + virtual void DoDownPress(); + + virtual void BuildDispatch(BMessage *message); + + void SetTo(uint32 hour, uint32 minute, uint32 second); +}; + + +#endif //DATETIME_H diff --git a/src/prefs/time/Jamfile b/src/prefs/time/Jamfile index 5b7e96c462..f60a3e7a5f 100644 --- a/src/prefs/time/Jamfile +++ b/src/prefs/time/Jamfile @@ -2,6 +2,6 @@ SubDir OBOS_TOP src prefs time ; AddResources Time : Time.rsrc ; -Preference Time : Bitmaps.cpp BaseView.cpp DateTimeEdit.cpp CalendarView.cpp AnalogClock.cpp SettingsView.cpp Time.cpp TimeSettings.cpp TimeView.cpp TimeWindow.cpp ZoneView.cpp DateUtils.cpp TZDisplay.cpp ; +Preference Time : AnalogClock.cpp BaseView.cpp Bitmaps.cpp CalendarView.cpp DateTimeEdit.cpp DateUtils.cpp SectionEdit.cpp SettingsView.cpp Time.cpp TimeSettings.cpp TimeView.cpp TimeWindow.cpp TZDisplay.cpp ZoneView.cpp ; LinkSharedOSLibs Time : be root ; diff --git a/src/prefs/time/SectionEdit.cpp b/src/prefs/time/SectionEdit.cpp new file mode 100644 index 0000000000..76e78e0288 --- /dev/null +++ b/src/prefs/time/SectionEdit.cpp @@ -0,0 +1,303 @@ +#include +#include + +#include "Bitmaps.h" +#include "SectionEdit.h" +#include "TimeMessages.h" + +const uint32 kArrowAreaWidth = 16; +const uint32 kSeperatorWidth = 8; + + +TSection::TSection(BRect frame) + : f_frame(frame) +{ +} + + +void +TSection::SetBounds(BRect frame) +{ + f_frame = frame; +} + + + BRect +TSection::Bounds() const +{ + BRect bounds(f_frame); + return bounds.OffsetByCopy(B_ORIGIN); +} + + + BRect +TSection::Frame() const +{ + return f_frame; +} + + + +TSectionEdit::TSectionEdit(BRect frame, const char *name, uint32 sections) + : BControl(frame, name, NULL, NULL, B_FOLLOW_NONE, B_NAVIGABLE|B_WILL_DRAW) + , f_focus(-1) +{ + f_sectioncount = sections; + InitView(); +} + + +TSectionEdit::~TSectionEdit() +{ +} + + +void +TSectionEdit::AttachedToWindow() +{ + if (Parent()) { + SetViewColor(Parent()->ViewColor()); + ReplaceTransparentColor(f_up, ViewColor()); + ReplaceTransparentColor(f_down, ViewColor()); + } +} + + +void +TSectionEdit::Draw(BRect updaterect) +{ + DrawBorder(); + for (uint32 idx = 0; idx < f_sectioncount; idx++) + { + DrawSection(idx, ((uint32)f_focus == idx) && IsFocus()); + if (idx CountItems()> 0) { + TSection *section; + for (uint32 idx = 0; idx < f_sectioncount; idx++) { + section = (TSection *)f_sections->ItemAt(idx); + if (section->Frame().Contains(where)) { + SectionFocus(idx); + return; + } + } + } +} + + +void +TSectionEdit::KeyDown(const char *bytes, int32 numbytes) +{ + if (f_focus == -1) + SectionFocus(0); + + switch (bytes[0]) { + case B_LEFT_ARROW: + f_focus -= 1; + if (f_focus < 0) + f_focus = f_sectioncount -1; + SectionFocus(f_focus); + break; + + case B_RIGHT_ARROW: + f_focus += 1; + if ((uint32)f_focus >= f_sectioncount) + f_focus = 0; + SectionFocus(f_focus); + break; + + case B_UP_ARROW: + DoUpPress(); + break; + + case B_DOWN_ARROW: + DoDownPress(); + break; + + default: + BControl::KeyDown(bytes, numbytes); + break; + } + Draw(Bounds()); +} + + +void +TSectionEdit::DispatchMessage() +{ + BMessage *msg = new BMessage(H_USER_CHANGE); + BuildDispatch(msg); + Window()->PostMessage(msg); +} + + +uint32 +TSectionEdit::CountSections() const +{ + return f_sections->CountItems(); +} + + +int32 +TSectionEdit::FocusIndex() const +{ + return f_focus; +} + + +void +TSectionEdit::InitView() +{ + // create arrow bitmaps + + f_up = new BBitmap(BRect(0, 0, kUpArrowWidth -1, kUpArrowHeight -1), kUpArrowColorSpace); + f_up->SetBits(kUpArrowBits, (kUpArrowWidth) *(kUpArrowHeight+1), 0, kUpArrowColorSpace); + + f_down = new BBitmap(BRect(0, 0, kDownArrowWidth -1, kDownArrowHeight -2), kDownArrowColorSpace); + f_down->SetBits(kDownArrowBits, (kDownArrowWidth) *(kDownArrowHeight), 0, kDownArrowColorSpace); + + + // setup sections + f_sections = new BList(f_sectioncount); + f_sectionsarea = Bounds().InsetByCopy(2, 2); + f_sectionsarea.right -= (kArrowAreaWidth); +} + + +void +TSectionEdit::Draw3DFrame(BRect frame, bool inset) +{ + rgb_color color1, color2; + + if (inset) { + color1 = HighColor(); + color2 = LowColor(); + } else { + color1 = LowColor(); + color2 = HighColor(); + } + + BeginLineArray(4); + // left side + AddLine(frame.LeftBottom(), frame.LeftTop(), color2); + // right side + AddLine(frame.RightTop(), frame.RightBottom(), color1); + // bottom side + AddLine(frame.RightBottom(), frame.LeftBottom(), color1); + // top side + AddLine(frame.LeftTop(), frame.RightTop(), color2); + EndLineArray(); +} + + +void +TSectionEdit::DrawBorder() +{ + rgb_color bgcolor = ViewColor(); + rgb_color light = tint_color(bgcolor, B_LIGHTEN_MAX_TINT); + rgb_color dark = tint_color(bgcolor, B_DARKEN_1_TINT); + rgb_color darker = tint_color(bgcolor, B_DARKEN_3_TINT); + + BRect bounds(Bounds()); + SetHighColor(light); + SetLowColor(dark); + Draw3DFrame(bounds, true); + StrokeLine(bounds.LeftBottom(), bounds.LeftBottom(), B_SOLID_LOW); + + bounds.InsetBy(1, 1); + bounds.right -= kArrowAreaWidth; + + f_showfocus = (IsFocus() && Window() && Window()->IsActive()); + if (f_showfocus) { + rgb_color navcolor = keyboard_navigation_color(); + + SetHighColor(navcolor); + StrokeRect(bounds); + } else { + // draw border thickening (erase focus) + SetHighColor(darker); + SetLowColor(bgcolor); + Draw3DFrame(bounds, false); + } + + // draw up/down control + SetHighColor(light); + bounds.left = bounds.right +1;// -kArrowAreaWidth; + bounds.right = Bounds().right -1; + f_uprect.Set(bounds.left +3, bounds.top +2, bounds.right, bounds.bottom /2.0); + f_downrect = f_uprect.OffsetByCopy(0, f_uprect.Height()+2); + + DrawBitmap(f_up, f_uprect.LeftTop()); + DrawBitmap(f_down, f_downrect.LeftTop()); + + Draw3DFrame(bounds, false); + SetHighColor(dark); + StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); + StrokeLine(bounds.RightBottom(), bounds.RightTop()); + SetHighColor(light); + StrokeLine(bounds.RightTop(), bounds.RightTop()); +} + + +void +TSectionEdit::SetSections(BRect) +{ +} + + +void +TSectionEdit::GetSeperatorWidth(uint32 *width) +{ + *width = 0; +} + + +void +TSectionEdit::DrawSection(uint32 index, bool isfocus) +{ +} + + +void +TSectionEdit::DrawSeperator(uint32 index) +{ +} + + +void +TSectionEdit::SectionFocus(uint32 index) +{ +} + + +void +TSectionEdit::SectionChange(uint32 section, uint32 value) +{ +} + + +void +TSectionEdit::DoUpPress() +{ +} + + +void +TSectionEdit::DoDownPress() +{ +} + + +//---// diff --git a/src/prefs/time/SectionEdit.h b/src/prefs/time/SectionEdit.h new file mode 100644 index 0000000000..1795003607 --- /dev/null +++ b/src/prefs/time/SectionEdit.h @@ -0,0 +1,67 @@ +#ifndef SECTIONEDIT_H +#define SECTIONEDIT_H + +#include +#include + +class TSection { + public: + TSection(BRect frame); + + void SetBounds(BRect frame); + + BRect Bounds() const; + BRect Frame() const; + private: + BRect f_frame; +}; + + +class TSectionEdit: public BControl { + public: + TSectionEdit(BRect frame, const char *name, uint32 sections); + ~TSectionEdit(); + + virtual void AttachedToWindow(); + virtual void Draw(BRect); + virtual void MouseDown(BPoint); + virtual void KeyDown(const char *bytes, int32 numbytes); + + uint32 CountSections() const; + int32 FocusIndex() const; + BRect SectionArea() const; + protected: + virtual void InitView(); + //hooks + virtual void DrawBorder(); + virtual void DrawSection(uint32 index, bool isfocus); + virtual void DrawSeperator(uint32 index); + virtual void Draw3DFrame(BRect frame, bool inset); + + virtual void SectionFocus(uint32 index); + virtual void SectionChange(uint32 index, uint32 value); + virtual void SetSections(BRect area); + virtual void GetSeperatorWidth(uint32 *width); + + virtual void DoUpPress(); + virtual void DoDownPress(); + + virtual void DispatchMessage(); + virtual void BuildDispatch(BMessage *) = 0; + + BBitmap *f_up; + BBitmap *f_down; + BList *f_sections; + + BRect f_uprect; + BRect f_downrect; + BRect f_sectionsarea; + + int32 f_focus; + uint32 f_sectioncount; + uint32 f_holdvalue; + + bool f_showfocus; +}; + +#endif diff --git a/src/prefs/time/SettingsView.cpp b/src/prefs/time/SettingsView.cpp index 083bfc9fbf..90a945bde6 100644 --- a/src/prefs/time/SettingsView.cpp +++ b/src/prefs/time/SettingsView.cpp @@ -45,7 +45,7 @@ TSettingsView::MessageReceived(BMessage *message) message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change); switch(change) { - case OB_TM_CHANGED: + case H_TM_CHANGED: UpdateDateTime(message); break; @@ -79,7 +79,7 @@ TSettingsView::InitView() // left side frame.InsetBy(6, 6); frame.bottom = frame.top +text_height +6; - f_dateedit = new TDateEdit(frame, "date_edit"); + f_dateedit = new TDateEdit(frame, "date_edit", 3); frame.top = f_dateedit->Frame().bottom; frame.bottom = bounds.bottom; @@ -97,13 +97,14 @@ TSettingsView::InitView() frame.InsetBy(26, 6); frame.bottom = frame.top +text_height +6; frame.right += 4; - f_timeedit = new TTimeEdit(frame, "time_edit"); + f_timeedit = new TTimeEdit(frame, "time_edit", 4); frame.top = f_timeedit->Frame().bottom; frame.bottom = bounds.bottom -(text_height *3); frame.InsetBy(10, 10); f_clock = new TAnalogClock(frame, "analog clock", B_FOLLOW_NONE, B_WILL_DRAW); + AddChild(f_timeedit); // clock radio buttons frame = bounds.InsetByCopy(6, 10); @@ -117,15 +118,14 @@ TSettingsView::InitView() frame.OffsetBy(frame.Width() +9, -1); frame.right = bounds.right-2; - f_local = new BRadioButton(frame, "local", "Local time", new BMessage(OB_RTC_CHANGE)); + f_local = new BRadioButton(frame, "local", "Local time", new BMessage(H_RTC_CHANGE)); AddChild(f_local); frame.OffsetBy(0, text_height +4); - f_gmt = new BRadioButton(frame, "gmt", "GMT", new BMessage(OB_RTC_CHANGE)); + f_gmt = new BRadioButton(frame, "gmt", "GMT", new BMessage(H_RTC_CHANGE)); AddChild(f_gmt); AddChild(text); - AddChild(f_timeedit); AddChild(f_clock); if (f_islocal) diff --git a/src/prefs/time/TZDisplay.cpp b/src/prefs/time/TZDisplay.cpp index ebc094aef6..2494c74b68 100644 --- a/src/prefs/time/TZDisplay.cpp +++ b/src/prefs/time/TZDisplay.cpp @@ -11,14 +11,14 @@ TTZDisplay::TTZDisplay(BRect frame, const char *name, uint32 resizingmode, uint32 flags, const char *label, const char *text, - int32 hour, int32 minute, int32 second) + int32 hour, int32 minute) : BView(frame, name, resizingmode, flags) { f_label = new BString(label); f_text = new BString(text); f_time = new BString(); - SetTo(hour, minute, second); + SetTo(hour, minute); } @@ -99,7 +99,7 @@ TTZDisplay::SetText(const char *text) } void -TTZDisplay::SetTo(int32 hour, int32 minute, int32 second) +TTZDisplay::SetTo(int32 hour, int32 minute) { // format time into f_time if (f_time == NULL) @@ -115,10 +115,10 @@ TTZDisplay::SetTo(int32 hour, int32 minute, int32 second) ahour = 12; char *ap; - if (hour> 12) - ap = "pm"; + if (hour> 11) + ap = "PM"; else - ap = "am"; + ap = "AM"; char *time = f_time->LockBuffer(8); sprintf(time, "%02lu:%02lu %s", ahour, minute, ap); @@ -126,3 +126,24 @@ TTZDisplay::SetTo(int32 hour, int32 minute, int32 second) Draw(Bounds()); } + +const char * +TTZDisplay::Text() const +{ + return f_text->String(); +} + +const char * +TTZDisplay::Label() const +{ + return f_label->String(); +} + +const char * +TTZDisplay::Time() const +{ + return f_time->String(); +} + + + diff --git a/src/prefs/time/TZDisplay.h b/src/prefs/time/TZDisplay.h index 5986dd9aa6..7ab78cdfca 100644 --- a/src/prefs/time/TZDisplay.h +++ b/src/prefs/time/TZDisplay.h @@ -9,7 +9,7 @@ class TTZDisplay: public BView TTZDisplay(BRect frame, const char *name, uint32 resizing, uint32 flags, const char *label = B_EMPTY_STRING, const char *name = B_EMPTY_STRING, - int32 hour = 0, int32 minute = 0, int32 second = 0); + int32 hour = 0, int32 minute = 0); ~TTZDisplay(); virtual void AttachedToWindow(); virtual void MessageReceived(BMessage *message); @@ -19,7 +19,11 @@ class TTZDisplay: public BView virtual void SetLabel(const char *label); virtual void SetText(const char *text); - virtual void SetTo(int32 hour, int32 minute, int32 second); + virtual void SetTo(int32 hour, int32 minute); + + virtual const char *Label() const; + virtual const char *Text() const; + virtual const char *Time() const; private: BString *f_label; BString *f_text; diff --git a/src/prefs/time/Time.cpp b/src/prefs/time/Time.cpp index 9d047dc924..8f0dadfb95 100644 --- a/src/prefs/time/Time.cpp +++ b/src/prefs/time/Time.cpp @@ -23,7 +23,7 @@ int main() TimeApplication::TimeApplication() - :BApplication(OBOS_APP_SIGNATURE) + :BApplication(HAIKU_APP_SIGNATURE) { f_settings = new TimeSettings(); f_window = new TTimeWindow(); diff --git a/src/prefs/time/Time.h b/src/prefs/time/Time.h index f9dd470a48..9a71f0d43f 100644 --- a/src/prefs/time/Time.h +++ b/src/prefs/time/Time.h @@ -3,8 +3,8 @@ #include -#include "TimeWindow.h" #include "TimeSettings.h" +#include "TimeWindow.h" class TimeApplication : public BApplication { public: diff --git a/src/prefs/time/Time.rsrc b/src/prefs/time/Time.rsrc index aeca022822..d1ee4204d8 100644 Binary files a/src/prefs/time/Time.rsrc and b/src/prefs/time/Time.rsrc differ diff --git a/src/prefs/time/TimeMessages.h b/src/prefs/time/TimeMessages.h index 0ce71d1405..42b117bce3 100644 --- a/src/prefs/time/TimeMessages.h +++ b/src/prefs/time/TimeMessages.h @@ -7,33 +7,35 @@ #ifndef TIME_MESSAGES_H #define TIME_MESSAGES_H -#define OBOS_APP_SIGNATURE "application/x-vnd.OpenBeOS-TIME" +#define HAIKU_APP_SIGNATURE "application/x-vnd.Haiku-TIME" const uint32 ERROR_DETECTED = 'ERor'; -//Timezonemessages -const uint32 REGION_CHANGED = 'REch'; -const uint32 TIME_ZONE_CHANGED = 'TZch'; +//Timezone messages +const uint32 H_REGION_CHANGED = 'h_RC'; +const uint32 H_CITY_CHANGED = 'h_CC'; +const uint32 H_CITY_SET = 'h_CS'; + //SetButton -const uint32 SET_TIME_ZONE = 'SEti'; +const uint32 H_SET_TIME_ZONE = 'hSTZ'; //local and GMT settings const uint32 RTC_SETTINGS = 'RTse'; // clock tick message -const uint32 OB_TIME_UPDATE ='obTU'; +const uint32 H_TIME_UPDATE ='obTU'; // clicked on day in claendar -const uint32 OB_DAY_CHANGED = 'obDC'; +const uint32 H_DAY_CHANGED = 'obDC'; //notice for clock ticks -const uint32 OB_TM_CHANGED = 'obTC'; +const uint32 H_TM_CHANGED = 'obTC'; //notice for user changes -const uint32 OB_USER_CHANGE = 'obUC'; +const uint32 H_USER_CHANGE = 'obUC'; // local/gmt radiobuttons -const uint32 OB_RTC_CHANGE = 'obRC'; +const uint32 H_RTC_CHANGE = 'obRC'; #endif //TIME_MESSAGES_H diff --git a/src/prefs/time/TimeWindow.cpp b/src/prefs/time/TimeWindow.cpp index d2b0802ef9..0f530aaf82 100644 --- a/src/prefs/time/TimeWindow.cpp +++ b/src/prefs/time/TimeWindow.cpp @@ -46,28 +46,19 @@ void TTimeWindow::MessageReceived(BMessage *message) { switch(message->what) { - case OB_USER_CHANGE: + case H_USER_CHANGE: { bool istime; if (message->FindBool("time", &istime) == B_OK) f_BaseView->ChangeTime(message); } break; - case OB_RTC_CHANGE: + case H_RTC_CHANGE: { f_BaseView->SetGMTime(f_TimeSettings->GMTime()); } break; - case REGION_CHANGED: - f_TimeZones->ChangeRegion(message); - break; - case SET_TIME_ZONE: - f_TimeZones->SetTimeZone(); - break; - case TIME_ZONE_CHANGED: - f_TimeZones->NewTimeZone(); - break; default: BWindow::MessageReceived(message); break; diff --git a/src/prefs/time/TimeWindow.h b/src/prefs/time/TimeWindow.h index aef08761ff..72a29b9eed 100644 --- a/src/prefs/time/TimeWindow.h +++ b/src/prefs/time/TimeWindow.h @@ -3,11 +3,10 @@ #include -///////////////////////////////// +#include "BaseView.h" #include "SettingsView.h" #include "TimeSettings.h" #include "ZoneView.h" -#include "BaseView.h" class TTimeWindow : public BWindow { public: diff --git a/src/prefs/time/ZoneView.cpp b/src/prefs/time/ZoneView.cpp index 0c4b741437..fa65362b35 100644 --- a/src/prefs/time/ZoneView.cpp +++ b/src/prefs/time/ZoneView.cpp @@ -1,56 +1,70 @@ /* - TZoneView.cpp + ZoneView.cpp + by Mike Berg (inseculous) + + Status: mimics original Time Zone tab of Time Pref App + Exceptions: doesn't calc "Time in" time. + Issues: After experimenting with both Time Prefs, it seems the original doesn't + use the link file in the users settings file to get the current Timezone. + Need to find the call it uses to get its inital info so I can get exact duplication. */ #include + #include #include #include -#include -#include +#include +#include #include #include -#include -#include +#include #include +#include +#include +#include #include #include - -#include +#include #include "TimeMessages.h" #include "ZoneView.h" /*=====> TZoneItem <=====*/ - -TZoneItem::TZoneItem(const char *text, const char *zonedata) +TZoneItem::TZoneItem(const char *text, const char *zone) : BStringItem(text) -{ - f_zonedata = new BPath(zonedata); +{ + f_zone = new BPath(zone); } TZoneItem::~TZoneItem() { - delete f_zonedata; + delete f_zone; +} + +const char * +TZoneItem::Zone() const +{ + return f_zone->Leaf(); } const char * -TZoneItem::GetZone() const +TZoneItem::Path() const { - return f_zonedata->Leaf(); + return f_zone->Path(); } /*=====> TZoneView <=====*/ TZoneView::TZoneView(BRect frame) - : BView(frame, "", B_FOLLOW_ALL, - B_WILL_DRAW|B_FRAME_EVENTS|B_NAVIGABLE_JUMP|B_PULSE_NEEDED) - , f_citylist(NULL) + : BView(frame, B_EMPTY_STRING, B_FOLLOW_ALL, B_WILL_DRAW|B_NAVIGABLE_JUMP) + , f_first(true) { + ReadTimeZoneLink(); InitView(); } @@ -60,11 +74,45 @@ TZoneView::~TZoneView() } + +void +TZoneView::AllAttached() +{ + + +} + + void TZoneView::AttachedToWindow() { if (Parent()) SetViewColor(Parent()->ViewColor()); + + if (f_first) // stupid hack + { + f_regionpopup->SetTargetForItems(this); + f_setzone->SetTarget(this); + f_citylist->SetTarget(this); + // update displays + BPath parent; + f_currentzone.GetParent(&parent); + int czone = FillCityList(parent.Path()); + if (czone> -1) { + f_citylist->Select(czone); + f_current->SetText( ((TZoneItem *)f_citylist->ItemAt(czone))->Text() ); + } + f_first = false; + } + f_citylist->ScrollToSelection(); +} + + +void +TZoneView::Draw(BRect updaterect) +{ + f_current->Draw(updaterect); + f_preview->Draw(updaterect); } @@ -76,7 +124,7 @@ TZoneView::MessageReceived(BMessage *message) case B_OBSERVER_NOTICE_CHANGE: message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change); switch(change) { - case OB_TM_CHANGED: + case H_TM_CHANGED: UpdateDateTime(message); break; @@ -85,34 +133,43 @@ TZoneView::MessageReceived(BMessage *message) break; } break; + case H_REGION_CHANGED: + ChangeRegion(message); + break; + + case H_SET_TIME_ZONE: + SetTimeZone(); + break; + + case H_CITY_CHANGED: + SetPreview(); + break; + default: BView::MessageReceived(message); - break; + break; } } -void -TZoneView::Draw(BRect updaterect) -{ - f_currentzone->Draw(updaterect); - f_timeinzone->Draw(updaterect); -} - - void TZoneView::UpdateDateTime(BMessage *message) { - int32 hour, minute, second; + // only need hour and minute + int32 hour, minute; if (message->FindInt32("hour", &hour) == B_OK - && message->FindInt32("minute", &minute) == B_OK - && message->FindInt32("second", &second) == B_OK) - { - f_currentzone->SetTo(hour, minute, second); + && message->FindInt32("minute", &minute) == B_OK) { + if (f_hour != hour || f_minute != minute) { + f_hour = hour; + f_minute = minute; + f_current->SetTo(hour, minute); - // do calc to get other zone time - f_timeinzone->SetTo(hour, minute, second); + if (f_citylist->CurrentSelection()> -1) { + // do calc to get other zone time + SetPreview(); + } + } } } @@ -124,22 +181,20 @@ TZoneView:: InitView() be_plain_font->GetHeight(&finfo); float text_height = finfo.ascent +finfo.descent +finfo.leading; - GetCurrentRegion(); - BRect bounds(Bounds().InsetByCopy(4, 2)); BRect frame(bounds); // Zone menu - f_zonepopup = new BPopUpMenu("", true, true, B_ITEMS_IN_COLUMN); - + f_regionpopup = new BPopUpMenu(B_EMPTY_STRING, true, true, B_ITEMS_IN_COLUMN); + float widest = 0; - CreateZoneMenu(&widest); + BuildRegionMenu(&widest); frame.right = frame.left +widest +25; frame.bottom = frame.top +text_height -1; BMenuField *mField; - mField= new BMenuField(frame, "mfield", NULL, f_zonepopup, true); + mField= new BMenuField(frame, "regions", NULL, f_regionpopup, true); mField->MenuBar()->SetBorder(B_BORDER_CONTENTS); mField->MenuBar()->ResizeToPreferred(); AddChild(mField); @@ -158,55 +213,50 @@ TZoneView:: InitView() B_FOLLOW_LEFT|B_FOLLOW_TOP, B_WILL_DRAW|B_NAVIGABLE|B_FRAME_EVENTS); - BMessage *citychange = new BMessage(TIME_ZONE_CHANGED); + BMessage *citychange = new BMessage(H_CITY_CHANGED); f_citylist->SetSelectionMessage(citychange); + BMessage *cityinvoke = new BMessage(H_SET_TIME_ZONE); + f_citylist->SetInvocationMessage(cityinvoke); + BScrollView *scrollList; scrollList = new BScrollView("scroll_list", f_citylist, B_FOLLOW_LEFT|B_FOLLOW_TOP, 0, false, true); AddChild(scrollList); - + // Time Displays frame.OffsetBy(scrollList->Bounds().Width() +9, 3); frame.bottom = frame.top +text_height *2; frame.right = bounds.right -6; - f_currentzone = new TTZDisplay(frame, "current", + f_current = new TTZDisplay(frame, "current", B_FOLLOW_LEFT|B_FOLLOW_TOP, 0, "Current time zone:", B_EMPTY_STRING); - f_currentzone->ResizeToPreferred(); + f_current->ResizeToPreferred(); frame.OffsetBy(0, (text_height *3) +2); - f_timeinzone = new TTZDisplay(frame, "timein", + f_preview = new TTZDisplay(frame, "timein", B_FOLLOW_LEFT|B_FOLLOW_TOP, 0, "Time in: ", B_EMPTY_STRING); - f_timeinzone->ResizeToPreferred(); - - AddChild(f_currentzone); - AddChild(f_timeinzone); + f_preview->ResizeToPreferred(); + AddChild(f_current); + AddChild(f_preview); // set button frame.Set(bounds.right -75, bounds.bottom -24, bounds.right, bounds.bottom); frame.OffsetBy(-2, -2); - f_settimezone = new BButton(frame, "set", "Set", new BMessage(SET_TIME_ZONE)); - f_settimezone->SetEnabled(false); - AddChild(f_settimezone); - - // update displays - int currentzone = FillZoneList(f_RegionStr.Leaf()); - f_citylist->Select(currentzone); - f_citylist->ScrollToSelection(); - f_citylist->Invalidate(); - f_currentzone->SetText( ((TZoneItem *)f_citylist->ItemAt(currentzone))->Text() ); + f_setzone = new BButton(frame, "set", "Set", new BMessage(H_SET_TIME_ZONE)); + f_setzone->SetEnabled(false); + AddChild(f_setzone); } void -TZoneView::CreateZoneMenu(float *widest) +TZoneView::BuildRegionMenu(float *widest) { BPath path; // return if /etc directory is not found @@ -215,138 +265,195 @@ TZoneView::CreateZoneMenu(float *widest) path.Append("timezones"); + // get current region + BPath region; + f_currentzone.GetParent(®ion); + float width = 0; - bool markitem; + bool markit; BEntry entry; - BMenuItem *zoneItem; + BMenuItem *item; BDirectory dir(path.Path()); dir.Rewind(); + // walk timezones dir and add entries to menu BString itemtext; while (dir.GetNextEntry(&entry) == B_NO_ERROR) { if (entry.IsDirectory()) { path.SetTo(&entry); itemtext = path.Leaf(); + + // skip Etc directory if (itemtext.Compare("Etc", 3) == 0) - continue; + continue; + markit = itemtext.Compare(region.Leaf()) == 0; + // add Ocean to oceans :) - if ((itemtext.Compare("Atlantic", 8) == 0) - ||(itemtext.Compare("Pacific", 7) == 0) - ||(itemtext.Compare("Indian", 6) == 0)) + if (itemtext.Compare("Atlantic", 8) == 0 + ||itemtext.Compare("Pacific", 7) == 0 + ||itemtext.Compare("Indian", 6) == 0) itemtext.Append(" Ocean"); - markitem = itemtext.Compare(f_RegionStr.Leaf()) == 0; - itemtext = itemtext.ReplaceAll('_', ' '); + itemtext = itemtext.ReplaceAll('_', ' '); // underscores are spaces width = be_plain_font->StringWidth(itemtext.String()); if (width> *widest) *widest = width; - BMessage *zoneMessage = new BMessage(REGION_CHANGED); - zoneMessage->AddString("region", path.Leaf()); + BMessage *msg = new BMessage(H_REGION_CHANGED); + msg->AddString("region", path.Path()); - zoneItem = new BMenuItem(itemtext.String(), zoneMessage); - zoneItem->SetMarked(markitem); - f_zonepopup->AddItem(zoneItem); + item = new BMenuItem(itemtext.String(), msg); + item->SetMarked(markit); + f_regionpopup->AddItem(item); } } } -void -TZoneView::ChangeRegion(BMessage *message) -{ - const char *area; - message->FindString("region", &area); - - FillZoneList(area); -} - - int -TZoneView::FillZoneList(const char *area) +TZoneView::FillCityList(const char *area) { - //clear listview from previous items - f_citylist->MakeEmpty(); - + // clear list + + // MakeEmpty() doesn't free items so... + int32 idx = f_citylist->CountItems(); + if (idx>= 1) + for (; idx>= 0; idx--) + delete f_citylist->RemoveItem(idx); + //Enter time zones directory. Find subdir with name that matches string stored in area. //Enter subdirectory and count the items. For each item, add a StringItem to f_CityList //Time zones directory BPath path; + // return if /etc directory is not found if (!(find_directory(B_BEOS_ETC_DIRECTORY, &path) == B_OK)) return 0; path.Append("timezones"); + BPath Area(area); BDirectory zoneDir(path.Path()); BDirectory cityDir; BStringItem *city; BString city_name; - entry_ref ref; - - int index = 0; // index of current setting + BEntry entry; + int index = -1; //locate subdirectory: - if ( zoneDir.Contains(area, B_DIRECTORY_NODE)) { - cityDir.SetTo(&zoneDir, area); //There is a subdir with a name that matches 'area'. That's the one!! + + if ( zoneDir.Contains(Area.Leaf(), B_DIRECTORY_NODE)) { + cityDir.SetTo(&zoneDir, Area.Leaf()); + //There is a subdir with a name that matches 'area'. That's the one!! + + //iterate over the items in the subdir and fill the listview with TZoneItems: - while(cityDir.GetNextRef(&ref) == B_NO_ERROR) { - city_name = ref.name; - city_name.ReplaceAll("__", ", "); - city_name.ReplaceAll("_", " "); - city = new TZoneItem(city_name.String(), ref.name); - f_citylist->AddItem(city); - - if (strcmp(f_ZoneStr.Leaf(), ref.name) == 0) - index = f_citylist->IndexOf(city); + + while(cityDir.GetNextEntry(&entry) == B_NO_ERROR) { + if (!entry.IsDirectory()) { + BPath zone(&entry); + city_name = zone.Leaf(); + city_name.ReplaceAll("_IN", ", Indiana"); + city_name.ReplaceAll("__Calif", ", Calif"); + city_name.ReplaceAll("__", ", "); + city_name.ReplaceAll("_", " "); + city = new TZoneItem(city_name.String(), zone.Path()); + f_citylist->AddItem(city); + if (strcmp(f_currentzone.Leaf(), zone.Leaf()) == 0) + index = f_citylist->IndexOf(city); + } } } - printf("%d\n", index); return index; } void -TZoneView::GetCurrentTZ() +TZoneView::ChangeRegion(BMessage *message) { + BString area; + message->FindString("region", &area); + + FillCityList(area.String()); +} + + +void +TZoneView::ReadTimeZoneLink() +{ + /* reads the timezone symlink from B_USER_SETTINGS_DIRECTORY + currently this sets f_currentzone to the symlink value. + this is wrong. the original can get users timezone without + a timezone symlink present. + + defaults are set to different values to clue in on what error was returned + GMT is set when the link is invalid + EST is set when the settings dir can't be found **should never happen** + */ + BPath path; BEntry tzLink; if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { + path.Append("timezone"); tzLink.SetTo(path.Path(), true); - if (!tzLink.InitCheck()) {// link is broken + + if (tzLink.InitCheck() != B_OK) {// link is broken + tzLink.SetTo("/boot/beos/etc/timezones/Pacific/fiji"); // do something like set to a default GMT??? -// return; } } else { - // set tzlink to default + // set tzlink to a default + tzLink.SetTo("/boot/beos/etc/timezones/EST"); } // we need something in the current zone - f_ZoneStr.SetTo(&tzLink); + f_currentzone.SetTo(&tzLink); } void -TZoneView::GetCurrentRegion() +TZoneView::SetPreview() { - GetCurrentTZ(); - - f_ZoneStr.GetParent(&f_RegionStr); -} - - -void -TZoneView::NewTimeZone() -{ - BString text; + // calc and display time based on users selection in city list int32 selection = f_citylist->CurrentSelection(); - text = ((TZoneItem *)f_citylist->ItemAt(selection))->Text(); - f_timeinzone->SetText(text.String()); - f_settimezone->SetEnabled(true); + if (selection>= 0) { + TZoneItem *item = (TZoneItem *)f_citylist->ItemAt(selection); + + BString text; + text = item->Text(); + + time_t current; + struct tm *ltime; + + // calc time to display and update + SetTimeZone(item->Path()); + current = time(0); + ltime = localtime(¤t); + SetTimeZone(f_currentzone.Path()); + + f_preview->SetTo(ltime->tm_hour, ltime->tm_min); + f_preview->SetText(text.String()); + + f_setzone->SetEnabled((strcmp(f_current->Text(), text.String()) != 0)); + } +} + + +void +TZoneView::SetCurrent(const char *text) +{ + time_t current; + struct tm *ltime; + SetTimeZone(f_currentzone.Path()); + current = time(0); + ltime = localtime(¤t); + + f_current->SetTo(ltime->tm_hour, ltime->tm_min); + f_current->SetText(text); } @@ -355,36 +462,86 @@ TZoneView::SetTimeZone() { /* set time based on supplied timezone. How to do this? - replace symlink, "timezone", in B_USER_SETTINGS_DIR with a link to the new timezone + 1) replace symlink, "timezone", in B_USER_SETTINGS_DIR with a link to the new timezone + 2) set TZ environment var + 3) call settz() + 4) call set_timezone from OS.h passing path to timezone file */ + + // update/create timezone symlink in B_USER_SETTINGS_DIRECTORY + // get path to current link BPath path; if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) return; path.Append("timezone"); - - // build target from selection - BPath target; - target.SetTo(f_RegionStr.Path()); + + + // build target for new link int32 selection = f_citylist->CurrentSelection(); - target.Append(((TZoneItem *)f_citylist->ItemAt(selection))->GetZone()); + if (selection < 0) + // nothing selected?? + return; - // create dir object to create link and remove old - BDirectory dir(target.Path()); + BPath target( ((TZoneItem *)f_citylist->ItemAt(selection))->Path()); + + // remove old BEntry entry(path.Path()); if (entry.Exists()) entry.Remove(); - - if (dir.CreateSymLink(path.Path(), target.Path(), NULL) != B_OK) - printf("timezone not linked\n"); - - // disable button - f_settimezone -> SetEnabled(false); - /* - Still doesn't change runtime timezone setting. - */ -} + // create new + BDirectory dir(target.Path()); + if (dir.CreateSymLink(path.Path(), target.Path(), NULL) != B_OK) + printf("timezone not linked\n"); + + // update environment + + char tz[B_PATH_NAME_LENGTH]; + sprintf(tz, "TZ=%s", target.Path()); + + putenv( tz); + tzset(); + + // update display + time_t current = time(0); + struct tm *ltime = localtime(¤t); + + + char tza[B_PATH_NAME_LENGTH]; + sprintf(tza, "%s", target.Path()); + set_timezone(tza); + + // disable button + f_setzone -> SetEnabled(false); + + time_t newtime = mktime(ltime); + ltime = localtime(&newtime); + stime(&newtime); + + f_hour = ltime->tm_hour; + f_minute = ltime->tm_min; + f_currentzone.SetTo(target.Path()); + SetCurrent(((TZoneItem *)f_citylist->ItemAt(selection))->Text()); +} + + + + + +void +TZoneView::SetTimeZone(const char *zone) +{ + BString tz; + + tz << "TZ=" << zone; + + putenv(tz.String()); + tzset(); +} + + +//---// diff --git a/src/prefs/time/ZoneView.h b/src/prefs/time/ZoneView.h index efc25b1458..2949f6cc02 100644 --- a/src/prefs/time/ZoneView.h +++ b/src/prefs/time/ZoneView.h @@ -1,61 +1,69 @@ /* - - TZoneView.h + ZoneView.h + Header file for the base class of the Time Zone tab in Time Pref App. */ #ifndef ZONE_VIEW_H #define ZONE_VIEW_H -#include -#include + #include +#include +#include #include "TZDisplay.h" class TZoneItem: public BStringItem { public: - TZoneItem(const char *text, const char *zonedata); + TZoneItem(const char *text, const char *zone); virtual ~TZoneItem(); - const char *GetZone() const; + const char *Zone() const; + const char *Path() const; + private: - BPath *f_zonedata; + BPath *f_zone; }; -class TZoneView : public BView { + + +class TZoneView: public BView{ public: TZoneView(BRect frame); - ~TZoneView(); + virtual ~TZoneView(); + virtual void AttachedToWindow(); - virtual void MessageReceived(BMessage *message); + virtual void AllAttached(); virtual void Draw(BRect); - - void ChangeRegion(BMessage *region); - void SetTimeZone(); - void NewTimeZone(); + virtual void MessageReceived(BMessage *message); protected: - virtual void UpdateDateTime(BMessage *message); + void UpdateDateTime(BMessage *message); + void ChangeRegion(BMessage *); + void SetTimeZone(); + void SetTimeZone(const char *zone); + void SetPreview(); + void SetCurrent(const char *text); private: - void InitView(); - void GetCurrentTZ(); - void GetCurrentRegion(); + virtual void InitView(); + void ReadTimeZoneLink(); + + // set widest to font width of longest item + void BuildRegionMenu(float *widest); - int FillZoneList(const char *area); - void CreateZoneMenu(float *widest); - - private: - BPopUpMenu *f_zonepopup; + // returns index of current zone + int FillCityList(const char *area); + + BPopUpMenu *f_regionpopup; BListView *f_citylist; - BButton *f_settimezone; - TTZDisplay *f_currentzone; - TTZDisplay *f_timeinzone; - private: - BPath f_ZoneStr; - BPath f_RegionStr; + BButton *f_setzone; + TTZDisplay *f_current; + TTZDisplay *f_preview; - int f_hour; - int f_minutes; - char f_TimeStr[10]; + BPath f_currentzone; + int32 f_hour; + int32 f_minute; + int32 f_diff; + bool f_first; }; -#endif +#endif //Zone_View_H