All pastes #18054 Raw Edit

Someone

public python v1 · immutable
#18054 ·published 2005-07-19 12:58 UTC
rendered paste body
#  GUIWrap v0.2# --------------## 18/07/05# --------## Notes:# ------## * Implemented all base functions including callbacks, helper functions#   init and registration functions as well as all globals and constants# * Buttons wrapper implemented and working well, no bugs found yet# * User definable hotkeys implemented.# * Text wrapper implemented ad working well, with selectable position#   and fontsize.# * Slider wrapper implmented but not working as expected, selected value#   is not persistent, it reverts back to initial value.  				---->	!!!ON HOLD!!!# * Slider get and set value functions implemented but not working#   as expected.  I assume this has something to do with the above#   error, but it may be unrelated. Set function needs revising anyway#   it causes crash if value is min < value > max, however this may#   still have something to do with the first bug, since the Get fucntion#   always returns 0.0.													---->   !!!ON HOLD!!!## 19/07/05# --------## Notes:# ------## * Moved Yes/No exit box from TODO to done.  Implemented as #   GUIoptionalExit()# * Implemented adaptable menu, GUImenu# * Implemented generalised inputbox, does not work as expected#   string input boxes do not show on the screen, int and float boxes#	work as expected.  Error checking code for this function also#	does not perform as expected, it does not raise an error in cases#	where type is not a valide type.									---->	!!!ON HOLD!!!# * Added GUIimage with selectable autoscaling and persistent drawing#	doesn't work at the moment, suspect it has to do with the errors#	problem below.														---->	!!!ON HOLD!!!# * NO ERRORS - errors are not being thrown or raised as they should be# * Implemented mouse events system including user definable clickable#	regions and hover overs.# * Added background colour change function.# * Horizontal rule code is doing very weird things, the exact same#   code I had working yesterday is now screwing with the Blender#	interface. Have to speak to someone who knows about OGL.			---->	!!!ON HOLD!!!# * Disabled mouse over code as it was particularly ineffective, for#	each event that occurs whilst the mouse is in the mouseover region#   the mouse event is called.  Should only be called once when mouse#	enters area.## TODO's:# -------## * Implement changable font colour, I assume this will be done with BGL#   -> requires further investigation.# * Implement wordwrapping for text, can be done with wordwrap module#   -> is it safe to assume anyone using this script would have a full#   install of python?#   -> distribute with wordwrap module?#   -> code word wrap from scratch?#	-> SOLVED - sys module required so full python install is required.# * Implement visibilty scheme for UI elements#   -> remove objects from draw loop when not visible?#	-> use BGL rect's to cover them up?# * Implement remaining UI items.# * Fix the hackish code that hides errors caused by the GUImenu code when#   when it returns and throws an unrecognised event.# * Implement a decent mouseover system, mouseclick works fine.## Ideas:# ------## * Multiline text box -#   -> Create interface for it using BGL, if mouse cursor is inside interface#	   then trap all text and print to string which is wordwrapped to fit# 	   interface.  Scroll bars pose more of a problem, limit to vertical scroll#	   only.  Could be done with BGL masks to hide unshown text, this could give#	   a true scroll look.  The string would still need to be dynamically#	   modified otherwise mask would be required to be too big and would hide#	   other interface elements.									----DOABLE----## * Horizontal Rule -#   -> More of a todo I guess, implementation should be very simple, just a #	   couple of BGL commands. Selectable colour and auto length.   ----WILL DO----## * Radio buttons -#	-> Could be done a couple of ways, create the interface itself with BGL#	   then test for clicks etc and do appropriate event.  Or, have groups of#	   buttons that automatically turnoff if another of the group is selected.#	   Buttons option is likely much easier to implement.			----DOABLE----## * User definable click regions - #	-> Another that is probably todo.  Should be relatively easy to implement# 	   with very little extra code, just Window module. Could extend to #      mouseover/mouseout events too.								----DOABLE----## * Tabs -#	-> Unsure how this could work since Blender UI elements can't be seperated#      into layers.  Perhaps some BGL trickery could do the job, but im doubtul.#	   Possibly to seperate UI's and showing one or the other depending on a#	   button press.												----INVESTIGATE----## * Tickers -#	-> An object that outputs a continuous 'tick', or calls a defined function#	   for every tick, which could be attached to a ui elements input such as#	   x position to allow for animating.##																timmeh 1959 19.02.05# ------------------------------------------------------------------------------------#import Blenderimport stringimport sysobjects = []																			#storage for our ui elementsevents = []																				#events callback lookupkeyevents = []																			#storage for key eventsmouseevents = []																		#storage for click regionsBGLbackCol = []																			#back ground colourinit = 0																				#initisalisation stateregistered = 0																			#registered stateTINYFONT = "tiny"																		#font constantsSMALLFONT = "small"MEDIUMFONT = NORMALFONT = DEFAULTFONT = "normal"LARGEFONT = "large"MENUSTRING = MENUSTR = "string"															#inputbox constantsMENUINT = MENUINT = "integer"MENUFLOAT = MENUFLT = "float"MOUSECLICK = 0																			#mouse event type constantsMOUSEOVER = 1		LMB = LEFTMOUSE = LMOUSE = Blender.Draw.LEFTMOUSE										#blender moouse eventsRMB = RIGHTMOUSE = RMOUSE = Blender.Draw.RIGHTMOUSEMMB = MIDDLEMOUSE = MMOUSE = Blender.Draw.MIDDLEMOUSE#helper function, appends a list of items to another list----------def multiappend(list, varlist):	for var in varlist:		list.append(var)	return list#callback for key and mouse events----------------------------------def GUIevent(event, val):			global keyevents	global mouseevents	mouse = []		for key in keyevents:																#event handler for user defined		if event == key[0]:																#key events			key[1]()		mouse = Blender.Window.GetMouseCoords()		for mevent in mouseevents:															#event handler for user defined		if event == mevent[7] and mevent[6] == 0:										#click regiods.			if mouse[0] > mevent[2] and mouse[0] < (mevent[2] + mevent[4]):				if mouse[1] > mevent[3] and mouse[1] < (mevent[3] + mevent[5]):					mevent[1]()					continue		#elif event == Blender.Draw.MOUSEX or event == Blender.Draw.MOUSEY:				#ineffective mouse over routine			#if mevent[6] == 1:															#calls event for every event that				#if mouse[0] > mevent[2] and mouse[0] < (mevent[2] + mevent[4]):		#occurs whilst mouse is over region.					#if mouse[1] > mevent[3] and mouse[1] < (mevent[3] + mevent[5]):						#mevent[1]()						#continue							#callback for buttons events----------------------------------------def GUIbevent(event):					global events		try:																				#HACK - find a fix for this, don't like the try..except		events[event]()																	#error catching to get around errors caused by	except:																				#GUImenu creating unknown events.		sys.exc_clear()		Blender.Draw.Redraw()#callback for rendering UI------------------------------------------def GUIdraw():							global objects																		#draw routines for all objects here	global BGLbackCol																						#obj, type, name, callback, data[]	if not objects:return																		for object in objects:																	if object[1] == "button":			object[0] = Blender.Draw.Button(object[4], object[3], object[5], object[6], object[7], object[8], object[9])							elif object [1] == "text":			Blender.BGL.glRasterPos2i(object[4], object[5])			object[0] = Blender.Draw.Text(object[3], object[6])				elif object[1] == "slider":			object[0] = Blender.Draw.Slider(object[4], object[3], object[5], object[6],object[7], object[8], object[9], object[10], object[11], object[12])		elif object[1] == "image":			Blender.Draw.Image(object[0], object[3], object[4], object[5])					elif object[1] == "HR":			#GUIdrawHR(object)															#produces strange artifacts on the screen			pass																		#not sure why, code works in other scripts				Blender.BGL.glClearColor(*BGLbackCol)											#set background colour as set by init or usr		Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)#change background colour, uses object interface-------------------def GUIbackgroundCol(r, g, b, a):															global BGLbackCol		BGLbackCol = [r, g, b, a]	def GUIdrawHR(object):				#<------- fix this		Blender.BGL.glColor3f(object[5], object[6], object[7])								#code produces strange artifacts on the	Blender.BGL.glBegin(Blender.BGL.GL_LINE_LOOP)										#screen rather than drawing a line as	Blender.BGL.glVert2i(object[3], object[4])											#expected	Blender.BGL.glVert2i(Blender.Window.GetScreenSize()[0] - object[3], object[4])	Blender.BGL.glEnd()#initialise module - at the moment uses a hackish method to stop---#event 0 being assigned, could be done automatically on loading----#the module, however for future proofing where futher init steps---#may be required, I will leave it here nd make it a requirement----#to initialise the module before use-------------------------------def GUIinit():	global events	global init		GUIbackgroundCol(0.5, 0.5, 0.5, 1.0)												#background default set to grey		if not init:		multiappend(events, [1,2,3,4,5,6,7,8,9,10])		init = 1	else:		raise RuntimeError, "GUIinit: GUIinit must only be called one"		#register callbacks once gui is set up, MUST only be called once---def GUIregister():	global registered		if not registered:		Blender.Draw.Register(GUIdraw, GUIevent, GUIbevent)		registered = 1	else:		raise RuntimeError, "GUIregister: GUIregister must only be called once"#set key events function------------------------------------------------def GUIregisterKeyEvent(event, callback):	global keyevents		if not init:		raise RuntimeError, "GUIregisterKeyEvent: GUIinit must preceed register functions"		key = []	multiappend(key, [event, callback])	keyevents.append(key)#set mouse events function---------------------------------------------def GUIregisterMouseEvent(name, callback, x, y, width, height, type, mbutton):	global mouseevents		if not init:		raise RuntimeError, "GUIregisterMouseEvent: GUIinit must preceed register functions"		key = []	multiappend(key, [name, callback, x, y, width, height, type, mbutton])	mouseevents.append(key)#button object creation function-----------------------------------	def GUIcreateButton(name, callback, text, x, y, w, h, tooltip):	global objects	global events	global init		if not init:		raise RuntimeError, "GUIcreateButton: GUIinit must preceed creation funtions"		object = []	events.append(callback)	#print "event assigned:", len(events)-1	object = multiappend(object, [Blender.Draw.Create(0.0), "button", name, len(events) -1, text, x, y, w, h, tooltip])	objects.append(object)#text object creation function-------------------------------------------	def GUIcreateText(name,text, x, y, fontsize):	global objects	global init		if not init:		raise RuntimeError, "GUIcreateText: GUIinit must preceed creation funtions"		object = []	multiappend(object, [Blender.Draw.Create(""), "text", name, text, x, y, fontsize])	objects.append(object)#create horizontal rule function----------------------------------------def GUIcreateHR(name, offset, height, r, g, b):	global objects		if not init:		raise RuntimeError, "GUIcreateHR: GUIinit must precede creation functions"		object = []	multiappend(object, ["HR", "HR", name, offset, height, r, g, b])	objects.append(object)	#slider object creation function----------------------------------------def GUIcreateSlider(name, callback, text, x, y, width, height, initial, min, max, realtime, tooltip):	global objects	global events	global init		if not init:		raise RuntimeError, "GUIcreateSlider: GUIinit must preceed creation functions"			object = []	events.append(callback)	object = multiappend(object, [Blender.Draw.Create(0.0), "slider", name, len(events) -1, text, x, y, width, height, initial, min, max, realtime, tooltip])	objects.append(object)#slider set value function----------------------------------------------def GUIsetSlider(name, value):	global objects		for object in objects:		if object[2] == name:			if value < object[10] and value > object[9]:				object[0].val = value			else:				raise ValueError, "GUIsetSlider: Slider value must be between min and max"			return		raise ValueError, string.join(["GUIsetSlider:", name, "is not a valide slider object"])#slider get value function----------------------------------------------def GUIgetSlider(name):	global objects		for object in objects:		if object[2] == name:			return object[0].val		raise ValueError, string.join(["GUIsetSlider:", name, "is not a valid slider object"])	#quit GUI function-----------------------------------------------------	def GUIquit():		if registered:		Blender.Draw.Exit()	else:		raise RuntimeError, "GUIquit: no registered UI"	#optional quit function------------------------------------------------def GUIoptionalQuit():	menustr = "OK?%t| Quit"		if not registered:		raise RuntimeError, "GUIoptionalQuit: no registered UI"				if Blender.Draw.PupMenu(menustr) == 1:		Blender.Draw.Exit()#menu creation function------------------------------------------------def GUImenu(title, menuopts):	menustr = string.join([title, "%t |"])	if not menuopts:		raise ValueError, "GUImenu: No menu options"				for item in menuopts:		menustr = string.join([menustr, item, "|"])		return Blender.Draw.PupMenu(menustr)			#input box creation funtion---------------------------------------------	def GUIinputBox(type, title, default, min=0, max=0, clickstep=10, floatlen=2):	type = string.strip(type)	#print type		if type in ('str', 'string'):		return Blender.Draw.PupStrInput(title, default, min)	elif type in ('int', 'integer'):		return Blender.Draw.PupIntInput(title, default, min, max)	elif type in ('flt', 'float'):		return Blender.Draw.PupFloatInput(title, default, min, max, clickstep, floatlen)	else:		raise ValueError, string.join(["GUIinputBox:", type, "is invalid"])			#<------ DOESNT RAISE ERROR#image placement function-----------------------------------------------def GUIimage(filename, name, x=0, y=0, scale=1, autosize=0):	global objects	object = []	imgsize = []	scrsize = []	sFactor = []		img = Blender.Image.Load(filename)	if autosize:		imgsize = img.getSize()		scrsize = Blender.Window.GetScreenSize()		sFactor = [scrsize[i] / imgsize[i] for i in imagesize]		if sFactor[0] < sFactor[1]:			scale = sFactor[0]		else:			scale = sFactor[1]		object = multiappend([object, img, "image", name, x, y, scale])	print object	objects.append(object)			#########################################################################def test():	GUIimage("d:/fire2.jpg", 10, 400,1,0)	sdsg	def test2():	print "hello"	returndef test3():	print "hello again"	returndef move():	print "slider event"def mevent():	rnd = Blender.Mathutils.Rand	GUIbackgroundCol(rnd(), rnd(), rnd(), 1)GUIinit()	GUIcreateButton("test",test, "Timmeh", 24,16,138,20, "test")GUIcreateSlider("slider", move, "Test", 24, 40, 138, 20, 100, 0, 200, 1, "test")GUIcreateHR("hr1", 24, 100, 0.0, 0.0, 0.0)#GUIcreateButton(test2, "Tim  ", 24,40,138,20, "test2")#GUIcreateButton(test3, "Tim2 ", 24,64,138,20, "test3")GUIcreateText("name","timmeh test", 24, 400, NORMALFONT)GUIregisterKeyEvent(Blender.Draw.ESCKEY, GUIoptionalQuit)GUIregisterKeyEvent(Blender.Draw.QKEY, GUIoptionalQuit)GUIregisterMouseEvent("mevent1", mevent, 1,100, 400, 400, MOUSECLICK, LEFTMOUSE)GUIregister()