Ejemplo n.º 1
0
class BaseObject(object):
    """Common functionality for all graphic objects.
    It's just a wrapper around a SoSeparator
    
    It has this OI structure:
    Switch {
      Separator {
        DrawStyle {}
        Translation { translation 0 0 0 }
      }
    }

    Has methods for hide/show itself, and for translation
    """

    def __init__(self):
        self.animation  = None
        self.root       = SoSwitch()
        self.separator  = SoSeparator()
        self.drawStyle  = SoDrawStyle()
        self.translation = SoTranslation()

        self.root.addChild(self.separator)
        self.separator.addChild(self.drawStyle)
        self.separator.addChild(self.translation)

        self.translation.translation = (0, 0, 0)

        self.show()

    @fluid
    def setVisible(self, visible):
        self.root.whichChild = SO_SWITCH_ALL if visible else SO_SWITCH_NONE

    def getVisible(self):
        return self.root.whichChild.getValue() == SO_SWITCH_ALL

    visible = property(fget=getVisible, fset=setVisible)

    @fluid
    def show(self):
        self.setVisible(True)

    @fluid
    def hide(self):
        self.setVisible(False)

    @fluid
    def setName(self,name):
        self.root.setName(name)

    @fluid
    def setBoundingBox(self, xrange=None, yrange=None, zrange=None):
        """
        @param xrange: 2-tuple
        @param yrange: 2-tuple
        @param zrange: 2-tuple
        """
        def createPlane(normalref, point):
            sfplane = SoSFPlane()
            sfplane.setValue(SbPlane(normalref, point))
            return sfplane

        if yrange is not None:
            self.clipPlaneXZ1 = SoClipPlane()
            self.clipPlaneXZ2 = SoClipPlane()
            self.clipPlaneXZ1.plane = createPlane(SbVec3f(0, 1, 0), SbVec3f(0, yrange[0], 0))
            self.clipPlaneXZ2.plane = createPlane(SbVec3f(0, -1, 0), SbVec3f(0, yrange[1], 0))
            self.separator.insertChild(self.clipPlaneXZ1, 0)
            self.separator.insertChild(self.clipPlaneXZ2, 1)
        if xrange is not None:
            self.clipPlaneYZ1 = SoClipPlane()
            self.clipPlaneYZ2 = SoClipPlane()
            self.clipPlaneYZ1.plane = createPlane(SbVec3f(1, 0, 0), SbVec3f(xrange[0], 0, 0))
            self.clipPlaneYZ2.plane = createPlane(SbVec3f(-1, 0, 0), SbVec3f(xrange[1], 0, 0))
            self.separator.insertChild(self.clipPlaneYZ1, 2)
            self.separator.insertChild(self.clipPlaneYZ2, 3)
        if zrange is not None:
            self.clipPlaneXY1 = SoClipPlane()
            self.clipPlaneXY2 = SoClipPlane()
            self.clipPlaneXY1.plane = createPlane(SbVec3f(0, 0, 1), SbVec3f(0, 0, zrange[0]))
            self.clipPlaneXY2.plane = createPlane(SbVec3f(0, 0, -1), SbVec3f(0, 0, zrange[1]))
            self.separator.insertChild(self.clipPlaneXY1, 4)
            self.separator.insertChild(self.clipPlaneXY2, 5)

    @fluid
    def setDrawStyle(self, style):
        self.drawStyle.style = style

    @fluid
    def setOrigin(self, pos):
        self.translation.translation = pos

    def getOrigin(self):
        return self.translation.translation.getValue()

    origin = property(fget=getOrigin, fset=setOrigin)

    def getAnimation(self):
        return self.animation

    def resetObjectForAnimation(self):
        pass

    def toText(self):
        """obtains the openinventor format representation"""
        wa = SoWriteAction()
        return wa.apply(self.root)

    @classmethod
    def Create(cls, oi_object):
        bo = cls()
        bo.separator.addChild(oi_object)
        return bo
