Beispiel #1
0
    def body(self, parent):

        self.bw = 2  # borderwidth
        width = self.cWidth + self.bw
        height = self.cHeight + self.bw
        self.label = Label(parent, text=self.text)
        self.label.grid(row=0, column=0, sticky=Tkinter.W)
        self.percent = Label(parent, text='    %')
        self.percent.grid(row=0, column=2, sticky=Tkinter.W)
        self.canvas = Canvas(parent,
                             background='grey70',
                             width=width,
                             height=height)
        self.canvas.grid(row=0, column=1, sticky=Tkinter.W)
        self.canvas.create_rectangle(0,
                                     0,
                                     width,
                                     height,
                                     outline='black',
                                     width=self.bw)
        self.bar = self.canvas.create_rectangle(self.bw,
                                                self.bw,
                                                self.bw,
                                                self.cHeight,
                                                outline='#B05848',
                                                fill='#B05848',
                                                width=self.bw)
        self.update()
Beispiel #2
0
  def __init__(self, parent, resizeCallback = None, width=600, height=600, *args, **kw):

    self.bbox = None
    self.busy = 0
    self.initialX = None
    self.initialY = None
    self.resizeCallback = resizeCallback

    apply(Frame.__init__, (self, parent) + args, kw)
 
    self.grid_rowconfigure(0, weight=1)
    self.grid_columnconfigure(0, weight=1)

    self.menu = Menu(self, tearoff=0, include_event=True)
    self.configMenu()

    self.canvas = Canvas(self, relief='flat', borderwidth=0, width=width, height=height)
    self.canvas.configure(xscrollincrement=2, yscrollincrement=2)
    self.canvas.grid(row = 0, column = 0, sticky = Tkinter.NSEW )
    
    self.horizScrollbar = Tkinter.Scrollbar(self, bg=self.cget('bg'), command=self.canvas.xview, orient=Tkinter.HORIZONTAL, borderwidth=1)
    self.vertScrollbar  = Tkinter.Scrollbar(self, bg=self.cget('bg'), command=self.canvas.yview, orient=Tkinter.VERTICAL, borderwidth=1)
    self.canvas.configure(xscrollcommand=self.horizScrollbar.set,yscrollcommand=self.vertScrollbar.set)

    self.canvas.bind('<Configure>',        self.resizeAfter)
    self.canvas.bind('<Button-1>',         self.mouseButton1)
    self.canvas.bind('<Button-2>',         self.mouseButton2)
    self.canvas.bind('<Button-3>',         self.mouseButton3)
    self.canvas.bind('<ButtonRelease-1>',  self.mouseButtonRelease1)
    self.canvas.bind('<ButtonRelease-2>',  self.mouseButtonRelease2)
    self.canvas.bind('<B2-Motion>',        self.mouseScroll)
    self.canvas.bind('<B3-Motion>',        self.doNothing)
    self.canvas.bind('<Motion>',           self.mouseEnter)
    self.canvas.bind('<Enter>',            self.mouseEnter)
Beispiel #3
0
  def __init__(self, parent, callback=None, texts=None, objects=None,
               categories=None, colors=None, index=0, prefix='', indent='',
               initCallback=False, forceCallback=False, numbering=False,   
               arrowLine='#602000', arrowFill='#B05848', labelColor='#501000',
               menuBg='#F0F0FF', sticky='w', docKey=None, tipText=None,
               categoriesLast=True, *args, **kw):

    Frame.__init__(self, parent, sticky=sticky, docKey=docKey, tipText=tipText, createToolTip=True, *args, **kw)

    self.callback      = callback
    self.texts         = texts or []
    self.objects       = objects or []
    self.categories    = categories or []
    self.colors        = colors or []
    self.prefix        = prefix
    self.indent        = indent
    self.initCallback  = initCallback
    self.numbering     = numbering
    self.arrowLine     = arrowLine
    self.arrowFill     = arrowFill
    self.labelColor    = labelColor
    self.active        = True
    self.categoriesLast = categoriesLast
    
    # Current selection
    self.index         = None
    self.object        = NullText
    
    self.rows   = []
    self.bg     = self.cget('bg')
    self.label  = Label(self, foreground=labelColor)
    self.canvas = Canvas(self, width=12, height=12, background=self.bg)
    self.menu   = Menu(self.canvas, tearoff=False, bg=menuBg, relief='solid',
                       borderwidth=1, activeborderwidth=1)
    
    self.menu.images = [] # Photoimage has to remain referenced

    self.setup(self.texts, self.objects, index,
               self.colors, self.categories)

    self.label.bind( "<Button-1>",  self._labelClick)
    self.menu.bind(  "<Leave>",     self._leave)
    self.canvas.bind("<Button-1>",  self._canvasClick)
    self.canvas.bind("<Configure>", self._resizeCallback)

    self.grid_columnconfigure(0, weight=1)
    self.label.grid(row=0, column=0, sticky='w')
    self.canvas.grid(row=0, column=1, sticky='w', padx=2)
Beispiel #4
0
    def __init__(self,
                 parent,
                 borderRelief='raised',
                 text=' ',
                 justify='left',
                 font=None,
                 sticky='ew',
                 docKey=None,
                 tipText=None,
                 *args,
                 **kw):

        Frame.__init__(self, parent, sticky=sticky, *args, **kw)

        self.borderRelief = borderRelief
        self.bg = self.cget('bg')
        self.justify = justify
        self.canvas1 = Canvas(self, background=self.bg)

        if self.borderRelief == 'sunken':
            fill1 = 'grey60'
            fill2 = 'white'
        else:
            fill1 = 'white'
            fill2 = 'grey60'
        fill3 = 'grey85'

        self.label = Label(self,
                           text=text,
                           font=font,
                           docKey=docKey,
                           tipText=tipText)
        self.label.grid()

        self.canvasL = [
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1),
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2),
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3)
        ]

        self.canvasR = [
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1),
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2),
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3)
        ]

        self.bind('<Configure>', self.resize)
Beispiel #5
0
    def __init__(self,
                 parent,
                 color='black',
                 side='both',
                 canvas_bg='lightgrey',
                 *args,
                 **kw):

        self.color = color
        self.side = side

        apply(Frame.__init__, (self, parent) + args, kw)

        #self.grid_rowconfigure(0, weight=1)
        #self.grid_columnconfigure(1, weight=1)

        fill = Tkinter.X
        w = kw.get('width', 1)
        z = h = kw.get('height', 1)
        #self.canvas.config(height=h)
        self.canvas = Canvas(self, width=w, height=h, background=canvas_bg)

        self.cross = {'upper': [], 'lower': [], 'both': []}

        #
        # This is setup only... coordinates do not matter here
        #

        if self.side in ['both', 'upper']:
            self.cross['upper'].append(
                self.canvas.create_line(0, 0, 0, 0, fill=color))
            self.cross['upper'].append(
                self.canvas.create_line(0, 0, 0, 0, fill=color))

        self.cross['both'].append(
            self.canvas.create_line(0, 0, 0, 0, fill=color))

        if self.side in ['both', 'lower']:
            self.cross['lower'].append(
                self.canvas.create_line(0, 0, 0, 0, fill=color))
            self.cross['lower'].append(
                self.canvas.create_line(0, 0, 0, 0, fill=color))

        self.canvas.pack(expand=Tkinter.YES, fill=fill)

        #self.canvas.bind('<Configure>', self.resizeCallback)
        self.bind('<Configure>', self.resizeCallback)
Beispiel #6
0
    def __init__(self,
                 parent,
                 arrowSize=11,
                 outline='#5050b0',
                 fill='#a0a0ff',
                 isArrowClosed=True,
                 callback=None,
                 *args,
                 **kw):

        self.arrowSize = arrowSize
        self.isArrowClosed = isArrowClosed
        self.callback = callback

        apply(Frame.__init__, (self, parent) + args, kw)

        bg = kw.get('bg')
        if (not bg):
            bg = kw.get('background')
        if (not bg):
            bg = parent.cget('bg')
        # below does not work for some reason, instead explicitly create rectangle below
        #self.canvas = Canvas(self, width=arrowSize, height=arrowSize, bg=bg)
        self.canvas = Canvas(self, width=arrowSize + 3, height=arrowSize + 1)
        self.canvas.grid(row=0, column=0)

        # need +/-1 otherwise get line along borders
        self.canvas.create_rectangle(-1,
                                     -1,
                                     arrowSize + 3,
                                     arrowSize + 1,
                                     fill=bg)

        # arbitrary coords
        self.arrow = self.canvas.create_polygon(0,
                                                0,
                                                1,
                                                0,
                                                1,
                                                1,
                                                fill=fill,
                                                outline=outline)
        self.drawArrow()

        self.canvas.bind('<Button-1>', self.flipState)
Beispiel #7
0
    def __init__(self, parent, relief='raised', *args, **kw):

        apply(Frame.__init__, (self, parent) + args, kw)

        #self.grid_rowconfigure(0, weight=1)
        #self.grid_columnconfigure(1, weight=1)

        self.bg = self.cget('bg')
        self.relief = relief
        self.grid_columnconfigure(0, weight=1)
        self.canvas = Canvas(self, background=self.bg, width=1, height=6)
        self.canvas.grid(row=0, column=0, sticky=Tkinter.NSEW)

        #self.canvas.bind('<Configure>', self.resizeCallback)
        self.grid(sticky=Tkinter.EW)
        self.canvasL1 = []
        self.canvasL2 = []
        self.canvasL3 = []
        self.refresh = 0
        self.event = None
        self.bind('<Configure>', self.resizeAfter)
Beispiel #8
0
  def __init__(self, parent, callback, speed = 1.5, delay = 50,
               fill = 'grey73', outline = 'grey90', hilight='grey90',
               width = 144, height = 24, *args, **kw):

    self.callback = callback
    self.speed   = speed
    self.delay   = delay
    self.fill    = fill
    self.outline = outline
    self.hilight = hilight

    Frame.__init__(self, parent=parent, *args, **kw)

    # if canvas width/height fixed then resizing has no effect, it seems
    #self.grid_rowconfigure(0, weight=1)
    #self.grid_columnconfigure(0, weight=1)
    font = '-schumacher-clean-bold-r-normal--14-140-75-75-c-70-iso646.1991-irv'
    self.canvas = c = Canvas(self, width=width, height=height, relief='flat', borderwidth=0)
    c.bind('<Configure>', self.resize)
    c.bind('<ButtonPress>', self.press)
    c.bind('<Motion>', self.motion)
    c.bind('<Enter>', self.mouseEnter)
    c.bind('<Leave>', self.mouseLeave)
    c.bind('<ButtonRelease>', self.release)
    self.bg      = c.create_rectangle(1, 1, 1, 1, fill='red', outline='grey50')
    self.boxes0   = []
    self.boxes1   = []
    self.boxes2   = []
    self.strikes  = []
    self.dashes   = []

    for n in range(24):
      box1    = c.create_rectangle(0, 0, 0, 0, fill=outline, outline=outline)
      box2    = c.create_rectangle(0, 0, 0, 0, fill=outline, outline=outline)
      box0    = c.create_rectangle(0, 0, 0, 0, fill=outline, outline=outline)
      self.boxes0.append(box0) 
      self.boxes1.append(box1) 
      self.boxes2.append(box2) 
     
    for n in range(8):
      dash    = c.create_line(0,0,0,0,fill='black')
      self.dashes.append( dash )

    for n in range(4):
      strike = c.create_line(0,0,0,0,fill='black')
      self.strikes.append( strike  )
     
    c.grid(row=0, column=0, sticky=Tkinter.NSEW)

    self.continue_callback = False
    self.multiplier = 1.0
Beispiel #9
0
    def refreshSize(self, event=None):

        canvas = Canvas(self)
        textItem = canvas.create_text(0, 0, text='A', font=self.font)
        coords = canvas.bbox(textItem)
        letterWidth = coords[2] - coords[0] + 2
        canvas.destroy()

        if not self.buttons:
            return

        if event:
            width = event.width
            height = event.height
        else:
            width = int(self.winfo_width())
            height = int(self.winfo_height())

        self.maxRowObjects = len(self.buttons)
        x = 0
        for i, button in enumerate(self.buttons):
            text = button.cget('text')

            if '\n' in text:
                texts = text.split('\n')
                text = texts[0]

                for t in texts[1:]:
                    if len(t) > len(text):
                        text = t

            n = len(text)
            x1 = x + int(letterWidth * n)

            if x1 > width:
                self.maxRowObjects = max(1, i)
                break

            x = x1

        self.update(self.objects, None, self.labels, self.colors, self.fonts)

        self.waiting = False
