Page 1 of 1

How to create a vertical Scrollable list of staticimages

Posted: Wed Dec 31, 2014 08:42
by Garibalde
Hi

I am trying to create a vertical scrollable list of images. So therefore i have created a Staticimage and added a bunch of staticimages into this container (staticimage).
This is seems to be good and works fine. However the number of images exceed the size of the window so i placed a vertical scrollbar so i can scroll through the images.
Is this the correct way? I cant seem to control the vertical scroll to move up and down with the images? Is there another item that can do the same with built in scroll logic
in CEGUI?

here is the code of the layout.

Code: Select all

<GUILayout version="4" >
    <Window type="TaharezLook/StaticImage" name="Sidebar" >
        <Property name="Area" value="{{0,0},{0,0},{0,146},{0,774}}" />
        <Property name="Alpha" value="0.5" />
        <Property name="MaxSize" value="{{1,0},{1,0}}" />
        <Property name="AlwaysOnTop" value="true" />
        <Property name="FrameEnabled" value="true" />
        <Property name="ClippedByParent" value="false" />
        <Property name="BackgroundEnabled" value="true" />
        <Window type="TaharezLook/VerticalScrollbar" name="VerticalScrollbar" >
            <Property name="Area" value="{{0,130},{0,0},{0,146},{1,0}}" />
            <Property name="InheritsAlpha" value="false" />
            <Property name="VerticalScrollbar" value="true" />
            <AutoWindow namePath="__auto_thumb__" >
                <Property name="MouseInputPropagationEnabled" value="true" />
            </AutoWindow>
        </Window>
    </Window>
</GUILayout>


There are no errors etc. I just need direction if i am doing this right. I think there should be an easier solution that i maybe just missing.

Thanks

Re: How to create a vertical Scrollable list of staticimages

Posted: Wed Dec 31, 2014 10:24
by Ident
Did you compile the CEGUI SampleBrowser/SampleFramework? If yes, please open it and check the ScrollablePane demo. This contains the element you need to have: ScrollablePane. StaticImage is not a container and cannot be used as such.

My suggestion for this is this hierarchy of parents and children: ScrollablePane -> VerticalLayoutContainer (for automatic positioning vertically) -> and here you add a couple of StaticImages

If you want to manually position your windows than just use the ScrollablePane as parent and add StaticImages to it. This is basically what the demo does.

The Scrollbar will come up for the ScrollablePane window without you needing to add it manually.
Do you want to make a simple Tutorial page for this on our wiki? It could be helpful for others and I could review it for you.

Re: How to create a vertical Scrollable list of staticimages

Posted: Tue Jan 06, 2015 04:42
by Garibalde
I could do a wiki after i get it to work. But i have a few issues.

I create the layout as below:

Code: Select all

