Source code for gui.toolbar

#
##
##  This file is part of pyFormex 1.0.7  (Mon Jun 17 12:20:39 CEST 2019)
##  pyFormex is a tool for generating, manipulating and transforming 3D
##  geometrical models by sequences of mathematical operations.
##  Home page: http://pyformex.org
##  Project page:  http://savannah.nongnu.org/projects/pyformex/
##  Copyright 2004-2019 (C) Benedict Verhegghe (benedict.verhegghe@ugent.be)
##  Distributed under the GNU General Public License version 3 or later.
##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation, either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program.  If not, see http://www.gnu.org/licenses/.
##
"""Toolbars for the pyFormex GUI.

This module defines the functions for creating the pyFormex window toolbars.
"""
from __future__ import absolute_import, division, print_function

import pyformex as pf
from pyformex import utils
from pyformex.gui import QtGui, QPixmap
from pyformex.gui import widgets


################### General Button Functions ###########

[docs]def addButton(toolbar, tooltip, icon, func, repeat=False, toggle=False, checked=False, icon0=None, enabled=True): """Add a button to a toolbar. - `toolbar`: the toolbar where the button will be added - `tooltip`: the text to appear as tooltip - `icon`: name of the icon to be displayed on the button, - `func`: function to be called when the button is pressed, - `repeat`: if True, the `func` will repeatedly be called if button is held down. - `toggle`: if True, the button is a toggle and stays in depressed state until pressed again. - `checked`: initial state for a toggle buton. - `icon1`: for a toggle button, icon to display when button is not checked. """ iconset = QtGui.QIcon() icon_on = QPixmap(utils.findIcon(icon)) iconset.addPixmap(icon_on, QtGui.QIcon.Normal, QtGui.QIcon.On) if toggle and icon0: icon_off = QPixmap(utils.findIcon(icon0)) iconset.addPixmap(icon_off, QtGui.QIcon.Normal, QtGui.QIcon.Off) a = toolbar.addAction(iconset, tooltip, func) a.setEnabled(enabled) b = toolbar.widgetForAction(a) if repeat: b.setAutoRepeat(True) b.setAutoRepeatDelay(500) b.clicked.connect(a.trigger) if toggle: b.setCheckable(True) b.clicked.connect(b.toggle) b.setChecked(checked) b.setToolTip(tooltip) return b
[docs]def removeButton(toolbar, button): """Remove a button from a toolbar.""" toolbar.removeAction(button)
################### Script action toolbar ###########
[docs]def addActionButtons(toolbar): """Add the script action buttons to the toolbar.""" from pyformex.gui import draw from pyformex.gui.menus import File action = {} avail_buttons = [ ("Play", "next", draw.play, False), ("ReRun", "rerun", draw.replay, False), ## ( "Step", "nextstop", draw.step, False ), ("Continue", "ff", draw.fforward, False), ("Stop", "stop", draw.raiseExit, False), ("Edit", "pencil", File.editApp, False), ("Info", "info", draw.showDoc, False), ] # Filter configured buttons show_buttons = pf.cfg['gui/actionbuttons'] show_buttons = [b for b in avail_buttons if b[0].lower() in show_buttons] for name, icon, func, enabled in show_buttons: action[name] = addButton(toolbar, '', icon, func, enabled=enabled) return action
################# Camera action toolbar ###############
[docs]def addCameraButtons(toolbar): """Add the camera buttons to a toolbar.""" # The buttons have the following fields: # 0 : tooltip # 1 : icon # 2 : function # optional: # 3 : REPEAT (default True) from pyformex.gui.menus import Camera buttons = [["Rotate left", "rotleft", Camera.rotLeft], ["Rotate right", "rotright", Camera.rotRight], ["Rotate up", "rotup", Camera.rotUp], ["Rotate down", "rotdown", Camera.rotDown], ["Twist left", "twistleft", Camera.twistLeft], ["Twist right", "twistright", Camera.twistRight], ["Translate left", "left", Camera.panLeft], ["Translate right", "right", Camera.panRight], ["Translate down", "down", Camera.panDown], ["Translate up", "up", Camera.panUp], ["Zoom Out", "zoomout", Camera.dollyOut], ["Zoom In", "zoomin", Camera.dollyIn], ["Zoom Rectangle", "zoomrect", Camera.zoomRectangle, False], ["Zoom All", "zoomall", Camera.zoomAll, False], ] for but in buttons: icon = widgets.pyformexIcon(but[1]) a = toolbar.addAction(icon, but[0], but[2]) b = toolbar.children()[-1] # Get the QToolButton for the last action if len(but) < 4 or but[3]: b.setAutoRepeat(True) b.setAutoRepeatDelay(500) # This causes a double action on the button click # only use it if we can detach the button press from trigger #b.released.connect(a.trigger) if len(but) >= 5: # This is currently not used b.setCheckable(but[4]) b.released.connect(a.toggle) b.setToolTip(but[0])
####################################################################### # Viewport Toggle buttons # ########################### class Toggle(object): def __init__(self, state=False): self.state = state def toggle(self, onoff=None): if onoff is None: onoff = not self.state self.state = onoff class ViewportToggleButton(object): def __init__(self, toolbar, tooltip, icon, func, attr, checked=False, icon0=None): self.button = addButton(toolbar, tooltip, icon, func, toggle=True, icon0=icon0) self.attr = attr def updateButton(self): """Update the button to current viewport state.""" #print "UPDATE TOGGLE %s" % attr vp = pf.GUI.viewports.current if vp == pf.canvas: self.setChecked(vp.settings[self.attr]) pf.GUI.processEvents() def toggle(self, attr, state=None): """Update the corresponding viewport attribute. This does not update the button state. """ vp = pf.GUI.viewports.current vp.setToggle(attr, state) vp.update() pf.GUI.processEvents()
[docs]def toggleButton(attr, state=None): """Update the corresponding viewport attribute. This does not update the button state. """ vp = pf.GUI.viewports.current vp.setToggle(attr, state) vp.update() pf.GUI.processEvents()
[docs]def updateButton(button, attr): """Update the button to correct state.""" if button: vp = pf.GUI.viewports.current button.setChecked(vp.settings[attr]) pf.GUI.processEvents()
def updateViewportButtons(vp): ## if vp != pf.GUI.viewports.current: ## print "viewport %s is not current" % pf.GUI.viewports.viewIndex(vp) if vp.focus: #print "viewport %s has focus" % pf.GUI.viewports.viewIndex(vp) updateWireButton() updateTransparencyButton() updateLightButton() updateNormalsButton() # # BEWARE: The toggle functions are currently not passed the state! # It should be got from # ################# Wire Button ############### wire_button = None # the toggle wire button def addWireButton(toolbar): global wire_button wire_button = addButton(toolbar, 'Toggle Wire Mode', 'wireall', toggleWire, icon0='wirenone', toggle=True) def toggleWire(state=None): vp = pf.GUI.viewports.current state = wire_button.isChecked() # TODO: # WELL, it looks like we get here BEFORE the button is updated, # so we need to change the state. # WE should really connect this to a signal that is raised # AFTER the button state is update state = not state vp.setWireMode(state) vp.update() pf.GUI.processEvents()
[docs]def updateWireButton(): """Update the wire button to correct state.""" if wire_button: vp = pf.GUI.viewports.current wire_button.setChecked(vp.settings['wiremode'] > 0) pf.GUI.processEvents()
################# Transparency Button ############### transparency_button = None # the toggle transparency button def addTransparencyButton(toolbar): global transparency_button transparency_button = addButton(toolbar, 'Toggle Transparent Mode', 'transparent', toggleTransparency, toggle=True) def toggleTransparency(state=None): toggleButton('alphablend', state)
[docs]def updateTransparencyButton(): """Update the transparency button to correct state.""" updateButton(transparency_button, 'alphablend')
################# Lights Button ############### light_button = None def addLightButton(toolbar): global light_button light_button = addButton(toolbar, 'Toggle Lights', 'lamp-on', toggleLight, icon0='lamp', toggle=True, checked=True) def toggleLight(state=None): toggleButton('lighting', state)
[docs]def updateLightButton(): """Update the light button to correct state.""" updateButton(light_button, 'lighting')
################# Normals Button ############### normals_button = None def addNormalsButton(toolbar): global normals_button normals_button = addButton(toolbar, 'Toggle Normals', 'normals-avg', toggleNormals, icon0='normals-ind', toggle=True, checked=False) def toggleNormals(state=None): toggleButton('avgnormals', state)
[docs]def updateNormalsButton(state=True): """Update the normals button to correct state.""" updateButton(normals_button, 'avgnormals')
################# Perspective Button ############### perspective_button = None # the toggle perspective button def togglePerspective(mode=None): # Called by the button, not by user vp = pf.GUI.viewports.current if mode is None: mode = not vp.camera.perspective vp.camera.setPerspective(mode) vp.display() vp.update() pf.GUI.processEvents() def addPerspectiveButton(toolbar): global perspective_button perspective_button = addButton(toolbar, 'Toggle Perspective/Projective Mode', 'perspect', togglePerspective, toggle=True, icon0='project', checked=True)
[docs]def updatePerspectiveButton(): """Update the normals button to correct state.""" #updateButton(perspective_button,'avgnormals') vp = pf.GUI.viewports.current if vp == pf.canvas: perspective_button.setChecked(vp.camera.perspective) pf.GUI.processEvents()
def setPerspective(): togglePerspective(True) updatePerspectiveButton() def setProjection(): togglePerspective(False) updatePerspectiveButton() ################# Shrink Button ############### # # The shrink button currently does not redraw, it only sets the default # shrink factor and clears the viewport # shrink_button = None # the toggle shrink button def toggleShrink(): # Called by the button from pyformex.gui import draw mode = draw.DrawOptions.get('shrink', None) if mode is None: mode = 0.8 else: mode = None draw.shrink(mode) def addShrinkButton(toolbar): global shrink_button shrink_button = addButton(toolbar, 'Toggle Shrink Mode', 'shrink', toggleShrink, toggle=True) def setShrink(mode): from pyformex.gui import draw draw.shrink(mode) if shrink_button: shrink_button.setChecked(mode != None) ################# Timeout Button ############### timeout_button = None # the timeout toggle button def toggleTimeout(onoff=None): if onoff is None: onoff = widgets.input_timeout < 0 if onoff: timeout = pf.cfg['gui/timeoutvalue'] else: timeout = -1 widgets.setInputTimeout(timeout) onoff = widgets.input_timeout > 0 if onoff: # THIS SUSPENDS ALL WAITING! WE SHOULD IMPLEMENT A TIMEOUT! # BY FORCING ALL INDEFINITE PAUSES TO A WAIT TIME EQUAL TO # WIDGET INPUT TIMEOUT pf.debug("FREEING the draw lock") pf.GUI.drawlock.free() else: pf.debug("ALLOWING the draw lock") pf.GUI.drawlock.allow() return onoff
[docs]def addTimeoutButton(toolbar): """Add or remove the timeout button,depending on cfg.""" global timeout_button if pf.cfg['gui/timeoutbutton']: if timeout_button is None: timeout_button = addButton(toolbar, 'Toggle Timeout', 'clock', toggleTimeout, toggle=True, checked=False) else: if timeout_button is not None: removeButton(toolbar, timeout_button) timeout_button = None
[docs]def timeout(onoff=None): """Programmatically toggle the timeout button""" if timeout_button is not None: timeout_button.setChecked(toggleTimeout(onoff))
# End