All pastes #364803 Raw Edit

Stuff

public text v1 · immutable
#364803 ·published 2007-02-20 12:17 UTC
rendered paste body
#!/usr/bin/env python

from OpenGL.GL import *
from OpenGL.GLU import *
import pygame
from pygame.locals import *
import sys, StringIO

class Log:

    history = []
    output = sys.stdout

    def Warning(info):
        history.append("  Warning - %s" % info)
        output.write("  Warning - %s" % info)

    def Error(info):
        history.append("  Error - %s" % info)
        output.write("  Error - %s" % info)

    def Critical(info, exception=None):
        history.append("!!Critical!! - %s" % info)
        output.write("!!Critical!! - %s" % info)
        if exception: raise exception

class Theme:
    canvas = (0.5, 0.5, 0.5, 1.0)
    raised = (0.7, 0.7, 0.7, 1.0)
    sunken = (0.3, 0.3, 0.3, 1.0)
    unsel = (0.3, 0.3, 0.3, 1.0)
    linecol = (0.2, 0.2, 0.2, 1.0)

def draw_rectangle(x, y, w, h, drawmode=GL_QUADS):
    glBegin(drawmode)
    glVertex2f(x, y)
    glVertex2f(x + w, y)
    glVertex2f(x + w, y + h)
    glVertex2f(x, y + h)
    glEnd()

class Entity:

    def __init__(self, x, y, w, h):
        self.x, self.y, self.w, self.h = x, y, w, h
        self.sel = 0
        self.entities = []
        self.parent = None

    def __getpos__(self):
        if not self.parent:
            return self.x, self.y
        x, y = self.parent.position
        return self.x + x, self.y + y

    position = property(__getpos__)

    def linkChild(self, child):
        self.entities.append(child)
        child.parent = self

    def linkChildren(self, *children):
        for child in children:
            self.linkChild(child)

    def unlinkChild(self, child):
        try:
            self.entities.remove(child)
        except ValueError:
            Log.Error('Unlink failed - No such child : Entity type - %s Child type - %s' % (self.__class__, child.__class__))

    def displayEntity(self):
        print self
        self.draw()
        if not self.entities: return                            #don't bother doing the rest if there are no children
        
        x, y, w, h = glGetFloatv(GL_SCISSOR_BOX)                #check here for wierd scissor issues
        if self.x > x:                                          #may be because of upside down y mapping
            x1 = self.x
        else:
            x1 = x
        if self.x + self.w < x + w:
            x2 = self.x + self.w
        else:
            x2 = x + w
        if self.y > y:
            y1 = self.y
        else:
            y1 = y
        if self.y + self.h < y + h:
            y2 = self.y + self.h
        else:
            y2 = y + h
        
        abspos = self.position
        glPushMatrix()
        glTranslatef(abspos[0], abspos[1], 0)
        glPushAttrib(GL_SCISSOR_BIT)
        glScissor(x1, y1, x2-x1, y2-y1)
        for entity in self.entities:
            entity.displayEntity()
        glPopAttrib()
        glPopMatrix()

    def draw(self):
        pass
    
class Rectangle(Entity):

    def __init__(self, x, y, w, h, col=[.0,.0,.0,1.], drawmode=GL_QUADS):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.col = col
        self.drawmode = drawmode
        Entity.__init__(self, x, y, w, h)

    def draw(self):
        glColor4f(*self.col)
        draw_rectangle(self.x, self.y, self.w, self.h, self.drawmode)

class PanelSunken(Entity):

    def __init__(self, x, y, w, h):
        Entity.__init__(self, x, y, w, h)
        self.linkChild(Rectangle(x, y, w, h, Theme.sunken))
        self.linkChild(Rectangle(x + 1, y, w - 1, h - 1, Theme.raised))
        self.linkChild(Rectangle(x + 1, y + 1, w - 2, h - 2, Theme.canvas))