Beispiel #10
0
class Tree(Frame):
    def __init__(self,
                 parent,
                 iconSize='medium',
                 multiSelect=False,
                 font='Helvetica 8',
                 doubleCallback=None,
                 *args,
                 **kw):

        Frame.__init__(self, parent, *args, **kw)

        self.multiSelect = multiSelect
        self.icons = {}
        self.openDict = {}
        self.scrollbarWidth = 15
        self.canvasList = []
        self.canvasDict = {}
        self.canvasLines = []
        self._wait = False
        self.vOffset = 0
        self.nodes = []  # Just a list of nodes
        self.nodeDict = {}  # To fetch nodes via objects
        self.font = font
        self.doubleCallback = doubleCallback

        #bg = self.cget('background')

        iconItems = [{
            'kind': 'command',
            'label': 'Small',
            'command': self.smallIcons
        }, {
            'kind': 'command',
            'label': 'Medium',
            'command': self.medIcons
        }, {
            'kind': 'command',
            'label': 'Large',
            'command': self.largeIcons
        }]

        self.menu = Menu(self, tearoff=False)
        menu_items = [
            {
                'kind': 'cascade',
                'label': 'Icon size',
                'submenu': iconItems
            },
        ]

        self.menu.setMenuItems(menu_items)

        self.rowHeight = None
        self.visibleRows = 80

        self.setIconSize(iconSize, redraw=False)

        self.canvas = Canvas(self,
                             relief='flat',
                             borderwidth=0,
                             background=BG_COLOR,
                             xscrollcommand=self._setHScrollbar,
                             *args,
                             **kw)

        self.canvas.pack()

        self.xScrollbar = Scrollbar(self,
                                    orient='horizontal',
                                    width=self.scrollbarWidth,
                                    borderwidth=1,
                                    callback=self._moveHScrollbar,
                                    background=BG_COLOR)

        self.yScrollbar = Scrollbar(self,
                                    orient='vertical',
                                    width=self.scrollbarWidth,
                                    borderwidth=1,
                                    callback=self._setVScrollbar,
                                    background=BG_COLOR)

        self.canvas.bind('<Button-1>', self._mouseClick)
        self.canvas.bind('<Double-1>', self._mouseDoubleClick)
        if isWindowsOS:
            self.canvas.bind('<MouseWheel>', self._windowsOsScroll)
        else:
            self.canvas.bind('<Button-4>', self._mouseUp)
            self.canvas.bind('<Button-5>', self._mouseDown)

        self.canvas.bind('<p>', self._printCanvas)
        self.canvas.bind('<KeyPress-Prior>', self._pageUp)
        self.canvas.bind('<KeyPress-Next>', self._pageDown)
        self.canvas.bind('<KeyPress-Up>', self._keyUp)
        self.canvas.bind('<KeyPress-Down>', self._keyDown)
        self.canvas.bind('<KeyPress-Home>', self._keyHome)
        self.canvas.bind('<KeyPress-End>', self._keyEnd)
        self.canvas.bind('<Enter>', self._enter)
        self.canvas.bind('<ButtonPress-3>', self._popupMenu)

        self.bind('<Configure>', self._changeSizeAfter)

    def _popupMenu(self, event):

        self.menu.popupMenu(event)

    def smallIcons(self):

        self.setIconSize('small')

    def medIcons(self):

        self.setIconSize('medium')

    def largeIcons(self):

        self.setIconSize('large')

    def setIconSize(self, iconSize, redraw=True):

        size = ICON_SIZE_DICT.get(iconSize, 22)
        if size != self.rowHeight:
            self.rowHeight = size + 1
            self.font = 'Helvetica %d' % (size / 2)

            ccpnDir = getTopDirectory()
            iconDir = '%dx%d' % (size, size)
            imageDir = path.join(ccpnDir, 'python', 'memops', 'gui',
                                 'graphics', iconDir)

            files = [f for f in listdir(imageDir) if f.endswith('.gif')]

            for file in files:
                imageFile = path.join(imageDir, file)
                self.icons[file[:-4]] = PhotoImage(file=imageFile)

            if redraw:
                self._changeSize()

        return size

    def _setHScrollbar(self, start, end):

        self.xScrollbar.set(float(start), float(end))

    def _moveHScrollbar(self, start, end):

        self.canvas.xview('moveto', start)

    def _enter(self, event):

        self.menu.popdownMenu()
        self.canvas.focus_force()

    def _printCanvas(self, *event):

        from memops.gui.FileSelect import FileType
        from memops.gui.FileSelectPopup import FileSelectPopup

        fileTypes = [FileType('PostScript', ['*.ps']), FileType('All', ['*'])]
        fileSelectPopup = FileSelectPopup(self,
                                          file_types=fileTypes,
                                          title='Print canvas to file',
                                          dismiss_text='Cancel',
                                          selected_file_must_exist=False)

        fileName = fileSelectPopup.getFile()

        self.canvas.postscript(colormode='color', file=fileName)

    def _windowsOsScroll(self, event):

        delta = event.delta
        if delta > 0:
            self._mouseUp(event)
        elif delta < 0:
            self._mouseDown(event)

    def _keyHome(self, event):

        self.vOffset = 0
        self._drawAfter()

    def _keyEnd(self, event):

        numNodes = len(self.nodes)
        visNodes = self.visibleRows
        self.vOffset = max(0, numNodes - visNodes)
        self._drawAfter()

    def _scroll(self, delta=1):

        height = int(self.winfo_height())
        numNodes = len(self.nodes)
        visNodes = self.visibleRows

        if numNodes <= visNodes:
            return

        vOffset = self.vOffset + delta
        vOffset = max(0, vOffset)
        vOffset = min(numNodes - visNodes, vOffset)

        if vOffset != self.vOffset:
            self.vOffset = vOffset
            self._drawAfter()

    def _pageUp(self, event):

        self._scroll(-1 * self.visibleRows)

    def _pageDown(self, event):

        self._scroll(self.visibleRows)

    def _mouseUp(self, event):

        self._scroll(-8)

    def _mouseDown(self, event):

        self._scroll(8)

    def _keyUp(self, event):

        self._scroll(-1)

    def _keyDown(self, event):

        self._scroll(1)

    def _setVScrollbar(self, start, end):

        self.cancelEdits()

        height = int(self.winfo_height())

        gaps = start + 1 - end

        nRows = float(len(self.nodes))

        if gaps == 0 or nRows == 0.0:
            self.yScrollbar.set(0, 1)
            self.vOffset = 0
        else:

            # Have to do this so that the bar keeps up with the mouse
            overlap = int(nRows - self.visibleRows)
            size = min(1.0, self.visibleRows / nRows)
            self.yScrollbar.set(min(gaps, max(0, start)),
                                max(size, min(1.0, start + size)))
            self.vOffset = min(
                max(0, int('%1.1d' % (start / gaps * (overlap + 1)))), overlap)

            #vOffset = max(0, start*nRows)
            #vOffset = min(nRows-self.visibleRows, vOffset)
            #self.vOffset = int(vOffset)

        self._drawAfter()

    def _updateScrollBars(self):

        allRows = len(self.nodes)
        visRows = self.visibleRows

        if allRows < visRows:
            self.vOffset = 0
            self.yScrollbar.set(0, 1)
            self.yScrollbar.place_forget()

        else:
            size = self.scrollbarWidth
            width = int(self.winfo_width()) - 1
            height = int(self.winfo_height()) - 1
            start = float(self.vOffset) / allRows
            end = float(self.vOffset + visRows) / allRows

            self.yScrollbar.set(start, end)
            self.yScrollbar.place(x=width - size + 1,
                                  y=1,
                                  width=size,
                                  height=height)

        self.update_idletasks()

    def _mouseClick(self, event):

        self.cancelEdits()

        x = self.canvas.canvasx(event.x)
        y = self.canvas.canvasy(event.y)
        obj = self.canvas.find('closest', x, y)[0]
        node, typ = self.canvasDict.get(obj, (None, None))

        if node:
            if typ is TOGGLE:
                node.toggle()

            else:
                if self.multiSelect and (event.state & 4 or event.state & 1):
                    if event.state & 4:
                        node.isSelected = not node.isSelected

                    elif event.state & 1:
                        indices = [
                            self.nodes.index(node),
                        ]
                        for i, node2 in enumerate(self.nodes):
                            if node2.isSelected:
                                indices.append(i)

                        for node2 in self.nodes[min(indices):max(indices) + 1]:
                            node2.isSelected = True

                else:
                    for node2 in self.nodes:
                        if node2.isSelected:
                            node2.isSelected = False

                    node.isSelected = True

            self._drawAfter()

    def _mouseDoubleClick(self, event):

        self.cancelEdits()

        x = self.canvas.canvasx(event.x)
        y = self.canvas.canvasy(event.y)
        obj = self.canvas.find('closest', x, y)[0]
        node, typ = self.canvasDict.get(obj, (None, None))

        if node:
            if typ is TOGGLE:
                #node.toggle()
                return

            elif self.doubleCallback:
                self.doubleCallback(node)

        self._drawAfter()

    def _drawAfter(self):

        if self._wait:
            return

        self._wait = True
        self.after_idle(self._draw)

    def _draw(self):

        self._updateScrollBars()

        delta = self.rowHeight
        canvas = self.canvas
        cImage = canvas.create_image
        cList = self.canvasList
        cDict = self.canvasDict
        cLines = self.canvasLines
        cConfig = canvas.itemconfigure
        cDel = canvas.delete
        cCoords = canvas.coords
        cText = canvas.create_text
        cRect = canvas.create_rectangle
        cBbox = canvas.bbox
        cLine = canvas.create_line
        cLift = canvas.lift
        cLower = canvas.lower
        cPoly = canvas.create_polygon
        nodes = self.nodes
        nodeDict = self.nodeDict
        visibleRows = self.visibleRows
        icons = self.icons
        font = self.font
        vOffset = self.vOffset
        bg = BG_COLOR  # self.cget('bg')

        roots = [n for n in nodes if not n.parent]

        if not roots:
            raise Exception('No rooted nodes')

        for item in cLines:
            cDel(item)

        stack = [(node, 0) for node in roots]
        nodes = []
        while stack:
            node, level = stack.pop(0)
            nodes.append((node, level))

            if node.isOpen:
                level2 = level + 1
                stack = [(c, level2) for c in node.children] + stack

        yDict = {}
        pLevel = 0
        pNode = None
        pad = 2 + (delta / 2)
        bSpace = 4
        nodes = nodes[vOffset:]
        for row, data in enumerate(nodes):

            node, level = data

            y = pad + row * delta
            x = pad + level * delta
            x1 = x + delta
            x2 = x1 + delta - bSpace

            yDict[node] = y, x1

            yP, xP = yDict.get(node.parent, (0, x))

            if yP is not None:
                line = cLine(xP, yP, xP, y, fill=LINE_COLOR, width=1)
                cLower(line)
                cLines.append(line)

            if row > visibleRows:
                break

            iconImage = icons[node.icon]

            if node.isSelected:
                bgColor = SELECT_BG_COLOR
                fgColor = SELECT_FG_COLOR
            else:
                bgColor = bg
                fgColor = bg

            if row < len(cList):
                line, rect, tog1, tog2, box, icon, text = cList[row]
                cConfig(rect, fill=bgColor, outline=fgColor)
                cConfig(icon, image=iconImage)
                cConfig(text, text=node.label or '', font=font)
                cCoords(icon, x1, y)
                cCoords(text, x2, y)
                cCoords(line, x, y, x1, y)

            else:
                line = cLine(x, y, x1, y, fill=LINE_COLOR)
                rect = cRect(x, y, x2, y, fill=bgColor, outline=fgColor)
                box = cRect(-2, -2, -2, -2, fill=NODE_BG_COLOR)
                tog1 = cLine(-2, -2, -2, -2)
                tog2 = cLine(-2, -2, -2, -2)
                icon = cImage(x1, y, image=iconImage)
                text = cText(x2,
                             y,
                             text=node.label or '',
                             justify='left',
                             anchor='w',
                             font=font)
                cList.append((line, rect, tog1, tog2, box, icon, text))

            if node.callback:
                cCoords(box, x - 4, y - 4, x + 4, y + 4)

                if node.isOpen:
                    cCoords(tog1, -2, -2, -2, -2)
                    cCoords(tog2, x - 2, y, x + 3, y)

                else:
                    cCoords(tog1, x, y - 2, x, y + 3)
                    cCoords(tog2, x - 2, y, x + 3, y)

            else:
                cCoords(tog1, -2, -2, -2, -2)
                cCoords(tog2, -2, -2, -2, -2)
                cCoords(box, -2, -2, -2, -2)

            bbox = cBbox(text)
            if bbox:
                cCoords(rect, bbox[0] - 2, bbox[1], bbox[2] + 2, bbox[3])

            cLift(box)
            cLift(tog1)
            cLift(tog2)

            cDict[tog1] = (node, TOGGLE)
            cDict[tog2] = (node, TOGGLE)
            cDict[box] = (node, TOGGLE)
            cDict[text] = (node, TEXT)
            cDict[icon] = (node, ICON)

        nRows = min(visibleRows, len(nodes))
        if len(cList) > nRows:
            for row in range(nRows, len(cList)):
                for item in cList[row]:
                    if cDict.get(item):
                        del cDict[item]
                    cDel(item)

            self.canvasList = cList[:nRows]

        self._wait = False

    def setFont(self, font):

        self.font = font
        self._drawAfter()

    def _changeSizeAfter(self, event):

        self.after_idle(lambda: self._changeSize(event))

    def _changeSize(self, event=None):

        self.cancelEdits()

        if event:
            width = event.width
            height = event.height
        else:
            width = int(self.winfo_width())
            height = int(self.winfo_height())

        self.canvas.config(width=width, height=height)
        self.visibleRows = height / self.rowHeight

        bbox = self.canvas.bbox('all')

        if bbox:  # None at startup: nothing drawn
            canvasWidth = bbox[2] - bbox[0]
            if width < canvasWidth:
                size = self.scrollbarWidth
                end = width / float(canvasWidth)
                self.canvas.config(scrollregion="0 0 %s %s" %
                                   (canvasWidth, height))

                if self.visibleRows < len(self.nodes):
                    self.xScrollbar.place(x=0,
                                          y=height - size,
                                          width=width - size,
                                          height=size)
                else:
                    self.xScrollbar.place(x=0,
                                          y=height - size,
                                          width=width,
                                          height=size)

                self.xScrollbar.set(0, end)
            else:
                self.xScrollbar.place_forget()
        else:
            self.xScrollbar.place_forget()

        self._drawAfter()

    # Public

    def cancelEdits(self):

        self.menu.popdownMenu()

    def getSelected(self):

        return [node.object for node in self.nodes if node.isSelected]

    def select(self, object, expand=True):

        node = self.nodeDict.get(object)
        if node is not None:
            node.isSelected = True

            if expand:
                parent = node.parent

                while parent:
                    parent.isOpen = True
                    parent = parent.parent

            self._drawAfter()

    def selectAll(self, expand=True):

        for node in self.nodes:
            node.isSelected = True
            if expand:
                node.isOpen = expand

    def selectDeep(self, object, expand=True):

        node = self.nodeDict.get(object)
        if node is not None:
            stack = [
                node,
            ]
            nodes = []

            while stack:
                node2 = stack.pop()
                stack.extend(node2.children)
                nodes.append(node2)

            for node2 in nodes:
                if expand:
                    node2.isOpen = True
                node2.isSelected = True

            self._drawAfter()

    def setSelected(self, objects, expand=True):

        select = self.select
        for object in objects:
            select(object, expand)

    def expand(self, object):

        node = self.nodeDict.get(object)
        if node is not None:
            node.expand()
            self._drawAfter()

    def expandAll(self):

        for node in self.nodes:
            node.expand()

        self._drawAfter()

    def expandDeep(self, object):

        node = self.nodeDict.get(object)
        if node is not None:
            stack = [
                node,
            ]
            nodes = []

            while stack:
                node2 = stack.pop()
                stack.extend(node2.children)
                nodes.append(node2)

            for node2 in nodes:
                node2.iexpand()

            self._drawAfter()

    def contract(self, object):

        node = self.nodeDict.get(object)
        if node is not None:
            node.collapse()
            self._drawAfter()

    def contractAll(self):

        for node in self.nodes:
            node.collapse()

        self._drawAfter()

    def contractDeep(self, object):

        node = self.nodeDict.get(object)
        if node is not None:
            stack = [
                node,
            ]
            nodes = []

            while stack:
                node2 = stack.pop()
                stack.extend(node2.children)
                nodes.append(node2)

            for node2 in nodes:
                node2.collapse()

            self._drawAfter()

    def update(self,
               parents,
               objects,
               labels=None,
               icons=None,
               callbacks=None,
               editWidgets=None):

        n = len(parents)

        for test in (objects, callbacks, labels, icons, editWidgets):
            if test is not None:
                assert len(test) == n

        self.nodes = nodes = []
        self.nodeDict = nodeDict = {}
        self.openDict = {}

        if not labels:
            labels = [None] * n

        if not icons:
            icons = [None] * n

        if not callbacks:
            callbacks = [None] * n

        if not editWidgets:
            editWidgets = [[] for x in xrange(n)]

        for i, parent in enumerate(parents):
            object = objects[i]

            node = Node(self, parent, object, labels[i], icons[i],
                        callbacks[i], False, False, editWidgets[i])

        # JMCI FIXME: need to understand how the redraw works

        self._draw()

    def add(self,
            parent,
            object,
            label=None,
            icon='media-playback-stop',
            callback=None,
            isOpen=False,
            isSelected=False,
            editWidgets=None):

        nodeDict = self.nodeDict
        if nodeDict.get(object):
            nodeDict[object].delete()

            #raise Exception('Node already present for object %s' % object)

        node = Node(self, parent, object, label, icon, callback, isOpen,
                    isSelected, editWidgets)

    def remove(self, object):

        node = self.nodeDict.get(object)
        if node is not None:
            if self.openDict.get(object):
                del self.openDict[object]

            node.delete()

            self._drawAfter()
