Gui you click on amongst 2 others gets ZOrder placed above the others

Started by Knox, Wed 02/03/2011 19:23:32

Previous topic - Next topic

Knox

Hi,

Ive gotten this far, but its not very elegant, nor compact...plus I think I made a mistake in my logic somewhere because it doesnt work 100% like Im envisioning.

Basically what Im doing is I have 3 guide booklets that are gui's. The zorders are initialized as:
QuickGuide_VC.ZOrder = 10;
QuickGuide_PC.ZOrder = 9;
QuickGuide_SS.ZOrder = 8;

I dont want the ZOrders to ever be anything different than 8, 9 or 10. The highest is always 10, the lowest, always 8.

When you click on any of the gui's, that gui's zorder will become 10, the others, depending on their order amongst themselves, will get their zorder knocked down so that its logical.

Here is what I have, where could my error be (Ive attempted debugging without luck so far) and more important, how to make this shorter/more elegant?
Code: ags

  if (mouse.IsButtonDown(eMouseLeft) && gQuickGuidesGUI.Visible)
  {
    if (overGUI == gQuickGuidePC)
    {
      iPCz = gQuickGuidePC.ZOrder;
      if (iPCz != 10)
      {
        gQuickGuidePC.ZOrder = 10;
        iVCz = gQuickGuideVC.ZOrder;  
        iSSz = gQuickGuideSS.ZOrder;
        if (iVCz == 10) gQuickGuideVC.ZOrder = 9;
        else if (iVCz == 9) gQuickGuideVC.ZOrder = 8;
        else if (iSSz == 10) gQuickGuideSS.ZOrder = 9;
        else if (iSSz == 9) gQuickGuideSS.ZOrder = 8;       
      }
    }
    else if (overGUI == gQuickGuideVC)
    {
      iVCz = gQuickGuideVC.ZOrder;
      if (iVCz != 10)
      {
        gQuickGuideVC.ZOrder = 10;
        iPCz = gQuickGuidePC.ZOrder;  
        iSSz = gQuickGuideSS.ZOrder;
        if (iPCz == 10) gQuickGuidePC.ZOrder = 9;
        else if (iPCz == 9) gQuickGuidePC.ZOrder = 8;
        else if (iSSz == 10) gQuickGuideSS.ZOrder = 9;
        else if (iSSz == 9) gQuickGuideSS.ZOrder = 8;       
      }       
    }
    else if (overGUI == gQuickGuideSS)
    {
      iSSz = gQuickGuideSS.ZOrder;
      if (iSSz != 10)
      {
        gQuickGuideSS.ZOrder = 10;
        iVCz = gQuickGuideVC.ZOrder;  
        iPCz = gQuickGuidePC.ZOrder;
        if (iVCz == 10) gQuickGuideVC.ZOrder = 9;
        else if (iVCz == 9) gQuickGuideVC.ZOrder = 8;
        else if (iPCz == 10) gQuickGuidePC.ZOrder = 9;
        else if (iPCz == 9) gQuickGuidePC.ZOrder = 8;       
      }       
    }
  }
--All that is necessary for evil to triumph is for good men to do nothing.

monkey0506

It seems to me that it would be as simple in this case as doing something like:

Code: ags
function gQuickGuide_OnClick(GUI *theGui, MouseButton button)
{
  // link the OnClick functions for gQuickGuideVC, gQuickGuidePC, and gQuickGuideSS to this function
  if (theGui.ZOrder == 10) return; // there's no need to process any of this if we clicked on the highest GUI already
  GUI *otherGUIs[2]; // we'll use this to make it a bit more generically simple :)
  // here..we figure out which GUIs belong where
  // theGui:		VC	PC	SS
  // otherGUIs[0]:	PC	VC	VC
  // otherGUIs[1]:	SS	SS	PC
  // NOTE: This isn't always an accurate depiction of the current z-orders, but it will always let us put each GUI into its own slot
  if (theGui != gQuickGuideVC) otherGUIs[0] = gQuickGuideVC;
  else otherGUIs[0] = gQuickGuidePC;
  if (theGui != gQuickGuideSS) otherGUIs[1] = gQuickGuideSS;
  else otherGUIs[1] = gQuickGuidePC;
  theGui.ZOrder = 10; // this GUI's z-order is always set to 10
  if (otherGUIs[0].ZOrder != 8) otherGUIs[0].ZOrder--; // these GUIs' z-orders may have been 8, 9, or 10..
  if (otherGUIs[1].ZOrder != 8) otherGUIs[1].ZOrder--; // ..as long as they weren't already 8 then they need to be bumped down one
}


The reason I created the array was simply to avoid having to duplicate code, which I think you were asking about, right?

Instead of constantly checking for clicks in repeatedly_execute (which I'm guessing is where you had the code), just set the OnClick event (in the Events pane in the editor for each of the GUIs) to this function (copy and paste the function name). AGS is already checking for these clicks anyway (even if you don't have an OnClick function linked, it still fires on_event for eEventGUIMouseDown and eEventGUIMouseUp), so there's no need for you to be checking for it yourself. ;)