class PanelFlat(Entity):

    def __init__(self, x, y, w, h, col=Theme.sunken, linecol=Theme.linecol):
        Entity.__init__(self, x, y, w, h)
        self.linkChild(Rectangle(x, y, w, h, col))
        self.linkChild(Rectangle(x, y, w, h, linecol, drawmode=GL_LINE_LOOP))

class GenericButton(PanelSunken):
    def __init__(self, x, y, w, h, draw=None):
        PanelSunken.__init__(self, x, y, w, h)
        self.draw = draw

class GenericNodeInterface(Entity):

    def __init__(self, x, y, w=100, h=100):
        Entity.__init__(self, x, y, w, h)
        self.mx = self.my = 0                   #offset for mouse moving
        self.cx = x + w / 2                     #center of box x axis
        self.cy = y + h / 2                     #center of box y axis
        self.border = Rectangle(x - 3, y - 3, w + 3, h + 3, Theme.unsel, drawmode=GL_LINE_LOOP)
        self.panel = PanelSunken(x, y, w, h)
        self.input = GenericButton(x + 1, y + 1, 16, 16)
        self.output = GenericButton(x + w - 17, y + 1, 16, 16)
        self.properties = GenericButton(x + 17, y + 1, w - 34, 16)
        self.linkChildren(self.panel, self.input, self.output, self.properties)

    def drawNodeButtonIdent(self):
        pass
        
        
        
class WindowManager(Entity):

    GL_MAPPING_Y_STANDARD = 0
    GL_MAPPING_Y_INVERT = 1

    def __init__(self, width, height, fullscreen=False, resize=False, frameless=False, title='Untitled'):
        Entity.__init__(self, 0, 0, width, height)
        self.fullscreen = fullscreen
        self.resizable = resize
        self.frameless = frameless
        self.title = title

        self.mouse = ()

        self.entities = []

        self.y_mapping = WindowManager.GL_MAPPING_Y_STANDARD

        self.exit = 0

    def __getitem__(self, key):
        if self.__dict__.has_key(key):
            return self.__dict__[key]
        else:
            raise AttributeError, 'Window Manage has no such attribute'

    def run(self):
        vid_flags = OPENGL | DOUBLEBUF
        if self.fullscreen: vid_flags |= FULLSCREEN
        if self.resizable: vid_flags |= RESIZABLE
        if self.frameless: vid_flags |= NOFRAME

        pygame.init()
        pygame.display.set_mode((self.w, self.h), vid_flags)
        pygame.display.set_caption(self.title)

        self.resize((self.w, self.h))

        glShadeModel(GL_SMOOTH)
        glClearColor(*Theme.canvas)
        glScissor(-self.w, -self.h, self.w * 2, self.h * 2)
        glEnable(GL_SCISSOR_TEST)

        while not self.exit:
            event = pygame.event.poll()
            self.event_handler(event)
            self.draw()
            pygame.display.flip()

        pygame.quit()
        

    def event_handler(self, event):
        if event.type == NOEVENT: return

        elif event.type == MOUSEMOTION:
            pass
        
        elif event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
            self.exit = 1

    def draw(self):
        glClear(GL_COLOR_BUFFER_BIT)
        for elem in self.entities:
            elem.displayEntity()
    
    def resize(self, (width, height)):
        if height==0:
            height=1
        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        if self.y_mapping == WindowManager.GL_MAPPING_Y_STANDARD:
            gluOrtho2D(0, width, 0, height)
        elif self.y_mapping == WindowManager.GL_MAPPING_Y_INVERSE:
            gluOrtho2D(0, width, height, 0)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

  
wm = WindowManager(500,500)
#rect = Rectangle(100, 100, 100, 100, (1.0, 0.0, 0.0, 1.0))
#rect2 = Rectangle(150, 150, 100, 100, (1.0, 1.0, 0.0, 1.0))
#rect.linkChild(rect2)
#wm.entities.append(rect)
#panel = PanelSunken(100,100,200,200)
node = GenericNodeInterface(300,300)
wm.entities.append(node)

wm.run()