PyCEGUI is now officially part of CEGUI

Kulik

13-08-2011 22:41:04

Hi,
a while back I have taken Python-Ogre's CEGUI bindings, improved them in some areas and made them officially part of CEGUI, so CEGUI supports Python now and the binding should be up to date every time a new CEGUI version is released. We use Python for CEGUI Unified Editor, the new all-in-one tool for CEGUI, so I think its future is quite safe for the moment :)

I made this post to prevent wasted efforts, anyone wanting to improve something on the CEGUI bindings is advised to contact the CEGUI team. The PyCEGUI bindings do exactly what Python-Ogre's CEGUI bindings do and a bit more (binding any callables with PyCEGUI 0.8 - even lambda functions, inheritance support, etc..).

Thanks Andy and everyone responsible for Python-Ogre, it was a great starting point for something like PyCEGUI!

Last note: We would like to make PyCEGUI more pythonic in the future: use lazy iterators and other fancy Python features to make it more convenient to use, please give us your ideas/opinions on our forums http://www.cegui.org.uk/phpBB2

iwanantonowitsch

14-08-2011 00:24:49

cegui never worked for me kinda... i got the basic framework up and working but when i compiled into binaries it would always crash... but if its working for everyone else this is great news!

filmore

14-08-2011 04:14:44

Got an ImportError when doing:

import PyCEGUI
import PyCEGUIOgreRenderer

ImportError: No module named PyCEGUIOgreRenderer

Mohican

14-08-2011 05:21:32

Hey Kulik!

Could you give some advice on how to sort the Queueing of CEGUI in relation to Overlays?
In the past you could set the queue order of CEGUI, but this functionality has been removed at some point.