Beispiel #11
0
class Spacer(Frame):
    def __init__(self, parent, relief='raised', *args, **kw):

        apply(Frame.__init__, (self, parent) + args, kw)

        #self.grid_rowconfigure(0, weight=1)
        #self.grid_columnconfigure(1, weight=1)

        self.bg = self.cget('bg')
        self.relief = relief
        self.grid_columnconfigure(0, weight=1)
        self.canvas = Canvas(self, background=self.bg, width=1, height=6)
        self.canvas.grid(row=0, column=0, sticky=Tkinter.NSEW)

        #self.canvas.bind('<Configure>', self.resizeCallback)
        self.grid(sticky=Tkinter.EW)
        self.canvasL1 = []
        self.canvasL2 = []
        self.canvasL3 = []
        self.refresh = 0
        self.event = None
        self.bind('<Configure>', self.resizeAfter)

    def resizeAfter(self, event):

        self.event = event
        if self.refresh:
            return
        else:
            self.refresh = 1
            self.after_idle(lambda: self.resize(self.event))

    def resize(self, event):

        m = 6
        w = event.width
        h = event.height
        N = int(h / m)

        self.canvas.config(width=w, height=h)
        if self.relief == 'sunken':
            fill1 = 'grey65'
            fill2 = 'grey95'
        else:
            fill1 = 'grey95'
            fill2 = 'grey65'

        for i in range(N):
            y = 1 + (i / float(N)) * h
            if i >= len(self.canvasL1):
                rect1 = self.canvas.create_rectangle(4,
                                                     y + 0,
                                                     w - 5,
                                                     y + 2,
                                                     width=0,
                                                     fill=fill1)
                rect2 = self.canvas.create_rectangle(5,
                                                     y + 1,
                                                     w - 4,
                                                     y + 3,
                                                     width=0,
                                                     fill=fill2)
                rect3 = self.canvas.create_rectangle(5,
                                                     y + 1,
                                                     w - 5,
                                                     y + 2,
                                                     width=0,
                                                     fill=self.bg)
                self.canvasL1.append(rect1)
                self.canvasL2.append(rect2)
                self.canvasL3.append(rect3)
            else:
                self.canvas.coords(self.canvasL1[i], 4, y + 0, w - 5, y + 2)
                self.canvas.coords(self.canvasL2[i], 5, y + 1, w - 4, y + 3)
                self.canvas.coords(self.canvasL3[i], 5, y + 1, w - 5, y + 2)

        if N > len(self.canvasL1):
            for i in range(N, len(self.canvasL1)):
                self.canvas.delete(self.canvasL1[i])
                self.canvas.delete(self.canvasL2[i])
                self.canvas.delete(self.canvasL3[i])

        self.refresh = 0
