Page 1 of 1

Fix for Multicolumn list scrollbars showing up when unneeded

Posted: Sun Apr 22, 2007 18:32
by Rakkar
I noticed that the multicolumn list horizontal scrollbar shows up even when not needed. This happens if the column header approaches the edges although doesn't reach it.

I fixed this by allowing you to set always on, always off, or as needed for setShowHorzScrollbar and setShowVertScrollbar, which also better matches the function name:

Code: Select all

String   ForceVertScrollbar::get(const PropertyReceiver* receiver) const
{
   switch (static_cast<const MultiColumnList*>(receiver)->isVertScrollbarAlwaysShown())
   {
      case MultiColumnList::AlwaysOn:
         return String("AlwaysOn");
         break;

      case MultiColumnList::AlwaysOff:
         return String("AlwaysOff");
         break;
   }

   return String("AsRequired");
}


void   ForceVertScrollbar::set(PropertyReceiver* receiver, const String& value)
{
   MultiColumnList::ScrollbarVisibility mode;

   if (value == "AlwaysOn")
   {
      mode = MultiColumnList::AlwaysOn;
   }
   else if (value == "AlwaysOff")
   {
      mode = MultiColumnList::AlwaysOff;
   }
   else
   {
      mode = MultiColumnList::AsRequired;
   }
   static_cast<MultiColumnList*>(receiver)->setShowVertScrollbar(mode);
}


String   ForceHorzScrollbar::get(const PropertyReceiver* receiver) const
{
   switch (static_cast<const MultiColumnList*>(receiver)->isHorzScrollbarAlwaysShown())
   {
   case MultiColumnList::AlwaysOn:
      return String("AlwaysOn");
      break;

   case MultiColumnList::AlwaysOff:
      return String("AlwaysOff");
      break;
   }

   return String("AsRequired");
}


void   ForceHorzScrollbar::set(PropertyReceiver* receiver, const String& value)
{
   MultiColumnList::ScrollbarVisibility mode;

   if (value == "AlwaysOn")
   {
      mode = MultiColumnList::AlwaysOn;
   }
   else if (value == "AlwaysOff")
   {
      mode = MultiColumnList::AlwaysOff;
   }
   else
   {
      mode = MultiColumnList::AsRequired;
   }
   static_cast<MultiColumnList*>(receiver)->setShowHorzScrollbar(mode);
}


Code: Select all

// KevinJ - fixes a bug with scrollbars showing up even though you set them off
   enum ScrollbarVisibility
   {
      AlwaysOn,
      AlwaysOff,
      AsRequired,
   };


Code: Select all

/*!
   \brief
      Return whether the vertical scroll bar is always shown.

      - AlwaysOn if the scroll bar will always be shown even if it is not required.
      - AlwaysOff if the scroll bar will never show up
      - AsRequired if the scroll bar will only be shown when it is required.
   */
   ScrollbarVisibility   isVertScrollbarAlwaysShown(void) const;


   /*!
   \brief
      Return whether the horizontal scroll bar is always shown.

   \return
      - AlwaysOn if the scroll bar will always be shown even if it is not required.
      - AlwaysOff if the scroll bar will never show up
      - AsRequired if the scroll bar will only be shown when it is required.
   */
   ScrollbarVisibility   isHorzScrollbarAlwaysShown(void) const;



Code: Select all

/*!
   \brief
      Set whether the vertical scroll bar should always be shown, never be shown, or only when needed

   \param setting
      - AlwaysOn to have the vertical scroll bar shown at all times.
      - AlwaysOff to have the vertical scroll bar never show
      - AsRequired to have the vertical scroll bar appear only when needed.

   \return
      Nothing.
   */
   void   setShowVertScrollbar(ScrollbarVisibility setting);


   /*!
   \brief
      Set whether the horizontal scroll bar should always be shown, never be shown, or only when needed

   \param setting
      - AlwaysOn to have the horizontal scroll bar shown at all times.
      - AlwaysOff to have the horizontal scroll bar never show
      - AsRequired to have the horizontal scroll bar appear only when needed.

   \return
      Nothing.
   */
   void   setShowHorzScrollbar(ScrollbarVisibility setting);


Code: Select all

// scrollbar settings.
   ScrollbarVisibility   d_forceVertScroll;      //!< Sets scrollbar visibility - always on, always off, or AsRequired
   ScrollbarVisibility   d_forceHorzScroll;      //!< Sets scrollbar visibility - always on, always off, or AsRequired