In my case, I would like to have a console overlay always showing in front of CEGUI.
I have found no way of doing that so far. :(

Cheers Mate!

dermont

14-08-2011 09:10:46

Hey Kulik!

Could you give some advice on how to sort the Queueing of CEGUI in relation to Overlays?
In the past you could set the queue order of CEGUI, but this functionality has been removed at some point.

In my case, I would like to have a console overlay always showing in front of CEGUI.
I have found no way of doing that so far. :(

Cheers Mate!


Can you not disable setFrameControlExecutionEnabled and update the CEGUI renderer in an Ogre RenderQueueListener?; something like:


###
### This demo is a based on the cegui Tree example
###
##/*************************************************************************
## Crazy Eddie's GUI System (http://www.cegui.org.uk)
## Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
##
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
##
## This library 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
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## *************************************************************************/

import sys
import os
sys.path.insert(0,'..')
import PythonOgreConfig
import ogre.renderer.OGRE as ogre
import ogre.io.OIS as OIS
import ogre.gui.CEGUI as CEGUI
import SampleFramework
import sys, exceptions, random
from CEGUI_framework import *

# Note: only taharez scheme works, the cegui demo Vanilla TreeDemo.layout is
# missing
def getSchemeDict(scheme):
SCHEME_DICT = {}
if scheme=="Vanilla":
SCHEME_DICT['SCHEME_FILE_NAME'] = "VanillaSkin.scheme"
SCHEME_DICT['IMAGES_FILE_NAME'] = "Vanilla-Images"
SCHEME_DICT['STATICIMAGE_NAME'] = "Vanilla/StaticImage"
SCHEME_DICT['TOOLTIP_NAME'] = "Vanilla/Tooltip"
SCHEME_DICT['LAYOUT_FILE_NAME'] = "TreeDemo.layout"
SCHEME_DICT['BRUSH_NAME'] = "GenericBrush"
else:
SCHEME_DICT['SCHEME_FILE_NAME'] = "TaharezLook.scheme"
SCHEME_DICT['IMAGES_FILE_NAME'] = "TaharezLook"
SCHEME_DICT['STATICIMAGE_NAME'] = "TaharezLook/StaticImage"
SCHEME_DICT['TOOLTIP_NAME'] = "TaharezLook/Tooltip"
SCHEME_DICT['LAYOUT_FILE_NAME'] = "TreeDemoTaharez.layout"
SCHEME_DICT['BRUSH_NAME'] = "TextSelectionBrush"
return SCHEME_DICT

def getSchemeFonts():
SCHEME_FONT = {}
SCHEME_FONT['Commonwealth-10'] = "Commonwealth-10.font"
SCHEME_FONT['BlueHighway-12'] = "bluehighway-12.font"
SCHEME_FONT['BlueHighway-10'] = "bluehighway-10.font"
SCHEME_FONT['BlueHighway-8'] = "bluehighway-8.font"
return SCHEME_FONT

def cegui_reldim ( x ) :
return CEGUI.UDim((x),0)

class GuiApplication ( SampleFramework.Application, GuiFrameListener, ogre.RenderQueueListener ):

def __init__(self):
SampleFramework.Application.__init__(self)
ogre.RenderQueueListener.__init__(self)
self.GUIRenderer=0
self.GUIsystem =0
self.EditorGuiSheet=0
self.ListItems = []
self.resourceEditor = None

def __del__(self):
##################
### Mohican
##################
self.sceneManager.removeRenderQueueListener(self)
del self.camera
del self.sceneManager
del self.frameListener
if self.resourceEditor:
self.resourceEditor = None
try:
if self.EditorGuiSheet:
CEGUI.WindowManager.getSingleton().destroyWindow(self.EditorGuiSheet)
except:
pass
del self.GUIsystem
del self.GUIRenderer
del self.root
del self.renderWindow

##################
### Mohican
##################
def renderQueueStarted(self, queueGroupId, invocation, skipThisQueue):
if queueGroupId == ogre.RENDER_QUEUE_SKIES_LATE:
CEGUI.System.getSingleton().renderGUI()
skipThisQueue=True

def renderQueueEnded(self, queueGroupId, invocation,repeatThisInvocation):
pass

##################
### Mohican
##################
def windowResized (self, rw):
dummyint = 0
width, height, depth, left, top= rw.getMetrics(dummyint,dummyint,dummyint, dummyint, dummyint) # Note the wrapped function as default needs unsigned int's
ms = self.Mouse.getMouseState()
ms.width = width
ms.height = height
CEGUI.System.getSingleton().notifyDisplaySizeChanged(CEGUI.Size(float(width), float(height)) )

def _setUpResources(self):
ogre.ResourceGroupManager.getSingleton().addResourceLocation("../media/gui", "FileSystem", "General", False)
SampleFramework.Application._setUpResources(self)

## Just override the mandatory create scene method
def _createScene(self):
sceneManager = self.sceneManager
sceneManager.ambientLight = ogre.ColourValue(0.5, 0.5, 0.5)

##################
### Mohican
##################
sceneManager.addRenderQueueListener(self)

## Create a skydome
self.sceneManager.setSkyDome(True, "Examples/CloudySky", 5, 8)

## Create a light
l = self.sceneManager.createLight("MainLight")

l.setPosition(20,80,50)

## setup GUI system
self.GUIRenderer = CEGUI.OgreRenderer.bootstrapSystem()
self.GUIsystem = CEGUI.System.getSingleton()

##################
### Mohican
##################
self.GUIRenderer.setFrameControlExecutionEnabled(False)

logger = CEGUI.Logger.getSingleton()
logger.setLoggingLevel( CEGUI.Informative )

# we will make extensive use of the WindowManager.
winMgr = CEGUI.WindowManager.getSingleton()

## get scheme characteristics
SCHEME_DICT = getSchemeDict('TaharezLook')

## load scheme and set up defaults
CEGUI.SchemeManager.getSingleton().create(SCHEME_DICT['SCHEME_FILE_NAME'])
self.GUIsystem.setDefaultMouseCursor(SCHEME_DICT['IMAGES_FILE_NAME'], "MouseArrow")

## Load Fonts
SCHEME_FONTS = getSchemeFonts()
for f in SCHEME_FONTS.keys():
if not CEGUI.FontManager.getSingleton().isDefined(f):
CEGUI.FontManager.getSingleton().create(SCHEME_FONTS[f])
self.GUIsystem.setDefaultFont( "BlueHighway-12")

## load image to use as a background
CEGUI.ImagesetManager.getSingleton().createFromImageFile("BackgroundImage", "GPN-2000-001437.tga")

## here we will use a StaticImage as the root, then we can use it to place a background image
background = winMgr.createWindow(SCHEME_DICT['STATICIMAGE_NAME'] , "background_wnd")

## set position and size
background.setPosition(CEGUI.UVector2(cegui_reldim(0), cegui_reldim( 0)))
background.setSize(CEGUI.UVector2(cegui_reldim(1), cegui_reldim( 1)))

## disable frame and standard background
background.setProperty("FrameEnabled", "false")
background.setProperty("BackgroundEnabled", "false")

## set the background image
background.setProperty("Image", "set:BackgroundImage image:full_image")

## install this as the root GUI sheet
CEGUI.System.getSingleton().setGUISheet(background)

## now we create a DefaultWindow which we will attach all the widgets to
sheet = winMgr.createWindow("DefaultWindow", "root_wnd")

## attach this to the 'real' root
background.addChildWindow(sheet)
#background.hide()

## load tree layout
TreeDemoWindow = winMgr.loadWindowLayout(SCHEME_DICT['LAYOUT_FILE_NAME'])
background.addChildWindow(TreeDemoWindow)

## activate the background window
background.activate()

### IMPORTANT
### - we have to create and hold a reference for our trees icon images
drives = CEGUI.ImagesetManager.getSingleton().create("DriveIcons.imageset")
iconArray = []
iconImages = [ "Artic",\
"Black",\
"Sunset",\
"DriveStack",\
"GlobalDrive",\
"Blue",\
"Lime",\
"Silver",\
"GreenCandy"]
iconArray = [ drives.getImage(image) for image in iconImages ]
self.iconArray = iconArray

## tree variables and events
IMAGES_FILE_NAME = SCHEME_DICT['IMAGES_FILE_NAME']
BRUSH_NAME = SCHEME_DICT['BRUSH_NAME']
theTree = winMgr.getWindow('DemoWindow/Tree')
theTree.initialise()

theTree.subscribeEvent( CEGUI.Tree.EventSelectionChanged,\
self,\
"handleEventSelectionChanged")
theTree.subscribeEvent( CEGUI.Tree.EventBranchOpened,\
self,\
"handleEventBranchOpened")
theTree.subscribeEvent( CEGUI.Tree.EventBranchClosed,\
self,\
"handleEventBranchClosed")

## helper to add list to TreeCtrl
def addListToTree(resourceList, parentItem, iconName):
for r in resourceList:
meshCtrlItem = CEGUI.TreeItem(r)
# meshCtrlItem.setIcon(drives.getImage(iconName))
image = iconArray[ iconImages.index(iconName) ]
meshCtrlItem.setIcon( image )
meshCtrlItem.setSelectionBrushImage(IMAGES_FILE_NAME, BRUSH_NAME)
meshCtrlItem.AutoDeleted = False
meshCtrlItem.setFont("BlueHighway-12")
parentItem.addItem(meshCtrlItem)
self.ListItems.append(meshCtrlItem)

## helper to create TreeCtrl item
def createListItem(text, parentItem, iconName):
meshCtrlItem = CEGUI.TreeItem(text)
# meshCtrlItem.setIcon(drives.getImage(iconName))
image = iconArray[ iconImages.index(iconName) ]
meshCtrlItem.setIcon( image )
meshCtrlItem.setSelectionBrushImage(IMAGES_FILE_NAME, BRUSH_NAME)
meshCtrlItem.AutoDeleted = False
meshCtrlItem.setFont("BlueHighway-12")
parentItem.addItem(meshCtrlItem)
self.ListItems.append(meshCtrlItem)
return meshCtrlItem

# create root Item
newTreeCtrlEntryLvl1 = createListItem("Ogre Resources",
theTree,"Silver")
# resource items
overlayCtrlItem = createListItem("overlays",
newTreeCtrlEntryLvl1,"Lime")

particleCtrlItem = createListItem("particles",
newTreeCtrlEntryLvl1,"Lime")

matCtrlItem = createListItem("materials",
newTreeCtrlEntryLvl1,"Lime")

matScriptCtrlItem = createListItem("scripts",
matCtrlItem,"Lime")

matProgramCtrlItem = createListItem("programs",
matCtrlItem,"Lime")

# add resource lists to tree
resManager = ogre.ResourceGroupManager.getSingleton()

## overlays
overlayList = resManager.findResourceNames("General", "*.overlay")
addListToTree(overlayList,overlayCtrlItem,"Silver")

## particles
particleList = resManager.findResourceNames("General", "*.particle")
addListToTree(particleList,particleCtrlItem,"Silver")

## materials
matList = resManager.findResourceNames("General", "*.material")
addListToTree(matList,matScriptCtrlItem,"Silver")

for p in ['cg', 'glsl','hlsl','frag']:
mProgramCtrlItem = createListItem(p, matProgramCtrlItem,"Lime")
matList = resManager.findResourceNames("General", "*.%s" %(p))
addListToTree(matList,mProgramCtrlItem,"Silver")
return True

## Create new frame listener
def _createFrameListener(self):
GuiFrameListener.__init__(self, self.renderWindow, self.camera, self.GUIRenderer) #self.sceneManager)
self.root.addFrameListener(self)
self.showDebugOverlay(True)

def handleEventSelectionChanged(self, args):
selectedItem = args.treeItem
if selectedItem:
text = selectedItem.getText().c_str()
## don't do anything
return True

def handleEventBranchOpened(self, args):
print "Branch Open"
return True

def handleEventBranchClosed(self, args):
print "Branch Closed"
return True

def handleQuit(self, e):
self.frameListener.requestShutdown()
return True

if __name__ == '__main__':
try:
ta = GuiApplication()
ta.go()
except ogre.OgreException, e:
print e

Kulik

14-08-2011 11:43:36

iwanantonowitsch: Interesting and useful discussion only please, you must have done something wrong when you turned source into binaries :D

filmore: This is one caveat, since we can't possibly predict what Ogre version you have, we don't ship prebuilt PyCEGUIOgreRenderer, you have to build it yourself and link to your Ogre version of choosing. This is a major pain but I can't see any other possibility, even shipping CEGUIOgreRenderer with CEGUI SDK is kind of not the "right thing" since we always link to the latest stable but Ogre and CEGUI releases are not synchronised! For any serious development, you should build it yourself IMO :-)

Mohican: as dermont said, you have to disable automatic rendering and call renderGUI yourself at the "right moment".

filmore

15-08-2011 01:20:08

I'm not at all experienced with building anything, so is there a guide for this somewhere?

Kulik

15-08-2011 12:41:12

I think the only way to make this effortless is for someone to maintain a Python-Ogre + PyCEGUI package for other people.

That said though, building PyCEGUI should be fairly simple (it takes a long time unfortunately). You have to get boost::python and then it's just a matter of setting the BUILD_PYTHON_MODULES option in the config.lua of CEGUI premake build (I don't remember the details but it should be somewhere :-D), if premake finds Ogre and boost::python it will build PyCEGUI and PyCEGUIOgreRenderer.

Mohican

15-08-2011 13:15:30

I think the only way to make this effortless is for someone to maintain a Python-Ogre + PyCEGUI package for other people.


Are you volunteering?
:wink:

Kulik

15-08-2011 13:36:38

Mohican: No I am not, I already have too much on my plate :-) But anyone is welcome really, I am willing to give advices but I am unlikely to do it myself.