Beispiel #12
0
    def __init__(self,
                 parent,
                 borderRelief='raised',
                 text=' ',
                 justify='left',
                 width=None,
                 font=None,
                 height=None,
                 docKey=None,
                 tipText=None,
                 *args,
                 **kw):

        kw['borderwidth'] = self.bw = 18

        Frame.__init__(self, parent, *args, **kw)

        self.borderRelief = borderRelief
        self.bg = self.cget('bg')
        self.justify = justify
        self.canvas1 = Canvas(self, background=self.bg)
        self.canvas2 = Canvas(self, background=self.bg)
        self.canvas3 = Canvas(self, background=self.bg)
        self.canvas4 = Canvas(self, background=self.bg)

        if self.borderRelief == 'sunken':
            fill1 = 'grey60'
            fill2 = 'white'
        else:
            fill1 = 'white'
            fill2 = 'grey60'
        fill3 = 'grey85'

        self.label = Label(self,
                           text=text,
                           font=font,
                           docKey=None,
                           tipText=tipText)

        self.canvasL1 = []
        self.canvasL1a = []
        self.canvasL2 = []
        self.canvasL3 = []
        self.canvasL3a = []
        self.canvasL3b = []
        self.canvasL4 = []
        self.canvasL5 = []
        self.canvasL5a = []

        self.canvasL1.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL1a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL2.append(
            self.canvas2.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL3a.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL3.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL3b.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL4.append(
            self.canvas4.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL5.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL5a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL1.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL1a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL2.append(
            self.canvas2.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL3a.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL3.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL3b.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL4.append(
            self.canvas4.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL5.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL5a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL1.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL1a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL2.append(
            self.canvas2.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL3a.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL3.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL3b.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL4.append(
            self.canvas4.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL5.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL5a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))

        self.bind('<Configure>', self.resize)
Beispiel #13
0
class LabelFrame(Frame):
    def __init__(self,
                 parent,
                 borderRelief='raised',
                 text=' ',
                 justify='left',
                 width=None,
                 font=None,
                 height=None,
                 docKey=None,
                 tipText=None,
                 *args,
                 **kw):

        kw['borderwidth'] = self.bw = 18

        Frame.__init__(self, parent, *args, **kw)

        self.borderRelief = borderRelief
        self.bg = self.cget('bg')
        self.justify = justify
        self.canvas1 = Canvas(self, background=self.bg)
        self.canvas2 = Canvas(self, background=self.bg)
        self.canvas3 = Canvas(self, background=self.bg)
        self.canvas4 = Canvas(self, background=self.bg)

        if self.borderRelief == 'sunken':
            fill1 = 'grey60'
            fill2 = 'white'
        else:
            fill1 = 'white'
            fill2 = 'grey60'
        fill3 = 'grey85'

        self.label = Label(self,
                           text=text,
                           font=font,
                           docKey=None,
                           tipText=tipText)

        self.canvasL1 = []
        self.canvasL1a = []
        self.canvasL2 = []
        self.canvasL3 = []
        self.canvasL3a = []
        self.canvasL3b = []
        self.canvasL4 = []
        self.canvasL5 = []
        self.canvasL5a = []

        self.canvasL1.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL1a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL2.append(
            self.canvas2.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL3a.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL3.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL3b.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL4.append(
            self.canvas4.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL5.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL5a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1))
        self.canvasL1.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL1a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL2.append(
            self.canvas2.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL3a.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL3.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL3b.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL4.append(
            self.canvas4.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL5.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL5a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2))
        self.canvasL1.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL1a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL2.append(
            self.canvas2.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL3a.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL3.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL3b.append(
            self.canvas3.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL4.append(
            self.canvas4.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL5.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))
        self.canvasL5a.append(
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3))

        self.bind('<Configure>', self.resize)

    def setText(self, text):

        self.label.set(text)
        self.resize()

    def resize(self, event=None):

        if event:
            w = event.width
            h = event.height
        else:
            w = int(self.winfo_width())
            h = int(self.winfo_height())

        self.after_idle(lambda: self.draw(w, h))

    def draw(self, w, h):

        bw = self.bw
        pad = bw / 2
        h2 = h - (2 * bw)

        textWidth = int(self.label.winfo_reqwidth())

        if self.justify == 'left':
            textLeft = (3 * pad) + (0.05 * w)
            textRight = min(w, textLeft + textWidth)
        elif self.justify == 'right':
            textRight = (3 * pad) + (0.05 * w)
            textLeft = w - (textWidth + textRight)
        else:
            textLeft = (w / 2) - (textWidth / 2)
            textRight = textLeft + textWidth

        c1 = self.canvas1
        c2 = self.canvas2
        c3 = self.canvas3
        c4 = self.canvas4

        c1coords = c1.coords
        c2coords = c2.coords
        c3coords = c3.coords
        c4coords = c4.coords

        c1.place(x=0,
                 y=0,
                 anchor='nw',
                 width=w,
                 height=bw,
                 bordermode='ignore')
        c2.place(x=0,
                 y=bw,
                 anchor='nw',
                 width=bw,
                 height=h2,
                 bordermode='ignore')
        c3.place(x=0,
                 y=h - bw,
                 anchor='nw',
                 width=w,
                 height=bw,
                 bordermode='ignore')
        c4.place(x=w - bw,
                 y=bw,
                 anchor='nw',
                 width=bw,
                 height=h2,
                 bordermode='ignore')
        self.label.place(x=textLeft, y=0, anchor='nw', bordermode='ignore')

        e1, e2, e3 = self.canvasL1
        c1coords(e1, pad, pad, textLeft - pad + 3, pad + 3)
        c1coords(e2, pad + 1, pad + 1, textLeft - pad + 3, pad + 3)
        c1coords(e3, pad + 1, pad + 1, textLeft - pad + 2, pad + 2)

        e1, e2, e3 = self.canvasL1a
        c1coords(e1, pad, pad, pad + 3, bw)
        c1coords(e2, pad + 1, pad + 1, pad + 3, bw)
        c1coords(e3, pad + 1, pad + 1, pad + 2, bw)

        e1, e2, e3 = self.canvasL2
        c2coords(e1, pad, 0, pad + 3, h2)
        c2coords(e2, pad + 1, 0, pad + 3, h2)
        c2coords(e3, pad + 1, 0, pad + 2, h2)

        e1, e2, e3 = self.canvasL3
        c3coords(e1, pad, pad, w - pad + 3, pad + 3)
        c3coords(e2, pad + 1, pad + 1, w - pad + 3, pad + 3)
        c3coords(e3, pad + 1, pad + 1, w - pad + 2, pad + 2)

        e1, e2, e3 = self.canvasL3a
        c3coords(e1, pad, 0, pad + 3, pad + 3)
        c3coords(e2, pad + 1, 0, pad + 3, pad + 3)
        c3coords(e3, pad + 1, 0, pad + 2, pad + 2)

        e1, e2, e3 = self.canvasL3b
        c3coords(e1, w - pad, 0, w - pad + 3, pad + 3)
        c3coords(e2, w - pad + 1, 0, w - pad + 3, pad + 3)
        c3coords(e3, w - pad + 1, 0, w - pad + 2, pad + 2)

        e1, e2, e3 = self.canvasL4
        c4coords(e1, pad, 0, pad + 3, h2)
        c4coords(e2, pad + 1, 0, pad + 3, h2)
        c4coords(e3, pad + 1, 0, pad + 2, h2)

        e1, e2, e3 = self.canvasL5
        c1coords(e1, textRight + pad, pad, w - pad + 3, pad + 3)
        c1coords(e2, textRight + pad + 1, pad + 1, w - pad + 3, pad + 3)
        c1coords(e3, textRight + pad + 1, pad + 1, w - pad + 2, pad + 2)

        e1, e2, e3 = self.canvasL5a
        c1coords(e1, w - pad, pad, w - pad + 3, bw)
        c1coords(e2, w - pad + 1, pad + 1, w - pad + 3, bw)
        c1coords(e3, w - pad + 1, pad + 1, w - pad + 2, bw)
Beispiel #14
0
    def __init__(self,
                 parent,
                 iconSize='medium',
                 multiSelect=False,
                 font='Helvetica 8',
                 doubleCallback=None,
                 *args,
                 **kw):

        Frame.__init__(self, parent, *args, **kw)

        self.multiSelect = multiSelect
        self.icons = {}
        self.openDict = {}
        self.scrollbarWidth = 15
        self.canvasList = []
        self.canvasDict = {}
        self.canvasLines = []
        self._wait = False
        self.vOffset = 0
        self.nodes = []  # Just a list of nodes
        self.nodeDict = {}  # To fetch nodes via objects
        self.font = font
        self.doubleCallback = doubleCallback

        #bg = self.cget('background')

        iconItems = [{
            'kind': 'command',
            'label': 'Small',
            'command': self.smallIcons
        }, {
            'kind': 'command',
            'label': 'Medium',
            'command': self.medIcons
        }, {
            'kind': 'command',
            'label': 'Large',
            'command': self.largeIcons
        }]

        self.menu = Menu(self, tearoff=False)
        menu_items = [
            {
                'kind': 'cascade',
                'label': 'Icon size',
                'submenu': iconItems
            },
        ]

        self.menu.setMenuItems(menu_items)

        self.rowHeight = None
        self.visibleRows = 80

        self.setIconSize(iconSize, redraw=False)

        self.canvas = Canvas(self,
                             relief='flat',
                             borderwidth=0,
                             background=BG_COLOR,
                             xscrollcommand=self._setHScrollbar,
                             *args,
                             **kw)

        self.canvas.pack()

        self.xScrollbar = Scrollbar(self,
                                    orient='horizontal',
                                    width=self.scrollbarWidth,
                                    borderwidth=1,
                                    callback=self._moveHScrollbar,
                                    background=BG_COLOR)

        self.yScrollbar = Scrollbar(self,
                                    orient='vertical',
                                    width=self.scrollbarWidth,
                                    borderwidth=1,
                                    callback=self._setVScrollbar,
                                    background=BG_COLOR)

        self.canvas.bind('<Button-1>', self._mouseClick)
        self.canvas.bind('<Double-1>', self._mouseDoubleClick)
        if isWindowsOS:
            self.canvas.bind('<MouseWheel>', self._windowsOsScroll)
        else:
            self.canvas.bind('<Button-4>', self._mouseUp)
            self.canvas.bind('<Button-5>', self._mouseDown)

        self.canvas.bind('<p>', self._printCanvas)
        self.canvas.bind('<KeyPress-Prior>', self._pageUp)
        self.canvas.bind('<KeyPress-Next>', self._pageDown)
        self.canvas.bind('<KeyPress-Up>', self._keyUp)
        self.canvas.bind('<KeyPress-Down>', self._keyDown)
        self.canvas.bind('<KeyPress-Home>', self._keyHome)
        self.canvas.bind('<KeyPress-End>', self._keyEnd)
        self.canvas.bind('<Enter>', self._enter)
        self.canvas.bind('<ButtonPress-3>', self._popupMenu)

        self.bind('<Configure>', self._changeSizeAfter)
Beispiel #15
0
class CrossLine(Frame):
    def __init__(self,
                 parent,
                 color='black',
                 side='both',
                 canvas_bg='lightgrey',
                 *args,
                 **kw):

        self.color = color
        self.side = side

        apply(Frame.__init__, (self, parent) + args, kw)

        #self.grid_rowconfigure(0, weight=1)
        #self.grid_columnconfigure(1, weight=1)

        fill = Tkinter.X
        w = kw.get('width', 1)
        z = h = kw.get('height', 1)
        #self.canvas.config(height=h)
        self.canvas = Canvas(self, width=w, height=h, background=canvas_bg)

        self.cross = {'upper': [], 'lower': [], 'both': []}

        #
        # This is setup only... coordinates do not matter here
        #

        if self.side in ['both', 'upper']:
            self.cross['upper'].append(
                self.canvas.create_line(0, 0, 0, 0, fill=color))
            self.cross['upper'].append(
                self.canvas.create_line(0, 0, 0, 0, fill=color))

        self.cross['both'].append(
            self.canvas.create_line(0, 0, 0, 0, fill=color))

        if self.side in ['both', 'lower']:
            self.cross['lower'].append(
                self.canvas.create_line(0, 0, 0, 0, fill=color))
            self.cross['lower'].append(
                self.canvas.create_line(0, 0, 0, 0, fill=color))

        self.canvas.pack(expand=Tkinter.YES, fill=fill)

        #self.canvas.bind('<Configure>', self.resizeCallback)
        self.bind('<Configure>', self.resizeCallback)

    def resizeCallback(self, event):

        self.update_idletasks()

        #w = self.canvas.winfo_width()
        #h = self.canvas.winfo_height()
        w = self.winfo_width()
        h = self.winfo_height()

        if self.side == 'both':
            mh = h / 2
        elif self.side == 'lower':
            mh = 0
        else:
            mh = h

        if self.side in ['both', 'upper']:
            self.canvas.coords(self.cross['upper'][0], 0, 0, w / 3, mh)
            self.canvas.coords(self.cross['upper'][1], w * 2 / 3, mh, w, 0)

        self.canvas.coords(self.cross['both'][0], w / 3, mh, w * 2 / 3, mh)

        if self.side in ['both', 'lower']:
            self.canvas.coords(self.cross['lower'][0], 0, h, w / 3, mh)
            self.canvas.coords(self.cross['lower'][1], w * 2 / 3, mh, w, h)

    # color is a tuple
    def setColor(self, color):

        (r, g, b) = color
        self.canvas.itemconfig(self.item, fill=hexRepr(r, g, b))
Beispiel #16
0
    def __init__(self, parent, *args, **kw):

        apply(Frame.__init__, (self, parent) + args, kw)

        self.grid_rowconfigure(0, weight=1)
        self.grid_rowconfigure(1, weight=0)
        self.grid_rowconfigure(2, weight=0)
        self.grid_rowconfigure(3, weight=0)

        self.canvas = Canvas(self, relief='sunken', borderwidth=2, width=150)
        self.canvas.grid(row=0,
                         column=1,
                         columnspan=1,
                         sticky=Tkinter.NSEW,
                         pady=2,
                         padx=2)

        frame = Frame(self)
        frame.grid_columnconfigure(1, weight=1)
        self.boxSize = 100
        self.numPixels = 10
        self.pixelWidth = round(self.boxSize / self.numPixels)
        self.colorBox = Canvas(frame,
                               relief='sunken',
                               borderwidth=2,
                               width=self.boxSize + 2,
                               height=self.boxSize + 2)
        self.colorBox.bind('<Button-1>', self.pickInColorBox)
        self.colorBox.bind('<Button-2>', self.pickInColorBox)
        self.colorBox.bind('<Button-3>', self.pickInColorBox)
        self.colorBox.grid(row=0,
                           column=2,
                           rowspan=3,
                           sticky=Tkinter.NSEW,
                           padx=4,
                           pady=4)
        self.pixel = []
        self.colors = []
        self.setupColorBox()
        self.scale = Tkinter.Scale(frame,
                                   orient=Tkinter.VERTICAL,
                                   length=self.boxSize,
                                   from_=0,
                                   to=99,
                                   label='',
                                   showvalue=0,
                                   command=self.refreshColorBox)
        self.scale.grid(row=0,
                        column=3,
                        rowspan=3,
                        sticky=Tkinter.NS,
                        padx=4,
                        pady=4)
        frame.grid(row=1, column=0, columnspan=2, sticky=Tkinter.NSEW)

        labels = ('Red', 'Green', 'Blue')
        self.labeled_scale = 3 * [None]

        for n in range(3):

            label = Label(frame, text=labels[n] + ':', anchor=Tkinter.W)
            label.grid(row=n, column=0, sticky=Tkinter.EW)

            self.labeled_scale[n] = LabeledScale(
                frame,
                values=range(101),
                label_format='%3d',
                set_callback=self.scaleCallback)
            self.labeled_scale[n].grid(row=n, column=1, sticky=Tkinter.EW)
Beispiel #17
0
class LabelDivider(Frame):
    def __init__(self,
                 parent,
                 borderRelief='raised',
                 text=' ',
                 justify='left',
                 font=None,
                 sticky='ew',
                 docKey=None,
                 tipText=None,
                 *args,
                 **kw):

        Frame.__init__(self, parent, sticky=sticky, *args, **kw)

        self.borderRelief = borderRelief
        self.bg = self.cget('bg')
        self.justify = justify
        self.canvas1 = Canvas(self, background=self.bg)

        if self.borderRelief == 'sunken':
            fill1 = 'grey60'
            fill2 = 'white'
        else:
            fill1 = 'white'
            fill2 = 'grey60'
        fill3 = 'grey85'

        self.label = Label(self,
                           text=text,
                           font=font,
                           docKey=docKey,
                           tipText=tipText)
        self.label.grid()

        self.canvasL = [
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1),
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2),
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3)
        ]

        self.canvasR = [
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill1),
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill2),
            self.canvas1.create_rectangle(0, 0, 0, 0, width=0, fill=fill3)
        ]

        self.bind('<Configure>', self.resize)

    def setText(self, text):

        self.label.set(text)
        self.resize()

    def resize(self, event=None):

        if event:
            w = event.width
            h = event.height
        else:
            w = int(self.winfo_width())
            h = int(self.winfo_height())

        self.after_idle(lambda: self.draw(w, h))

    def draw(self, w, h):

        bw = int(self.label.winfo_height())
        pad = bw / 2
        h2 = h - (2 * bw)

        textWidth = int(self.label.winfo_reqwidth())

        if self.justify == 'left':
            textLeft = (3 * pad) + (0.05 * w)
            textRight = min(w, textLeft + textWidth)
        elif self.justify == 'right':
            textRight = (3 * pad) + (0.05 * w)
            textLeft = w - (textWidth + textRight)
        else:
            textLeft = (w / 2) - (textWidth / 2)
            textRight = textLeft + textWidth

        c1 = self.canvas1
        c1coords = c1.coords
        c1.place(x=0, y=0, anchor='nw', width=w, height=bw)

        self.label.place(x=textLeft, y=0, anchor='nw')

        e1, e2, e3 = self.canvasL
        c1coords(e1, pad, pad, textLeft - pad + 3, pad + 3)
        c1coords(e2, pad + 1, pad + 1, textLeft - pad + 3, pad + 3)
        c1coords(e3, pad + 1, pad + 1, textLeft - pad + 2, pad + 2)

        e1, e2, e3 = self.canvasR
        c1coords(e1, textRight + pad, pad, w - pad + 3, pad + 3)
        c1coords(e2, textRight + pad + 1, pad + 1, w - pad + 3, pad + 3)
        c1coords(e3, textRight + pad + 1, pad + 1, w - pad + 2, pad + 2)
