Move DateTimeEdit into libshared

BInvoker methods are now used, and input-handling is also tweaked.

Change-Id: I120cca8df9f11c11aac80911108d62fb49488f8f
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4927
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
Jaidyn Ann
2022-05-20 05:19:05 +00:00
committed by Jérôme Duval
parent f43b88e836
commit cc9bc8c6fb
8 changed files with 449 additions and 470 deletions
@@ -11,20 +11,78 @@
#ifndef _DATE_TIME_EDIT_H #ifndef _DATE_TIME_EDIT_H
#define _DATE_TIME_EDIT_H #define _DATE_TIME_EDIT_H
#include <Control.h>
#include <DateFormat.h> #include <DateFormat.h>
#include <DateTime.h> #include <DateTime.h>
#include <Locale.h> #include <Locale.h>
#include <String.h> #include <String.h>
#include <TimeFormat.h> #include <TimeFormat.h>
#include "SectionEdit.h" class BBitmap;
class BList;
class TTimeEdit : public TSectionEdit { namespace BPrivate {
class SectionEdit : public BControl {
public: public:
TTimeEdit(const char* name, uint32 sections); SectionEdit(const char* name,
virtual ~TTimeEdit(); uint32 sections, BMessage* message);
virtual ~SectionEdit();
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint point);
virtual void MakeFocus(bool focused = true);
virtual void KeyDown(const char* bytes, int32 numBytes);
BSize MaxSize();
BSize MinSize();
BSize PreferredSize();
uint32 CountSections() const;
int32 FocusIndex() const;
BRect SectionArea() const;
virtual status_t Invoke(BMessage* message = NULL);
protected:
virtual void DrawBorder(const BRect& updateRect);
virtual void DrawSection(uint32 index, BRect bounds,
bool isFocus) {}
virtual void DrawSeparator(uint32 index, BRect bounds) {}
BRect FrameForSection(uint32 index);
BRect FrameForSeparator(uint32 index);
virtual void SectionFocus(uint32 index) {}
virtual void SectionChange(uint32 index, uint32 value) {}
virtual void SetSections(BRect area) {}
virtual float SeparatorWidth() = 0;
virtual float MinSectionWidth() = 0;
virtual float PreferredHeight() = 0;
virtual void DoUpPress() {}
virtual void DoDownPress() {}
virtual void PopulateMessage(BMessage* message) = 0;
BRect fUpRect;
BRect fDownRect;
int32 fFocus;
uint32 fSectionCount;
uint32 fHoldValue;
};
class TimeEdit : public SectionEdit {
public:
TimeEdit(const char* name, uint32 sections,
BMessage* message);
virtual ~TimeEdit();
virtual void KeyDown(const char* bytes, int32 numBytes); virtual void KeyDown(const char* bytes, int32 numBytes);
@@ -41,9 +99,10 @@ public:
virtual void DoUpPress(); virtual void DoUpPress();
virtual void DoDownPress(); virtual void DoDownPress();
virtual void BuildDispatch(BMessage* message); virtual void PopulateMessage(BMessage* message);
void SetTime(int32 hour, int32 minute, int32 second); void SetTime(int32 hour, int32 minute, int32 second);
BTime GetTime();
private: private:
void _UpdateFields(); void _UpdateFields();
@@ -66,10 +125,11 @@ private:
}; };
class TDateEdit : public TSectionEdit { class DateEdit : public SectionEdit {
public: public:
TDateEdit(const char* name, uint32 sections); DateEdit(const char* name, uint32 sections,
virtual ~TDateEdit(); BMessage* message);
virtual ~DateEdit();
virtual void KeyDown(const char* bytes, int32 numBytes); virtual void KeyDown(const char* bytes, int32 numBytes);
virtual void InitView(); virtual void InitView();
@@ -85,10 +145,11 @@ public:
virtual void DoUpPress(); virtual void DoUpPress();
virtual void DoDownPress(); virtual void DoDownPress();
virtual void BuildDispatch(BMessage* message); virtual void PopulateMessage(BMessage* message);
void SetDate(int32 year, int32 month, int32 day); void SetDate(int32 year, int32 month, int32 day);
BDate GetDate();
private: private:
void _UpdateFields(); void _UpdateFields();
@@ -111,5 +172,7 @@ private:
}; };
#endif // _DATE_TIME_EDIT_H } // namespace BPrivate
#endif // _DATE_TIME_EDIT_H
@@ -16,19 +16,24 @@
#include <stdlib.h> #include <stdlib.h>
#include <ControlLook.h>
#include <DateFormat.h> #include <DateFormat.h>
#include <LayoutUtils.h>
#include <List.h> #include <List.h>
#include <Locale.h> #include <Locale.h>
#include <String.h> #include <String.h>
#include <Window.h> #include <Window.h>
using BPrivate::B_LOCAL_TIME; namespace BPrivate {
TTimeEdit::TTimeEdit(const char* name, uint32 sections) const uint32 kArrowAreaWidth = 16;
TimeEdit::TimeEdit(const char* name, uint32 sections, BMessage* message)
: :
TSectionEdit(name, sections), SectionEdit(name, sections, message),
fLastKeyDownTime(0), fLastKeyDownTime(0),
fFields(NULL), fFields(NULL),
fFieldCount(0), fFieldCount(0),
@@ -39,7 +44,7 @@ TTimeEdit::TTimeEdit(const char* name, uint32 sections)
} }
TTimeEdit::~TTimeEdit() TimeEdit::~TimeEdit()
{ {
free(fFieldPositions); free(fFieldPositions);
free(fFields); free(fFields);
@@ -47,18 +52,21 @@ TTimeEdit::~TTimeEdit()
void void
TTimeEdit::KeyDown(const char* bytes, int32 numBytes) TimeEdit::KeyDown(const char* bytes, int32 numBytes)
{ {
TSectionEdit::KeyDown(bytes, numBytes); if (IsEnabled() == false)
return;
SectionEdit::KeyDown(bytes, numBytes);
// only accept valid input // only accept valid input
int32 number = atoi(bytes); int32 number = atoi(bytes);
if (number - 1 < 0) if (number < 0 || bytes[0] < '0')
return; return;
int32 section = FocusIndex(); int32 section = FocusIndex();
if (section < 0 || section > 2) if (section < 0 || section > 2)
return; return;
bigtime_t currentTime = system_time(); bigtime_t currentTime = system_time();
if (currentTime - fLastKeyDownTime < 1000000) { if (currentTime - fLastKeyDownTime < 1000000) {
int32 doubleDigit = number + fLastKeyDownInt * 10; int32 doubleDigit = number + fLastKeyDownInt * 10;
@@ -72,16 +80,16 @@ TTimeEdit::KeyDown(const char* bytes, int32 numBytes)
// update display value // update display value
fHoldValue = number; fHoldValue = number;
_CheckRange(); _CheckRange();
_UpdateFields();
// send message to change time // send message to change time
DispatchMessage(); Invoke();
} }
void void
TTimeEdit::InitView() TimeEdit::InitView()
{ {
// make sure we call the base class method, as it // make sure we call the base class method, as it
// will create the arrow bitmaps and the section list // will create the arrow bitmaps and the section list
@@ -91,7 +99,7 @@ TTimeEdit::InitView()
void void
TTimeEdit::DrawSection(uint32 index, BRect bounds, bool hasFocus) TimeEdit::DrawSection(uint32 index, BRect bounds, bool hasFocus)
{ {
if (fFieldPositions == NULL || index * 2 + 1 >= (uint32)fFieldPosCount) if (fFieldPositions == NULL || index * 2 + 1 >= (uint32)fFieldPosCount)
return; return;
@@ -116,7 +124,7 @@ TTimeEdit::DrawSection(uint32 index, BRect bounds, bool hasFocus)
void void
TTimeEdit::DrawSeparator(uint32 index, BRect bounds) TimeEdit::DrawSeparator(uint32 index, BRect bounds)
{ {
if (fFieldPositions == NULL || index * 2 + 2 >= (uint32)fFieldPosCount) if (fFieldPositions == NULL || index * 2 + 2 >= (uint32)fFieldPosCount)
return; return;
@@ -134,21 +142,21 @@ TTimeEdit::DrawSeparator(uint32 index, BRect bounds)
float float
TTimeEdit::SeparatorWidth() TimeEdit::SeparatorWidth()
{ {
return 10.0f; return 10.0f;
} }
float float
TTimeEdit::MinSectionWidth() TimeEdit::MinSectionWidth()
{ {
return be_plain_font->StringWidth("00"); return be_plain_font->StringWidth("00");
} }
void void
TTimeEdit::SectionFocus(uint32 index) TimeEdit::SectionFocus(uint32 index)
{ {
fLastKeyDownTime = 0; fLastKeyDownTime = 0;
fFocus = index; fFocus = index;
@@ -158,7 +166,7 @@ TTimeEdit::SectionFocus(uint32 index)
void void
TTimeEdit::SetTime(int32 hour, int32 minute, int32 second) TimeEdit::SetTime(int32 hour, int32 minute, int32 second)
{ {
// make sure to update date upon overflow // make sure to update date upon overflow
if (hour == 0 && minute == 0 && second == 0) if (hour == 0 && minute == 0 && second == 0)
@@ -175,8 +183,15 @@ TTimeEdit::SetTime(int32 hour, int32 minute, int32 second)
} }
BTime
TimeEdit::GetTime()
{
return fTime.Time();
}
void void
TTimeEdit::DoUpPress() TimeEdit::DoUpPress()
{ {
if (fFocus == -1) if (fFocus == -1)
SectionFocus(0); SectionFocus(0);
@@ -185,14 +200,15 @@ TTimeEdit::DoUpPress()
fHoldValue += 1; fHoldValue += 1;
_CheckRange(); _CheckRange();
_UpdateFields();
// send message to change time // send message to change time
DispatchMessage(); Invoke();
} }
void void
TTimeEdit::DoDownPress() TimeEdit::DoDownPress()
{ {
if (fFocus == -1) if (fFocus == -1)
SectionFocus(0); SectionFocus(0);
@@ -201,49 +217,27 @@ TTimeEdit::DoDownPress()
fHoldValue -= 1; fHoldValue -= 1;
_CheckRange(); _CheckRange();
_UpdateFields();
// send message to change time Invoke();
DispatchMessage();
} }
void void
TTimeEdit::BuildDispatch(BMessage* message) TimeEdit::PopulateMessage(BMessage* message)
{ {
if (fFocus < 0 || fFocus >= fFieldCount) if (fFocus < 0 || fFocus >= fFieldCount)
return; return;
message->AddBool("time", true); message->AddBool("time", true);
message->AddInt32("hour", fTime.Time().Hour());
for (int32 index = 0; index < (int)fSectionCount; ++index) { message->AddInt32("minute", fTime.Time().Minute());
uint32 data = _SectionValue(index); message->AddInt32("second", fTime.Time().Second());
if (fFocus == index)
data = fHoldValue;
switch (fFields[index]) {
case B_DATE_ELEMENT_HOUR:
message->AddInt32("hour", data);
break;
case B_DATE_ELEMENT_MINUTE:
message->AddInt32("minute", data);
break;
case B_DATE_ELEMENT_SECOND:
message->AddInt32("second", data);
break;
default:
break;
}
}
} }
void void
TTimeEdit::_UpdateFields() TimeEdit::_UpdateFields()
{ {
time_t time = fTime.Time_t(); time_t time = fTime.Time_t();
@@ -263,7 +257,7 @@ TTimeEdit::_UpdateFields()
void void
TTimeEdit::_CheckRange() TimeEdit::_CheckRange()
{ {
if (fFocus < 0 || fFocus >= fFieldCount) if (fFocus < 0 || fFocus >= fFieldCount)
return; return;
@@ -318,13 +312,14 @@ TTimeEdit::_CheckRange()
return; return;
} }
fHoldValue = value; fHoldValue = value;
Invalidate(Bounds()); Invalidate(Bounds());
} }
bool bool
TTimeEdit::_IsValidDoubleDigit(int32 value) TimeEdit::_IsValidDoubleDigit(int32 value)
{ {
if (fFocus < 0 || fFocus >= fFieldCount) if (fFocus < 0 || fFocus >= fFieldCount)
return false; return false;
@@ -355,7 +350,7 @@ TTimeEdit::_IsValidDoubleDigit(int32 value)
int32 int32
TTimeEdit::_SectionValue(int32 index) const TimeEdit::_SectionValue(int32 index) const
{ {
if (index < 0 || index >= fFieldCount) if (index < 0 || index >= fFieldCount)
return 0; return 0;
@@ -384,7 +379,7 @@ TTimeEdit::_SectionValue(int32 index) const
float float
TTimeEdit::PreferredHeight() TimeEdit::PreferredHeight()
{ {
font_height fontHeight; font_height fontHeight;
GetFontHeight(&fontHeight); GetFontHeight(&fontHeight);
@@ -395,9 +390,9 @@ TTimeEdit::PreferredHeight()
// #pragma mark - // #pragma mark -
TDateEdit::TDateEdit(const char* name, uint32 sections) DateEdit::DateEdit(const char* name, uint32 sections, BMessage* message)
: :
TSectionEdit(name, sections), SectionEdit(name, sections, message),
fFields(NULL), fFields(NULL),
fFieldCount(0), fFieldCount(0),
fFieldPositions(NULL), fFieldPositions(NULL),
@@ -407,7 +402,7 @@ TDateEdit::TDateEdit(const char* name, uint32 sections)
} }
TDateEdit::~TDateEdit() DateEdit::~DateEdit()
{ {
free(fFieldPositions); free(fFieldPositions);
free(fFields); free(fFields);
@@ -415,13 +410,15 @@ TDateEdit::~TDateEdit()
void void
TDateEdit::KeyDown(const char* bytes, int32 numBytes) DateEdit::KeyDown(const char* bytes, int32 numBytes)
{ {
TSectionEdit::KeyDown(bytes, numBytes); if (IsEnabled() == false)
return;
SectionEdit::KeyDown(bytes, numBytes);
// only accept valid input // only accept valid input
int32 number = atoi(bytes); int32 number = atoi(bytes);
if (number - 1 < 0) if (number < 0 || bytes[0] < '0')
return; return;
int32 section = FocusIndex(); int32 section = FocusIndex();
@@ -447,19 +444,19 @@ TDateEdit::KeyDown(const char* bytes, int32 numBytes)
number += 70; number += 70;
number += oldCentury; number += oldCentury;
} }
// update display value
fHoldValue = number; fHoldValue = number;
// update display value
_CheckRange(); _CheckRange();
_UpdateFields();
// send message to change time // send message to change time
DispatchMessage(); Invoke();
} }
void void
TDateEdit::InitView() DateEdit::InitView()
{ {
// make sure we call the base class method, as it // make sure we call the base class method, as it
// will create the arrow bitmaps and the section list // will create the arrow bitmaps and the section list
@@ -469,7 +466,7 @@ TDateEdit::InitView()
void void
TDateEdit::DrawSection(uint32 index, BRect bounds, bool hasFocus) DateEdit::DrawSection(uint32 index, BRect bounds, bool hasFocus)
{ {
if (fFieldPositions == NULL || index * 2 + 1 >= (uint32)fFieldPosCount) if (fFieldPositions == NULL || index * 2 + 1 >= (uint32)fFieldPosCount)
return; return;
@@ -494,7 +491,7 @@ TDateEdit::DrawSection(uint32 index, BRect bounds, bool hasFocus)
void void
TDateEdit::DrawSeparator(uint32 index, BRect bounds) DateEdit::DrawSeparator(uint32 index, BRect bounds)
{ {
if (index >= 2) if (index >= 2)
return; return;
@@ -515,7 +512,7 @@ TDateEdit::DrawSeparator(uint32 index, BRect bounds)
void void
TDateEdit::SectionFocus(uint32 index) DateEdit::SectionFocus(uint32 index)
{ {
fLastKeyDownTime = 0; fLastKeyDownTime = 0;
fFocus = index; fFocus = index;
@@ -525,21 +522,21 @@ TDateEdit::SectionFocus(uint32 index)
float float
TDateEdit::MinSectionWidth() DateEdit::MinSectionWidth()
{ {
return be_plain_font->StringWidth("00"); return be_plain_font->StringWidth("00");
} }
float float
TDateEdit::SeparatorWidth() DateEdit::SeparatorWidth()
{ {
return 10.0f; return 10.0f;
} }
void void
TDateEdit::SetDate(int32 year, int32 month, int32 day) DateEdit::SetDate(int32 year, int32 month, int32 day)
{ {
fDate.SetDate(year, month, day); fDate.SetDate(year, month, day);
@@ -552,8 +549,15 @@ TDateEdit::SetDate(int32 year, int32 month, int32 day)
} }
BDate
DateEdit::GetDate()
{
return fDate;
}
void void
TDateEdit::DoUpPress() DateEdit::DoUpPress()
{ {
if (fFocus == -1) if (fFocus == -1)
SectionFocus(0); SectionFocus(0);
@@ -562,14 +566,15 @@ TDateEdit::DoUpPress()
fHoldValue += 1; fHoldValue += 1;
_CheckRange(); _CheckRange();
_UpdateFields();
// send message to change Date // send message to change Date
DispatchMessage(); Invoke();
} }
void void
TDateEdit::DoDownPress() DateEdit::DoDownPress()
{ {
if (fFocus == -1) if (fFocus == -1)
SectionFocus(0); SectionFocus(0);
@@ -578,48 +583,28 @@ TDateEdit::DoDownPress()
fHoldValue -= 1; fHoldValue -= 1;
_CheckRange(); _CheckRange();
_UpdateFields();
// send message to change Date // send message to change Date
DispatchMessage(); Invoke();
} }
void void
TDateEdit::BuildDispatch(BMessage* message) DateEdit::PopulateMessage(BMessage* message)
{ {
if (fFocus < 0 || fFocus >= fFieldCount) if (fFocus < 0 || fFocus >= fFieldCount)
return; return;
message->AddBool("time", false); message->AddBool("time", false);
message->AddInt32("year", fDate.Year());
for (int32 index = 0; index < (int)fSectionCount; ++index) { message->AddInt32("month", fDate.Month());
uint32 data = _SectionValue(index); message->AddInt32("day", fDate.Day());
if (fFocus == index)
data = fHoldValue;
switch (fFields[index]) {
case B_DATE_ELEMENT_MONTH:
message->AddInt32("month", data);
break;
case B_DATE_ELEMENT_DAY:
message->AddInt32("day", data);
break;
case B_DATE_ELEMENT_YEAR:
message->AddInt32("year", data);
break;
default:
break;
}
}
} }
void void
TDateEdit::_UpdateFields() DateEdit::_UpdateFields()
{ {
time_t time = BDateTime(fDate, BTime()).Time_t(); time_t time = BDateTime(fDate, BTime()).Time_t();
@@ -640,7 +625,7 @@ TDateEdit::_UpdateFields()
void void
TDateEdit::_CheckRange() DateEdit::_CheckRange()
{ {
if (fFocus < 0 || fFocus >= fFieldCount) if (fFocus < 0 || fFocus >= fFieldCount)
return; return;
@@ -660,13 +645,21 @@ TDateEdit::_CheckRange()
} }
case B_DATE_ELEMENT_MONTH: case B_DATE_ELEMENT_MONTH:
{
if (value > 12) if (value > 12)
value = 1; value = 1;
else if (value < 1) else if (value < 1)
value = 12; value = 12;
fDate.SetDate(fDate.Year(), value, fDate.Day()); int32 day = fDate.Day();
fDate.SetDate(fDate.Year(), value, 1);
// changing between months with differing amounts of days
while (day > fDate.DaysInMonth())
day--;
fDate.SetDate(fDate.Year(), value, day);
break; break;
}
case B_DATE_ELEMENT_YEAR: case B_DATE_ELEMENT_YEAR:
fDate.SetDate(value, fDate.Month(), fDate.Day()); fDate.SetDate(value, fDate.Month(), fDate.Day());
@@ -677,12 +670,12 @@ TDateEdit::_CheckRange()
} }
fHoldValue = value; fHoldValue = value;
Draw(Bounds()); Invalidate(Bounds());
} }
bool bool
TDateEdit::_IsValidDoubleDigit(int32 value) DateEdit::_IsValidDoubleDigit(int32 value)
{ {
if (fFocus < 0 || fFocus >= fFieldCount) if (fFocus < 0 || fFocus >= fFieldCount)
return false; return false;
@@ -721,7 +714,7 @@ TDateEdit::_IsValidDoubleDigit(int32 value)
int32 int32
TDateEdit::_SectionValue(int32 index) const DateEdit::_SectionValue(int32 index) const
{ {
if (index < 0 || index >= fFieldCount) if (index < 0 || index >= fFieldCount)
return 0; return 0;
@@ -749,10 +742,273 @@ TDateEdit::_SectionValue(int32 index) const
float float
TDateEdit::PreferredHeight() DateEdit::PreferredHeight()
{ {
font_height fontHeight; font_height fontHeight;
GetFontHeight(&fontHeight); GetFontHeight(&fontHeight);
return ceilf((fontHeight.ascent + fontHeight.descent) * 1.4); return ceilf((fontHeight.ascent + fontHeight.descent) * 1.4);
} }
// #pragma mark -
SectionEdit::SectionEdit(const char* name, uint32 sections, BMessage* message)
:
BControl(name, NULL, message, B_WILL_DRAW | B_NAVIGABLE),
fFocus(-1),
fSectionCount(sections),
fHoldValue(0)
{
}
SectionEdit::~SectionEdit()
{
}
void
SectionEdit::AttachedToWindow()
{
AdoptParentColors();
BControl::AttachedToWindow();
}
void
SectionEdit::Draw(BRect updateRect)
{
DrawBorder(updateRect);
for (uint32 idx = 0; idx < fSectionCount; idx++) {
DrawSection(idx, FrameForSection(idx),
((uint32)fFocus == idx) && IsFocus());
if (idx < fSectionCount - 1)
DrawSeparator(idx, FrameForSeparator(idx));
}
}
void
SectionEdit::MouseDown(BPoint where)
{
if (IsEnabled() == false)
return;
MakeFocus(true);
if (fUpRect.Contains(where))
DoUpPress();
else if (fDownRect.Contains(where))
DoDownPress();
else if (fSectionCount > 0) {
for (uint32 idx = 0; idx < fSectionCount; idx++) {
if (FrameForSection(idx).Contains(where)) {
SectionFocus(idx);
return;
}
}
}
}
BSize
SectionEdit::MaxSize()
{
return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
BSize(B_SIZE_UNLIMITED, PreferredHeight()));
}
BSize
SectionEdit::MinSize()
{
BSize minSize;
minSize.height = PreferredHeight();
minSize.width = (SeparatorWidth() + MinSectionWidth())
* fSectionCount;
return BLayoutUtils::ComposeSize(ExplicitMinSize(),
minSize);
}
BSize
SectionEdit::PreferredSize()
{
return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
MinSize());
}
BRect
SectionEdit::FrameForSection(uint32 index)
{
BRect area = SectionArea();
float sepWidth = SeparatorWidth();
float width = (area.Width() -
sepWidth * (fSectionCount - 1))
/ fSectionCount;
area.left += index * (width + sepWidth);
area.right = area.left + width;
return area;
}
BRect
SectionEdit::FrameForSeparator(uint32 index)
{
BRect area = SectionArea();
float sepWidth = SeparatorWidth();
float width = (area.Width() -
sepWidth * (fSectionCount - 1))
/ fSectionCount;
area.left += (index + 1) * width + index * sepWidth;
area.right = area.left + sepWidth;
return area;
}
void
SectionEdit::MakeFocus(bool focused)
{
if (focused == IsFocus())
return;
BControl::MakeFocus(focused);
if (fFocus == -1)
SectionFocus(0);
else
SectionFocus(fFocus);
}
void
SectionEdit::KeyDown(const char* bytes, int32 numbytes)
{
if (IsEnabled() == false)
return;
if (fFocus == -1)
SectionFocus(0);
switch (bytes[0]) {
case B_LEFT_ARROW:
fFocus -= 1;
if (fFocus < 0)
fFocus = fSectionCount - 1;
SectionFocus(fFocus);
break;
case B_RIGHT_ARROW:
fFocus += 1;
if ((uint32)fFocus >= fSectionCount)
fFocus = 0;
SectionFocus(fFocus);
break;
case B_UP_ARROW:
DoUpPress();
break;
case B_DOWN_ARROW:
DoDownPress();
break;
default:
BControl::KeyDown(bytes, numbytes);
break;
}
Draw(Bounds());
}
status_t
SectionEdit::Invoke(BMessage* message)
{
if (message == NULL)
message = Message();
if (message == NULL)
return BControl::Invoke(NULL);
BMessage clone(*message);
PopulateMessage(&clone);
return BControl::Invoke(&clone);
}
uint32
SectionEdit::CountSections() const
{
return fSectionCount;
}
int32
SectionEdit::FocusIndex() const
{
return fFocus;
}
BRect
SectionEdit::SectionArea() const
{
BRect sectionArea = Bounds().InsetByCopy(2, 2);
sectionArea.right -= kArrowAreaWidth;
return sectionArea;
}
void
SectionEdit::DrawBorder(const BRect& updateRect)
{
BRect bounds(Bounds());
bool showFocus = (IsFocus() && Window() && Window()->IsActive());
be_control_look->DrawBorder(this, bounds, updateRect, ViewColor(),
B_FANCY_BORDER, showFocus ? BControlLook::B_FOCUSED : 0);
// draw up/down control
bounds.left = bounds.right - kArrowAreaWidth;
bounds.right = Bounds().right - 2;
fUpRect.Set(bounds.left + 3, bounds.top + 2, bounds.right,
bounds.bottom / 2.0);
fDownRect = fUpRect.OffsetByCopy(0, fUpRect.Height() + 2);
BPoint middle(floorf(fUpRect.left + fUpRect.Width() / 2),
fUpRect.top + 1);
BPoint left(fUpRect.left + 3, fUpRect.bottom - 1);
BPoint right(left.x + 2 * (middle.x - left.x), fUpRect.bottom - 1);
SetPenSize(2);
SetLowColor(ViewColor());
if (updateRect.Intersects(fUpRect)) {
FillRect(fUpRect, B_SOLID_LOW);
BeginLineArray(2);
AddLine(left, middle, HighColor());
AddLine(middle, right, HighColor());
EndLineArray();
}
if (updateRect.Intersects(fDownRect)) {
middle.y = fDownRect.bottom - 1;
left.y = right.y = fDownRect.top + 1;
FillRect(fDownRect, B_SOLID_LOW);
BeginLineArray(2);
AddLine(left, middle, HighColor());
AddLine(middle, right, HighColor());
EndLineArray();
}
SetPenSize(1);
}
} // namespace BPrivate
+1
View File
@@ -36,6 +36,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
CalendarView.cpp CalendarView.cpp
ColorQuantizer.cpp ColorQuantizer.cpp
CommandPipe.cpp CommandPipe.cpp
DateTimeEdit.cpp
DragTrackingFilter.cpp DragTrackingFilter.cpp
DriverSettingsMessageAdapter.cpp DriverSettingsMessageAdapter.cpp
HashString.cpp HashString.cpp
+5 -3
View File
@@ -21,6 +21,7 @@
#include <CheckBox.h> #include <CheckBox.h>
#include <ControlLook.h> #include <ControlLook.h>
#include <DateTime.h> #include <DateTime.h>
#include <DateTimeEdit.h>
#include <Entry.h> #include <Entry.h>
#include <File.h> #include <File.h>
#include <FindDirectory.h> #include <FindDirectory.h>
@@ -31,7 +32,6 @@
#include <Window.h> #include <Window.h>
#include "AnalogClock.h" #include "AnalogClock.h"
#include "DateTimeEdit.h"
#include "TimeMessages.h" #include "TimeMessages.h"
#include "TimeWindow.h" #include "TimeWindow.h"
@@ -43,6 +43,8 @@
using BPrivate::BCalendarView; using BPrivate::BCalendarView;
using BPrivate::BDateTime; using BPrivate::BDateTime;
using BPrivate::B_LOCAL_TIME; using BPrivate::B_LOCAL_TIME;
using BPrivate::DateEdit;
using BPrivate::TimeEdit;
DateTimeView::DateTimeView(const char* name) DateTimeView::DateTimeView(const char* name)
@@ -178,8 +180,8 @@ DateTimeView::_InitView()
fCalendarView->SetSelectionMessage(new BMessage(kDayChanged)); fCalendarView->SetSelectionMessage(new BMessage(kDayChanged));
fCalendarView->SetInvocationMessage(new BMessage(kDayChanged)); fCalendarView->SetInvocationMessage(new BMessage(kDayChanged));
fDateEdit = new TDateEdit("dateEdit", 3); fDateEdit = new DateEdit("dateEdit", 3, new BMessage(H_USER_CHANGE));
fTimeEdit = new TTimeEdit("timeEdit", 5); fTimeEdit = new TimeEdit("timeEdit", 5, new BMessage(H_USER_CHANGE));
fClock = new TAnalogClock("analogClock"); fClock = new TAnalogClock("analogClock");
BTime time(BTime::CurrentTime(B_LOCAL_TIME)); BTime time(BTime::CurrentTime(B_LOCAL_TIME));
+6 -4
View File
@@ -16,15 +16,17 @@
#include <LayoutBuilder.h> #include <LayoutBuilder.h>
class TDateEdit;
class TTimeEdit;
class TAnalogClock; class TAnalogClock;
namespace BPrivate { namespace BPrivate {
class BCalendarView; class BCalendarView;
class DateEdit;
class TimeEdit;
} }
using BPrivate::BCalendarView; using BPrivate::BCalendarView;
using BPrivate::DateEdit;
using BPrivate::TimeEdit;
class DateTimeView : public BGroupView { class DateTimeView : public BGroupView {
@@ -43,8 +45,8 @@ private:
void _Revert(); void _Revert();
time_t _PrefletUptime() const; time_t _PrefletUptime() const;
TDateEdit* fDateEdit; DateEdit* fDateEdit;
TTimeEdit* fTimeEdit; TimeEdit* fTimeEdit;
BCalendarView* fCalendarView; BCalendarView* fCalendarView;
TAnalogClock* fClock; TAnalogClock* fClock;
-2
View File
@@ -8,8 +8,6 @@ local sources =
AnalogClock.cpp AnalogClock.cpp
BaseView.cpp BaseView.cpp
ClockView.cpp ClockView.cpp
DateTimeEdit.cpp
SectionEdit.cpp
DateTimeView.cpp DateTimeView.cpp
NetworkTimeView.cpp NetworkTimeView.cpp
ntp.cpp ntp.cpp
-270
View File
@@ -1,270 +0,0 @@
/*
* Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mike Berg <[email protected]>
* Julun <[email protected]>
* Hamish Morrison <[email protected]>
*/
#include "SectionEdit.h"
#include <Bitmap.h>
#include <ControlLook.h>
#include <LayoutUtils.h>
#include <List.h>
#include <Window.h>
#include "TimeMessages.h"
const uint32 kArrowAreaWidth = 16;
TSectionEdit::TSectionEdit(const char* name, uint32 sections)
:
BControl(name, NULL, NULL, B_WILL_DRAW | B_NAVIGABLE),
fFocus(-1),
fSectionCount(sections),
fHoldValue(0)
{
}
TSectionEdit::~TSectionEdit()
{
}
void
TSectionEdit::AttachedToWindow()
{
AdoptParentColors();
}
void
TSectionEdit::Draw(BRect updateRect)
{
DrawBorder(updateRect);
for (uint32 idx = 0; idx < fSectionCount; idx++) {
DrawSection(idx, FrameForSection(idx),
((uint32)fFocus == idx) && IsFocus());
if (idx < fSectionCount - 1)
DrawSeparator(idx, FrameForSeparator(idx));
}
}
void
TSectionEdit::MouseDown(BPoint where)
{
MakeFocus(true);
if (fUpRect.Contains(where))
DoUpPress();
else if (fDownRect.Contains(where))
DoDownPress();
else if (fSectionCount > 0) {
for (uint32 idx = 0; idx < fSectionCount; idx++) {
if (FrameForSection(idx).Contains(where)) {
SectionFocus(idx);
return;
}
}
}
}
BSize
TSectionEdit::MaxSize()
{
return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
BSize(B_SIZE_UNLIMITED, PreferredHeight()));
}
BSize
TSectionEdit::MinSize()
{
BSize minSize;
minSize.height = PreferredHeight();
minSize.width = (SeparatorWidth() + MinSectionWidth())
* fSectionCount;
return BLayoutUtils::ComposeSize(ExplicitMinSize(),
minSize);
}
BSize
TSectionEdit::PreferredSize()
{
return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
MinSize());
}
BRect
TSectionEdit::FrameForSection(uint32 index)
{
BRect area = SectionArea();
float sepWidth = SeparatorWidth();
float width = (area.Width() -
sepWidth * (fSectionCount - 1))
/ fSectionCount;
area.left += index * (width + sepWidth);
area.right = area.left + width;
return area;
}
BRect
TSectionEdit::FrameForSeparator(uint32 index)
{
BRect area = SectionArea();
float sepWidth = SeparatorWidth();
float width = (area.Width() -
sepWidth * (fSectionCount - 1))
/ fSectionCount;
area.left += (index + 1) * width + index * sepWidth;
area.right = area.left + sepWidth;
return area;
}
void
TSectionEdit::MakeFocus(bool focused)
{
if (focused == IsFocus())
return;
BControl::MakeFocus(focused);
if (fFocus == -1)
SectionFocus(0);
else
SectionFocus(fFocus);
}
void
TSectionEdit::KeyDown(const char* bytes, int32 numbytes)
{
if (fFocus == -1)
SectionFocus(0);
switch (bytes[0]) {
case B_LEFT_ARROW:
fFocus -= 1;
if (fFocus < 0)
fFocus = fSectionCount - 1;
SectionFocus(fFocus);
break;
case B_RIGHT_ARROW:
fFocus += 1;
if ((uint32)fFocus >= fSectionCount)
fFocus = 0;
SectionFocus(fFocus);
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 message(H_USER_CHANGE);
BuildDispatch(&message);
Window()->PostMessage(&message);
}
uint32
TSectionEdit::CountSections() const
{
return fSectionCount;
}
int32
TSectionEdit::FocusIndex() const
{
return fFocus;
}
BRect
TSectionEdit::SectionArea() const
{
BRect sectionArea = Bounds().InsetByCopy(2, 2);
sectionArea.right -= kArrowAreaWidth;
return sectionArea;
}
void
TSectionEdit::DrawBorder(const BRect& updateRect)
{
BRect bounds(Bounds());
bool showFocus = (IsFocus() && Window() && Window()->IsActive());
be_control_look->DrawBorder(this, bounds, updateRect, ViewColor(),
B_FANCY_BORDER, showFocus ? BControlLook::B_FOCUSED : 0);
// draw up/down control
bounds.left = bounds.right - kArrowAreaWidth;
bounds.right = Bounds().right - 2;
fUpRect.Set(bounds.left + 3, bounds.top + 2, bounds.right,
bounds.bottom / 2.0);
fDownRect = fUpRect.OffsetByCopy(0, fUpRect.Height() + 2);
BPoint middle(floorf(fUpRect.left + fUpRect.Width() / 2),
fUpRect.top + 1);
BPoint left(fUpRect.left + 3, fUpRect.bottom - 1);
BPoint right(left.x + 2 * (middle.x - left.x), fUpRect.bottom - 1);
SetPenSize(2);
SetLowColor(ViewColor());
if (updateRect.Intersects(fUpRect)) {
FillRect(fUpRect, B_SOLID_LOW);
BeginLineArray(2);
AddLine(left, middle, HighColor());
AddLine(middle, right, HighColor());
EndLineArray();
}
if (updateRect.Intersects(fDownRect)) {
middle.y = fDownRect.bottom - 1;
left.y = right.y = fDownRect.top + 1;
FillRect(fDownRect, B_SOLID_LOW);
BeginLineArray(2);
AddLine(left, middle, HighColor());
AddLine(middle, right, HighColor());
EndLineArray();
}
SetPenSize(1);
}
-73
View File
@@ -1,73 +0,0 @@
/*
* Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mike Berg <[email protected]>
* Julun <[email protected]>
* Hamish Morrison <[email protected]>
*/
#ifndef _SECTION_EDIT_H
#define _SECTION_EDIT_H
#include <Control.h>
class BBitmap;
class BList;
class TSectionEdit : public BControl {
public:
TSectionEdit(const char* name,
uint32 sections);
virtual ~TSectionEdit();
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint point);
virtual void MakeFocus(bool focused = true);
virtual void KeyDown(const char* bytes, int32 numBytes);
BSize MaxSize();
BSize MinSize();
BSize PreferredSize();
uint32 CountSections() const;
int32 FocusIndex() const;
BRect SectionArea() const;
protected:
virtual void DrawBorder(const BRect& updateRect);
virtual void DrawSection(uint32 index, BRect bounds,
bool isFocus) {}
virtual void DrawSeparator(uint32 index, BRect bounds) {}
BRect FrameForSection(uint32 index);
BRect FrameForSeparator(uint32 index);
virtual void SectionFocus(uint32 index) {}
virtual void SectionChange(uint32 index, uint32 value) {}
virtual void SetSections(BRect area) {}
virtual float SeparatorWidth() = 0;
virtual float MinSectionWidth() = 0;
virtual float PreferredHeight() = 0;
virtual void DoUpPress() {}
virtual void DoDownPress() {}
virtual void DispatchMessage();
virtual void BuildDispatch(BMessage* message) = 0;
BRect fUpRect;
BRect fDownRect;
int32 fFocus;
uint32 fSectionCount;
uint32 fHoldValue;
};
#endif // _SECTION_EDIT_H