dermont

15-08-2011 14:43:08

I think the only way to make this effortless is for someone to maintain a Python-Ogre + PyCEGUI package for other people.


Not too sure if maintaining a Python-Ogre + PyCEGUI package is really necessary. The python-ogre build (environment.py) already contains the build commands for CEGUI. You could create a separate module for pycegui and update the lua and configure commands for Windows and Linux.

The generate code(-g) part could be empty or create an CEGUIOgreRender module and copy across the python modules to fit into the python-ogre structure if necessary.

There could be a flag in the python-ogre config flags that allows users to either build the current python-ogre cegui module or the official CEGUI bindings. There may be other things that need tweaking but it seems pretty easy to implement.

http://python-ogre.svn.sourceforge.net/ ... iew=markup

Kulik

16-08-2011 11:06:00

dermont: I think for quick prototypes and for people who are unable/unwilling to build things themselves, packaging it in packages ready to be easy_installed from the python repository is the only way. The overhead with creating the packages is quite painful though. The right thing to do is to have PyCEGUI, Python-Ogre and then PyCEGUIOgreRenderer that would depend on both of them.

dermont

16-08-2011 12:50:59

dermont: I think for quick prototypes and for people who are unable/unwilling to build things themselves, packaging it in packages ready to be easy_installed from the python repository is the only way. The overhead with creating the packages is quite painful though. The right thing to do is to have PyCEGUI, Python-Ogre and then PyCEGUIOgreRenderer that would depend on both of them.

