#include #include "Controls4U.h" using namespace Upp; #define TFILE #include #define IMAGECLASS Controls4UImg #define IMAGEFILE #include #define TOPICFILE #include void PaintCenterText(Painter &w, double x, double y, String text, Font fnt, Color color) { Size sz = GetTextSize(text, fnt); w.Text(x - sz.cx / 2., y - sz.cy / 2., text, fnt).Fill(color); } void PaintArc(Painter &w, double cx, double cy, double R, double ang0, double ang1, int direction, double width, Color color) { if (direction == -1) { double c = ang0; ang0 = ang1; ang1 = c; } ang0 = ToRad(ang0); ang1 = ToRad(ang1); double delta = ToRad(0.5); if (ang0 > ang1) ang1 += 2*M_PI; double x1, y1; x1 = cx + R*cos(ang0 + delta); y1 = cy - R*sin(ang0 + delta); w.Move(x1, y1).Arc(cx, cy, R, R, -ang0, ang0-ang1).Stroke(width, color); } void EditFileFolder::Init() { WhenEnter = THISBACK1(DoGo, true); butBrowseLeft.SetImage(Controls4UImg::Folder()); butBrowseLeft.Tip(t_("Browse")); butBrowseLeft <<= THISBACK(DoBrowse); AddFrame(butBrowseRight); butBrowseRight.SetImage(Controls4UImg::Folder()); butBrowseRight <<= THISBACK(DoBrowse); butBrowseRight.Width(40); butLeft.SetImage(CtrlImg::SmallLeft()); butLeft <<= THISBACK(DoLeft); butLeft.Tip(t_("Go to previous")); butLeft.Enable(false); butRight.SetImage(CtrlImg::SmallRight()); butRight <<= THISBACK(DoRight); butRight.Tip(t_("Go to next")); butRight.Enable(false); butUp.SetImage(CtrlImg::DirUp());//SmallUp()); butUp <<= THISBACK(DoUp); butUp.Tip(t_("Directory up")); butUp.Enable(false); //EditString::AddFrame(butGo); butGo.SetImage(CtrlImg::SmallRight()); butGo <<= THISBACK1(DoGo, true); butFolder.Tip(t_("Open folder")); butFolder.Width(10); isFile = isLoad = true; histInd = -1; pfs = 0; Dropping(false); } void EditFileFolder::InitFs() { if (pfs) return; pfs = new FileSel_(); pfs->Asking(!isLoad); } EditFileFolder::~EditFileFolder() { if (pfs) delete pfs; } EditFileFolder &EditFileFolder::UseOpenFolder(bool use) { if (use) InsertFrame(0, butFolder); else RemoveFrame(butFolder); return *this; } EditFileFolder &EditFileFolder::UseHistory(bool use) { if (use) { if (EditString::FindFrame(butLeft) == -1) { EditString::InsertFrame(0, butRight); EditString::InsertFrame(0, butLeft); } } else { EditString::RemoveFrame(butLeft); EditString::RemoveFrame(butRight); } return *this; } EditFileFolder &EditFileFolder::UseUp(bool use) { if (use) { if (EditString::FindFrame(butUp) == -1) { int _pos = EditString::FindFrame(butRight); EditString::InsertFrame(_pos+1, butUp); } } else EditString::RemoveFrame(butUp); return *this; } EditFileFolder &EditFileFolder::UseBrowse(bool use) { if (use) { if (EditString::FindFrame(butBrowseLeft) == -1) { int _pos = EditString::FindFrame(butUp); if (_pos == -1) _pos = EditString::FindFrame(butRight); EditString::InsertFrame(_pos+1, butBrowseLeft); } } else EditString::RemoveFrame(butBrowseLeft); return *this; } EditFileFolder &EditFileFolder::UseBrowseRight(bool use) { if (use) { if (EditString::FindFrame(butBrowseRight) == -1) { int _pos = EditString::FindFrame(butRight); EditString::InsertFrame(_pos+1, butBrowseRight); } } else EditString::RemoveFrame(butBrowseRight); return *this; } EditFileFolder &EditFileFolder::UseGo(bool use) { if (use) { if (EditString::FindFrame(butGo) == -1) { int _pos = EditString::FindFrame(butRight); EditString::InsertFrame(_pos+1, butGo); } } else EditString::RemoveFrame(butGo); return *this; } void EditFileFolder::DoBrowse() { InitFs(); FileSel_ &fs = *pfs; String s = GetData(); if (!s.IsEmpty()) { if (DirectoryExists(AppendFileName(fs.GetBaseDir(), s))) fs.PreSelect(s); else { String folder = GetFileFolder(s); if (folder.IsEmpty() || folder.Find("..") >= 0 || !DirectoryExists(AppendFileName(fs.GetBaseDir(), folder))) s = AppendFileName(NormalizePath(folder, fs.GetActiveDir()), GetFileName(s)); fs.PreSelect(s); } } if (isFile && isLoad) { if (fs.ExecuteOpen(title)) SetData(~fs); } else if (isFile && !isLoad) { if (fs.ExecuteSaveAs(title)) SetData(~fs); } else if (!isFile) { fs.ClearFiles(); if (fs.ExecuteSelectDir(title)) SetData(~fs); } } void EditFileFolder::SetData(const Value& data) { EditString::SetData(data); DoGo(); } void EditFileFolder::DoGo(bool add) { InitFs(); pfs->Set(GetData()); // Write Edit to FileSel if (!IsRootFolder(GetData().ToString())) butUp.Enable(true); else butUp.Enable(false); if (add) { histInd++; history.SetCount(histInd); history.Add(GetData()); if (histInd > 0) butLeft.Enable(true); if (histInd >= history.GetCount()-1) butRight.Enable(false); } if (WhenChange()) { AddHistory(); //WhenAction(); Accept(); } } void EditFileFolder::DoLeft() { histInd--; if (histInd < 0) { histInd = 0; return; } else if (histInd == 0) butLeft.Enable(false); butRight.Enable(true); EditString::SetData(history[histInd]); DoGo(false); } void EditFileFolder::DoRight() { histInd++; if (histInd >= history.GetCount()-1) butRight.Enable(false); butLeft.Enable(true); EditString::SetData(history[histInd]); DoGo(false); } void EditFileFolder::DoUp() { String folder = GetData(); folder = GetUpperFolder(folder); SetData(folder); } EditFile::EditFile() { isFile = true; title = t_("Select file"); EditFileFolder(); butBrowseRight.Tip(t_("Browse file")); butFolder.WhenAction = [&] { String fileName = GetData(); String folder = GetFileFolder(fileName); if (Trim(fileName).IsEmpty()) Exclamation(t_("No file set")); else if (!DirectoryExists(folder)) Exclamation(::Format(t_("Folder '%s' does not exist"), DeQtf(folder))); else { if (folder.StartsWith("\\")) system("explorer " + folder); else LaunchWebBrowser(folder); } }; } EditFolder::EditFolder() { isFile = false; title = t_("Select folder"); EditFileFolder(); butBrowseRight.Tip(t_("Browse folder")); butFolder.WhenAction = [&] { String folder = GetData(); if (Trim(folder).IsEmpty()) Exclamation(t_("No folder set")); else if (!DirectoryExists(folder)) Exclamation(::Format(t_("Folder '%s' does not exist"), DeQtf(folder))); else LaunchWebBrowser(folder);}; } bool SetFirstChild(Ctrl *ctrl) { if (Ctrl *p = ctrl->GetParent()) { if (p->GetFirstChild() != ctrl) { p->RemoveChild(ctrl); p->AddChildBefore(ctrl, p->GetFirstChild()); } return true; } else return false; } void ImagePopUp::Paint(Draw &w) { Size sz = GetSize(); Size imagesize = image.GetSize(); switch (fit) { case StaticImage::BestFit: { Rect _rect = FitInFrame(sz, imagesize); sz = _rect.GetSize(); w.DrawImage(sz, image); break; } case StaticImage::FillFrame: w.DrawImage(0, 0, sz.cx, sz.cy, image); break; case StaticImage::NoScale: w.DrawImage(0, 0, image); break; case StaticImage::RepeatToFill: for (int left = 0; left < sz.cx; left += imagesize.cx) for (int _top = 0; _top < sz.cy; _top += imagesize.cy) w.DrawImage(left, _top, image); break; } DrawBorder(w, sz, BlackBorder); } Point ImagePopUp::Offset(Point p) { return p + GetScreenView().TopLeft() - ctrl->GetScreenView().TopLeft(); } void ImagePopUp::LeftDown(Point p, dword flags) { ctrl->LeftDown(Offset(p), flags); } void ImagePopUp::LeftDrag(Point p, dword flags) { Close(); ctrl->LeftDrag(Offset(p), flags); } void ImagePopUp::LeftDouble(Point p, dword flags) { ctrl->LeftDouble(Offset(p), flags); } void ImagePopUp::RightDown(Point p, dword flags) { ctrl->RightDown(Offset(p), flags); } void ImagePopUp::LeftUp(Point p, dword flags) { ctrl->LeftUp(Offset(p), flags); } void ImagePopUp::MouseWheel(Point p, int zdelta, dword flags) { ctrl->MouseWheel(Offset(p), zdelta, flags); } void ImagePopUp::MouseLeave() { ctrl->MouseLeave(); Close(); } void ImagePopUp::MouseEnter(Point p, dword flags) { ctrl->MouseEnter(Offset(p), flags); } void ImagePopUp::MouseMove(Point p, dword flags) { ctrl->MouseMove(Offset(p), flags); } Image ImagePopUp::CursorImage(Point p, dword flags) { return ctrl->CursorImage(Offset(p), flags); } void ImagePopUp::LostFocus() { Close(); } void ImagePopUp::PopUp(Ctrl *owner, int x, int y, int width, int height, Image &_image, int _angle, int _fit) { if (width == 0 || height == 0 || IsNull(_image)) return; Size imagesize = _image.GetSize(); if (imagesize.cx == 0 || imagesize.cy == 0) return; Rect r(x, y, x + width, y + height); if (fit == StaticImage::BestFit) { r = FitInFrame(r.GetSize(), imagesize); Size sz = r.GetSize(); r.left = x; r.top = y; r.SetSize(sz); } Size ssz = GetScreenSize(); if (ssz.cx < r.left + r.GetWidth()) { r.left = ssz.cx - r.GetWidth(); r.right = ssz.cx; } if (ssz.cy < r.top + r.GetHeight()) { r.top = ssz.cy - r.GetHeight(); r.bottom = ssz.cy; } if(r != GetRect()) SetRect(r); ctrl = owner; image = ::GetRect(_image, _image.GetSize()); angle = _angle; fit = _fit; Ctrl::PopUp(owner, true, false, GUI_DropShadows()); SetAlpha(230); } void ImagePopUp::Close() { Ctrl::Close(); } void StaticImage::MouseEnter(Point, dword) { if (isPopUp) { Point pt = GetScreenRect().TopLeft(); popup.PopUp(this, pt.x, pt.y, szPopUp.cx, szPopUp.cy, origImage, angle, fit); } } void StaticImage::MouseLeave() { if (isPopUp) popup.Close(); } void StaticImage::Layout() { if (useAsBackground) { //Ctrl *q = GetFirstChild(); SetFirstChild(static_cast(this)); SizePos(); } } StaticImage& StaticImage::SetPopUpSize(Size sz) { if (!IsNull(sz)) szPopUp = sz; else szPopUp = origImage.GetSize(); return *this; } void StaticImage::Paint(Draw& w) { Size sz = GetSize(); w.DrawRect(sz, background); if (!origImage) return; if (sz.cx == 0 || sz.cy == 0) return; Size imagesize = origImage.GetSize(); if (imagesize.cx == 0 || imagesize.cy == 0) return; Image *imageView; if (angle == StaticImage::Angle_0) imageView = &origImage; else { imageView = ℑ imagesize = imageView->GetSize(); } switch (fit) { case StaticImage::BestFit: w.DrawImage(FitInFrame(sz, imagesize), *imageView); break; case StaticImage::FillFrame: w.DrawImage(0, 0, sz.cx, sz.cy, *imageView); break; case StaticImage::NoScale: w.DrawImage(0, 0, *imageView); break; case StaticImage::RepeatToFill: for (int left = 0; left < sz.cx; left += imagesize.cx) for (int _top = 0; _top < sz.cy; _top += imagesize.cy) w.DrawImage(left, _top, *imageView); break; } } bool StaticImage::Set(String _fileName) { fileName = _fileName; origImage.Clear(); origImage = StreamRaster::LoadFileAny(_fileName); if (angle != Angle_0) SetAngle(angle); Refresh(); return !IsNull(origImage); } bool StaticImage::Set(Image _image) { origImage.Clear(); origImage = _image; if (angle != Angle_0) SetAngle(angle); fileName = ""; Refresh(); return !IsNull(origImage); } StaticImage& StaticImage::SetAngle(int _angle) { angle = _angle; if (origImage) { switch (angle) { case Angle_90: image = RotateClockwise(origImage); break; case Angle_180: image = Rotate180(origImage); break; case Angle_270: image = RotateAntiClockwise(origImage); break; } Refresh(); } return *this; } void StaticImage::RightDown(Point , dword ) { if(!IsEditable()) return; WhenRightDown(); } void StaticImage::LeftDown(Point , dword ) { if(!IsEditable()) return; WhenLeftDown(); } void StaticImage::LeftDouble(Point , dword ) { if(!IsEditable()) return; WhenLeftDouble(); } StaticImage::StaticImage() { Transparent(); NoWantFocus(); origImage = Null; background = Null; angle = Angle_0; fit = BestFit; useAsBackground = false; isPopUp = false; szPopUp = Size(300, 300); } void StaticImageSet::Paint(Draw& w) { Size sz = GetSize(); w.DrawRect(sz, background); if (sz.cx == 0 || sz.cy == 0) return; Size imagesize = images[id].GetSize(); if (imagesize.cx == 0 || imagesize.cy == 0) return; w.DrawImage(FitInFrame(sz, imagesize), images[id]); } void StaticImageSet::LeftDown(Point , dword ) { if(!IsEditable()) return; SetWantFocus(); Next(); SetCapture(); Refresh(); } void StaticImageSet::LeftRepeat(Point _pos, dword keyflags) { if(!HasCapture()) LeftDown(_pos, keyflags); } void StaticImageSet::LeftUp(Point , dword ) { if (!HasCapture()) return; Refresh(); } void StaticImageSet::MouseMove(Point , dword ) { if(!HasCapture()) return; } void StaticImageSet::GotFocus() {Refresh();} void StaticImageSet::LostFocus() {Refresh();} bool StaticImageSet::Add(String fileName) { return Add(StreamRaster::LoadFileAny(fileName)); } bool StaticImageSet::Add(Image image) { if (IsNull(image)) return false; images.Add(image); return true; } StaticImageSet::StaticImageSet() { Transparent(); // NoWantFocus(); background = Null; id = 0; } void StaticRectangle::Paint(Draw& w) { Size sz = GetSize(); ImageBuffer ib(sz); BufferPainter sw(ib); sw.Clear(RGBAZero()); double wid; if (background) wid = width*2; else wid = width; double sheight; if (isSquare) sheight = sz.cx-wid; else sheight = sz.cy-wid; sw.Rectangle(wid/2, wid/2, sz.cx-wid, sheight).Stroke(wid, color).Fill(background); w.DrawImage(0, 0, ib); } void StaticRectangle::Layout() { if (isSquare) { Rect r = GetRect(); SetRect(r.left, r.top, r.GetWidth(), r.GetWidth()); } } StaticRectangle::StaticRectangle() { Transparent(); NoWantFocus(); color = Black(); background = Null; width = 1; isSquare = false; } void StaticEllipse::Paint(Draw& w) { Size sz = GetSize(); ImageBuffer ib(sz); BufferPainter sw(ib); sw.Clear(RGBAZero()); double wid; if (background) wid = width*2; else wid = width; sw.Ellipse(sz.cx/2, sz.cy/2, sz.cx/2-wid/2, sz.cy/2-wid/2).Stroke(wid, color).Fill(background); w.DrawImage(0, 0, ib); } StaticEllipse::StaticEllipse() { Transparent(); NoWantFocus(); color = Black(); background = Null; width = 1; } StaticFrame::StaticFrame() { Transparent(); NoWantFocus(); SetFrame(InsetFrame()); } void StaticFrame::Paint(Draw& w) { Size sz = GetSize(); if (background) w.DrawRect(0, 0, sz.cx, sz.cy, background); } void StaticLine::FramePaint(Draw& w, const Rect& rr) { int off = int(0.25*max(rr.GetWidth(), rr.GetHeight())); ImageBuffer ib(rr.GetWidth()+2*off, rr.GetHeight()+2*off); BufferPainter sw(ib); Rect r = rr; r.Offset(off, off); sw.Clear(RGBAZero()); sw.LineCap(LINECAP_BUTT); if (orientation == OrVert) sw.DrawLine((r.right+r.left)/2, r.top, (r.right+r.left)/2, r.bottom, width, color); else if (orientation == OrHor) sw.DrawLine(r.left, (r.bottom+r.top)/2, r.right, (r.bottom+r.top)/2, width, color); else if (orientation == OrSW_NE) sw.DrawLine(r.left, r.bottom, r.right, r.top, width, color); else sw.DrawLine(r.left, r.top, r.right, r.bottom, width, color); w.DrawImage(-off, -off, ib); } StaticLine& StaticLine::SetOrientation(String o) { if (o == "|") return SetOrientation(OrVert); else if (o == "-") return SetOrientation(OrHor); else if (o == "\\") return SetOrientation(OrNW_SE); else return SetOrientation(OrSW_NE); } StaticLine::StaticLine() { SetFrame(*this); Transparent(); NoWantFocus(); color = Black(); width = 1; orientation = OrVert; } void PaintArrowEnd(Painter &sw, double x0, double y0, double x1, double y1, int width, Color &color, bool direction) { double alen, awidth; double wd = width; if (width == 1) { alen = 16; awidth = 2; } else { alen = 9*wd; awidth = 1.5*wd; } if (!direction) alen = -alen; if (x0 == x1) { sw.Move(x0, y0).Line(x0 + awidth, y0 + alen).Line(x0 - awidth, y0 + alen).Line(x0, y0); sw.Fill(color); } else if (y0 == y1) { sw.Move(x0, y0).Line(x0 + alen, y0 - awidth).Line(x0 + alen, y0 + awidth).Line(x0, y0); sw.Fill(color); } else { double t = atan((y1-y0)/static_cast(x1-x0)); double xa = alen*cos(t); double ya = alen*sin(t); double xb = awidth*sin(t); double yb = awidth*cos(t); sw.Move(x0, y0).Line(x0+xa+xb, y0+ya-yb).Line(x0+xa-xb, y0+ya+yb).Line(x0, y0); sw.Fill(color); } } void StaticArrow::FramePaint(Draw& w, const Rect& rr) { int off = int(0.25*max(rr.GetWidth(), rr.GetHeight())); ImageBuffer ib(rr.GetWidth()+2*off, rr.GetHeight()+2*off); BufferPainter sw(ib); Rect r = rr; r.Offset(off, off); //Size sz = rr.GetSize(); sw.Clear(RGBAZero()); sw.LineCap(LINECAP_BUTT); double x0, y0, x1, y1, middle; if (orientation == OrVert) { x0 = x1 = (r.right+r.left)/2; y0 = r.top; y1 = r.bottom; } else if (orientation == OrHor) { x0 = r.left; y0 = y1 = (r.bottom+r.top)/2; x1 = r.right; } else if (orientation == OrSW_NE) { x0 = r.left; y0 = r.bottom; x1 = r.right; y1 = r.top; } else if (orientation == OrNW_SE_HVH) { x0 = r.left; y0 = r.top + 2*width; x1 = r.right; y1 = r.bottom - 2*width; middle = (r.left+r.right)/2; } else if (orientation == OrSW_NE_HVH) { x0 = r.left; y0 = r.bottom - 2*width; x1 = r.right; y1 = r.top + 2*width; middle = (r.left + r.right)/2; } else if (orientation == OrNW_SE_VHV) { x0 = r.left + 2*width; y0 = r.top; x1 = r.right - 2*width; y1 = r.bottom; middle = (r.top + r.bottom)/2; } else if (orientation == OrSW_NE_VHV) { x1 = r.left + 2*width; y1 = r.bottom; x0 = r.right - 2*width; y0 = r.top; middle = (r.top + r.bottom)/2; } else { // OrNW_SE x0 = r.left; y0 = r.top; x1 = r.right; y1 = r.bottom; } // Arrow len is 9*width, but 8 joins better arrow end with line if (ends == EndLeft || ends == EndLeftRight) { if (x0 == x1 || orientation == OrVert || orientation == OrNW_SE_VHV || orientation == OrSW_NE_VHV) { PaintArrowEnd(sw, x0, y0, x0, y1, width, color, true); y0 += 8*width; } else if (y0 == y1 || orientation == OrHor || orientation == OrNW_SE_HVH || orientation == OrSW_NE_HVH) { PaintArrowEnd(sw, x0, y0, x1, y0, width, color, true); x0 += 8*width; } else { PaintArrowEnd(sw, x0, y0, x1, y1, width, color, true); double t = atan((y1-y0)/static_cast(x1-x0)); x0 += 8*width*cos(t); y0 += 8*width*sin(t); } } if (ends == EndRight || ends == EndLeftRight) { // Same as other but swapping points if (x0 == x1 || orientation == OrVert || orientation == OrNW_SE_VHV || orientation == OrSW_NE_VHV) { PaintArrowEnd(sw, x1, y1, x1, y0, width, color, false); y1 -= 8*width; } else if (y0 == y1 || orientation == OrHor || orientation == OrNW_SE_HVH || orientation == OrSW_NE_HVH) { PaintArrowEnd(sw, x1, y1, x0, y1, width, color, false); x1 -= 8*width; } else { PaintArrowEnd(sw, x1, y1, x0, y0, width, color, false); double t = atan((y1-y0)/static_cast(x1-x0)); x1 -= 8*width*cos(t); y1 -= 8*width*sin(t); } } if (orientation == OrVert) sw.Move(x0, y0).Line(x1, y1).Stroke(width, color); else if (orientation == OrHor) sw.Move(x0, y0).Line(x1, y1).Stroke(width, color); else if (orientation == OrSW_NE) sw.Move(x0, y0).Line(x1, y1).Stroke(width, color); else if (orientation == OrNW_SE_HVH) { middle = (r.left+r.right)/2; sw.Move(x0, y0).Line(middle, y0).Stroke(width, color); sw.Move(middle, y0).Line(middle, y1).Stroke(width, color); sw.Move(middle, y1).Line(x1, y1).Stroke(width, color); } else if (orientation == OrSW_NE_HVH) { middle = (r.left + r.right)/2; sw.Move(x0, y0).Line(middle, y0).Stroke(width, color); sw.Move(middle, y0).Line(middle, y1).Stroke(width, color); sw.Move(middle, y1).Line(x1, y1).Stroke(width, color); } else if (orientation == OrNW_SE_VHV) { middle = (r.top + r.bottom)/2; sw.Move(x0, y0).Line(x0, middle).Stroke(width, color); sw.Move(x0, middle).Line(x1, middle).Stroke(width, color); sw.Move(x1, middle).Line(x1, y1).Stroke(width, color); } else if (orientation == OrSW_NE_VHV) { middle = (r.top + r.bottom)/2; sw.Move(x0, y0).Line(x0, middle).Stroke(width, color); sw.Move(x0, middle).Line(x1, middle).Stroke(width, color); sw.Move(x1, middle).Line(x1, y1).Stroke(width, color); } else sw.Move(x0, y0).Line(x1, y1).Stroke(width, color); w.DrawImage(-off, -off, ib); } StaticArrow& StaticArrow::SetOrientation(String o) { if (o == "|") return SetOrientation(OrVert); else if (o == "-") return SetOrientation(OrHor); else if (o == "\\") return SetOrientation(OrNW_SE); else if (o == "/") return SetOrientation(OrSW_NE); else if (o == "┐_") return SetOrientation(OrNW_SE_HVH); else if (o == "_┌") return SetOrientation(OrSW_NE_HVH); else if (o == "└┐") return SetOrientation(OrNW_SE_VHV); else //if (o == "┌┘") { return SetOrientation(OrSW_NE_VHV); } StaticArrow& StaticArrow::SetEnds(String e) { if (e == "<-") return SetEnds(EndLeft); else if (e == "->") return SetEnds(EndRight); else if (e == "<->") return SetEnds(EndLeftRight); else return SetEnds(NoEnd); } StaticArrow::StaticArrow() { SetFrame(*this); Transparent(); NoWantFocus(); color = Black(); width = 1; orientation = OrVert; ends = EndLeft; } void StaticClock::PaintPtr(BufferPainter &w, double cmx, double cmy, double _pos, double m, double d, Color color, double cf) { double dx = m * sin(_pos * 2 * M_PI); double dy = m * cos(_pos * 2 * M_PI); double sx = cmx - dx * 35 / 2.0; double sy = cmy + dy * 35 / 2.0; double ex = cmx + dx * cf; double ey = cmy - dy * cf; w.Move(sx, sy).Line(ex, ey).Stroke(d, color); } void StaticClock::Paint(Draw& ww) { Size sz = GetSize(); ImageBuffer ib(sz); BufferPainter w(ib); w.Clear(RGBAZero()); w.LineCap(LINECAP_BUTT); Rect r = GetRect(); //Rect ro = GetRect(); Color letterColor, background;; if (colorType == WhiteType) { background = White(); letterColor = Black(); } else { background = Black(); letterColor = White(); } //double hs = 20; int width = min(r.right - r.left, r.bottom - r.top); double bigF = width/200.; if (image) w.DrawImage(0, 0, width, width, image); else w.Circle(width/2, width/2, width/2).Fill(background); double cmx = width / 2; double cmy = width / 2; double cf = min(cmy, cmx) - 2; if (hourType != StaticClock::No) { for(int i = 1; i <= 60; i++) { double x = cmx + (0.95 * sin(i * M_PI / 30.0) * cf); double y = cmy - (0.95 * cos(i * M_PI / 30.0) * cf); if (hourType == StaticClock::Square) { if(i % 5 == 0) w.Rectangle(x, y, 3*bigF, 3*bigF).Fill(letterColor); else w.Rectangle(x, y, 2*bigF, 2*bigF).Fill(letterColor); } else if (hourType == StaticClock::Rectangle) { if(i % 5 == 0) { double x2 = cmx + (0.7 * sin(i * M_PI / 30.0) * cf); double y2 = cmy - (0.7 * cos(i * M_PI / 30.0) * cf); w.Move(x, y).Line(x2, y2).Stroke(4*bigF, Gray()); w.Move(x, y).Line(x2, y2).Stroke(2*bigF, letterColor); } else { double x2 = cmx + (0.8 * sin(i * M_PI / 30.0) * cf); double y2 = cmy - (0.8 * cos(i * M_PI / 30.0) * cf); w.Move(x, y).Line(x2, y2).Stroke(1*bigF, Gray()); } } } } if (numberType != StaticClock::NoNumber) { double numberPos = 0; if (hourType == StaticClock::No) numberPos = 1; else if (hourType == StaticClock::Square) numberPos = 0.96; else if (hourType == StaticClock::Rectangle) numberPos = 0.75; double numberd = numberPos - 0.2; Font fnt, fnt4; if (numberType == StaticClock::Small) { fnt4 = Arial(static_cast(14*bigF)); fnt = Arial(static_cast(14*bigF)); } else if (numberType == StaticClock::Big) { fnt4 = Arial(static_cast(20*bigF)); fnt = Arial(static_cast(20*bigF)); } else if (numberType == StaticClock::BigSmall) { fnt4 = Arial(static_cast(20*bigF)); fnt = Arial(static_cast(14*bigF)); } else if (numberType == StaticClock::Big4) { fnt4 = Arial(static_cast(20*bigF)); } for(int i = 1; i <= 12; i++) { double x = cmx + (numberd * sin(i * M_PI / 6.0) * cf); double y = cmy - (numberd * cos(i * M_PI / 6.0) * cf); if (i % 3 == 0) PaintCenterText(w, x, y, FormatInt(i), fnt4, letterColor); else if (numberType != StaticClock::Big4) PaintCenterText(w, x, y, FormatInt(i), fnt, letterColor); } } double handleF = bigF; double tm = t.hour * 3600 + t.minute * 60 + t.second; PaintPtr(w, cmx, cmy, tm / 3600 / 12, 0.5, 4*handleF, Color(200, 200, 200), cf); PaintPtr(w, cmx, cmy, tm / 3600 / 12, 0.5, 3*handleF, letterColor, cf); PaintPtr(w, cmx, cmy, tm / 3600, 0.6, 3*handleF, Color(200, 200, 200), cf); PaintPtr(w, cmx, cmy, tm / 3600, 0.6, 2*handleF, letterColor, cf); if (seconds) PaintPtr(w, cmx, cmy, tm / 60, 0.75, 1*handleF, Color(200, 200, 200), cf); int wm = width; if (colorType == WhiteType) { w.Begin(); w.BeginMask(); w.Move(0, 0).Line(wm, 0) .Line(wm, wm).Line(0, wm) .Fill(wm/4, wm/4, Black(), 2*wm, Color(220, 220, 220)); w.End(); w.Circle(wm/2, wm/2, wm/2).Fill(Black()); w.End(); } else { w.Begin(); w.BeginMask(); w.Ellipse(wm/2, wm/4, wm/3, wm/4).Fill(Color(60, 60, 60)); w.End(); w.Ellipse(wm/2, wm/4, wm/3, wm/4).Fill(White()); w.End(); } ww.DrawImage(0, 0, ib); } StaticClock& StaticClock::SetImage(String _fileName) { image = StreamRaster::LoadFileAny(_fileName); Refresh(); return *this; } void StaticClock::SetData(const Value& v) { SetTime(static_cast