Code: Select all

d_forceVertScroll(AsRequired),
   d_forceHorzScroll(AsRequired),


Code: Select all

/*************************************************************************
   Enable / Disable forced display of the vertical scroll bar
*************************************************************************/
void MultiColumnList::setShowVertScrollbar(ScrollbarVisibility setting)
{
   if (d_forceVertScroll != setting)
   {
      d_forceVertScroll = setting;

      configureScrollbars();

      // Event firing.
      WindowEventArgs args(this);
      onVertScrollbarModeChanged(args);
   }

}


/*************************************************************************
   Enable / Disable forced display of the horizontal scroll bar
*************************************************************************/
void MultiColumnList::setShowHorzScrollbar(ScrollbarVisibility setting)
{
   if (d_forceHorzScroll != setting)
   {
      d_forceHorzScroll = setting;

      configureScrollbars();

      // Event firing.
      WindowEventArgs args(this);
      onHorzScrollbarModeChanged(args);
   }

}


Code: Select all

/*************************************************************************
   display required integrated scroll bars according to current state
   of the list box and update their values.   
*************************************************************************/
void MultiColumnList::configureScrollbars(void)
{
    Scrollbar* vertScrollbar = getVertScrollbar();
    Scrollbar* horzScrollbar = getHorzScrollbar();
   float totalHeight   = getTotalRowsHeight();
   float fullWidth      = getListHeader()->getTotalSegmentsPixelExtent();

   //
   // First show or hide the scroll bars as needed (or requested)
   //
   // show or hide vertical scroll bar as required (or as specified by option)
   if (((totalHeight > getListRenderArea().getHeight()) && d_forceVertScroll==AsRequired) || d_forceVertScroll==AlwaysOn)
   {
      vertScrollbar->show();

      // show or hide horizontal scroll bar as required (or as specified by option)
      if (((fullWidth > getListRenderArea().getWidth()) && d_forceHorzScroll==AsRequired) || d_forceHorzScroll==AlwaysOn)
      {
         horzScrollbar->show();
      }
      else
      {
         horzScrollbar->hide();
      }

   }
   else
   {
      // show or hide horizontal scroll bar as required (or as specified by option)
      if (((fullWidth > getListRenderArea().getWidth()) && d_forceHorzScroll==AsRequired) || d_forceHorzScroll==AlwaysOn)
      {
         horzScrollbar->show();

         // show or hide vertical scroll bar as required (or as specified by option)
         if (((totalHeight > getListRenderArea().getHeight()) && d_forceVertScroll==AsRequired) || d_forceVertScroll==AlwaysOn)
         {
            vertScrollbar->show();
         }
         else
         {
            vertScrollbar->hide();
         }

      }
      else
      {
         vertScrollbar->hide();
         horzScrollbar->hide();
      }

   }

   //
   // Set up scroll bar values
   //
   Rect renderArea(getListRenderArea());

   vertScrollbar->setDocumentSize(totalHeight);
   vertScrollbar->setPageSize(renderArea.getHeight());
   vertScrollbar->setStepSize(ceguimax(1.0f, renderArea.getHeight() / 10.0f));
   vertScrollbar->setScrollPosition(vertScrollbar->getScrollPosition());

   horzScrollbar->setDocumentSize(fullWidth);
   horzScrollbar->setPageSize(renderArea.getWidth());
   horzScrollbar->setStepSize(ceguimax(1.0f, renderArea.getWidth() / 10.0f));
   horzScrollbar->setScrollPosition(horzScrollbar->getScrollPosition());
}



Code: Select all

/*************************************************************************
   Return whether the vertical scroll bar is always shown.
*************************************************************************/
MultiColumnList::ScrollbarVisibility MultiColumnList::isVertScrollbarAlwaysShown(void) const
{
   return d_forceVertScroll;
}


/*************************************************************************
   Return whether the horizontal scroll bar is always shown.
*************************************************************************/
MultiColumnList::ScrollbarVisibility MultiColumnList::isHorzScrollbarAlwaysShown(void) const
{
   return d_forceHorzScroll;
}



Posted: Wed Mar 18, 2009 19:16
by Mikademus
Has this been added to the code base? I find nothing of it in the documentation and have this issue.

That is, the items of my multicolumnlist cannot fill the box, or even overlap the space where a scrollbar would be if it was there, without them showing up. Looks very ugly.

Posted: Wed Mar 18, 2009 20:29
by CrazyEddie
Hi, and welcome :)