Beispiel #18
0
class ProgressBar(BasePopup):
    def __init__(self,
                 parent,
                 text='',
                 progress=0,
                 total=100,
                 title=None,
                 width=200,
                 height=15,
                 transient=True,
                 *args,
                 **kw):

        self.progress = float(progress)
        self.cWidth = width
        self.cHeight = height
        self.total = float(total) or 1.0
        self.text = text

        BasePopup.__init__(self,
                           parent=parent,
                           title=title or 'Progress Bar',
                           transient=transient,
                           *args,
                           **kw)

    def body(self, parent):

        self.bw = 2  # borderwidth
        width = self.cWidth + self.bw
        height = self.cHeight + self.bw
        self.label = Label(parent, text=self.text)
        self.label.grid(row=0, column=0, sticky=Tkinter.W)
        self.percent = Label(parent, text='    %')
        self.percent.grid(row=0, column=2, sticky=Tkinter.W)
        self.canvas = Canvas(parent,
                             background='grey70',
                             width=width,
                             height=height)
        self.canvas.grid(row=0, column=1, sticky=Tkinter.W)
        self.canvas.create_rectangle(0,
                                     0,
                                     width,
                                     height,
                                     outline='black',
                                     width=self.bw)
        self.bar = self.canvas.create_rectangle(self.bw,
                                                self.bw,
                                                self.bw,
                                                self.cHeight,
                                                outline='#B05848',
                                                fill='#B05848',
                                                width=self.bw)
        self.update()

    def update(self):

        p = self.progress / self.total
        width = int(self.cWidth * p)
        self.canvas.coords(self.bar, self.bw, self.bw, width, self.cHeight)
        self.percent.set(' %3.1d' % int(100 * p) + "%")
        self.label.set(self.text)
        self.update_idletasks()
        if self.progress == self.total:
            time.sleep(0.1)
            self.close()

    def increment(self, n=1):

        p = self.progress + n
        self.progress = max(min(self.total, p), 0)
        self.update()

    def get(self):

        return self.progress / self.total

    def set(self, value):

        if value <= 1:
            self.progress = float(value) * self.total
        elif value <= self.total:
            self.progress = float(value)
        else:
            raise 'Cannot set to a value exceeding the total'

        self.update()

    def setText(self, text=''):
        self.text = text
        self.label.set(self.text)
Beispiel #19
0
class ScrolledCanvas(Frame):
    def __init__(self,
                 parent,
                 resizeCallback=None,
                 width=600,
                 height=600,
                 *args,
                 **kw):

        self.bbox = None
        self.busy = 0
        self.initialX = None
        self.initialY = None
        self.resizeCallback = resizeCallback

        apply(Frame.__init__, (self, parent) + args, kw)

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        self.menu = Menu(self, tearoff=0, include_event=True)
        self.configMenu()

        self.canvas = Canvas(self,
                             relief='flat',
                             borderwidth=0,
                             width=width,
                             height=height)
        self.canvas.configure(xscrollincrement=2, yscrollincrement=2)
        self.canvas.grid(row=0, column=0, sticky=Tkinter.NSEW)

        self.horizScrollbar = Tkinter.Scrollbar(self,
                                                bg=self.cget('bg'),
                                                command=self.canvas.xview,
                                                orient=Tkinter.HORIZONTAL,
                                                borderwidth=1)
        self.vertScrollbar = Tkinter.Scrollbar(self,
                                               bg=self.cget('bg'),
                                               command=self.canvas.yview,
                                               orient=Tkinter.VERTICAL,
                                               borderwidth=1)
        self.canvas.configure(xscrollcommand=self.horizScrollbar.set,
                              yscrollcommand=self.vertScrollbar.set)

        self.canvas.bind('<Configure>', self.resizeAfter)
        self.canvas.bind('<Button-1>', self.mouseButton1)
        self.canvas.bind('<Button-2>', self.mouseButton2)
        self.canvas.bind('<Button-3>', self.mouseButton3)
        self.canvas.bind('<ButtonRelease-1>', self.mouseButtonRelease1)
        self.canvas.bind('<ButtonRelease-2>', self.mouseButtonRelease2)
        self.canvas.bind('<B2-Motion>', self.mouseScroll)
        self.canvas.bind('<B3-Motion>', self.doNothing)
        self.canvas.bind('<Motion>', self.mouseEnter)
        self.canvas.bind('<Enter>', self.mouseEnter)

    def doNothing(self, event):

        pass

    def mouseEnter(self, event):

        if self.menu.winfo_ismapped():
            self.removeMenu()

    def refresh(self):

        self.bbox = self.canvas.bbox('all')
        bbox = self.bbox

        if not bbox:
            self.busy = 0
            return

        cWidth = int(self.canvas.cget('width'))
        cHeight = int(self.canvas.cget('height'))

        if cHeight > bbox[3] - bbox[1]:
            self.vertScrollbar.grid_forget()
        else:
            self.vertScrollbar.grid(row=0, column=1, sticky=Tkinter.NS)

        if cWidth > bbox[2] - bbox[0]:
            self.horizScrollbar.grid_forget()
        else:
            self.horizScrollbar.grid(row=1, column=0, sticky=Tkinter.EW)

        x1 = bbox[0]
        y1 = bbox[1]
        x2 = max(bbox[0] + cWidth, bbox[2])
        y2 = max(bbox[1] + cHeight, bbox[3])

        self.canvas.configure(scrollregion=(x1, y1, x2, y2))
        self.update_idletasks()
        self.busy = 0

    def printCanvas(self, *event):

        fileTypes = [FileType('PostScript', ['*.ps']), FileType('All', ['*'])]
        fileSelectPopup = FileSelectPopup(self,
                                          file_types=fileTypes,
                                          title='Print canvas to file',
                                          dismiss_text='Cancel',
                                          selected_file_must_exist=False)

        fileName = fileSelectPopup.getFile()

        self.bbox = bbox = self.canvas.bbox('all')
        w = bbox[2] - bbox[0]
        h = bbox[3] - bbox[1]
        self.canvas.postscript(colormode='color',
                               file=fileName,
                               x=bbox[0],
                               y=bbox[1],
                               width=w + 2,
                               pagewidth='21.c',
                               height=h + 2)

    def configMenu(self):

        items = [
            {
                'kind': 'command',
                'label': 'Print to file',
                'command': self.printCanvas
            },
        ]

        self.menu.setMenuItems(items)

    def removeMenu(self, *event):

        self.menu.unpost()

    def mouseButton3(self, event):

        self.menu.popupMenu(event)

    def mouseButton1(self, event):

        self.removeMenu()

        if not self.initialX:
            self.initialX = event.x
            self.initialY = event.y

    def mouseButton2(self, event):

        self.removeMenu()

        if not self.initialX:
            self.initialX = event.x
            self.initialY = event.y
            self.initialPX = self.horizScrollbar.get()[0]
            self.initialPY = self.vertScrollbar.get()[0]

    def mouseButtonRelease1(self, event):

        self.initialX = None
        self.initialY = None

    def mouseButtonRelease2(self, event):

        self.initialX = None
        self.initialY = None
        self.initialPX = None
        self.initialPY = None

    def mouseScroll(self, event):

        self.menu.unpost()
        bbox = self.bbox
        if not bbox:
            return
        bW = float(bbox[2] - bbox[0])
        bH = float(bbox[3] - bbox[1])
        cWidth = int(self.canvas.cget('width'))
        cHeight = int(self.canvas.cget('height'))

        if cWidth < bW:
            dx = self.initialX - event.x
            prop = self.initialPX + (dx / bW)
            self.canvas.xview('moveto', prop)

        if cHeight < bH:
            dy = self.initialY - event.y
            prop = self.initialPY + (dy / bH)
            self.canvas.yview('moveto', prop)

    def resizeAfter(self, event):

        if self.busy:
            return
        else:
            self.busy = 1
            self.removeMenu()
            self.after_idle(lambda: self.resize(event))

    def resize(self, event):

        if self.resizeCallback:
            self.after_idle(
                lambda: self.resizeCallback(event.width, event.height))
        self.canvas.configure(width=event.width, height=event.height)
        self.after_idle(self.refresh)
Beispiel #20
0
  def __init__(self, parent,
               # arguments below are Tkinter.Scrollbar options
               orient = Tkinter.HORIZONTAL,
               width = 15, borderwidth = 1,
               background = None, troughcolor = None,
               repeatdelay = 300, # msecs before repeat action on arrows and troughs
               repeatinterval = 100, # msecs between repeat action on arrows and troughs
               # arguments below are not Tkinter.Scrollbar options
               # callback is approximately same as Tkinter.Scrollbar command
               # option but has different (more convenient) arguments
               allow_resize = False, callback = None, relief='sunken',
               show_text = False, text_color = '#000000', text_func = None,
               units_scroll = 0.1, pages_scroll = 1.0,
               min_thickness = None, *args, **kw):

    assert orient in (Tkinter.HORIZONTAL, Tkinter.VERTICAL)
    if (show_text):
      assert text_func is not None

    self.relief = relief
    self.orient = orient
    self.callback = callback
    self.borderwidth = borderwidth
    self.repeatdelay = repeatdelay
    self.repeatinterval = repeatinterval
    self.show_text = show_text
    self.text_func = text_func
    self.units_scroll = units_scroll
    self.pages_scroll = pages_scroll
    self.min_thickness = min_thickness
    
    self.mode = 0
    self.lo = 0.0
    self.hi = 1.0
    self.first_pass = True

    Frame.__init__(self, parent, *args, **kw)

    if (background is None):
      bg = parent.cget('bg')
    else:
      bg = background

    if (troughcolor is None):
      bg_trough = scaleColor(self, bg, 0.9)
    else:
      bg_trough = troughcolor

    # below are for shadows
    
    if relief == 'sunken':
      color1 = scaleColor(self, bg_trough, 0.7)
      color2 = scaleColor(self, bg_trough, 1.2)
      color3 = scaleColor(self, bg, 1.2)
      color4 = scaleColor(self, bg, 0.7)
      
    elif relief == 'raised':
      color1  = scaleColor(self, bg_trough, 1.2)
      color2 = scaleColor(self, bg_trough, 0.7)
      color3 = scaleColor(self, bg, 0.7)
      color4 = scaleColor(self, bg, 1.2)
      
    else:
      color1 = color2 = scaleColor(self, bg_trough, 0.7)
      color3 = color4 = scaleColor(self, bg, 1.2)

    self.brColor = color4
    self.tlColor = color3
    
    defaultSize = 10 # gets overriden by other widgets in container
    # but need to do something otherwise canvas asks for too much space

    kw2 = {}
    if (orient == Tkinter.HORIZONTAL):
      kw2['width'] = defaultSize
      kw2['height'] = width
    else:
      kw2['width'] = width
      kw2['height'] = defaultSize

    self.canvas = c = Canvas(self, bg=bg, **kw2)
    # grid does not seem to work because once canvas size specified
    # in any way it never seems to be resized
    c.pack(side=Tkinter.TOP, expand=Tkinter.YES, fill=Tkinter.BOTH)

    self.tlOuter = c.create_polygon(0, 0, 0, 0, 0, 0,0, 0,fill=color1, outline='')
    self.brOuter = c.create_polygon(0, 0, 0, 0, 0, 0,0, 0,fill=color2, outline='')
    self.bgOuter = c.create_rectangle(0, 0, 0, 0, fill=bg_trough, outline='')


    # self.arrowXTl,Br are for shadows of the arrows
    # self.arrowXFill is for triangle infill
    # arrow and rectangle boundaries which are colored the
    # same as (and so in some sense are part of) the trough
    # the main part of the arrow does not need its own polygon
    # because it is the same color as the main rectangle
    self.arrow1Tl = c.create_polygon(0, 0, 0, 0, 0, 0, 0, 0,
                                    fill=color3, outline='')
    self.arrow1Br = c.create_polygon(0, 0, 0, 0, 0, 0, 0, 0,
                                    fill=color4, outline='')
    self.arrow1Fill = c.create_polygon(0, 0, 0, 0, 0, 0,
                                    fill=bg, outline='')
                                    
    self.arrow2Tl = c.create_polygon(0, 0, 0, 0, 0, 0, 0, 0,
                                    fill=color3, outline='')
    self.arrow2Br = c.create_polygon(0, 0, 0, 0, 0, 0, 0, 0,
                                    fill=color4, outline='')
    self.arrow2Fill = c.create_polygon(0, 0, 0, 0, 0, 0,
                                    fill=bg, outline='')

    # slider is the bit you grab in the middle
    # created with two triangles for the shadowsed border
    # with rectangle panel in middle
    
    self.tlSlider = c.create_polygon(0, 0, 0, 0, 0, 0,fill=color3, outline='')
    self.brSlider = c.create_polygon(0, 0, 0, 0, 0, 0,fill=color4, outline='')
    self.bgSlider = c.create_rectangle(0, 0, 0, 0, fill=bg, outline='')
    

    if (show_text):
      self.text0 = c.create_text(0, 0, fill=text_color)
      self.text1 = c.create_text(0, 0, fill=text_color)
      if (orient == Tkinter.HORIZONTAL):
        c.itemconfig(self.text0, anchor=Tkinter.W)
        c.itemconfig(self.text1, anchor=Tkinter.E)
      else:
        c.itemconfig(self.text0, anchor=Tkinter.S)
        c.itemconfig(self.text1, anchor=Tkinter.N)

    c.bind('<Configure>', self.configure)
    c.bind('<Button-1>', self.buttonPressMove)
    c.bind('<B1-Motion>', self.buttonMotionMove)
    c.bind('<ButtonRelease-1>', self.buttonReleaseMove) 
    if (allow_resize):
      c.bind('<Button-2>', self.buttonPressResize)
      c.bind('<B2-Motion>', self.resize)