Knox

Wow, so much better...how do you guys do it? Ill be able to apply your solution to many other things now aswell, since you explained it too.

Works perfect sir!

Thanx :)
--All that is necessary for evil to triumph is for good men to do nothing.

monkey0506

It took me a second to wrap my head around the array mapping (in simplest terms), which is why I made that table. As I noted, that table doesn't necessarily reflect the z-order of the GUIs, but it ensures that each of them gets used.

That along with the information you provided is, as you say, "how [I] do it". :=

You're welcome.

Knox

Say if I wanted to add a 4th booklet (or even 5th), is this how I would process  the zorders? What is the "formula" you used exactly? I cant figure it out (you're smart).

Code: ags

  GUI *otherGUIs[3];
  if (theGui != gQuickGuideVC) otherGUIs[0] = gQuickGuideVC;
  else otherGUIs[0] = gQuickGuidePC;
  
  if (theGui != gQuickGuideSS) otherGUIs[1] = gQuickGuideSS;
  else otherGUIs[1] = gQuickGuidePC;
  
  if (theGui != gQuickGuideFM) otherGUIs[2] = gQuickGuideFM;
  else otherGUIs[2] = gQuickGuidePC;
  
  theGui.ZOrder = 10; // this GUI's z-order is always set to 10

  if (otherGUIs[0].ZOrder != 7) otherGUIs[0].ZOrder--; // these GUIs' z-orders may have been 7,8, 9, or 10..
  if (otherGUIs[1].ZOrder != 7) otherGUIs[1].ZOrder--; //...as long as they weren't already 7 then they need to be bumped down one
  if (otherGUIs[2].ZOrder != 7) otherGUIs[2].ZOrder--;
--All that is necessary for evil to triumph is for good men to do nothing.

monkey0506

Retrospectively that solution was somewhat specialized whereas a more generic solution would have been more flexible and you probably wouldn't have to be asking about it again now..

Code: ags
  if (theGui.ZOrder == 10) return;
  GUI *sortedGUIs[SORTED_GUI_COUNT];
  // just add each of the GUIs to this array
  sortedGUIs[0] = gQuickGuideVC;
  sortedGUIs[1] = gQuickGuidePC;
  sortedGUIs[2] = gQuickGuideSS;
  sortedGUIs[3] = gQuickGuideFM;
  int maxZOrder = 10; // highest Z order of any of the GUIs
  int minZOrder = (maxZOrder - (SORTED_GUI_COUNT - 1)); // lowest Z order of any of the GUIs
  int i = 0;
  while (i < SORTED_GUI_COUNT)
  {
    if (sortedGUIs[i] == theGui) sortedGUIs[i].ZOrder = maxZOrder; // if this was the GUI that the user clicked on, bring it to the top
    else if (sortedGUIs[i].ZOrder != minZOrder) sortedGUIs[i].ZOrder--; // if this was not already the lowest GUI, then it should be shifted down
    i++;
  }

Knox

--All that is necessary for evil to triumph is for good men to do nothing.

Knox

Hey Monkey,

I've run into a little problem with testing today:
1) There are 4 guides (a,b,c,d).
2) The present Z order is like this (from farthest to closest to screen): d,c,b,a

When I click on c or d, alternating the clicks, after a few clicks, the zOrder of guide "a" will pop-up above guide "b" without clicking on it.

Is it something with the logic or perhaps somehow I need to test out if my clicks are going through some guides?

**Short vid on youtube: http://www.youtube.com/watch?v=YUYn4rtxBHI**
--All that is necessary for evil to triumph is for good men to do nothing.

monkey0506

Ugh, I overlooked something when I wrote that last bit of code..if you have more than 3 GUIs then..it won't work right! 8)

Code: ags
  if (theGui.ZOrder == 10) return;
  GUI *sortedGUIs[SORTED_GUI_COUNT];
  // just add each of the GUIs to this array
  sortedGUIs[0] = gQuickGuideVC;
  sortedGUIs[1] = gQuickGuidePC;
  sortedGUIs[2] = gQuickGuideSS;
  sortedGUIs[3] = gQuickGuideFM;
  int maxZOrder = 10; // highest Z order of any of the GUIs
  int curZOrder = theGui.ZOrder; // we need the current Z order..only the GUIs above this level need to be shifted down
  int i = 0;
  while (i < SORTED_GUI_COUNT)
  {
    if (sortedGUIs[i] == theGui) sortedGUIs[i].ZOrder = maxZOrder; // if this was the GUI that the user clicked on, bring it to the top
    else if (sortedGUIs[i].ZOrder > curZOrder) sortedGUIs[i].ZOrder--; // if this GUI was above the clicked GUI previously, it needs to be shifted down
    i++;
  }


I still haven't tested this (at all!! :=), but it should..probably work now.

SMF spam blocked by CleanTalk