<GUILayout version="4" >
    <Window type="TaharezLook/ScrollablePane" name="Sidebar" >
        <Property name="Area" value="{{0,1},{0,0},{0,154},{0,759}}" />
        <Property name="AlwaysOnTop" value="true" />
        <Property name="ContentArea" value="l:0 t:0 r:135 b:27" />
        <AutoWindow namePath="__auto_container__" >
            <Property name="ContentArea" value="l:0 t:0 r:135 b:27" />
            <Property name="MouseInputPropagationEnabled" value="true" />
            <Window type="TaharezLook/Combobox" name="Combobox" >
                <Property name="Area" value="{{0,0},{0,0},{0,135},{0,27}}" />
                <Property name="Text" value="Vinay" />
                <Property name="AlwaysOnTop" value="true" />
                <AutoWindow namePath="__auto_editbox__" >
                    <Property name="Text" value="Vinay" />
                    <Property name="ActiveSelectionColour" value="tl:FF6060FF tr:FF6060FF bl:FF6060FF br:FF6060FF" />
                </AutoWindow>
                <AutoWindow namePath="__auto_droplist__" >
                    <AutoWindow namePath="__auto_hscrollbar__" >
                        <AutoWindow namePath="__auto_incbtn__" >
                            <Property name="RestoreOldCapture" value="true" />
                        </AutoWindow>
                        <AutoWindow namePath="__auto_decbtn__" >
                            <Property name="RestoreOldCapture" value="true" />
                        </AutoWindow>
                        <AutoWindow namePath="__auto_thumb__" >
                            <Property name="RestoreOldCapture" value="true" />
                            <Property name="MouseInputPropagationEnabled" value="true" />
                        </AutoWindow>
                    </AutoWindow>
                    <AutoWindow namePath="__auto_vscrollbar__" >
                        <Property name="VerticalScrollbar" value="true" />
                        <AutoWindow namePath="__auto_incbtn__" >
                            <Property name="RestoreOldCapture" value="true" />
                        </AutoWindow>
                        <AutoWindow namePath="__auto_decbtn__" >
                            <Property name="RestoreOldCapture" value="true" />
                        </AutoWindow>
                        <AutoWindow namePath="__auto_thumb__" >
                            <Property name="RestoreOldCapture" value="true" />
                            <Property name="MouseInputPropagationEnabled" value="true" />
                        </AutoWindow>
                    </AutoWindow>
                </AutoWindow>
            </Window>
        </AutoWindow>
        <AutoWindow namePath="__auto_hscrollbar__" >
            <Property name="NonClient" value="true" />
            <Property name="AlwaysOnTop" value="true" />
            <AutoWindow namePath="__auto_thumb__" >
                <Property name="MouseInputPropagationEnabled" value="true" />
            </AutoWindow>
        </AutoWindow>
        <AutoWindow namePath="__auto_vscrollbar__" >
            <Property name="NonClient" value="true" />
            <Property name="AlwaysOnTop" value="true" />
            <Property name="VerticalScrollbar" value="true" />
            <AutoWindow namePath="__auto_thumb__" >
                <Property name="MouseInputPropagationEnabled" value="true" />
            </AutoWindow>
        </AutoWindow>
    </Window>
</GUILayout>


My StaticImage (main object template)

Code: Select all

<GUILayout version="4" >
    <Window type="TaharezLook/StaticImage" name="ObjectIcon" >
        <Property name="Area" value="{{0,469},{0,287},{0,597},{0,415}}" />
        <Property name="Image" value="OgreTrayImages/OgreLogo" />
        <Property name="MaxSize" value="{{1,0},{1,0}}" />
        <Property name="AlwaysOnTop" value="true" />
        <Property name="FrameEnabled" value="true" />
        <Property name="InheritsAlpha" value="false" />
        <Property name="DragDropTarget" value="false" />
        <Property name="ClippedByParent" value="false" />
        <Property name="BackgroundEnabled" value="true" />
    </Window>
</GUILayout>


The scrollpane is defined in the class Sidebarwindow as below:

Code: Select all

SidebarWindow::SidebarWindow(CEGUI::Window* Sheet, CEGUI::Window* Window, Ogre::SceneManager* ScnMgr)
{
   mGUISheet = Sheet;
   mGUIWindow = Window;
   mGUISheet->addChild(mGUIWindow);
   Hide();
   
   mGUIWindow->subscribeEvent(CEGUI::Window::EventMouseLeavesArea, CEGUI::Event::Subscriber(&SidebarWindow::MouseLeavesSidebar,this));
   mGUIWindow->subscribeEvent(CEGUI::Window::EventMouseButtonDown, CEGUI::Event::Subscriber(&SidebarWindow::MouseClickSidebar,this));
   mCloneIcon = CEGUI::WindowManager::getSingleton().loadLayoutFromFile("ObjectIcon.layout");
   InitializeSidebarList();
}

SidebarWindow::~SidebarWindow()
{

}

void SidebarWindow::Hide()
{
   mGUIWindow->setVisible(false);
   ListOfObjectIcons::iterator p;
   for (p=mListofObjects.begin(); p!=mListofObjects.end(); p++)
   {
      (*p)->GetObjectIconWindow()->setProperty("Disabled","true");
   }
}

