IGUIElement clippingrect change
IGUIElement clippingrect change
I have created a nice windowing system that detects when IGUIElement children are outside of the parents clientrect. If this is detected, the window creates scrollbars and allows the user to 'move' the client area to view the entire child element. this all works well.
unfortunately, the children are clipped against the absolute rect of the parent, which allows them to be in the 'titlebar' area of the window.
what I need is the ability to change the child's clipping rectangle prior to it being rendered. unfortunately, the clip rect is a protected variable and I cannot have access to it from the parent.
short of changing the IGUIElement interface and adding a setClippingRect() type function, is there a way to manipulate the clipping rect from the instance of the parent?
unfortunately, the children are clipped against the absolute rect of the parent, which allows them to be in the 'titlebar' area of the window.
what I need is the ability to change the child's clipping rectangle prior to it being rendered. unfortunately, the clip rect is a protected variable and I cannot have access to it from the parent.
short of changing the IGUIElement interface and adding a setClippingRect() type function, is there a way to manipulate the clipping rect from the instance of the parent?
Re: IGUIElement clippingrect change
I fear it is as you have found out already. You could maybe add another element in between that has the size of your client area.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: IGUIElement clippingrect change
any chance of getting a setClippingRect(rect<s32>) to the engine?
I can easily modify my copy so it isnt critical, but the windowing system I have is pretty sweet if I do say so myself
I use a 'father knows best' approach for the layout, cascading from the topmost window (the Desktop) down through the children, each of them arranging their children to fit as desired.
minimizing, maximizing, docking are complete.
the next step is resizing. I have it working on another testbed, but need to integrate it into this testbed.
for example
I can easily modify my copy so it isnt critical, but the windowing system I have is pretty sweet if I do say so myself
I use a 'father knows best' approach for the layout, cascading from the topmost window (the Desktop) down through the children, each of them arranging their children to fit as desired.
minimizing, maximizing, docking are complete.
the next step is resizing. I have it working on another testbed, but need to integrate it into this testbed.
for example
Code: Select all
// create the top level window
// the desktop class auto includes a CSGUI_Minimizebar that handles minimizing windows correctly
Desktop = new CSGUI_Desktop(device, env, ID_DESKTOP);
// create a new window that has a vertical / horiz scrollbar and is docked to the left side of its parent
// the sysmenu flag auto creates a CSGUI_SysToolbar that houses the close, min, max, restore buttons
// the system will handle minimizing, maximizing and restoring this window
CSGUI_Window* w1 = new CSGUI_Window(Desktop, env, Desktop, ID_WINDOW1, rect<s32>(100, 100, 400, 600), CS_HSCROLLBAR | CS_VSCROLLBAR | CS_VISIBLE | CS_CAPTION | CS_BORDER | CS_SYSMENU, CSGUI_Layout(layoutStyle::LEFTFILL));
// add it to the desktop
Desktop->addCSChild(w1);
// add a regular gui element. since the w1 window has scrollbars, the client rect can be scrolled to move the button around relatively
env->addButton(rect<s32>(100, 10, 200, 200), w1, -1, L"testing");
// add another window that is docked to the left side of its parent (in this case w1 above)
CSGUI_Window* w2 = new CSGUI_Window(w1, env, w1, ID_WINDOW2, rect<s32>(0, 0, 100, 100), CS_VISIBLE | CS_CAPTION | CS_BORDER , CSGUI_Layout(layoutStyle::LEFTFILL));
w1->addCSChild(w2);
// add a toolbar to it
CSGUI_Toolbar* w3 = new CSGUI_Toolbar(w2,ID_WINDOW3);
w2->addCSChild(w3);
// here we can add guielements to the toolbar as desired
// toolbar guielement notifications are sent to w2 since it is the parent of the toolbar
// add a window that is docked to the right hand side of the desktop
CSGUI_Window* w4 = new CSGUI_Window(Desktop, env, Desktop, ID_WINDOW4, rect<s32>(100, 100, 400, 600), CS_VISIBLE | CS_CAPTION | CS_BORDER | CS_SYSMENU, CSGUI_Layout(layoutStyle::RIGHTFILL));
Desktop->addCSChild(w4);
// add a window that fills in the remainder of the desktop client area after all of the docked windows layouts are complete
// in a real app, this would be a CSGUI_LevelViewer instance to render the smgr etc....
CSGUI_Window* w5 = new CSGUI_Window(Desktop, env, Desktop, ID_WINDOW4, rect<s32>(100, 100, 100, 0), CS_VISIBLE | CS_CAPTION | CS_BORDER, CSGUI_Layout(layoutStyle::REST));
Desktop->addCSChild(w5);
Re: IGUIElement clippingrect change
added sizing
if i figure out how to redo my github upload i will post the demo.
I made the mistake of adding all files to my git repository. now it wont upload because one of the files is too large.
I deleted the file and tried again, but it still wants that file.
can someone tell me how to undo this?
if i figure out how to redo my github upload i will post the demo.
I made the mistake of adding all files to my git repository. now it wont upload because one of the files is too large.
I deleted the file and tried again, but it still wants that file.
can someone tell me how to undo this?
Re: IGUIElement clippingrect change
Can't help with git. And don't know right now about clipping, would have to check first how that is used in all the elements and can be changed without trouble. Unfortunately I can't work on Irrlicht for the next few weeks (at least next 6 weeks).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: IGUIElement clippingrect change
Cool stuff :-)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: IGUIElement clippingrect change
a little tester for the gui system.
*** directory structure is the same as irrlicht so use your own media folder that is two levels up from the exe ***
i dont do any checks for loading the test scene, so it looks for normal irrlicht bin directory at ../../media
it will crash if it doesnt find it
uses a VERY slightly modified irrlicht.dll (only exposed clippingRect so I could clip against scrollbars)
includes: resizing, minimizing, maximizing, restoring and embedding irrlicht gui elements
also detects mouse hovering resizable window and modifies color to indicate that the window is resizable in that direction
examples :
LEFTFILL windows can be resized to the right only
TOPFILL windows can resize at bottom etc....
CSGUIToolbars cannot be resized
CSGUISysMenu toolbar is derived from CSGUIToolbar and houses min, max buttons
allows user to 'move' clientarea around so that irrlicht guielements can be fully seen.
window #1 is an example of this. use scrollbars OR click and drag mouse in clientarea to see what it does.
theory :
Desktop is top level window and cascades down through children
uses a 'father knows best' approach for child window layouts
example: CS_LAYOUT_STYLE :: LEFTFILL will put the child at the left side of the parent and resize it to fill the parent clientRect to the bottom
example: CS_LAYOUT_STYLE :: RIGHTFILL will put the child at the right side of the parent and resize it to fill the parent clientRect to the bottom
as father lays out children, it keeps track of remaining clientrect and uses it for next child so....
if LEFTFILL then father clientrect is reduced
then the toolbar (TOPFILL) will start at child.lowerrightcorner.X and extend to end of clientrect
all windows use flags for creation :
CS_VISIBLE | CS_THICKFRAME | CS_BORDER | CS_SYSMENU | CS_TRANSPARENT
creates a visible, resizable, bordered window with a CSGUI_SysMenu toolbar (close, min, max, restore) and will prevent rendering the clientarea (transparent)
added CSGUI_Window_Viewer to show how a transparent clientArea allows us to render the smgr into a window.
right click mouse to toggle camera input enabled / disabled
anyhow, I will release the source once I get it cleaned up, but wanted feedback if anyone tries it out.........
http://www.filedropper.com/csguitester
*** directory structure is the same as irrlicht so use your own media folder that is two levels up from the exe ***
i dont do any checks for loading the test scene, so it looks for normal irrlicht bin directory at ../../media
it will crash if it doesnt find it
uses a VERY slightly modified irrlicht.dll (only exposed clippingRect so I could clip against scrollbars)
includes: resizing, minimizing, maximizing, restoring and embedding irrlicht gui elements
also detects mouse hovering resizable window and modifies color to indicate that the window is resizable in that direction
examples :
LEFTFILL windows can be resized to the right only
TOPFILL windows can resize at bottom etc....
CSGUIToolbars cannot be resized
CSGUISysMenu toolbar is derived from CSGUIToolbar and houses min, max buttons
allows user to 'move' clientarea around so that irrlicht guielements can be fully seen.
window #1 is an example of this. use scrollbars OR click and drag mouse in clientarea to see what it does.
theory :
Desktop is top level window and cascades down through children
uses a 'father knows best' approach for child window layouts
example: CS_LAYOUT_STYLE :: LEFTFILL will put the child at the left side of the parent and resize it to fill the parent clientRect to the bottom
example: CS_LAYOUT_STYLE :: RIGHTFILL will put the child at the right side of the parent and resize it to fill the parent clientRect to the bottom
as father lays out children, it keeps track of remaining clientrect and uses it for next child so....
if LEFTFILL then father clientrect is reduced
then the toolbar (TOPFILL) will start at child.lowerrightcorner.X and extend to end of clientrect
all windows use flags for creation :
CS_VISIBLE | CS_THICKFRAME | CS_BORDER | CS_SYSMENU | CS_TRANSPARENT
creates a visible, resizable, bordered window with a CSGUI_SysMenu toolbar (close, min, max, restore) and will prevent rendering the clientarea (transparent)
added CSGUI_Window_Viewer to show how a transparent clientArea allows us to render the smgr into a window.
right click mouse to toggle camera input enabled / disabled
anyhow, I will release the source once I get it cleaned up, but wanted feedback if anyone tries it out.........
http://www.filedropper.com/csguitester
Re: IGUIElement clippingrect change
in reference to the download above......
code showing the createGui() function in tester3.cpp (create a desktop and add in some test windows)
full test3.exe to show how device, scene, gui etc is created..........
nothing spectacular here............
code showing the createGui() function in tester3.cpp (create a desktop and add in some test windows)
Code: Select all
void createGui()
{
// create the desktop
Desktop = new CSGUI_Desktop(device, env, ID_DESKTOP);
// add a resizable, clientarea scrollable, visible, titlbarred, bordered window with a min/max/restore/close toolbar and stick it to the left side of it's parent (the desktop in this case)
CSGUI_Window* w1 = new CSGUI_Window(Desktop, env, Desktop, ID_WINDOW1, stringw("Scroll Client Area Mouse or Scrollbars"), rect<s32>(100, 100, 400, 600), CS_THICKFRAME | CS_HSCROLLBAR | CS_VSCROLLBAR | CS_VISIBLE | CS_CAPTION | CS_BORDER | CS_SYSMENU, CSGUI_Layout(layoutStyle::LEFTFILL));
Desktop->addCSChild(w1);
// testing the ability to modify the clientwindow after primary creation is completed
w1->setClientWindow(new CSGUI_ClientAreaWindow(w1));
// add a simple button that the user can scroll around in the client window
env->addButton(rect<s32>(100, 10, 200, 200), w1->getClientWindow(), -1, L"testing");
// add a visible, titlebarred, bordered and resizable window that is a child of w1 and stick it to the bottom of it's parent
CSGUI_Window* w2 = new CSGUI_Window(w1, env, w1, ID_WINDOW2, stringw("Window #2"), rect<s32>(0, 0, 100, 100), CS_VISIBLE | CS_CAPTION | CS_BORDER | CS_THICKFRAME, CSGUI_Layout(layoutStyle::BOTTOMFILL));
w1->addCSChild(w2);
// a simple test of adding normal irrlight guielements ( in this case a tree of the scenenodes in the smgr)
CSGUI_SceneTree* w4 = new CSGUI_SceneTree(Desktop, env, Desktop, ID_WINDOW4, stringw("SceneTree"), rect<s32>(100, 100, 400, 600), CS_VISIBLE | CS_CAPTION | CS_BORDER | CS_SYSMENU | CS_THICKFRAME, CSGUI_Layout(layoutStyle::RIGHTFILL), smgr);
Desktop->addCSChild(w4);
// add a transparent clientwindow that renders the smgr. note that it is of style REST which means it fills whatver is left of the parents clientarea
CSGUI_Viewer* w5 = new CSGUI_Viewer(Desktop, env, Desktop, ID_WINDOW5, stringw("Scene Viewer Right Click for mouse control"), rect<s32>(100, 100, 100, 0), CS_TRANSPARENT | CS_VISIBLE | CS_CAPTION | CS_BORDER, CSGUI_Layout(layoutStyle::REST), smgr);
Desktop->setClientWindow(w5);
// add a toolbar to the smgr viewer. add some buttons to the toolbar (only the LIGHT actually does anything in this demo)
CSGUI_Toolbar* w3 = new CSGUI_Toolbar(w5, ID_WINDOW3);
w5->addCSChild(w3);
w3->addButton(env->addButton(rect<s32>(0, 0, 64, 16), w3, ID_LIGHT, L"Light"));
w3->addButton(env->addButton(rect<s32>(0, 0, 64, 16), w3, -1, L"Button2"));
w3->addButton(env->addButton(rect<s32>(0, 0, 64, 16), w3, -1, L"Button3"));
w3->addButton(env->addButton(rect<s32>(0, 0, 64, 16), w3, -1, L"Button4"));
}
full test3.exe to show how device, scene, gui etc is created..........
nothing spectacular here............
Code: Select all
#include "stdafx.h"
#include "common.h"
#include <conio.h>
#include <ctype.h>
#include "CSGUI_Desktop.h"
#include "CSGUI_Toolbar.h"
#include "CSGUI_Viewer.h"
#include "CSGUI_SceneTree.h"
#include "CSGUI_ClientAreaWindow.h"
using namespace CS;
IrrlichtDevice * device;
IVideoDriver* driver;
IGUIEnvironment* env;
ISceneManager* smgr;
dimension2d<u32> oldScreenSize(dimension2d<u32>(0, 0));
CSGUI_Desktop* Desktop = 0;
#define ID_DESKTOP 777
#define ID_WINDOW1 1
#define ID_WINDOW2 2
#define ID_WINDOW3 3
#define ID_WINDOW4 4
#define ID_WINDOW5 5
void createGui()
{
Desktop = new CSGUI_Desktop(device, env, ID_DESKTOP);
CSGUI_Window* w1 = new CSGUI_Window(Desktop, env, Desktop, ID_WINDOW1, stringw("Scroll Client Area Mouse or Scrollbars"), rect<s32>(100, 100, 400, 600), CS_THICKFRAME | CS_HSCROLLBAR | CS_VSCROLLBAR | CS_VISIBLE | CS_CAPTION | CS_BORDER | CS_SYSMENU, CSGUI_Layout(layoutStyle::LEFTFILL));
Desktop->addCSChild(w1);
w1->setClientWindow(new CSGUI_ClientAreaWindow(w1));
env->addButton(rect<s32>(100, 10, 200, 200), w1->getClientWindow(), -1, L"testing");
CSGUI_Window* w2 = new CSGUI_Window(w1, env, w1, ID_WINDOW2, stringw("Window #2"), rect<s32>(0, 0, 100, 100), CS_VISIBLE | CS_CAPTION | CS_BORDER | CS_THICKFRAME, CSGUI_Layout(layoutStyle::BOTTOMFILL));
w1->addCSChild(w2);
CSGUI_SceneTree* w4 = new CSGUI_SceneTree(Desktop, env, Desktop, ID_WINDOW4, stringw("SceneTree"), rect<s32>(100, 100, 400, 600), CS_VISIBLE | CS_CAPTION | CS_BORDER | CS_SYSMENU | CS_THICKFRAME, CSGUI_Layout(layoutStyle::RIGHTFILL), smgr);
Desktop->addCSChild(w4);
CSGUI_Viewer* w5 = new CSGUI_Viewer(Desktop, env, Desktop, ID_WINDOW5, stringw("Scene Viewer Right Click for mouse control"), rect<s32>(100, 100, 100, 0), CS_TRANSPARENT | CS_VISIBLE | CS_CAPTION | CS_BORDER, CSGUI_Layout(layoutStyle::REST), smgr);
Desktop->setClientWindow(w5);
CSGUI_Toolbar* w3 = new CSGUI_Toolbar(w5, ID_WINDOW3);
w5->addCSChild(w3);
w3->addButton(env->addButton(rect<s32>(0, 0, 64, 16), w3, ID_LIGHT, L"Light"));
w3->addButton(env->addButton(rect<s32>(0, 0, 64, 16), w3, -1, L"Button2"));
w3->addButton(env->addButton(rect<s32>(0, 0, 64, 16), w3, -1, L"Button3"));
w3->addButton(env->addButton(rect<s32>(0, 0, 64, 16), w3, -1, L"Button4"));
}
void createScene()
{
smgr->getRootSceneNode()->setName("RootNode");
scene::IAnimatedMesh* mesh = smgr->getMesh("../../media/room.3ds");
smgr->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.004f);
scene::ISceneNode* node = 0;
node = smgr->addAnimatedMeshSceneNode(mesh);
node->setName("Room");
node->setMaterialTexture(0, driver->getTexture("../../media/wall.jpg"));
node->getMaterial(0).SpecularColor.set(0, 0, 0, 0);
mesh = smgr->addHillPlaneMesh("myHill",
core::dimension2d<f32>(20, 20),
core::dimension2d<u32>(40, 40), 0, 0,
core::dimension2d<f32>(0, 0),
core::dimension2d<f32>(10, 10));
node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), 3.0f, 300.0f, 30.0f);
node->setPosition(core::vector3df(0, 7, 0));
node->setMaterialTexture(0, driver->getTexture("../../media/stones.jpg"));
node->setMaterialTexture(1, driver->getTexture("../../media/water.jpg"));
node->setMaterialType(video::EMT_REFLECTION_2_LAYER);
node->setName("Water");
// create light
node = smgr->addLightSceneNode(0, core::vector3df(0, 0, 0),
video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 800.0f);
scene::ISceneNodeAnimator* anim = 0;
anim = smgr->createFlyCircleAnimator(core::vector3df(0, 150, 0), 250.0f);
node->addAnimator(anim);
anim->drop();
node->setName("Light");
// attach billboard to light
node = smgr->addBillboardSceneNode(node, core::dimension2d<f32>(50, 50));
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
node->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp"));
node->setName("Light Billboard");
// create a particle system
scene::IParticleSystemSceneNode* ps =
smgr->addParticleSystemSceneNode(false);
ps->setName("Particle System");
scene::IParticleEmitter* em = ps->createBoxEmitter(
core::aabbox3d<f32>(-7, 0, -7, 7, 1, 7), // emitter size
core::vector3df(0.0f, 0.06f, 0.0f), // initial direction
80, 100, // emit rate
video::SColor(0, 255, 255, 255), // darkest color
video::SColor(0, 255, 255, 255), // brightest color
800, 2000, 0, // min and max age, angle
core::dimension2df(10.f, 10.f), // min size
core::dimension2df(20.f, 20.f)); // max size
ps->setEmitter(em); // this grabs the emitter
em->drop(); // so we can drop it here without deleting it
scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();
ps->addAffector(paf); // same goes for the affector
paf->drop();
ps->setPosition(core::vector3df(-70, 60, 40));
ps->setScale(core::vector3df(2, 2, 2));
ps->setMaterialFlag(video::EMF_LIGHTING, false);
ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
ps->setMaterialTexture(0, driver->getTexture("../../media/fire.bmp"));
ps->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
scene::IVolumeLightSceneNode * n = smgr->addVolumeLightSceneNode(0, -1,
32, // Subdivisions on U axis
32, // Subdivisions on V axis
video::SColor(0, 255, 255, 255), // foot color
video::SColor(0, 0, 0, 0)); // tail color
if (n)
{
n->setName("Volume Light");
n->setScale(core::vector3df(56.0f, 56.0f, 56.0f));
n->setPosition(core::vector3df(-120, 50, 40));
// load textures for animation
core::array<video::ITexture*> textures;
for (s32 g = 7; g > 0; --g)
{
core::stringc tmp;
tmp = "../../media/portal";
tmp += g;
tmp += ".bmp";
video::ITexture* t = driver->getTexture(tmp.c_str());
textures.push_back(t);
}
// create texture animator
scene::ISceneNodeAnimator* glow = smgr->createTextureAnimator(textures, 150);
// add the animator
n->addAnimator(glow);
// drop the animator because it was created with a create() function
glow->drop();
}
// add animated character
mesh = smgr->getMesh("../../media/dwarf.x");
scene::IAnimatedMeshSceneNode* anode = 0;
anode = smgr->addAnimatedMeshSceneNode(mesh);
anode->setPosition(core::vector3df(-50, 20, -60));
anode->setAnimationSpeed(15);
// add shadow
anode->addShadowVolumeSceneNode();
smgr->setShadowColor(video::SColor(150, 0, 0, 0));
// make the model a little bit bigger and normalize its normals
// because of the scaling, for correct lighting
anode->setScale(core::vector3df(2, 2, 2));
anode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
anode->setName("Dwarf");
}
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver() : IEventReceiver() { }
virtual bool OnEvent(const SEvent& event)
{
return false;
}
};
int main()
{
// create device and exit if creation failed
device = createDevice(EDT_DIRECT3D9, core::dimension2d<u32>(1024, 768));
// could not create selected driver.
if (device == 0) return 1;
/* The creation was successful, now we set the event receiver and
store pointers to the driver and to the gui environment. */
device->setWindowCaption(L"Irrlicht Engine - User Interface Demo");
device->setResizable(true);
driver = device->getVideoDriver();
env = device->getGUIEnvironment();
smgr = device->getSceneManager();
IGUISkin* skin = env->getSkin();
IGUIFont* font = env->getFont("media/fonthaettenschweiler.bmp");
if (font) skin->setFont(font);
skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);
// Then create the event receiver, giving it that context structure.
MyEventReceiver receiver;
// And tell the device to use our custom event receiver.
// device->setEventReceiver(&receiver);
createGui();
createScene();
while (device->run() && driver)
{
if (device->isWindowActive())
{
if (driver->getScreenSize() != oldScreenSize)
{
if (Desktop) Desktop->onSize(rect<s32>(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height));
oldScreenSize = driver->getScreenSize();
}
driver->beginScene(true, true);
//smgr->drawAll();
env->drawAll();
driver->endScene();
}
}
device->drop();
return 0;
}