As far as I am aware this has not been added to the code; in fact this is the first time I myself ever seen this post.

With regards to Rakkar's post (and with reference to your other post), this is not a patch, this is just a bunch of code, and as such is pretty useless to us. Patches have to be submitted in unified diff format, and preferably posted on the mantis tracker - posting of code snippets like this and/or complete 'replacement files' will just be ignored as a waste of our time (I'm not having a go or anything, just stating how it is :) ).

I do like the idea of three modes of scrollbar setting though, so I might steal that and use it throughout the system at some stage.

CE.

Re: Fix for Multicolumn list scrollbars showing up when unne

Posted: Sat May 31, 2014 18:12
by Jabberwocky
Howdy folks,

Necro time.

There is still a problem with MultiColumnLists and horizontal scrollbars in 0.8.2
31/05/2014 12:55:55 (Std) ---- Version: 0.8.2 (Build: Dec 19 2013 Debug Microsoft Windows MSVC++ Great Scott! 32 bit) ----
31/05/2014 12:55:55 (Std) ---- Renderer module is: CEGUI::OpenGLRenderer - Official OpenGL based 2nd generation renderer module. TextureTarget support enabled via FBO extension. ----
31/05/2014 12:55:55 (Std) ---- XML Parser module is: CEGUI::ExpatParser - Official expat based parser module for CEGUI ----
31/05/2014 12:55:55 (Std) ---- Image Codec module is: SILLYImageCodec - Official SILLY based image codec ----
31/05/2014 12:55:55 (Std) ---- Scripting module is: None ----


Repro steps:
  • Create a MCL widget
  • mine has 2 columns of width 0.4 and 0.6, although I'm not sure this matters.
  • while the MCL has no entries: no scrollbars are shown (correct).
  • add some elements (less than a full pane): no scrollbars are shown (correct).
  • add more elements (more than a full pane): the vertical scrollbar is now shown (correct), the horizontal scrollbar also appears at the same time (incorrect).

Rakkar's fix looks like it would work, and provide a solution to the problem. Plus it provides some new functionality. But really, it is just patching over the underlying error that the horizontal scrollbar shows when it shouldn't.

Just one other quick comment. I'm working on a 2D game right now, using SFML. CEGUI integrated in pretty seamlessly, via the CEGUIOpenGLRenderer. I was really happy to bring along my trusty GUI sidekick on this new ride. Cheers! :pint:

Re: Fix for Multicolumn list scrollbars showing up when unne

Posted: Sun Jun 01, 2014 19:02
by Ident
Glad you could integrate it easily.

Regarding the MCL - i think this widget has got some minor issues beside the ones you mentioned. I am not sure if timotei is working on it during this GSOC but this widget, next to some others, needs an overhaul or rework.

However , if you have any pull request (preferred)or patch to provide, that would be helpful in any case and could probably go into the next v 0-8 release.

Re: Fix for Multicolumn list scrollbars showing up when unne

Posted: Mon Jun 02, 2014 20:20
by Jabberwocky
Hiya Ident.

I don't have a fix for it currently. I'm in the early phases of prototyping a new game, so minor UI quirks are pretty far down the list of priorities. I just thought I'd share my observations in case it is useful to anyone.

I have more clearly figured out the issue though. When the vertical scrollbar gets added, it "steals" some of the list area (a sliver along the right side). As a result, the header widgets are now too wide to display in the list area. This causes the horizontal scrollbar to appear.

A workaround is to make the sum of the header widths somewhat less than 1.0, so that they still fit when the vertical scrollbar is added.

I am using the OgreTrays scheme.

In the off-chance someone here is squashing bugs in the MCL code, perhaps the ideal CEGUI fix would be this: The vert scrollbar is instead drawn outside of the list area, such that the list area doesn't get any smaller when the vert scrollbar is added. Let me know if you'd like me to make a bug tracker entry.

Re: Fix for Multicolumn list scrollbars showing up when unne

Posted: Mon Jun 02, 2014 20:25
by Ident
Sure, make an entry on bug tracker. Add the reproduction also. Thx.

Did you try if the bug persists if u use another skin's MCL? Preferrably TaharezLook?

Re: Fix for Multicolumn list scrollbars showing up when unne

Posted: Tue Jun 03, 2014 07:05
by Jabberwocky
Bug filed. http://cegui.org.uk/mantis/view.php?id=1026
I recall it is a problem in other skins as well.