Beispiel #21
0
class PulldownList(Frame):

    # if using indentation then should use list as stack only
    # in other words only delete or insert at end

    # There is a 1:1 correspondance between the ordered lists of texts and
    # list of objects

    # categories is the category name for each text/object
    # objects with the same category will go under a submenu
    # of that name

    def __init__(self,
                 parent,
                 callback=None,
                 texts=None,
                 objects=None,
                 categories=None,
                 colors=None,
                 index=0,
                 prefix='',
                 indent='',
                 initCallback=False,
                 forceCallback=False,
                 numbering=False,
                 arrowLine='#602000',
                 arrowFill='#B05848',
                 labelColor='#501000',
                 menuBg='#F0F0FF',
                 sticky='w',
                 *args,
                 **kw):

        Frame.__init__(self, parent, sticky=sticky, *args, **kw)

        self.callback = callback
        self.texts = texts or []
        self.objects = objects or []
        self.categories = categories or []
        self.colors = colors or []
        self.prefix = prefix
        self.indent = indent
        self.initCallback = initCallback
        self.numbering = numbering
        self.arrowLine = arrowLine
        self.arrowFill = arrowFill
        self.labelColor = labelColor

        # Current selection
        self.index = None
        self.object = NullText

        self.rows = []
        self.bg = self.cget('bg')
        self.label = Label(self, foreground=labelColor)
        self.canvas = Canvas(self, width=12, height=12, background=self.bg)
        self.menu = Menu(self.canvas,
                         tearoff=False,
                         bg=menuBg,
                         relief='solid',
                         borderwidth=1,
                         activeborderwidth=1)

        self.menu.images = []  # Photoimage has to remain referenced

        self.setup(self.texts, self.objects, index, self.colors,
                   self.categories)

        self.label.bind("<Button-1>", self._labelClick)
        self.menu.bind("<Leave>", self._leave)
        self.canvas.bind("<Button-1>", self._canvasClick)
        self.canvas.bind("<Configure>", self._resizeCallback)

        self.grid_columnconfigure(0, weight=1)
        self.label.grid(row=0, column=0, sticky='w')
        self.canvas.grid(row=0, column=1, sticky='w', padx=2)

    #
    # Retrieval
    #

    def get(self):

        return (self.getText(), self.getObject())

    def getSelected(self):

        return self.get()

    def getObject(self):

        return self._fetch(self.index, self.objects)

    def getText(self):

        return self._fetch(self.index, self.texts)

    def getSelectedIndex(self):

        return self.index

    #
    # Setting selected
    #

    def set(self, item):
        # Works with an object or a text

        index = None

        if item in self.texts:
            index = list(self.texts).index(item)

        elif item in self.objects:
            index = list(self.objects).index(item)

        if index is not None:
            self.setIndex(index)

    def setSelected(self, item):

        self.set(item)

    def setIndex(self, index, doCallback=False):

        self.index = index

        if self.objects:
            obj = self.objects[index]

            if obj is not self.object:
                self.object = obj

                if (doCallback
                        or self.initCallback) and self.texts and self.callback:
                    self.callback(obj)

        self._updateLabel()

    #
    # Bulk configuration
    #

    def clear(self):

        self.setup([], [], 0)

    def setup(self, texts, objects, index, colors=None, categories=None):

        self.texts = texts
        nTexts = len(texts)

        if not objects:
            objects = texts

        while len(objects) < nTexts:
            objects.append(None)

        self.objects = objects

        if colors is None:
            self.colors = [None] * nTexts
        else:
            while len(colors) < nTexts:
                colors.append(None)
            self.colors = colors

        if categories is None:
            self.categories = [None] * nTexts

        else:
            while len(categories) < nTexts:
                categories.append(None)
            self.categories = categories

        self._setMenuItems()

        self.setIndex(index or 0)

    #
    # In-place/minor configuration
    #

    def insert(self,
               index,
               text,
               object=None,
               color=None,
               category=None,
               select=False):

        index = max(0, min(len(self.texts), index))

        self.texts.insert(index, text)
        self.objects.insert(index, object)
        self.colors.insert(index, color)
        self.categories.insert(index, category)

        self._setMenuItems()

        if select:
            self.setIndex(index)

    def append(self,
               text,
               object=None,
               color=None,
               category=None,
               select=False):

        self.insert(len(self.texts),
                    text,
                    object=None,
                    color=None,
                    category=None,
                    select=False)

    def delete(self, index, howMany=1):

        if index < 0:
            return
        elif index >= len(self.texts):
            return

        end = min(index + howMany, len(self.texts))

        self._clearMenu()

        del self.texts[index:end]
        del self.objects[index:end]
        del self.colors[index:end]
        del self.categories[index:end]

        self._setMenuItems()

        index = min(len(self.texts) - 1, self.index)

        self.setIndex(index)

    #
    # Internal methods
    #

    def _leave(self, event):

        x = event.x
        y = event.y
        x1 = self.menu.winfo_width()
        y1 = self.menu.winfo_height()

        if (x < 0) or (y < 0) or (x >= x1) or (y >= y1):
            self._popdown()

    def _resizeCallback(self, *event):

        c = self.canvas
        w = c.winfo_width() - 1
        h = c.winfo_height() - 1
        c.delete('all')
        c.create_rectangle(0,
                           0,
                           10,
                           2,
                           fill=self.arrowFill,
                           outline=self.arrowLine)
        c.create_polygon(0,
                         4,
                         0,
                         6,
                         5,
                         11,
                         10,
                         6,
                         10,
                         4,
                         fill=self.arrowFill,
                         outline=self.arrowLine)

    def _fetch(self, index, array):

        if index is None:
            return None

        if index < 0:
            index += len(array)

        if index < 0:
            return None

        elif index >= len(array):
            return None

        else:
            return array[index]

    def _setMenuItems(self):
        self._clearMenu()
        self.menu.images = []  # Clear photoimages

        if not self.texts and not self.menu.entrycget(1, 'label'):

            item = {'kind': 'command', 'label': NullText, 'command': None}
            self.menu.addMenuItem(item)
            self.rows = [0]

            return

        topList = []
        categoryDict = {}

        for i in range(len(self.texts)):
            text = self.texts[i]
            color = self.colors[i]
            category = self.categories[i]

            if category:
                if categoryDict.get(category) is None:
                    categoryDict[category] = []
                    topList.append((None, category, None, category))

                categoryDict[category].append((i, text, color))

            else:
                topList.append((i, text, color, None))

        row = 0
        for index, text, color, cat in topList:
            columnbreak = 0
            if row and row % 20 == 0:
                columnbreak = 1

            if cat:
                string = (self.indent * row) + self.prefix + text
                items = []

                rowB = 0
                for index2, text2, color2 in categoryDict.get(cat, []):
                    columnbreakB = 0
                    if rowB and rowB % 20 == 0:
                        columnbreakB = 1

                    if self.numbering:
                        number = '%d%. ' % (index2 + 1)
                    else:
                        number = ''

                    string2 = number + self.prefix + text2
                    command = lambda n=index2: self.setIndex(n, True)
                    if color2:
                        image = self._makeColorTile(color2)
                        item2 = {
                            'kind': 'command',
                            'accelerator': string2,
                            'command': command,
                            'image': image,
                            'columnbreak': columnbreakB
                        }
                    else:
                        item2 = {
                            'kind': 'command',
                            'label': string2,
                            'command': command,
                            'columnbreak': columnbreakB
                        }

                    items.append(item2)
                    self.rows.append(row)
                    rowB += 1

                item = {
                    'kind': 'cascade',
                    'label': string,
                    'submenu': items,
                    'columnbreak': columnbreak
                }

            else:

                if self.numbering:
                    number = '%d%. ' % (index + 1)
                else:
                    number = ''

                string = (self.indent * row) + number + self.prefix + text
                command = lambda n=index: self.setIndex(n, True)

                if color:
                    image = self._makeColorTile(color)
                    item = {
                        'kind': 'command',
                        'accelerator': string,
                        'command': command,
                        'image': image,
                        'columnbreak': columnbreak
                    }
                else:
                    item = {
                        'kind': 'command',
                        'label': string,
                        'command': command,
                        'columnbreak': columnbreak
                    }

            self.menu.addMenuItem(item)
            self.rows.append(row)

            row += 1

    def _clearMenu(self):

        self.menu.delete(0, 'end')
        self.index = 0
        self.rows = []

    def _popdown(self, *event):

        self.menu.unpost()

    def _labelClick(self, event):

        s = self.rows[self.index]
        #x = event.x_root - event.x + 2 + self.label.winfo_width()
        x = event.x_root - 2
        y = event.y_root - event.y - max(0,
                                         s) * (self.label.winfo_height() + 1)
        self.menu.post(x, y)

    def _canvasClick(self, event):

        s = self.rows[self.index]
        x = event.x_root - event.x + 2
        y = event.y_root - event.y - max(0,
                                         s) * (self.label.winfo_height() + 1)
        self.menu.post(x, y)

    def _updateLabel(self):

        if self.texts:
            text = self.texts[self.index] or NullText
        else:
            text = NullText

        self.label.set(text=text)

    def _makeColorTile(self, color):

        image = Tkinter.PhotoImage()
        self.menu.images.append(image)

        if type(color) == type([]):
            colors = [scaleColor(self.menu, c, 1.0) for c in color]
        else:
            colors = [
                scaleColor(self.menu, color, 1.0),
            ]

        cols = max(8, len(colors))

        for x in range(cols):
            i = x % len(colors)
            c = colors[i]

            for y in range(16):
                image.put('{%s %s}' % (c, c), to=(2 * x, y))

        return image