Kulik: Sorry for being dumb here but why is installing from the python repository the only way? Why can't the existing sourceforge python-ogre "package/ file archive" for Windows just not build and include your version of PyCEGUI and PyCEGUIOgreRenderer(built against the same version of Ogre that python-ogre uses)?

On Linux things would obviously be different, is there a even a package for PyCEGUI for various distros?

As a side note I did try PyCEGUI/PyCEGUIOgreRenderer(CEGUI 08) with python-ogre and other than a duplicate converter for std::vector<int, std::allocator<int> > everything ran OK. So good work on that. There were a couple of minor problems I encountered but I will post on the CEGUI forum if I can't resolve the issues.

Kulik

16-08-2011 14:02:55


Kulik: Sorry for being dumb here but why is installing from the python repository the only way? Why can't the existing sourceforge python-ogre "package/ file archive" for Windows just not build and include your version of PyCEGUI and PyCEGUIOgreRenderer(built against the same version of Ogre that python-ogre uses)?

Valid question, I guess saying that it's the only way was wrong. But it certainly is something people using Python expect. They want to just install it and start working. And the first place they look is the Python repository. On the other hand for more advanced uses and integration with existing games/engines it's best to just compile it yourself IMO.


On Linux things would obviously be different, is there a even a package for PyCEGUI for various distros?