Ejemplo n.º 2
0
class Chapter(QtCore.QObject):
    """A Chapter"""

    pageChanged = QtCore.pyqtSignal(Page, int)

    def __init__(self, name=""):
        super(Chapter, self).__init__()
        self.name = name
        self.book = None
        self.root = SoSeparator()
        self.root.setName("Chapter:root")
        self.pagesSwitch = SoSwitch()
        self.pagesSwitch.setName("Chapter:pages")
        self.root.addChild(self.pagesSwitch)

        self.__pages = nodeDict()
        ## ============================
        self.setupGui()

    def setupGui(self):
        ## self.widget has next, prev buttons, plus a QStackedWidget for holding per page controls
        self.widget = ChangePageUI()
        ## the initial state
        self.widget.previous.hide()
        self.widget.next.hide()
        connect(self.widget.next, "clicked(bool)", self.nextPage)
        connect(self.widget.previous, "clicked(bool)", self.prevPage)
        ## ============================
        self.notesStack = QtGui.QStackedWidget()
        ## ============================

    def setBook(self, book):
        self.book = book

    @property
    def pages(self):
        """The list of pages"""
        return self.__pages

    def createPage(self):
        """
        Creates a new page and appends it to this chapter
        """
        page = Page()
        self.addPage(page)
        return page

    def addPage(self, page):
        """
        Adds 'page' to this chapter. page can be a Page or a SoNode. Searches
        page for a 'getGui' function, which should return a widget.
        @param page: Page | SoNode
        """
        ## ============================
        ## page can be a Page or SoNode
        root = getattr(page, "root", page)
        self.pages[root] = page
        self.pagesSwitch.addChild(root)
        ## ============================
        guiLayout = QtGui.QVBoxLayout()
        guiLayout.setMargin(0)
        guiLayout.setSpacing(0)
        widget = QtGui.QWidget()
        widget.setObjectName("PageGui")
        widget.setLayout(guiLayout)
        self.widget.pageStack.addWidget(widget)
        ## ============================
        notesLayout = QtGui.QVBoxLayout()
        notesLayout.setMargin(0)
        notesLayout.setSpacing(0)
        widget = QtGui.QWidget()
        widget.setObjectName("PageNotas")
        widget.setLayout(notesLayout)
        self.notesStack.addWidget(widget)
        ## ============================
        ## this sets self.pagesSwitch, self.widget.pageStack, self.notasStack
        ## only change the page if theres a book already
        if self.book is not None:
            self.whichPage = len(self.pagesSwitch) - 1
        ## ============================
        guiLayout.addWidget(page.getGui())
        notesLayout.addWidget(page.getNotes())
        ## ============================
        if len(self.pagesSwitch) == 2:
            self.widget.previous.show()
            self.widget.next.show()

    def getGui(self):
        return self.widget

    def getNotes(self):
        return self.notesStack

    def chapterSpecificIn(self):
        """code to be executed whenever the chapter is displayed
        this is intended for global changes to the scenegraph that
        are needed by this chapter
        """
        pass

    @property
    def page(self):
        """the current page"""
        if self.whichPage < 0:
            return None
        return self.pages[self.pagesSwitch[self.whichPage]]

    def getWhichPage(self):
        """
        Returns the index of the current page
        """
        return self.pagesSwitch.whichChild.getValue()

    def setWhichPage(self, n):
        """
        Activates the n-th page
        @param n:
        """
        if len(self.pagesSwitch) > 0:
            self.pagesSwitch.getChild(n)
            self.pagesSwitch.whichChild = n
            self.widget.pageStack.setCurrentIndex(n)
            self.notesStack.setCurrentIndex(n)
            self.pageChanged.emit(self.page, n)

    whichPage = property(getWhichPage, setWhichPage)

    def changePage(self, direction):
        self.whichPage = (self.whichPage + direction) % len(self.pagesSwitch)

    def nextPage(self):
        self.changePage(1)

    def prevPage(self):
        self.changePage(-1)
Ejemplo n.º 3
0
class Book(QtCore.QObject):
    """A Book-like object"""

    chapterChanged = QtCore.pyqtSignal(int)
    pageChanged = QtCore.pyqtSignal(Page, int)

    def __init__(self):
        super(Book, self).__init__()
        self.root = SoSeparator()
        self.root.setName("Book:root")
        self.chapters = SoSwitch()
        self.chapters.setName("Book:chapters")
        self.root.addChild(self.chapters)
        ## this dictionary contains the chapters python objects
        ## not only the SoSeparator
        self.chaptersObjects = nodeDict()
        self.setupGui()

    def __len__(self):
        """The number of chapters"""
        return len(self.chapters)

    def setupGui(self):
        ## chapterStack has one widget (of controls) per chapter
        self.chaptersStack = QtGui.QStackedWidget()
        self.notesStack = QtGui.QStackedWidget()

    def createChapter(self):
        """Creates a new empty Chapter"""
        chapter = Chapter()
        self.addChapter(chapter)
        return chapter

    def addChapter(self, chapter):
        """
        Appends chapter to this book
        @param chapter: Chapter
        """
        ## we probably should check that chapter is derived
        ## from base.Chapter
        self.chaptersObjects[chapter.pagesSwitch] = chapter
        self.chapters.addChild(chapter.root)
        chapter.setBook(self)
        ## ============================
        ## setup the UI
        self.chaptersStack.addWidget(chapter.getGui())
        self.notesStack.addWidget(chapter.getNotes())
        self.whichChapter = len(self.chapters) - 1
        #=======================================================================
        chapter.pageChanged.connect(self.relayPageChangedSignal)

    def relayPageChangedSignal(self, page, n):
        logger.debug('relayPageChangedSignal: %s', n)
        self.pageChanged.emit(page, n)

    @property
    def chapterSwitch(self):
        """the switch of the current chapter"""
        if self.whichChapter < 0:
            return None
        return self.chapters[self.whichChapter][0]

    @property
    def chapter(self):
        """returns the current chapter"""
        if self.whichChapter < 0:
            return None
        return self.chaptersObjects[self.chapterSwitch]

    @property
    def page(self):
        """returns the current page in the chapter"""
        return self.chapter.page if self.whichChapter >= 0 else None

    def getWhichChapter(self):
        """returns the selected chapter"""
        return self.chapters.whichChild.getValue()

    def setWhichChapter(self, n):
        """
        Sets the current chapter
        @param n: int
        """
        self.chapters.whichChild = n
        self.chaptersStack.setCurrentIndex(n)
        self.notesStack.setCurrentIndex(n)
        self.chapter.chapterSpecificIn()
        self.chapterChanged.emit(n)
        # noinspection PyStatementEffect
        self.chapter.page and self.pageChanged.emit(self.chapter.page, self.chapter.whichPage)

    whichChapter = property(getWhichChapter, setWhichChapter)