void SidebarWindow::UnHide()
{
        mGUIWindow->setVisible(true);
   ListOfObjectIcons::iterator p;
   for (p=mListofObjects.begin(); p!=mListofObjects.end(); p++)
   {
      (*p)->GetObjectIconWindow()->setProperty("Disabled","false");
   }
}

bool SidebarWindow::InitializeSidebarList()
{
   std::string path = "..\\Media\\Properties\\Game\\";
   std::vector<std::string> ListofObjects;
   bool found = ListFilesGivenExtension(path,".Body",ListofObjects);
   std::vector<std::string>::iterator p;

   // Create an Object for each body.
   int i = 0;
   for (p=ListofObjects.begin(); p!=ListofObjects.end(); p++)
   {
      boost::filesystem::path filename = (*p);
      std::string SetImage = "DriveIcons/" + filename.stem().string();
      bool test = CEGUI::ImageManager::getSingleton().isDefined((CEGUI::String)SetImage);
      if (test)
      {
         CEGUI::Vector2f location(0.5,0.22+(i*0.175));
         CEGUI::Sizef CloneIconSize = mCloneIcon->getPixelSize();
         ObjectIcon* MyObjectIcon = new ObjectIcon;
         CEGUI::Window* MyIcon = MyObjectIcon->CreateIcon(mCloneIcon, mGUIWindow, (*p), location, 1.0, SetImage, true);
         mListofObjects.push_back(MyObjectIcon);
         mGUIWindow->addChild((CEGUI::Element*) MyIcon);
         i++;
      }
   }
   _cprintf("-> Number of items in sidebar: %i, with a length of %f\n", i, 0.175+(i*0.175));
   return true;
}

//! callback activates on Mouse leaving side bar.
bool SidebarWindow::MouseLeavesSidebar(const CEGUI::EventArgs& eventArgs)
{
   this->Hide();
   return true;
}

bool SidebarWindow::MouseClickSidebar(const CEGUI::EventArgs& eventArgs)
{
   _cprintf("-> You have Clicked in the Sidebar. Test for object icon clicked..\n");
   ListOfObjectIcons::iterator p;
   for (p=mListofObjects.begin(); p!=mListofObjects.end(); p++)
   {
      CEGUI::MouseCursor* CEGUIMouse = &CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor();
      if ((*p)->GetObjectIconWindow()->isHit(CEGUIMouse->getPosition()))
      {
         _cprintf("-> You have Clicked on ICON.\n");
      }
   }
   return true;
}

bool SidebarWindow::OnObjectSelection(const CEGUI::EventArgs& eventArgs)
{
   return true;
}

bool SidebarWindow::UpdateObjectList(std::string mode)
{
   return true;
}

void SidebarWindow::Update(CEGUI::Vector2<float> myMouse, const Ogre::FrameEvent& evt)
{
   //! check to see if you need to open the top menu bar.
   if (myMouse.d_x < SIDEBAR_DETECTION_THRESHOLD_WIDTH)
   {
      if (!this->isVisible())
      {
         mGUIWindow->setProperty("AlwaysOnTop","true");
      }
      UnHide();
   }
}


The ObjectWindow is cloned to create multiple objects in the scrollpane:

Code: Select all

ObjectIcon::ObjectIcon()
{

}

ObjectIcon::~ObjectIcon()
{

}

CEGUI::Window* ObjectIcon::CreateIcon(CEGUI::Window* CloneWin, CEGUI::Window* Container, std::string ObjName, CEGUI::Vector2f Pos, float scale, CEGUI::String SetImage, bool SetVisible)
{
   mObjectName = ObjName + ".Icon";
   mIconImage = CEGUI::WindowManager::getSingleton().createWindow(CloneWin->getType(), mObjectName);   
   CEGUI::Sizef IconImageSize = mIconImage->getPixelSize();
   CEGUI::UVector2 Mypos(CEGUI::UDim(Pos.d_x,-IconImageSize.d_width/(2.0*scale)),CEGUI::UDim(Pos.d_y,-IconImageSize.d_height/scale));
   //IconImage->setSize(CEGUI::USize(CEGUI::UDim(0,IconImageSize.d_width/scale), CEGUI::UDim(0,IconImageSize.d_height/scale)));
   mIconImage->setPosition(Mypos);
   mIconImage->enable();
   mIconImage->setVisible(SetVisible);
   mIconImage->setProperty("Image",SetImage);
   mIconImage->setProperty("Alpha","1.0");
   return mIconImage;
}