We do put PyCEGUI, PyCEGUIOpenGLRenderer and PyCEGUINullRenderer into the SDK on all platforms. IMO it doesn't make sense to expose DirectX renderers since there is no convenient way to work with DirectX inside python. We have yet to decide whether to package PyCEGUIOgreRenderer there and if so, which version of Ogre to link against. Perhaps you could join the discussion irc.freenode.net/#cegui sometimes, we need advice from people actually using the stuff :-D


As a side note I did try PyCEGUI/PyCEGUIOgreRenderer(CEGUI 08) with python-ogre and other than a duplicate converter for std::vector<int, std::allocator<int> > everything ran OK. So good work on that. There were a couple of minor problems I encountered but I will post on the CEGUI forum if I can't resolve the issues.

Good to know that this works, to be honest I haven't tested it with python-ogre yet myself. I still have some string related issues to solve before full inheritance is possible but I want to be able to make CEGUI widgets from within python in 0.8

ccc

24-08-2011 15:23:36

Hi, I've been looking around for info on how to build PyCEGUIOgreRenderer and I just can't seem to find many details anywhere. Has anyone else been able to solve this?

Kulik

25-08-2011 12:04:37

Hi, I've been looking around for info on how to build PyCEGUIOgreRenderer and I just can't seem to find many details anywhere. Has anyone else been able to solve this?

Just setting it up in config.lua (premake config) and generating the build files should do the trick. But you have to set the correct boost::python and Ogre paths.

dermont

14-11-2011 03:08:17

So what was the outcome of any discussions regarding the cegui module and PyCEGUI. Is the cegui module being deprecated in favour of PyCEGUI?

Looking at the CEGUI code there has been a number of changes so it would probably take a few hours work to update the existing code generation to support 0.8. However, there will then be duplication of effort/ subtle differences between versions.

If the cegui module is being deprecated then should MyGUI (which appears to have been in release candidate for 1 year now) now be the default gui for python-ogre?

Kulik

14-11-2011 09:53:06

0.7 PyCEGUI works with python-ogre, 0.8 works with it as well. The only difference is that the vendor isn't python-ogre anymore but CEGUI directly. I see that as an advantage for users, python is a first-citizen language for CEGUI and is officially supported. The only remaining problem is that we need to somehow synchronise/arrange releases so that binary precompiled python-ogre works with binary precompiled PyCEGUI.

dermont

14-11-2011 18:53:27

0.7 PyCEGUI works with python-ogre, 0.8 works with it as well. The only difference is that the vendor isn't python-ogre anymore but CEGUI directly. I see that as an advantage for users, python is a first-citizen language for CEGUI and is officially supported. The only remaining problem is that we need to somehow synchronise/arrange releases so that binary precompiled python-ogre works with binary precompiled PyCEGUI.

Ok but that wasn't what I really asked. What I wanted to know is If the current cegui module is being deprecated. If it is then I won't bother uploading the python-ogre cegui module updates to support 0.8 to svn.

Kulik

25-11-2011 11:28:24

Dunno about that, not my decision. However I think it's wasted effort since we have bindings that support 0.8 in the mercurial tree.