Ejemplo n.º 4
0
class BaseObject(object):
    """Common functionality for all graphic objects.
    It's just a wrapper around a SoSeparator
    
    It has this OI structure:
    Switch {
      Separator {
        DrawStyle {}
        Translation { translation 0 0 0 }
      }
    }

    Has methods for hide/show itself, and for translation
    """
    def __init__(self):
        self.animation = None
        self.root = SoSwitch()
        self.separator = SoSeparator()
        self.drawStyle = SoDrawStyle()
        self.translation = SoTranslation()

        self.root.addChild(self.separator)
        self.separator.addChild(self.drawStyle)
        self.separator.addChild(self.translation)

        self.translation.translation = (0, 0, 0)

        self.show()

    @fluid
    def setVisible(self, visible):
        self.root.whichChild = SO_SWITCH_ALL if visible else SO_SWITCH_NONE

    def getVisible(self):
        return self.root.whichChild.getValue() == SO_SWITCH_ALL

    visible = property(fget=getVisible, fset=setVisible)

    @fluid
    def show(self):
        self.setVisible(True)

    @fluid
    def hide(self):
        self.setVisible(False)

    @fluid
    def setName(self, name):
        self.root.setName(name)

    @fluid
    def setBoundingBox(self, xrange=None, yrange=None, zrange=None):
        """
        @param xrange: 2-tuple
        @param yrange: 2-tuple
        @param zrange: 2-tuple
        """
        def createPlane(normalref, point):
            sfplane = SoSFPlane()
            sfplane.setValue(SbPlane(normalref, point))
            return sfplane

        if yrange is not None:
            self.clipPlaneXZ1 = SoClipPlane()
            self.clipPlaneXZ2 = SoClipPlane()
            self.clipPlaneXZ1.plane = createPlane(SbVec3f(0, 1, 0),
                                                  SbVec3f(0, yrange[0], 0))
            self.clipPlaneXZ2.plane = createPlane(SbVec3f(0, -1, 0),
                                                  SbVec3f(0, yrange[1], 0))
            self.separator.insertChild(self.clipPlaneXZ1, 0)
            self.separator.insertChild(self.clipPlaneXZ2, 1)
        if xrange is not None:
            self.clipPlaneYZ1 = SoClipPlane()
            self.clipPlaneYZ2 = SoClipPlane()
            self.clipPlaneYZ1.plane = createPlane(SbVec3f(1, 0, 0),
                                                  SbVec3f(xrange[0], 0, 0))
            self.clipPlaneYZ2.plane = createPlane(SbVec3f(-1, 0, 0),
                                                  SbVec3f(xrange[1], 0, 0))
            self.separator.insertChild(self.clipPlaneYZ1, 2)
            self.separator.insertChild(self.clipPlaneYZ2, 3)
        if zrange is not None:
            self.clipPlaneXY1 = SoClipPlane()
            self.clipPlaneXY2 = SoClipPlane()
            self.clipPlaneXY1.plane = createPlane(SbVec3f(0, 0, 1),
                                                  SbVec3f(0, 0, zrange[0]))
            self.clipPlaneXY2.plane = createPlane(SbVec3f(0, 0, -1),
                                                  SbVec3f(0, 0, zrange[1]))
            self.separator.insertChild(self.clipPlaneXY1, 4)
            self.separator.insertChild(self.clipPlaneXY2, 5)

    @fluid
    def setDrawStyle(self, style):
        self.drawStyle.style = style

    @fluid
    def setOrigin(self, pos):
        self.translation.translation = pos

    def getOrigin(self):
        return self.translation.translation.getValue()

    origin = property(fget=getOrigin, fset=setOrigin)

    def getAnimation(self):
        return self.animation

    def resetObjectForAnimation(self):
        pass

    def toText(self):
        """obtains the openinventor format representation"""
        wa = SoWriteAction()
        return wa.apply(self.root)

    @classmethod
    def Create(cls, oi_object):
        bo = cls()
        bo.separator.addChild(oi_object)
        return bo