A few issues i am having.

I am trying to do a ishit() test on the staticimages in MouseClickSidebar() on EventMouseButtonDown() on the scrollpane.. however it does not detect hits on the staticimages only
when i hit the actual scrollpane it detects a hit and makes the callback MouseClickSidebar(). I.e the code loop for staticimage in MouseClickSidebar() does not print "-> You have Clicked on ICON."
when i am clicking on the staticimage.

Another issue is that when the scrollpane and stateimages are hidden. if i put the test loop (ishit()) in Update() which is run in a loop all the time from the main program. It generates hits
for the staticimages weather they are hidden or unhidden. I guess hiding them just changes their visibility. Is there a way to disable the staticimages when not visible. I tried Disabled() on all
the staticimages when they are hidden or unhidden didnt seem to work either. This has been fixed i added Disabled() to Hide() and UnHide(). Must have done something wrong last time. Modified code above.

If you see anything that can be improved i am welcome to suggestions to improve the code.

Thanks

Re: How to create a vertical Scrollable list of staticimages

Posted: Tue Jan 06, 2015 11:19
by Ident
You always need to have a root window that covers your entire application, this is also described in the official API docs clearly. Do you have that? If not then create a DefaultWindow and give it the relative size 1,1 and place everything inside it. If I understand correctly, currently your scrollablepane is the root which is not good. Try if this also resolves your issue with isHit() please!

Re: How to create a vertical Scrollable list of staticimages

Posted: Tue Jan 06, 2015 15:31
by Garibalde
I do have a root window which I attach all my windows too.

The root window is mGUISheet in the class SidebarWindow which is passed in via the constructor. mGUIWindow (Scrollpane) is added to this root as a child in the constructor also. I can post a picture tonight how the window looks if it helps.

Re: How to create a vertical Scrollable list of staticimages

Posted: Tue Jan 06, 2015 16:33
by Ident
What happens if u remove this node: <AutoWindow namePath="__auto_container__" > and all its contents, inside <Window type="TaharezLook/ScrollablePane" name="Sidebar" > ? Same effect?

Re: How to create a vertical Scrollable list of staticimages

Posted: Thu Jan 08, 2015 05:41
by Garibalde
Yes i removed the section from the layout and the same thing occurs.

When i click directly on the sidebarwindow (around the staticimages) the callback MouseClickSidebar() is called. But when i
click on the staticimages in the sidebarwindow the Callback is not called. Does the staticimage swallow the mouseclick in someway?

Re: How to create a vertical Scrollable list of staticimages

Posted: Thu Jan 08, 2015 06:13
by Garibalde
I tried the following:

I added the following line to the InitializeSidebarList() after creating the icon. It seems to work now.

Code: Select all

MyIcon->subscribeEvent(CEGUI::Window::EventMouseButtonDown, CEGUI::Event::Subscriber(&SidebarWindow::MouseClickSidebar,this));


What did i do wrong before. I thought clicking on the sidebar window should call MouseClickSidebar() and then i check for a ishit() on the list of icons?
This works too for me. But i am curious why the other didnt work?

Thanks for your help. I will work on the wiki if you still like it done?

Re: How to create a vertical Scrollable list of staticimages

Posted: Thu Jan 08, 2015 12:51
by Ident
I think I didnt understand you correctly. Are you saying you got a window and it has children and if you click the children, then the parent doesnt receive a click event? If this is the case I can give you an easy solution. Activate "MousePassThroughEnabled" and your child window will basically be unclickable and pass through all inputs. Is that what you want?

I am trying to do a ishit() test on the staticimages in MouseClickSidebar() on EventMouseButtonDown() on the scrollpane..

Why dont you just subscribe to a mouse click event on the static images instead?