void Ctrl::ScrollView(const Rect& _r, int dx, int dy) { GuiLock __; LLOG("ScrollView " << _r << " " << dx << " " << dy); if(IsFullRefresh() || !IsVisible()) return; Size vsz = GetSize(); dx = sgn(dx) * min(abs(dx), vsz.cx); dy = sgn(dy) * min(abs(dy), vsz.cy); Rect r = _r & vsz; LLOG("ScrollView2 " << r << " " << dx << " " << dy); Ctrl *w; for(w = this; w->parent; w = w->parent) if(w->InFrame()) { Refresh(); return; } if(!w || !w->top) return; Rect view = InFrame() ? GetView() : GetClippedView(); Rect sr = (r + view.TopLeft()) & view; sr += GetScreenRect().TopLeft() - w->GetScreenRect().TopLeft(); if(w->AddScroll(sr, dx, dy)) Refresh(); else { LTIMING("ScrollCtrls1"); Top *top = GetTopCtrl()->top; for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) if(q->InView()) ScrollCtrl(top, q, r, q->GetRect(), dx, dy); if(parent) for(Ctrl *q = parent->GetFirstChild(); q; q = q->GetNext()) if(q->InView() && q != this) ScrollCtrl(top, q, r, q->GetScreenRect() - GetScreenView().TopLeft(), dx, dy); } }
PasteClip Ctrl::GtkDnd(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data, bool paste) { DndTargets(context); g_object_ref(context); // make sure these always survive the action... g_object_ref(widget); dnd_context = context; dnd_widget = widget; dnd_time = time; PasteClip clip; clip.type = 1; clip.paste = paste; clip.accepted = false; clip.allowed = DND_MOVE|DND_COPY; gint dummy; GdkModifierType mod; gdk_window_get_pointer(gdk_get_default_root_window(), &dummy, &dummy, &mod); clip.action = mod & GDK_CONTROL_MASK ? DND_COPY : DND_MOVE; Ctrl *w = DragWnd(user_data); if(w) { gint mx, my; GdkModifierType mod; gdk_window_get_pointer(gdk_get_default_root_window(), &mx, &my, &mod); CurrentState = mod; CurrentMousePos = Point(x, y) + w->GetScreenRect().TopLeft(); w->DnD(CurrentMousePos, clip); } gdk_drag_status(context, clip.IsAccepted() ? clip.GetAction() == DND_MOVE ? GDK_ACTION_MOVE : GDK_ACTION_COPY : GdkDragAction(0), time); return clip; }
ViewDraw::ViewDraw(Ctrl *ctrl) { EnterGuiMutex(); Ctrl *top = ctrl->GetTopCtrl(); cr = gdk_cairo_create(top->gdk()); Clipoff(ctrl->GetScreenView() - top->GetScreenRect().TopLeft()); }
void PaintBarArea(Draw& w, Ctrl *x, const Value& look, int bottom) { Ctrl *tc = x->GetTopCtrl(); Rect sr = tc->GetScreenRect(); sr.bottom = Nvl(bottom, tc->GetScreenView().top); sr.Offset(-x->GetScreenRect().TopLeft()); ChPaint(w, sr, look); }
ViewDraw::ViewDraw(Ctrl *ctrl) { EnterGuiMutex(); Ctrl *top = ctrl->GetTopCtrl(); hwnd = top->GetHWND(); ASSERT(hwnd); Attach(GetDC(hwnd)); Clipoff(ctrl->GetScreenView() - top->GetScreenRect().TopLeft()); }
DockCont *DockWindow::FindDockTarget(DockCont &dc, int &dock) { Point p = GetMousePos(); Rect r = GetScreenView(); DockCont *target = NULL; int align = DOCK_NONE; dock = DOCK_NONE; if (r.Contains(p)) { dock = GetPointAlign(p, r, true, true, true); if (dock != DOCK_NONE && dockpane[dock].IsVisible()) dock = DOCK_NONE; } else { target = GetMouseDockTarget(); if (target) { r = target->GetScreenRect(); dock = GetDockAlign(*target); align = GetPointAlign(p, r, IsTabbing(), IsTB(dock), !IsTB(dock)); } else return NULL; } if (dock != DOCK_NONE && (!dc.IsDockAllowed(dock) || IsPaneAnimating(dock) || IsFrameAnimating(dock)) || (dock == DOCK_NONE && !target)) { dock = DOCK_NONE; return NULL; } // Prepare for highlight if (target) { GetHighlightCtrl().bounds = GetAlignBounds(align, r, IsTabbing(), IsTB(dock), !IsTB(dock)); if (align == DOCK_NONE) dock = DOCK_NONE; // Tabbing // The following code handles the case of an insertion between two docked controls. In this case we must set // the highlight bounds to be a union of the bounds from each control. Very ugly. if (dock != DOCK_NONE) { Ctrl *c = IsTL(align) ? target->GetPrev() : target->GetNext(); if (c) { int opal = align > 1 ? align-2 : align+2; GetHighlightCtrl().bounds.Union(GetAlignBounds(opal, c->GetScreenRect(), IsTabbing())); } target = IsTL(align) ? target : dynamic_cast<DockCont*>(target->GetNext()); } } else if (dock != DOCK_NONE) GetHighlightCtrl().bounds = GetAlignBounds(dock, r, true); return target; }
Ctrl *Ctrl::FindBestOpaque(const Rect& clip) { GuiLock __; Ctrl *w = NULL; for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) { if(q->IsVisible() && GetScreenView().Contains(q->GetScreenRect())) { Rect sw = q->GetScreenView(); if((q->GetOpaqueRect() + sw.TopLeft()).Contains(clip)) { w = q; Ctrl *h = q->FindBestOpaque(clip); if(h) w = h; } else if(q->GetScreenView().Contains(clip)) w = q->FindBestOpaque(clip); else if(q->GetScreenRect().Intersects(clip)) w = NULL; } } return w; }
Rect Ctrl::GetClippedView() { GuiLock __; Rect sv = GetScreenView(); Rect view = sv; Ctrl *q = parent; Ctrl *w = this; while(q) { view &= w->InFrame() ? q->GetScreenRect() : q->GetScreenView(); w = q; q = q->parent; } return view - GetScreenRect().TopLeft(); }
void Ctrl::UpdateArea(SystemDraw& draw, const Rect& clip) { GuiLock __; if(IsPanicMode()) return; RemoveFullRefresh(); Point sp = GetScreenRect().TopLeft(); Ctrl *b = FindBestOpaque(clip + sp); if(b) { Point p = b->GetScreenRect().TopLeft() - sp; draw.Offset(p); b->UpdateArea0(draw, clip.Offseted(-p), backpaint); draw.End(); } else UpdateArea0(draw, clip, backpaint); }
void Ctrl::ScrollView(const Rect& _r, int dx, int dy) { GuiLock __; if(IsFullRefresh() || !IsVisible()) return; Size vsz = GetSize(); dx = sgn(dx) * min(abs(dx), vsz.cx); dy = sgn(dy) * min(abs(dy), vsz.cy); Rect r = _r & vsz; Ctrl *w; for(w = this; w->parent; w = w->parent) if(w->InFrame()) { Refresh(); return; } if(!w || !w->top) return; Rect view = InFrame() ? GetView() : GetClippedView(); Rect sr = (r + view.TopLeft()) & view; sr += GetScreenRect().TopLeft() - w->GetScreenRect().TopLeft(); if(w->AddScroll(sr, dx, dy)) Refresh(); else { LTIMING("ScrollCtrls1"); Top *top = GetTopCtrl()->top; for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) if(q->InView()) { Rect cr = q->GetRect(); if(top && r.Intersects(cr)) { // Uno: Contains -> Intersetcs Rect to = cr; GetTopRect(to, false); if(r.Intersects(cr.Offseted(-dx, -dy))) { // Uno's suggestion 06/11/26 Contains -> Intersetcs Rect from = cr.Offseted(-dx, -dy); GetTopRect(from, false); MoveCtrl *m = FindMoveCtrlPtr(top->move, q); if(m && m->from == from && m->to == to) { LLOG("ScrollView Matched " << from << " -> " << to); m->ctrl = NULL; goto done; } } if(r.Intersects(cr.Offseted(dx, dy))) { // Uno's suggestion 06/11/26 Contains -> Intersetcs Rect from = to; to = cr.Offseted(dx, dy); GetTopRect(to, false); MoveCtrl& m = top->scroll_move.Add(q); m.from = from; m.to = to; m.ctrl = q; LLOG("ScrollView Add " << UPP::Name(q) << from << " -> " << to); goto done; } cr &= r; if(!cr.IsEmpty()) { Refresh(cr); Refresh(cr + Point(dx, dy)); } done:; } } } }