Ejemplo n.º 5
0
class Chapter(QtCore.QObject):
    """A Chapter"""

    pageChanged = QtCore.pyqtSignal(Page, int)

    def __init__(self, name=""):
        super(Chapter, self).__init__()
        self.name = name
        self.book = None
        self.root = SoSeparator()
        self.root.setName("Chapter:root")
        self.pagesSwitch = SoSwitch()
        self.pagesSwitch.setName("Chapter:pages")
        self.root.addChild(self.pagesSwitch)

        self.__pages = nodeDict()
        ## ============================
        self.setupGui()

    def setupGui(self):
        ## self.widget has next, prev buttons, plus a QStackedWidget for holding per page controls
        self.widget = ChangePageUI()
        ## the initial state
        self.widget.previous.hide()
        self.widget.next.hide()
        connect(self.widget.next, "clicked(bool)", self.nextPage)
        connect(self.widget.previous, "clicked(bool)", self.prevPage)
        ## ============================
        self.notesStack = QtGui.QStackedWidget()
        ## ============================

    def setBook(self, book):
        self.book = book

    @property
    def pages(self):
        """The list of pages"""
        return self.__pages

    def createPage(self):
        """
        Creates a new page and appends it to this chapter
        """
        page = Page()
        self.addPage(page)
        return page

    def addPage(self, page):
        """
        Adds 'page' to this chapter. page can be a Page or a SoNode. Searches
        page for a 'getGui' function, which should return a widget.
        @param page: Page | SoNode
        """
        ## ============================
        ## page can be a Page or SoNode
        root = getattr(page, "root", page)
        self.pages[root] = page
        self.pagesSwitch.addChild(root)
        ## ============================
        guiLayout = QtGui.QVBoxLayout()
        guiLayout.setMargin(0)
        guiLayout.setSpacing(0)
        widget = QtGui.QWidget()
        widget.setObjectName("PageGui")
        widget.setLayout(guiLayout)
        self.widget.pageStack.addWidget(widget)
        ## ============================
        notesLayout = QtGui.QVBoxLayout()
        notesLayout.setMargin(0)
        notesLayout.setSpacing(0)
        widget = QtGui.QWidget()
        widget.setObjectName("PageNotas")
        widget.setLayout(notesLayout)
        self.notesStack.addWidget(widget)
        ## ============================
        ## this sets self.pagesSwitch, self.widget.pageStack, self.notasStack
        ## only change the page if theres a book already
        if self.book is not None:
            self.whichPage = len(self.pagesSwitch) - 1
        ## ============================
        guiLayout.addWidget(page.getGui())
        notesLayout.addWidget(page.getNotes())
        ## ============================
        if len(self.pagesSwitch) == 2:
            self.widget.previous.show()
            self.widget.next.show()

    def getGui(self):
        return self.widget

    def getNotes(self):
        return self.notesStack

    def chapterSpecificIn(self):
        """code to be executed whenever the chapter is displayed
        this is intended for global changes to the scenegraph that
        are needed by this chapter
        """
        pass

    @property
    def page(self):
        """the current page"""
        if self.whichPage < 0:
            return None
        return self.pages[self.pagesSwitch[self.whichPage]]

    def getWhichPage(self):
        """
        Returns the index of the current page
        """
        return self.pagesSwitch.whichChild.getValue()

    def setWhichPage(self, n):
        """
        Activates the n-th page
        @param n:
        """
        if len(self.pagesSwitch) > 0:
            self.pagesSwitch.getChild(n)
            self.pagesSwitch.whichChild = n
            self.widget.pageStack.setCurrentIndex(n)
            self.notesStack.setCurrentIndex(n)
            self.pageChanged.emit(self.page, n)

    whichPage = property(getWhichPage, setWhichPage)

    def changePage(self, direction):
        self.whichPage = (self.whichPage + direction) % len(self.pagesSwitch)

    def nextPage(self):
        self.changePage(1)

    def prevPage(self):
        self.changePage(-1)