patch by Clemens Zeidler:
* Support dragging the clock hour and minute hands to set the time. * Improved keyboard support for the time and date controls. Thanks a lot! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28713 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e11c40c4e2
commit
3e58fe9e70
@ -6,14 +6,20 @@
|
|||||||
* Mike Berg <mike@berg-net.us>
|
* Mike Berg <mike@berg-net.us>
|
||||||
* Julun <host.haiku@gmx.de>
|
* Julun <host.haiku@gmx.de>
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Clemens <mail@Clemens-Zeidler.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AnalogClock.h"
|
#include "AnalogClock.h"
|
||||||
#include "TimeMessages.h"
|
#include "TimeMessages.h"
|
||||||
|
|
||||||
|
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define DRAG_DELTA_PHI 0.2
|
||||||
|
|
||||||
|
|
||||||
class OffscreenClock : public BView {
|
class OffscreenClock : public BView {
|
||||||
@ -22,17 +28,44 @@ class OffscreenClock : public BView {
|
|||||||
~OffscreenClock();
|
~OffscreenClock();
|
||||||
|
|
||||||
void SetTime(int32 hour, int32 minute, int32 second);
|
void SetTime(int32 hour, int32 minute, int32 second);
|
||||||
|
void GetTime(int32 *hour, int32 *minute, int32 *second);
|
||||||
bool IsDirty() const { return fDirty; }
|
bool IsDirty() const { return fDirty; }
|
||||||
void DrawClock();
|
void DrawClock();
|
||||||
|
|
||||||
|
bool InHourHand(BPoint point);
|
||||||
|
bool InMinuteHand(BPoint point);
|
||||||
|
|
||||||
|
void SetHourHand(BPoint point);
|
||||||
|
void SetMinuteHand(BPoint point);
|
||||||
|
|
||||||
|
void SetHourDragging(bool val) {
|
||||||
|
fHourDragging = val;
|
||||||
|
fDirty = true;
|
||||||
|
}
|
||||||
|
void SetMinuteDragging(bool val) {
|
||||||
|
fMinuteDragging = val;
|
||||||
|
fDirty = true;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
|
float _GetPhi(BPoint point);
|
||||||
|
bool _InHand(BPoint point, int32 ticks, float radius);
|
||||||
void _DrawHands(float x, float y, float radius,
|
void _DrawHands(float x, float y, float radius,
|
||||||
rgb_color hourMinuteColor, rgb_color secondsColor);
|
rgb_color hourHourColor,
|
||||||
|
rgb_color hourMinuteColor,
|
||||||
|
rgb_color secondsColor,
|
||||||
|
rgb_color knobColor);
|
||||||
|
|
||||||
int32 fHours;
|
int32 fHours;
|
||||||
int32 fMinutes;
|
int32 fMinutes;
|
||||||
int32 fSeconds;
|
int32 fSeconds;
|
||||||
bool fDirty;
|
bool fDirty;
|
||||||
|
|
||||||
|
float fCenterX;
|
||||||
|
float fCenterY;
|
||||||
|
float fRadius;
|
||||||
|
|
||||||
|
bool fHourDragging;
|
||||||
|
bool fMinuteDragging;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -41,9 +74,20 @@ OffscreenClock::OffscreenClock(BRect frame, const char *name)
|
|||||||
fHours(0),
|
fHours(0),
|
||||||
fMinutes(0),
|
fMinutes(0),
|
||||||
fSeconds(0),
|
fSeconds(0),
|
||||||
fDirty(true)
|
fDirty(true),
|
||||||
|
fHourDragging(false),
|
||||||
|
fMinuteDragging(false)
|
||||||
{
|
{
|
||||||
SetFlags(Flags() | B_SUBPIXEL_PRECISE);
|
SetFlags(Flags() | B_SUBPIXEL_PRECISE);
|
||||||
|
|
||||||
|
BRect bounds = Bounds();
|
||||||
|
fCenterX = floorf((bounds.left + bounds.right) / 2 + 0.5) + 0.5;
|
||||||
|
fCenterY = floorf((bounds.top + bounds.bottom) / 2 + 0.5) + 0.5;
|
||||||
|
// + 0.5 is for the offset to pixel centers
|
||||||
|
// (important when drawing with B_SUBPIXEL_PRECISE)
|
||||||
|
|
||||||
|
fRadius = floorf((MIN(bounds.Width(), bounds.Height()) / 2.0)) - 2.5;
|
||||||
|
fRadius -= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -66,6 +110,15 @@ OffscreenClock::SetTime(int32 hour, int32 minute, int32 second)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
OffscreenClock::GetTime(int32 *hour, int32 *minute, int32 *second)
|
||||||
|
{
|
||||||
|
*hour = fHours;
|
||||||
|
*minute = fMinutes;
|
||||||
|
*second = fSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
OffscreenClock::DrawClock()
|
OffscreenClock::DrawClock()
|
||||||
{
|
{
|
||||||
@ -78,13 +131,9 @@ OffscreenClock::DrawClock()
|
|||||||
SetHighColor(background);
|
SetHighColor(background);
|
||||||
FillRect(bounds);
|
FillRect(bounds);
|
||||||
|
|
||||||
float radius = floorf((MIN(bounds.Width(), bounds.Height()) / 2.0)) - 2.5;
|
|
||||||
float x = floorf((bounds.left + bounds.right) / 2 + 0.5) + 0.5;
|
bounds.Set(fCenterX - fRadius, fCenterY - fRadius,
|
||||||
float y = floorf((bounds.top + bounds.bottom) / 2 + 0.5) + 0.5;
|
fCenterX + fRadius, fCenterY + fRadius);
|
||||||
// + 0.5 is for the offset to pixel centers
|
|
||||||
// (important when drawing with B_SUBPIXEL_PRECISE)
|
|
||||||
|
|
||||||
bounds.Set(x - radius, y - radius, x + radius, y + radius);
|
|
||||||
|
|
||||||
SetPenSize(2.0);
|
SetPenSize(2.0);
|
||||||
|
|
||||||
@ -99,8 +148,7 @@ OffscreenClock::DrawClock()
|
|||||||
|
|
||||||
SetLowColor(255, 255, 255);
|
SetLowColor(255, 255, 255);
|
||||||
FillEllipse(bounds, B_SOLID_LOW);
|
FillEllipse(bounds, B_SOLID_LOW);
|
||||||
radius -= 3;
|
|
||||||
|
|
||||||
SetHighColor(tint_color(HighColor(), B_DARKEN_2_TINT));
|
SetHighColor(tint_color(HighColor(), B_DARKEN_2_TINT));
|
||||||
|
|
||||||
// minutes
|
// minutes
|
||||||
@ -109,10 +157,10 @@ OffscreenClock::DrawClock()
|
|||||||
for (int32 minute = 1; minute < 60; minute++) {
|
for (int32 minute = 1; minute < 60; minute++) {
|
||||||
if (minute % 5 == 0)
|
if (minute % 5 == 0)
|
||||||
continue;
|
continue;
|
||||||
float x1 = x + sinf(minute * PI / 30.0) * radius;
|
float x1 = fCenterX + sinf(minute * PI / 30.0) * fRadius;
|
||||||
float y1 = y + cosf(minute * PI / 30.0) * radius;
|
float y1 = fCenterY + cosf(minute * PI / 30.0) * fRadius;
|
||||||
float x2 = x + sinf(minute * PI / 30.0) * (radius * 0.95);
|
float x2 = fCenterX + sinf(minute * PI / 30.0) * (fRadius * 0.95);
|
||||||
float y2 = y + cosf(minute * PI / 30.0) * (radius * 0.95);
|
float y2 = fCenterY + cosf(minute * PI / 30.0) * (fRadius * 0.95);
|
||||||
StrokeLine(BPoint(x1, y1), BPoint(x2, y2));
|
StrokeLine(BPoint(x1, y1), BPoint(x2, y2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,20 +170,32 @@ OffscreenClock::DrawClock()
|
|||||||
SetPenSize(2.0);
|
SetPenSize(2.0);
|
||||||
SetLineMode(B_ROUND_CAP, B_MITER_JOIN);
|
SetLineMode(B_ROUND_CAP, B_MITER_JOIN);
|
||||||
for (int32 hour = 0; hour < 12; hour++) {
|
for (int32 hour = 0; hour < 12; hour++) {
|
||||||
float x1 = x + sinf(hour * PI / 6.0) * radius;
|
float x1 = fCenterX + sinf(hour * PI / 6.0) * fRadius;
|
||||||
float y1 = y + cosf(hour * PI / 6.0) * radius;
|
float y1 = fCenterY + cosf(hour * PI / 6.0) * fRadius;
|
||||||
float x2 = x + sinf(hour * PI / 6.0) * (radius * 0.9);
|
float x2 = fCenterX + sinf(hour * PI / 6.0) * (fRadius * 0.9);
|
||||||
float y2 = y + cosf(hour * PI / 6.0) * (radius * 0.9);
|
float y2 = fCenterY + cosf(hour * PI / 6.0) * (fRadius * 0.9);
|
||||||
StrokeLine(BPoint(x1, y1), BPoint(x2, y2));
|
StrokeLine(BPoint(x1, y1), BPoint(x2, y2));
|
||||||
}
|
}
|
||||||
|
|
||||||
rgb_color hourMinutColor = tint_color(HighColor(), B_DARKEN_2_TINT);
|
rgb_color knobColor = tint_color(HighColor(), B_DARKEN_2_TINT);;
|
||||||
|
rgb_color hourColor;
|
||||||
|
if (fHourDragging)
|
||||||
|
hourColor = (rgb_color){ 0, 0, 255, 255 };
|
||||||
|
else
|
||||||
|
hourColor = tint_color(HighColor(), B_DARKEN_2_TINT);
|
||||||
|
rgb_color minuteColor;
|
||||||
|
if (fMinuteDragging)
|
||||||
|
minuteColor = (rgb_color){ 0, 0, 255, 255 };
|
||||||
|
else
|
||||||
|
minuteColor = tint_color(HighColor(), B_DARKEN_2_TINT);
|
||||||
rgb_color secondsColor = (rgb_color){ 255, 0, 0, 255 };
|
rgb_color secondsColor = (rgb_color){ 255, 0, 0, 255 };
|
||||||
rgb_color shadowColor = tint_color(LowColor(),
|
rgb_color shadowColor = tint_color(LowColor(),
|
||||||
(B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2);
|
(B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2);
|
||||||
|
|
||||||
_DrawHands(x + 1.5, y + 1.5, radius, shadowColor, shadowColor);
|
_DrawHands(fCenterX + 1.5, fCenterY + 1.5, fRadius,
|
||||||
_DrawHands(x, y, radius, hourMinutColor, secondsColor);
|
shadowColor, shadowColor, shadowColor, knobColor);
|
||||||
|
_DrawHands(fCenterX, fCenterY, fRadius,
|
||||||
|
hourColor, minuteColor, secondsColor, knobColor);
|
||||||
|
|
||||||
Sync();
|
Sync();
|
||||||
|
|
||||||
@ -143,16 +203,116 @@ OffscreenClock::DrawClock()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
OffscreenClock::InHourHand(BPoint point)
|
||||||
|
{
|
||||||
|
int32 ticks = fHours;
|
||||||
|
if (ticks > 12)
|
||||||
|
ticks -= 12;
|
||||||
|
ticks *= 5;
|
||||||
|
ticks += int32(5. * fMinutes / 60.0);
|
||||||
|
if (ticks > 60)
|
||||||
|
ticks -= 60;
|
||||||
|
return _InHand(point, ticks, fRadius * 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
OffscreenClock::InMinuteHand(BPoint point)
|
||||||
|
{
|
||||||
|
return _InHand(point, fMinutes, fRadius * 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
OffscreenClock::SetHourHand(BPoint point)
|
||||||
|
{
|
||||||
|
point.x -= fCenterX;
|
||||||
|
point.y -= fCenterY;
|
||||||
|
|
||||||
|
float pointPhi = _GetPhi(point);
|
||||||
|
float hoursExact = 6.0 * pointPhi / PI;
|
||||||
|
if (fHours >= 12)
|
||||||
|
fHours = 12;
|
||||||
|
else
|
||||||
|
fHours = 0;
|
||||||
|
fHours += int32(hoursExact);
|
||||||
|
|
||||||
|
SetTime(fHours, fMinutes, fSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
OffscreenClock::SetMinuteHand(BPoint point)
|
||||||
|
{
|
||||||
|
point.x -= fCenterX;
|
||||||
|
point.y -= fCenterY;
|
||||||
|
|
||||||
|
float pointPhi = _GetPhi(point);
|
||||||
|
float minutesExact = 30.0 * pointPhi / PI;
|
||||||
|
fMinutes = int32(ceilf(minutesExact));
|
||||||
|
|
||||||
|
SetTime(fHours, fMinutes, fSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
OffscreenClock::_GetPhi(BPoint point)
|
||||||
|
{
|
||||||
|
if (point.x == 0 && point.y < 0)
|
||||||
|
return 2 * PI;
|
||||||
|
if (point.x == 0 && point.y > 0)
|
||||||
|
return PI;
|
||||||
|
if (point.y == 0 && point.x < 0)
|
||||||
|
return PI * 3 / 2;
|
||||||
|
if (point.y == 0 && point.x > 0)
|
||||||
|
return PI / 2;
|
||||||
|
|
||||||
|
float pointPhi = atanf(-1. * point.y / point.x);
|
||||||
|
if (point.y < 0. && point.x > 0.) // right upper corner
|
||||||
|
pointPhi = PI / 2. - pointPhi;
|
||||||
|
if (point.y > 0. && point.x > 0.) // right lower corner
|
||||||
|
pointPhi = PI / 2 - pointPhi;
|
||||||
|
if (point.y > 0. && point.x < 0.) // left lower corner
|
||||||
|
pointPhi = (PI * 3. / 2. - pointPhi);
|
||||||
|
if (point.y < 0. && point.x < 0.) // left upper corner
|
||||||
|
pointPhi = 3. / 2. * PI - pointPhi;
|
||||||
|
return pointPhi;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
OffscreenClock::_InHand(BPoint point, int32 ticks, float radius)
|
||||||
|
{
|
||||||
|
point.x -= fCenterX;
|
||||||
|
point.y -= fCenterY;
|
||||||
|
|
||||||
|
float pRadius = sqrt(pow(point.x, 2) + pow(point.y, 2));
|
||||||
|
|
||||||
|
if (radius < pRadius)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float pointPhi = _GetPhi(point);
|
||||||
|
float handPhi = PI / 30.0 * ticks;
|
||||||
|
float delta = pointPhi - handPhi;
|
||||||
|
if (abs(delta) > DRAG_DELTA_PHI)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
OffscreenClock::_DrawHands(float x, float y, float radius,
|
OffscreenClock::_DrawHands(float x, float y, float radius,
|
||||||
rgb_color hourMinuteColor, rgb_color secondsColor)
|
rgb_color hourColor,
|
||||||
|
rgb_color minuteColor,
|
||||||
|
rgb_color secondsColor,
|
||||||
|
rgb_color knobColor)
|
||||||
{
|
{
|
||||||
SetHighColor(hourMinuteColor);
|
|
||||||
|
|
||||||
float offsetX;
|
float offsetX;
|
||||||
float offsetY;
|
float offsetY;
|
||||||
|
|
||||||
// calc, draw hour hand
|
// calc, draw hour hand
|
||||||
|
SetHighColor(hourColor);
|
||||||
SetPenSize(4.0);
|
SetPenSize(4.0);
|
||||||
float hours = fHours + float(fMinutes) / 60.0;
|
float hours = fHours + float(fMinutes) / 60.0;
|
||||||
offsetX = (radius * 0.7) * sinf((hours * PI) / 6.0);
|
offsetX = (radius * 0.7) * sinf((hours * PI) / 6.0);
|
||||||
@ -160,22 +320,22 @@ OffscreenClock::_DrawHands(float x, float y, float radius,
|
|||||||
StrokeLine(BPoint(x, y), BPoint(x + offsetX, y - offsetY));
|
StrokeLine(BPoint(x, y), BPoint(x + offsetX, y - offsetY));
|
||||||
|
|
||||||
// calc, draw minute hand
|
// calc, draw minute hand
|
||||||
|
SetHighColor(minuteColor);
|
||||||
SetPenSize(3.0);
|
SetPenSize(3.0);
|
||||||
float minutes = fMinutes + float(fSeconds) / 60.0;
|
float minutes = fMinutes + float(fSeconds) / 60.0;
|
||||||
offsetX = (radius * 0.9) * sinf((minutes * PI) / 30.0);
|
offsetX = (radius * 0.9) * sinf((minutes * PI) / 30.0);
|
||||||
offsetY = (radius * 0.9) * cosf((minutes * PI) / 30.0);
|
offsetY = (radius * 0.9) * cosf((minutes * PI) / 30.0);
|
||||||
StrokeLine(BPoint(x, y), BPoint(x + offsetX, y - offsetY));
|
StrokeLine(BPoint(x, y), BPoint(x + offsetX, y - offsetY));
|
||||||
|
|
||||||
SetHighColor(secondsColor);
|
|
||||||
|
|
||||||
// calc, draw second hand
|
// calc, draw second hand
|
||||||
|
SetHighColor(secondsColor);
|
||||||
SetPenSize(1.0);
|
SetPenSize(1.0);
|
||||||
offsetX = (radius * 0.95) * sinf((fSeconds * PI) / 30.0);
|
offsetX = (radius * 0.95) * sinf((fSeconds * PI) / 30.0);
|
||||||
offsetY = (radius * 0.95) * cosf((fSeconds * PI) / 30.0);
|
offsetY = (radius * 0.95) * cosf((fSeconds * PI) / 30.0);
|
||||||
StrokeLine(BPoint(x, y), BPoint(x + offsetX, y - offsetY));
|
StrokeLine(BPoint(x, y), BPoint(x + offsetX, y - offsetY));
|
||||||
|
|
||||||
// draw the center knob
|
// draw the center knob
|
||||||
SetHighColor(hourMinuteColor);
|
SetHighColor(knobColor);
|
||||||
FillEllipse(BPoint(x, y), radius * 0.06, radius * 0.06);
|
FillEllipse(BPoint(x, y), radius * 0.06, radius * 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +346,10 @@ OffscreenClock::_DrawHands(float x, float y, float radius,
|
|||||||
TAnalogClock::TAnalogClock(BRect frame, const char *name)
|
TAnalogClock::TAnalogClock(BRect frame, const char *name)
|
||||||
: BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW | B_DRAW_ON_CHILDREN),
|
: BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW | B_DRAW_ON_CHILDREN),
|
||||||
fBitmap(NULL),
|
fBitmap(NULL),
|
||||||
fClock(NULL)
|
fClock(NULL),
|
||||||
|
fDraggingHourHand(false),
|
||||||
|
fDraggingMinuteHand(false),
|
||||||
|
fTimeChangeIsOngoing(false)
|
||||||
{
|
{
|
||||||
_InitView(frame);
|
_InitView(frame);
|
||||||
}
|
}
|
||||||
@ -247,6 +410,58 @@ TAnalogClock::MessageReceived(BMessage *message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TAnalogClock::MouseDown(BPoint point)
|
||||||
|
{
|
||||||
|
fDraggingMinuteHand = fClock->InMinuteHand(point);
|
||||||
|
if (fDraggingMinuteHand) {
|
||||||
|
fClock->SetMinuteDragging(true);
|
||||||
|
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
|
||||||
|
Invalidate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fDraggingHourHand = fClock->InHourHand(point);
|
||||||
|
if (fDraggingHourHand) {
|
||||||
|
fClock->SetHourDragging(true);
|
||||||
|
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
|
||||||
|
Invalidate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TAnalogClock::MouseUp(BPoint point)
|
||||||
|
{
|
||||||
|
if (fDraggingHourHand || fDraggingMinuteHand) {
|
||||||
|
int32 hour, minute, second;
|
||||||
|
fClock->GetTime(&hour, &minute, &second);
|
||||||
|
BMessage message(H_USER_CHANGE);
|
||||||
|
message.AddBool("time", true);
|
||||||
|
message.AddInt32("hour", hour);
|
||||||
|
message.AddInt32("minute", minute);
|
||||||
|
Window()->PostMessage(&message);
|
||||||
|
fTimeChangeIsOngoing = true;
|
||||||
|
}
|
||||||
|
fDraggingHourHand = false;
|
||||||
|
fDraggingMinuteHand = false;
|
||||||
|
fClock->SetMinuteDragging(false);
|
||||||
|
fClock->SetHourDragging(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TAnalogClock::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (fDraggingMinuteHand)
|
||||||
|
fClock->SetMinuteHand(point);
|
||||||
|
if (fDraggingHourHand)
|
||||||
|
fClock->SetHourHand(point);
|
||||||
|
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TAnalogClock::Draw(BRect /*updateRect*/)
|
TAnalogClock::Draw(BRect /*updateRect*/)
|
||||||
{
|
{
|
||||||
@ -261,9 +476,19 @@ TAnalogClock::Draw(BRect /*updateRect*/)
|
|||||||
void
|
void
|
||||||
TAnalogClock::SetTime(int32 hour, int32 minute, int32 second)
|
TAnalogClock::SetTime(int32 hour, int32 minute, int32 second)
|
||||||
{
|
{
|
||||||
|
// don't set the time if the hands are in a drag action
|
||||||
|
if (fDraggingHourHand || fDraggingMinuteHand || fTimeChangeIsOngoing)
|
||||||
|
return;
|
||||||
|
|
||||||
if (fClock)
|
if (fClock)
|
||||||
fClock->SetTime(hour, minute, second);
|
fClock->SetTime(hour, minute, second);
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TAnalogClock::ChangeTimeFinished()
|
||||||
|
{
|
||||||
|
fTimeChangeIsOngoing = false;
|
||||||
|
}
|
||||||
|
@ -25,14 +25,24 @@ class TAnalogClock : public BView {
|
|||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
virtual void Draw(BRect updateRect);
|
virtual void Draw(BRect updateRect);
|
||||||
virtual void MessageReceived(BMessage *message);
|
virtual void MessageReceived(BMessage *message);
|
||||||
|
virtual void MouseDown(BPoint point);
|
||||||
|
virtual void MouseUp(BPoint point);
|
||||||
|
virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message);
|
||||||
|
|
||||||
void SetTime(int32 hour, int32 minute, int32 second);
|
void SetTime(int32 hour, int32 minute, int32 second);
|
||||||
|
|
||||||
|
bool IsChangingTime() { return fTimeChangeIsOngoing; }
|
||||||
|
void ChangeTimeFinished();
|
||||||
private:
|
private:
|
||||||
void _InitView(BRect frame);
|
void _InitView(BRect frame);
|
||||||
|
|
||||||
BBitmap *fBitmap;
|
BBitmap *fBitmap;
|
||||||
OffscreenClock *fClock;
|
OffscreenClock *fClock;
|
||||||
|
|
||||||
|
bool fDraggingHourHand;
|
||||||
|
bool fDraggingMinuteHand;
|
||||||
|
|
||||||
|
bool fTimeChangeIsOngoing;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ANALOG_CLOCK_H
|
#endif // ANALOG_CLOCK_H
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
* McCall <mccall@@digitalparadise.co.uk>
|
* McCall <mccall@@digitalparadise.co.uk>
|
||||||
* Mike Berg <mike@berg-net.us>
|
* Mike Berg <mike@berg-net.us>
|
||||||
* Julun <host.haiku@gmx.de>
|
* Julun <host.haiku@gmx.de>
|
||||||
|
* Clemens <mail@Clemens-Zeidler.de>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -14,13 +15,15 @@
|
|||||||
|
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
|
||||||
using BPrivate::B_LOCAL_TIME;
|
using BPrivate::B_LOCAL_TIME;
|
||||||
|
|
||||||
|
|
||||||
TTimeEdit::TTimeEdit(BRect frame, const char *name, uint32 sections)
|
TTimeEdit::TTimeEdit(BRect frame, const char *name, uint32 sections)
|
||||||
: TSectionEdit(frame, name, sections)
|
: TSectionEdit(frame, name, sections),
|
||||||
|
fLastKeyDownTime(0)
|
||||||
{
|
{
|
||||||
InitView();
|
InitView();
|
||||||
fTime = BTime::CurrentTime(B_LOCAL_TIME);
|
fTime = BTime::CurrentTime(B_LOCAL_TIME);
|
||||||
@ -32,6 +35,42 @@ TTimeEdit::~TTimeEdit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TTimeEdit::KeyDown(const char* bytes, int32 numBytes)
|
||||||
|
{
|
||||||
|
TSectionEdit::KeyDown(bytes, numBytes);
|
||||||
|
|
||||||
|
BMessage* keyDownMsg = Window()->CurrentMessage();
|
||||||
|
int32 number;
|
||||||
|
keyDownMsg->FindInt32("raw_char", &number);
|
||||||
|
// only accept int
|
||||||
|
if (number < 48 || number > 57)
|
||||||
|
return;
|
||||||
|
number -= 48;
|
||||||
|
int32 section = FocusIndex();
|
||||||
|
if (section < 0 || section > 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bigtime_t currentTime = system_time();
|
||||||
|
if (currentTime - fLastKeyDownTime < 1000000) {
|
||||||
|
number += fLastKeyDownInt * 10;
|
||||||
|
fLastKeyDownTime = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fLastKeyDownTime = currentTime;
|
||||||
|
fLastKeyDownInt = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update display value
|
||||||
|
fHoldValue = number;
|
||||||
|
|
||||||
|
_CheckRange();
|
||||||
|
|
||||||
|
// send message to change time
|
||||||
|
DispatchMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TTimeEdit::InitView()
|
TTimeEdit::InitView()
|
||||||
{
|
{
|
||||||
@ -173,6 +212,7 @@ TTimeEdit::SeperatorWidth() const
|
|||||||
void
|
void
|
||||||
TTimeEdit::SectionFocus(uint32 index)
|
TTimeEdit::SectionFocus(uint32 index)
|
||||||
{
|
{
|
||||||
|
fLastKeyDownTime = 0;
|
||||||
fFocus = index;
|
fFocus = index;
|
||||||
fHoldValue = _SectionValue(index);
|
fHoldValue = _SectionValue(index);
|
||||||
Draw(Bounds());
|
Draw(Bounds());
|
||||||
@ -341,6 +381,45 @@ TDateEdit::~TDateEdit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TDateEdit::KeyDown(const char* bytes, int32 numBytes)
|
||||||
|
{
|
||||||
|
TSectionEdit::KeyDown(bytes, numBytes);
|
||||||
|
|
||||||
|
BMessage* keyDownMsg = Window()->CurrentMessage();
|
||||||
|
int32 number;
|
||||||
|
keyDownMsg->FindInt32("raw_char", &number);
|
||||||
|
// only accept int
|
||||||
|
if (number < 48 || number > 57)
|
||||||
|
return;
|
||||||
|
number -= 48;
|
||||||
|
int32 section = FocusIndex();
|
||||||
|
if (section < 1 || section > 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bigtime_t currentTime = system_time();
|
||||||
|
if (currentTime - fLastKeyDownTime < 1000000) {
|
||||||
|
number += fLastKeyDownInt * 10;
|
||||||
|
fLastKeyDownTime = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fLastKeyDownTime = currentTime;
|
||||||
|
fLastKeyDownInt = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if year add 2000
|
||||||
|
if (section == 2)
|
||||||
|
number += 2000;
|
||||||
|
// update display value
|
||||||
|
fHoldValue = number;
|
||||||
|
|
||||||
|
_CheckRange();
|
||||||
|
|
||||||
|
// send message to change time
|
||||||
|
DispatchMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TDateEdit::InitView()
|
TDateEdit::InitView()
|
||||||
{
|
{
|
||||||
@ -452,6 +531,7 @@ TDateEdit::SeperatorWidth() const
|
|||||||
void
|
void
|
||||||
TDateEdit::SectionFocus(uint32 index)
|
TDateEdit::SectionFocus(uint32 index)
|
||||||
{
|
{
|
||||||
|
fLastKeyDownTime = 0;
|
||||||
fFocus = index;
|
fFocus = index;
|
||||||
fHoldValue = _SectionValue(index);
|
fHoldValue = _SectionValue(index);
|
||||||
Draw(Bounds());
|
Draw(Bounds());
|
||||||
|
@ -26,6 +26,7 @@ class TTimeEdit : public TSectionEdit {
|
|||||||
public:
|
public:
|
||||||
TTimeEdit(BRect frame, const char *name, uint32 sections);
|
TTimeEdit(BRect frame, const char *name, uint32 sections);
|
||||||
virtual ~TTimeEdit();
|
virtual ~TTimeEdit();
|
||||||
|
virtual void KeyDown(const char* bytes, int32 numBytes);
|
||||||
|
|
||||||
virtual void InitView();
|
virtual void InitView();
|
||||||
virtual void DrawSection(uint32 index, bool isfocus);
|
virtual void DrawSection(uint32 index, bool isfocus);
|
||||||
@ -48,6 +49,8 @@ class TTimeEdit : public TSectionEdit {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BTime fTime;
|
BTime fTime;
|
||||||
|
bigtime_t fLastKeyDownTime;
|
||||||
|
int32 fLastKeyDownInt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -55,6 +58,7 @@ class TDateEdit : public TSectionEdit {
|
|||||||
public:
|
public:
|
||||||
TDateEdit(BRect frame, const char *name, uint32 sections);
|
TDateEdit(BRect frame, const char *name, uint32 sections);
|
||||||
virtual ~TDateEdit();
|
virtual ~TDateEdit();
|
||||||
|
virtual void KeyDown(const char* bytes, int32 numBytes);
|
||||||
|
|
||||||
virtual void InitView();
|
virtual void InitView();
|
||||||
virtual void DrawSection(uint32 index, bool isfocus);
|
virtual void DrawSection(uint32 index, bool isfocus);
|
||||||
@ -77,6 +81,8 @@ class TDateEdit : public TSectionEdit {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BDate fDate;
|
BDate fDate;
|
||||||
|
bigtime_t fLastKeyDownTime;
|
||||||
|
int32 fLastKeyDownInt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DATETIME_H
|
#endif // DATETIME_H
|
||||||
|
@ -139,6 +139,11 @@ DateTimeView::MessageReceived(BMessage *message)
|
|||||||
_Revert();
|
_Revert();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case kChangeTimeFinished:
|
||||||
|
if (fClock->IsChangingTime())
|
||||||
|
fTimeEdit->MakeFocus(false);
|
||||||
|
fClock->ChangeTimeFinished();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
BView::MessageReceived(message);
|
BView::MessageReceived(message);
|
||||||
break;
|
break;
|
||||||
|
@ -44,5 +44,8 @@ const uint32 kDayChanged = '_kdc';
|
|||||||
// clicked on revert button
|
// clicked on revert button
|
||||||
const uint32 kMsgRevert = 'rvrt';
|
const uint32 kMsgRevert = 'rvrt';
|
||||||
|
|
||||||
|
// change time finished
|
||||||
|
const uint32 kChangeTimeFinished = 'tcfi';
|
||||||
|
|
||||||
#endif //TIME_MESSAGES_H
|
#endif //TIME_MESSAGES_H
|
||||||
|
|
||||||
|
@ -52,6 +52,8 @@ TTimeWindow::MessageReceived(BMessage *message)
|
|||||||
switch(message->what) {
|
switch(message->what) {
|
||||||
case H_USER_CHANGE:
|
case H_USER_CHANGE:
|
||||||
fBaseView->ChangeTime(message);
|
fBaseView->ChangeTime(message);
|
||||||
|
// To make sure no old time message is in the queue
|
||||||
|
_SendTimeChangeFinished();
|
||||||
SetRevertStatus();
|
SetRevertStatus();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -160,3 +162,12 @@ TTimeWindow::_AlignWindow()
|
|||||||
MoveTo(leftTop);
|
MoveTo(leftTop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TTimeWindow::_SendTimeChangeFinished()
|
||||||
|
{
|
||||||
|
BMessenger messenger(fDateTimeView);
|
||||||
|
BMessage msg(kChangeTimeFinished);
|
||||||
|
messenger.SendMessage(&msg);
|
||||||
|
}
|
||||||
|
@ -33,6 +33,8 @@ class TTimeWindow : public BWindow {
|
|||||||
void _InitWindow();
|
void _InitWindow();
|
||||||
void _AlignWindow();
|
void _AlignWindow();
|
||||||
|
|
||||||
|
void _SendTimeChangeFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TTimeBaseView *fBaseView;
|
TTimeBaseView *fBaseView;
|
||||||
DateTimeView *fDateTimeView;
|
DateTimeView *fDateTimeView;
|
||||||
|
Loading…
Reference in New Issue
Block a user