Beispiel #22
0
    def __init__(self, parent, scrollX=True, scrollY=True, *args, **kw):

        self.parent = parent
        self.scrollX = scrollX
        self.scrollY = scrollY

        self.prototypes = []
        self.nodes = []
        self.node = None  # Selected
        self.links = []
        self.link = None  # Selected
        self.objDict = {}  # Map canvas to nodes, links
        self.cornerDict = {}
        self.editWidget = None
        self.mouseOver = None
        self.inMotion = None
        self.inMotion2 = None
        self.inMotion3 = None
        self.dragRegion = None
        self._resizeBusy = False

        self.selectedNodes = []
        self.selectedLinks = []
        self.highlightNodes = []
        self.highlightLinks = []

        kw['relief'] = 'flat'
        kw['borderwidth'] = 0

        Frame.__init__(self, parent, *args, **kw)

        self.canvas = canvas = Canvas(self, relief='flat', borderwidth=0)
        self.canvas.configure(xscrollincrement=2,
                              yscrollincrement=2,
                              bg=self.cget('bg'))
        self.canvas.grid(row=0, column=0, sticky='nsew')

        if scrollX:
            self.horizScrollbar = Tkinter.Scrollbar(self,
                                                    bg=self.cget('bg'),
                                                    command=self.canvas.xview,
                                                    orient=Tkinter.HORIZONTAL,
                                                    borderwidth=1)
            self.canvas.configure(xscrollcommand=self.horizScrollbar.set)

        if scrollY:
            self.vertScrollbar = Tkinter.Scrollbar(self,
                                                   bg=self.cget('bg'),
                                                   command=self.canvas.yview,
                                                   orient=Tkinter.VERTICAL,
                                                   borderwidth=1)
            self.canvas.configure(yscrollcommand=self.vertScrollbar.set)

        canvas.bind('<Button-1>', self._mouseSingleClick)
        if not isWindowsOS():
            canvas.bind('<Button-4>', self.scrollUp)
            canvas.bind('<Button-5>', self.scrollDown)
        else:
            canvas.bind('<MouseWheel>', self._windowsOsScroll)

        canvas.bind('<Double-1>', self._mouseDoubleClick)
        canvas.bind('<B1-Motion>', self._mouseDrag)
        canvas.bind('<ButtonRelease-1>', self._mouseRelease)
        canvas.bind('<Motion>', self._mouseEnter)
        canvas.bind('<Enter>', self._mouseEnter)
        canvas.bind('<Leave>', self._mouseLeave)
        canvas.bind('<KeyPress-Up>', self._moveUp)
        canvas.bind('<KeyPress-Down>', self._moveDown)
        canvas.bind('<KeyPress-Right>', self._moveRight)
        canvas.bind('<KeyPress-Left>', self._moveLeft)
        canvas.bind('<KeyPress-Delete>', self.deleteSelected)
        self.bind('<Configure>', self._resizeAfter)

        self.menu = Menu(self, tearoff=False)

        alignItems = [{
            'kind': 'command',
            'label': 'Y axis',
            'command': self._alignHorizontal
        }, {
            'kind': 'command',
            'label': 'X axis',
            'command': self._alignVertical
        }]

        distributeItems = [{
            'kind': 'command',
            'label': 'Horizontal',
            'command': self._distributeHorizontal
        }, {
            'kind': 'command',
            'label': 'Verical',
            'command': self._distributeVertical
        }]

        menuItems = [
            {
                'kind': 'cascade',
                'label': 'Align',
                'submenu': alignItems
            },  #0
            {
                'kind': 'cascade',
                'label': 'Distribute',
                'submenu': distributeItems
            },  #1
            {
                'kind': 'command',
                'label': 'Link Selected',
                'command': self.linkSelected
            },  #2
            {
                'kind': 'command',
                'label': 'Reset Links',
                'command': self._resetLinks
            },  #3
            {
                'kind': 'separator'
            },
            {
                'kind': 'command',
                'label': 'Delete Links',  #5
                'command': self.deleteLinks
            },
            {
                'kind': 'command',
                'label': 'Delete Items',  #6
                'command': self.deleteNodes
            },
            {
                'kind': 'separator'
            },
            {
                'kind': 'command',
                'label': 'Save PostScript File',
                'command': self.printCanvas
            },
        ]

        self.menuItems = menuItems
        self.menu.setMenuItems(menuItems)

        canvas.bind('<ButtonPress-3>', self._popupMenu)

        self._drawAfter()
Beispiel #23
0
    def __init__(self,
                 parent,
                 numButtons,
                 state=None,
                 orient='h',
                 background=None,
                 selectColor='#C0C0FF',
                 size=15,
                 callback=None,
                 label=None,
                 grid=None,
                 *args,
                 **kw):

        self.numButtons = numButtons
        self.orient = orient
        self.selectColor = selectColor
        self.size = size
        self.callback = callback
        self.state = state or [False] * numButtons
        self.canvasDict = {}
        self.canvasNums = {}
        self.initialN = None
        self.initialS = None

        if (background is None):
            self.bg = parent.cget('bg')
        else:
            self.bg = background

        Frame.__init__(self, parent, grid=grid, *args, **kw)

        self.bgLight = scaleColor(self, self.bg, 1.5)
        self.bgDark = scaleColor(self, self.bg, 0.4)
        self.bgLight2 = scaleColor(self, self.bg, 1.2)
        self.bgDark2 = scaleColor(self, self.bg, 0.7)

        if label:
            self.label = Label(self, text=label, tipText=TOOL_TIP)
            self.label.grid(row=0, column=0, sticky=Tkinter.EW)
            if orient in (Tkinter.HORIZONTAL, 'horizontal', 'h'):
                c_row = 0
                c_col = 1
            else:
                c_row = 1
                c_col = 0
        else:
            self.label = None

        if orient in (Tkinter.HORIZONTAL, 'horizontal', 'h'):
            self.orient = 'h'
            self.canvas = c = Canvas(self, bg=self.bg, height=size)
            self.grid_columnconfigure(c_col, weight=1)
        else:
            self.orient = 'v'
            self.canvas = c = Canvas(self, bg=self.bg, width=size)
            self.grid_rowconfigure(c_row, weight=1)

        c.grid(row=c_row, column=c_col, sticky='nsew')

        c.bind('<Configure>', self.resizeCanvas)
        c.bind('<Button-1>', self.slideState)
        c.bind('<B1-Motion>', self.slideState)
        c.bind('<ButtonRelease-1>', self.slideStateDone)
        c.bind('<Button-2>', self.clickState)
        c.bind('<B2-Motion>', self.clickState)
        c.bind('<ButtonRelease-2>', self.clickStateDone)
Beispiel #24
0
class PulldownMenu(Frame):

    # if using indentation then should use list as stack only
    # in other words only delete or insert at end

    # entries entries must have attribute text_attr or if this is
    # None then assume that entries entries themselves provide name

    def __init__(self,
                 parent,
                 callback=None,
                 entries=None,
                 text_attr=None,
                 colors=None,
                 outline='#602000',
                 fill='#B05848',
                 label_color='#501000',
                 selected_index=-1,
                 indent='',
                 extra='',
                 sticky='w',
                 do_initial_callback=True,
                 force_callback=False,
                 *args,
                 **kw):

        if (entries is None):
            entries = []

        Frame.__init__(self, parent, sticky=sticky, *args, **kw)

        self.text_attr = text_attr

        #indentation and extra string for popup information
        self.indent = indent
        self.extra = extra

        self.callback = callback
        self.do_initial_callback = do_initial_callback
        self.force_callback = force_callback

        frame = Frame(self)
        #frame = parent
        self.frame = frame
        self.bg = frame.cget('bg')
        self.outline = outline
        self.fill = fill
        self.label_color = label_color

        self.menu = Menu(parent, tearoff=0, borderwidth=1, activeborderwidth=1)
        self.menu.images = []
        self.label = Label(self, foreground=label_color)

        self.first_pass = True
        #self.entries = entries
        self.entries = []
        self.colors = []
        self.setup(entries, selected_index, colors=colors)

        s = 10
        self.canvas = Canvas(self, width=s, height=s, background=self.bg)

        self.label.bind("<Button-1>", self.labelPopup)
        # below does not work for some reason
        #self.bind("<Button-1>", self.labelPopup)

        # below does not work any more since can have submenus and
        # no way to reach those with below since involves leaving menu
        #self.menu.bind("<Leave>", self.popdown)
        self.menu.bind("<Leave>", self.leave)
        self.menu.bind("<Button-1>", self.buttonPress)
        self.poppedUpSubmenu = False

        self.canvas.bind("<Button-1>", self.canvasPopup)
        self.canvas.bind("<Configure>", self.resizeCallback)

        self.label.grid(row=0, column=0, sticky=Tkinter.W)
        self.canvas.grid(row=0, column=1, sticky=Tkinter.E, padx=2)

    def leave(self, event):

        if (not self.poppedUpSubmenu):
            x = event.x
            y = event.y
            x1 = self.menu.winfo_width()
            y1 = self.menu.winfo_height()

            if (x < 0) or (y < 0) or (x >= x1) or (y >= y1):
                self.popdown()

    def buttonPress(self, event):

        if (event.widget != self.menu):
            return

        for n in range(len(self.entries) - 1, -1, -1):
            if event.y >= self.menu.yposition(n):
                break
        else:
            return

        item = self.entries[n]
        if (isinstance(item, {}.__class__) and item['kind'] == 'cascade'):
            self.poppedUpSubmenu = True
        else:
            self.poppedUpSubmenu = False

    def resizeCallback(self, *event):

        w = self.canvas.winfo_width() / 2
        h = self.canvas.winfo_height() / 2
        self.canvas.delete('all')
        self.canvas.create_polygon(1,
                                   1,
                                   w,
                                   2 * h - 1,
                                   2 * w - 1,
                                   1,
                                   fill=self.fill,
                                   outline=self.outline)

    def getEntry(self, entry_index, entries=None):

        if not entries:
            entries = self.entries

        if type(entry_index) == types.TupleType:
            e = entry_index[0]
            if len(entry_index) > 1:
                items = entries[e]['submenu']
                entry = self.getEntry(entry_index[1:], items)
            else:
                entry = entries[e]['label']
        elif (entry_index >= 0):
            entry = entries[entry_index]
        else:
            entry = None

        return entry

    def getEntryText(self, entry_index, entries=None):

        if not entries:
            entries = self.entries

        if type(entry_index) in (types.TupleType, types.ListType):
            e = entry_index[0]
            if len(entry_index) > 1:
                items = entries[e]['submenu']
                text = self.getEntryText(entry_index[1:], items)
            else:
                text = entries[e]['label']
        elif (entry_index != -1):
            #print 'getEntryText', entry_index, entries
            entry = entries[entry_index]
            if (self.text_attr):
                text = getattr(entry, self.text_attr)
            else:
                text = entry
        else:
            text = ''

        # TBD: for now text returned should not be unicode
        text = str(text)
        # below did not work for one person (Chinese characters??) but above did
        ###text = text.encode('utf-8')

        return text

    def setup(self, entries, selected_index, first_pass=True, colors=None):

        #print 'setup', entries, selected_index
        if first_pass is not None:
            self.first_pass = first_pass

        self.clearMenuItems()
        if (entries):
            e = list(entries)
        else:
            e = [No_entries_label]

        self.entries = e
        self.colors = colors or [None] * len(e)

        if type(selected_index) in (types.TupleType, types.ListType):
            if (not selected_index or selected_index[0] >= len(entries)):
                selected_index = -1
        else:
            if (selected_index >= len(entries)):
                selected_index = -1

        if (selected_index == -1):
            selected_index = 0

        self.selected_index = -1  # changed in setSelectedIndex()
        self.setMenuItems()
        self.setSelectedIndex(selected_index)

    def substituteCascadeCallbacks(self, item, selected_index):

        if (item['kind'] == 'cascade'):
            n = 0
            for subitem in item['submenu']:
                self.substituteCascadeCallbacks(subitem, selected_index + [n])
                n = n + 1
        else:
            callback = item.get('command')
            if (callback):
                label = item['label']
                item['command'] = lambda: self.cascadeCallback(
                    callback, label, tuple(selected_index))

    def cascadeCallback(self, callback, label, selected_index):

        self.selected_index = selected_index
        self.setLabel(selected_index)
        callback(selected_index, label)

    def setMenuItems(self):

        self.menu.images = []
        for n in range(len(self.entries)):
            columnbreak = 0
            if n and n % 20 == 0:
                columnbreak = 1
            item = self.entries[n]
            color = None
            if n < len(self.colors):
                color = self.colors[n]

            if isinstance(item, {}.__class__):
                if (item['kind'] == 'cascade'):
                    self.substituteCascadeCallbacks(item, [n])
            else:
                t = (self.indent * n) + self.extra + str(self.getEntryText(n))
                command = lambda n=n: self.setSelectedIndex(n)
                if color:
                    image = self.makeColorTile(color)
                    item = {
                        'kind': 'command',
                        'accelerator': t,
                        'command': command,
                        'image': image,
                        'columnbreak': columnbreak
                    }
                else:
                    item = {
                        'kind': 'command',
                        'label': t,
                        'command': command,
                        'columnbreak': columnbreak
                    }
            self.menu.addMenuItem(item)

    def clearMenuItems(self):

        if self.entries:
            self.menu.delete(0, len(self.entries))

    # below assumes entry_index is integer not tuple
    def insert(self, entry_index, entry, make_selected=False, color=None):

        if (self.haveNoEntries()):
            if (entry_index != 0):
                return
        elif ((entry_index < 0) or (entry_index >= len(self.entries))):
            return

        self.clearMenuItems()
        self.checkForNone()
        self.entries.insert(entry_index, entry)
        self.colors.insert(entry_index, color)
        self.setMenuItems()

        if (make_selected or (self.selected_index == -1)):
            self.setSelectedIndex(entry_index, force_callback=True)
        else:
            self.setSelectedIndex(self.selected_index)

    # below assumes entry is integer not tuple
    def append(self, entry, make_selected=False, color=None):

        self.clearMenuItems()
        self.checkForNone()
        self.entries.append(entry)
        self.colors.append(color)
        self.setMenuItems()

        if (make_selected or (self.selected_index == -1)):
            self.setSelectedIndex(len(self.entries) - 1, force_callback=True)
        else:
            self.setSelectedIndex(self.selected_index)

    def checkForNone(self):

        if (self.haveNoEntries()):
            self.entries = []
            self.colors = []
            self.menu.delete(0)

    def haveNoEntries(self):

        if (len(self.entries) == 1 and self.entries[0] == No_entries_label):
            return True
        else:
            return False

    def baseIndex(self, ind):

        if type(ind) == types.TupleType:
            ind = ind[0]

        return ind

    # below assumes entry_index is integer not tuple
    def delete(self, entry_index, n=1):

        if (self.haveNoEntries()):
            return

        if ((entry_index < 0) or (entry_index >= len(self.entries))):
            return

        self.clearMenuItems()

        n1 = entry_index
        n2 = n1 + n

        m = self.baseIndex(self.selected_index)

        del self.entries[n1:n2]
        del self.colors[n1:n2]

        if (not self.entries):
            self.entries = [No_entries_label]
            self.colors = [None]

        self.setMenuItems()

        if ((m >= n1) and (m < n2)):
            if (n1 == 0):
                selected_index = 0
            else:
                selected_index = n1 - 1
            self.setSelectedIndex(selected_index, force_callback=True)

    def replace(self, entries, selected_index=-1, colors=None):

        self.menu.delete(0, len(self.entries))
        self.setup(entries, selected_index, first_pass=False, colors=colors)

    def popdown(self, *event):

        self.menu.unpost()

    def setLabel(self, selected_index):

        text = self.getEntryText(selected_index)
        if (not text):
            text = self.extra  # arbitrary

        self.label.set(text=text)

    def labelPopup(self, event):

        self.poppedUpSubmenu = False

        s = self.baseIndex(self.selected_index)
        x = event.x_root - event.x + 2
        y = event.y_root - event.y - \
            max(0, s) * (self.label.winfo_height() + 1)
        self.menu.post(x, y)

    def canvasPopup(self, event):

        s = self.baseIndex(self.selected_index)
        x = event.x_root - event.x - self.label.winfo_width() + 2
        y = event.y_root - event.y - \
            max(0, s) * (self.label.winfo_height() + 1) + \
            self.canvas.winfo_height() - self.label.winfo_height()
        self.menu.post(x, y)

    def getSelectedIndex(self):

        return self.selected_index

    def setSelectedIndex(self, selected_index, force_callback=False):

        if (force_callback or self.force_callback or \
            (selected_index != self.selected_index)):

            #print 'setSelectedIndex', self.entries, selected_index, self.selected_index, self.first_pass
            self.selected_index = selected_index
            self.setLabel(selected_index)

            if (self.callback):
                if (self.haveNoEntries()):
                    if (not self.first_pass):
                        self.callback(-1, None)
                elif (selected_index != -1):
                    if (not self.first_pass or self.do_initial_callback):
                        self.callback(selected_index,
                                      self.entries[selected_index])

        self.first_pass = False

    def get(self):

        return self.getSelected()

    def getSelected(self):

        ind = self.getSelectedIndex()

        if (ind == -1):
            return None
        else:
            return self.getEntry(ind)

    def set(self, selected):

        self.setSelected(selected)

    def findEntryIndex(self, entry, entries=None):

        #print 'findEntryIndex1', entry, entries
        if (entries):
            noEntries = True
        else:
            noEntries = False
            entries = self.entries
            try:
                ind = entries.index(entry)
                return ind
            except:
                pass

        #print 'findEntryIndex2', entry, entries
        for n in range(len(entries)):
            e = entries[n]
            #print 'findEntryIndex3', entry, e
            if e == entry:
                if noEntries:
                    return [n]
                else:
                    return n
            elif type(e) == types.DictType:
                if (len(entries) > 1):
                    try:
                        ind = self.findEntryIndex(entry, e['submenu'])
                        return [n] + ind
                    except:
                        pass
                else:
                    if (entry == e['label']):
                        return [n]

        raise 'unknown entry "%s"' % entry

    # selects first item found in entries which matches
    def setSelected(self, selected):

        #print 'setSelected1', selected, type(selected), self.entries
        try:
            selected_index = self.findEntryIndex(selected)
        except:
            #selected_index = -1
            return

        #print 'setSelected2', selected_index
        self.setSelectedIndex(selected_index)

    def makeColorTile(self, color):

        image = Tkinter.PhotoImage()
        self.menu.images.append(image)

        if type(color) == type([]):
            colors = [scaleColor(self.menu, c, 1.0) for c in color]
        else:
            colors = [
                scaleColor(self.menu, color, 1.0),
            ]

        cols = max(8, len(colors))

        for x in range(cols):
            i = x % len(colors)
            c = colors[i]

            for y in range(16):
                image.put('{%s %s}' % (c, c), to=(2 * x, y))

        return image
