#include "Local.h" #ifdef GUI_SDL20 NAMESPACE_UPP #define LLOG(x) // LOG(x) #define LDUMP(x) //DDUMP(x) TopWindowFrame::TopWindowFrame() { close.SetImage(FBImg::close()); close.EdgeStyle(); Add(close); maximize.SetImage(FBImg::maximize()); maximize.EdgeStyle(); Add(maximize); maximize <<= THISBACK(ToggleMaximize); maximized = false; sizeable = false; holding = false; } void TopWindowFrame::SyncRect() { if(maximized) { Size sz = framebuffer.GetSize(); if(GetRect().GetSize() != sz) SetRect(sz); } } void TopWindowFrame::Maximize() { if(!maximized && maximize.IsShown()) { maximized = true; overlapped = GetRect(); SetRect(framebuffer.GetSize()); maximize.SetImage(FBImg::overlap()); } } void TopWindowFrame::Overlap() { if(maximized && maximize.IsShown()) { maximized = false; SetRect(overlapped); maximize.SetImage(FBImg::maximize()); } } void TopWindowFrame::ToggleMaximize() { if(maximized) Overlap(); else Maximize(); } Rect TopWindowFrame::Margins() const { return maximized ? Rect(0, 0, 0, 0) : ChMargins(FBImg::border()); } void TopWindowFrame::Paint(Draw& w) { Size sz = GetSize(); Rect m = Margins(); int c = GetStdFontCy() + 4; ChPaintEdge(w, sz, FBImg::border()); ChPaint(w, m.left, m.top, sz.cx - m.left - m.right, GetStdFontCy() + 4, window->IsForeground() ? FBImg::title() : FBImg::bgtitle()); int tx = m.left + 2; int tcx = sz.cx - m.left - m.right - 4 - c * (close.IsShown() + maximize.IsShown()); if(!IsNull(icon)) { Image h = icon; if(h.GetWidth() > c || h.GetHeight() > c) h = Rescale(h, GetFitSize(h.GetSize(), Size(c))); w.DrawImage(tx, m.top + 2, h); tx += c; tcx -= c; } DrawTextEllipsis(w, tx, m.top + 2, tcx, title, "..", StdFont(), SColorHighlightText()); } void TopWindowFrame::Layout() { Size sz = GetSize(); Rect m = Margins(); int c = GetStdFontCy() + 4; int x = sz.cx - m.right; if(close.IsShown()) close.SetRect(x -= c, m.top, c, c); if(maximize.IsShown()) maximize.SetRect(x -= c, m.top, c, c); } Rect TopWindowFrame::GetClient() const { Rect r = GetRect(); Rect m = Margins(); r.left += m.left; r.right -= m.right; r.top += m.top; r.bottom -= m.bottom; r.top += GetStdFontCy() + 4; return r; } Rect TopWindowFrame::ComputeClient(Rect r) { Rect m = Margins(); r.left -= m.left; r.right += m.right; r.top -= m.top; r.bottom += m.bottom; r.top -= GetStdFontCy() + 4; return r; } void TopWindowFrame::SetClient(Rect r) { SetRect(ComputeClient(r)); } Point TopWindowFrame::GetDragMode(Point p) { Size sz = GetSize(); Rect m = ChMargins(FBImg::border()); Point dir; dir.y = p.y < m.top ? -1 : p.y > sz.cy - m.top ? 1 : 0; dir.x = p.x < m.left ? -1 : p.x > sz.cx - m.right ? 1 : 0; return dir; } void TopWindowFrame::StartDrag() { if(maximized) return; if(!sizeable && (dir.x || dir.y)) return; if(FullWindowDrag) { SetCapture(); startrect = GetRect(); startpos = GetMousePos(); } else { Rect r = GetScreenRect(); RectTracker tr(*this); tr.SetCursorImage(GetDragImage(dir)) .MaxRect(framebuffer.GetSize()) .MinSize(ComputeClient(minsize).GetSize()) .Pattern(DRAWDRAGRECT_DASHED | DRAWDRAGRECT_SCREEN) .Width(2) .Animation(); PaintLock++; r = tr.Track(r, dir.x < 0 ? ALIGN_LEFT : dir.x > 0 ? ALIGN_RIGHT : ALIGN_CENTER, dir.y < 0 ? ALIGN_TOP : dir.y > 0 ? ALIGN_BOTTOM : ALIGN_CENTER); PaintLock--; SetRect(r); } LLOG("START DRAG ---------------"); } void TopWindowFrame::GripResize() { dir = Point(1, 1); StartDrag(); } void TopWindowFrame::LeftDown(Point p, dword keyflags) { dir = GetDragMode(p); if(dir.x || dir.y || FullWindowDrag) StartDrag(); else { SetCapture(); holding = true; hold.Set(GetKbdDelay() / 3, THISBACK(Hold)); } } void TopWindowFrame::CancelMode() { holding = false; } void TopWindowFrame::LeftUp(Point p, dword keyflags) { holding = false; } void TopWindowFrame::Hold() { if(HasCapture()) { if(HasMouse() && GetMouseLeft() && holding) StartDrag(); ReleaseCapture(); holding = false; } } void TopWindowFrame::LeftHold(Point p, dword keyflags) { if(HasCapture() || FullWindowDrag) return; dir = GetDragMode(p); if(!dir.x && !dir.y) StartDrag(); } void TopWindowFrame::LeftDouble(Point p, dword keyflags) { ToggleMaximize(); IgnoreMouseUp(); } void TopWindowFrame::MouseMove(Point, dword) { LDUMP(HasWndCapture()); LDUMP(HasCapture()); if(!HasCapture() || holding) return; Size msz = ComputeClient(minsize).GetSize(); Point p = GetMousePos() - startpos; Rect r = startrect; if(dir.x == -1) r.left = min(r.left + p.x, startrect.right - msz.cx); if(dir.x == 1) r.right = max(r.right + p.x, startrect.left + msz.cx); if(dir.y == -1) r.top = min(r.top + p.y, startrect.bottom - msz.cy); if(dir.y == 1) r.bottom = max(r.bottom + p.y, startrect.top + msz.cy); if(dir.y == 0 && dir.x == 0) r.Offset(p); SetRect(r); } Image TopWindowFrame::GetDragImage(Point dir) { static Image (*im[9])() = { Image::SizeTopLeft, Image::SizeLeft, Image::SizeBottomLeft, Image::SizeTop, Image::Arrow, Image::SizeBottom, Image::SizeTopRight, Image::SizeRight, Image::SizeBottomRight, }; return (*im[(dir.x + 1) * 3 + (dir.y + 1)])(); } Image TopWindowFrame::CursorImage(Point p, dword) { if(!sizeable) return Image::Arrow(); return GetDragImage(HasCapture() ? dir : GetDragMode(p)); } END_UPP_NAMESPACE #endif