#-------------------------------------------------------------------- # # PyGUI - ScrollableView - Win32 # #-------------------------------------------------------------------- import win32con as wc, win32ui as ui from GUI.Components import win_none from GUI.Canvases import Canvas from GUI.GScrollableViews import ScrollableView as GScrollableView, \ default_extent, default_line_scroll_amount from GUI.Geometry import add_pt, sub_pt, offset_rect, offset_rect_neg win_style = ui.AFX_WS_DEFAULT_VIEW #print "ScrollableViews: Creating dummy doc" # PyWin32 insists on being given a CDocument when creating a CScrollView, # and doesn't provide any way of creating a real one without using a resource. if 1: # The following uses a resource included in win32ui.pyd. import pywin.mfc.object win_dummy_doc_template = pywin.mfc.object.CmdTarget( ui.CreateDocTemplate(ui.IDR_PYTHONTYPE)) ui.GetApp().AddDocTemplate(win_dummy_doc_template) def win_get_dummy_doc(): return win_dummy_doc_template.DoCreateDoc() else: # The following hack creates something that looks enough # like a CDocument to keep it happy. But it doesn't work with # pywin32 builds later than 212. win_dummy_doc = ui.CreateRichEditView().GetDocument() def win_get_dummy_doc(): return win_dummy_doc class ScrollableView(GScrollableView): _line_scroll_amount = default_line_scroll_amount def __init__(self, **kwds): kwds.setdefault('extent', default_extent) doc = win_get_dummy_doc() win = ui.CreateView(doc) #win.CreateWindow(win_none, 0, win_style, (0, 0, 100, 100)) win.CreateWindow(win_none, ui.AFX_IDW_PANE_FIRST, win_style, (0, 0, 100, 100)) GScrollableView.__init__(self, _win = win) self.set(**kwds) def get_hscrolling(self): return self._win.GetStyle() & wc.WS_HSCROLL != 0 def get_vscrolling(self): return self._win.GetStyle() & wc.WS_VSCROLL != 0 def set_hscrolling(self, x): self._win_set_flag(x, wc.WS_HSCROLL) def set_vscrolling(self, x): self._win_set_flag(x, wc.WS_VSCROLL) def get_line_scroll_amount(self): return self._line_scroll_amount def get_extent(self): return self._win.GetTotalSize() def set_extent(self, extent): self._win_update_scroll_sizes(extent) def get_scroll_offset(self): return self._win.GetScrollPosition() def set_scroll_offset(self, p): px, py = p ex, ey = self.extent vx, vy = self.content_size xmax = max(0, ex - vx) ymax = max(0, ey - vy) x = max(0, min(px, xmax)) y = max(0, min(py, ymax)) self._win.ScrollToPosition((x, y)) def set_bounds(self, bounds): GScrollableView.set_bounds(self, bounds) extent = self._win.GetTotalSize() self._win_update_scroll_sizes(extent) def _invalidate_rect(self, r): win = self._win s = win.GetScrollPosition() self._win.InvalidateRect(offset_rect_neg(r, s)) def local_to_global(self, p): win = self._win q = sub_pt(p, win.GetScrollPosition()) return win.ClientToScreen(q) def global_to_local(self, g): win = self._win q = win.ScreenToClient(g) return add_pt(q, win.GetScrollPosition()) # def global_to_local(self, g): # win = self._win # l = win.ScreenToClient(g) # s = win.GetScrollPosition() # q = add_pt(l, s) # print "ScrollableView.global_to_local: g =", g, "l =", l, "s =", s, "q =", q ### # return q def _win_update_scroll_sizes(self, extent): ph = self.h_page_scroll_amount() pv = self.v_page_scroll_amount() ls = self.line_scroll_amount self._win.SetScrollSizes(wc.MM_TEXT, extent, (ph, pv), ls) def OnDraw(self, dc): #print "ScrollableView.OnDraw" ### update_rect = dc.GetClipBox() canvas = Canvas._from_win_dc(dc) self.draw(canvas, update_rect) def _win_prepare_dc(self, dc, pinfo = None): self._win.OnPrepareDC(dc, None)