Beispiel #25
0
    def __init__(self,
                 parent,
                 callback=None,
                 entries=None,
                 text_attr=None,
                 colors=None,
                 outline='#602000',
                 fill='#B05848',
                 label_color='#501000',
                 selected_index=-1,
                 indent='',
                 extra='',
                 sticky='w',
                 do_initial_callback=True,
                 force_callback=False,
                 *args,
                 **kw):

        if (entries is None):
            entries = []

        Frame.__init__(self, parent, sticky=sticky, *args, **kw)

        self.text_attr = text_attr

        #indentation and extra string for popup information
        self.indent = indent
        self.extra = extra

        self.callback = callback
        self.do_initial_callback = do_initial_callback
        self.force_callback = force_callback

        frame = Frame(self)
        #frame = parent
        self.frame = frame
        self.bg = frame.cget('bg')
        self.outline = outline
        self.fill = fill
        self.label_color = label_color

        self.menu = Menu(parent, tearoff=0, borderwidth=1, activeborderwidth=1)
        self.menu.images = []
        self.label = Label(self, foreground=label_color)

        self.first_pass = True
        #self.entries = entries
        self.entries = []
        self.colors = []
        self.setup(entries, selected_index, colors=colors)

        s = 10
        self.canvas = Canvas(self, width=s, height=s, background=self.bg)

        self.label.bind("<Button-1>", self.labelPopup)
        # below does not work for some reason
        #self.bind("<Button-1>", self.labelPopup)

        # below does not work any more since can have submenus and
        # no way to reach those with below since involves leaving menu
        #self.menu.bind("<Leave>", self.popdown)
        self.menu.bind("<Leave>", self.leave)
        self.menu.bind("<Button-1>", self.buttonPress)
        self.poppedUpSubmenu = False

        self.canvas.bind("<Button-1>", self.canvasPopup)
        self.canvas.bind("<Configure>", self.resizeCallback)

        self.label.grid(row=0, column=0, sticky=Tkinter.W)
        self.canvas.grid(row=0, column=1, sticky=Tkinter.E, padx=2)
Beispiel #26
0
class ColorChooser(Frame):
    def __init__(self, parent, *args, **kw):

        apply(Frame.__init__, (self, parent) + args, kw)

        self.grid_rowconfigure(0, weight=1)
        self.grid_rowconfigure(1, weight=0)
        self.grid_rowconfigure(2, weight=0)
        self.grid_rowconfigure(3, weight=0)

        self.canvas = Canvas(self, relief='sunken', borderwidth=2, width=150)
        self.canvas.grid(row=0,
                         column=1,
                         columnspan=1,
                         sticky=Tkinter.NSEW,
                         pady=2,
                         padx=2)

        frame = Frame(self)
        frame.grid_columnconfigure(1, weight=1)
        self.boxSize = 100
        self.numPixels = 10
        self.pixelWidth = round(self.boxSize / self.numPixels)
        self.colorBox = Canvas(frame,
                               relief='sunken',
                               borderwidth=2,
                               width=self.boxSize + 2,
                               height=self.boxSize + 2)
        self.colorBox.bind('<Button-1>', self.pickInColorBox)
        self.colorBox.bind('<Button-2>', self.pickInColorBox)
        self.colorBox.bind('<Button-3>', self.pickInColorBox)
        self.colorBox.grid(row=0,
                           column=2,
                           rowspan=3,
                           sticky=Tkinter.NSEW,
                           padx=4,
                           pady=4)
        self.pixel = []
        self.colors = []
        self.setupColorBox()
        self.scale = Tkinter.Scale(frame,
                                   orient=Tkinter.VERTICAL,
                                   length=self.boxSize,
                                   from_=0,
                                   to=99,
                                   label='',
                                   showvalue=0,
                                   command=self.refreshColorBox)
        self.scale.grid(row=0,
                        column=3,
                        rowspan=3,
                        sticky=Tkinter.NS,
                        padx=4,
                        pady=4)
        frame.grid(row=1, column=0, columnspan=2, sticky=Tkinter.NSEW)

        labels = ('Red', 'Green', 'Blue')
        self.labeled_scale = 3 * [None]

        for n in range(3):

            label = Label(frame, text=labels[n] + ':', anchor=Tkinter.W)
            label.grid(row=n, column=0, sticky=Tkinter.EW)

            self.labeled_scale[n] = LabeledScale(
                frame,
                values=range(101),
                label_format='%3d',
                set_callback=self.scaleCallback)
            self.labeled_scale[n].grid(row=n, column=1, sticky=Tkinter.EW)

    def setupColorBox(self):

        pw = self.pixelWidth
        np = self.numPixels
        for x in range(np):
            self.pixel.append([])
            self.colors.append([])
            for y in range(np):
                rgb = hsbToRgb(0, 1 - x / float(np), 1 - y / float(np))
                c = '#%02x%02x%02x' % (rgb[0] * 255, rgb[1] * 255,
                                       rgb[2] * 255)
                p = self.colorBox.create_rectangle(2 + pw * x,
                                                   2 + pw * y,
                                                   2 + (pw * x) + pw,
                                                   (2 + pw * y) + pw,
                                                   outline=c,
                                                   fill=c)
                self.pixel[x].append(p)
                self.colors[x].append(rgb)

    def pickInColorBox(self, event):

        x = int(event.x / self.pixelWidth)
        y = int(event.y / self.pixelWidth)
        X = min(x, self.numPixels - 1)
        Y = min(y, self.numPixels - 1)
        x = max(X, 0)
        y = max(Y, 0)

        rgb = self.colors[x][y]
        self.setColor(rgb[0], rgb[1], rgb[2])

    def refreshColorBox(self, H):

        np = self.numPixels
        H = int(H) / 100.
        for x in range(np):
            for y in range(np):
                rgb = hsbToRgb(H, 1 - x / float(np), 1 - y / float(np))
                c = '#%02x%02x%02x' % (rgb[0] * 255, rgb[1] * 255,
                                       rgb[2] * 255)
                self.colorBox.itemconfigure(self.pixel[x][y],
                                            outline=c,
                                            fill=c)
                self.colors[x][y] = rgb

    def scaleCallback(self, *index):

        c = 3 * [0]
        for n in range(3):
            c[n] = int(2.559 * float(self.labeled_scale[n].getValue()))

        color = '#%02x%02x%02x' % (c[0], c[1], c[2])
        self.canvas.config(bg=color)

    def setColor(self, r, g, b):

        c = (r, g, b)
        for n in range(3):
            s = round(100.0 * c[n])
            s = min(100, s)
            self.labeled_scale[n].set(s)

    def getColor(self):

        c = 3 * [0]
        for n in range(3):
            c[n] = float(self.labeled_scale[n].getValue()) / 100.0

        return tuple(c)