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()