Right-Click GUI (SOLVED... for now)

Started by ScottDoom, Tue 17/01/2006 04:37:29

Previous topic - Next topic

ScottDoom

I thought I was better at this...Ã,  :-\ It's been a while though, and last time I didn't create a custom GUI. I just had no GUI, and made it so you right-clicked through cursors.

Anyways, I would like to have a GUI that pops up on a right-click where you then select a cursor mode by clicking a button on the interface, and then right-click again (or just click a button) and have the GUI vanish. I think something like this was used in Grrr! Bearly Sane and probably other games as well.

I have the buttons set up and I have the GUI set to Popup Modal but from there I don't know where to go. Where should I put the scripting, and how should it look?

Edit: I got the GUI to pop-up on right click but now I can't get it to go away. It just stays there.

This is what's written in the global script:
Code: ags
#sectionstart on_mouse_clickÃ,  // DO NOT EDIT OR REMOVE THIS LINE
function on_mouse_click(MouseButton button) // called when a mouse button is clicked. button is either LEFT or RIGHT
Ã,  {
Ã,  {
Ã,  Ã,  }
Ã,  if (button == eMouseLeft) 
Ã,  Ã,  {
Ã,  Ã,  ProcessClick(mouse.x,mouse.y, mouse.Mode);
Ã,  Ã,  }
Ã,  if (button == eMouseRight) // right-click, bring up GUI
Ã,  Ã,  {Ã,  Ã, 
Ã,  Ã,  gKarma.Visible = true;
Ã,  Ã,  }
Ã,  }


There was some code in there about not allowing clicks while paused but I just whacked that right off, and also changed some other stuff from the default. What I want to happen is that when the GUI is up once you click a button (to select a new cursor type) the GUI goes away, or if you right-click again it defaults to the walk cursor and the GUI goes away. What lines of code do I need to add for this?

I mean if I put:
Code: ags

if (button == eMouseRight)
 {
 gKarma.Visible = false;
 }


I'm just going to get some weird reaction or error, right?

I notice there's a section in the global script called #sectionstart interface_click. Would I put the "close-code" in there instead?

Also, is there any way I can get the GUI to pop-up where the player right-clicks? As of now it just pops up rougly in the middle of the screen where I have specified the coordinates.

Ashen

Code: ags

if (button == eMouseRight) {
  if (gKarma.Visible == false) gKarma.Visible = true;
  else gKarma.Visible = false;
}

Will turn gKarma on if it's off, and off if it's on. It won't work if you right-click on the GUI itself - if that's a problem you're probably going to have to set up the on_event function.

interface_click isn't really recommended - it's obsolete, and I think it's really only included for backwards compatability. You could create a control function for the GUI (like you do for the individual buttons, etc) - but that doesn't run if you click an object ON the GUI, just if you click on blank space. I think you'll have to add gKarma.Visible = false; to every control to get it to switch off when you click one.

GUI.SetPosition
Just set gKarma's position to mouse.x, mouse.y before you turn it on. You'll need to add some checks, though, to make sure the whole thing is visible.

Do a search for verb coin interfaces - there's probably more detailed answers available somewhere, or you could try a template (e.g. from Skimbleshanks - 9th down, "Verb Coin". It's old-style script, but might give you some pointers.)
I know what you're thinking ... Don't think that.

ScottDoom

I didn't want to use a template because I thought I could learn more from asking for help or doing it myself.

I've got one final question on the GUI...

Is it possible to link buttons? Say I have some graphic icons to the left and over to the right the list of the same actions but in text. Now I've made graphics so that the words light up, but what I want is that not only when you scroll over the text do they light up via roll-over but also when you move the mouse over the image icons on the other side the corresponding text still lights up. Is this even possible or am I dreaming?

hedgefield

Wouldn't it be easier to close the GUI when you press/select a cursor mode there? I'm not sure how extensive your GUI is. I have a similar GUI (Right-click = GUI with all cursor modes. You click on one, and it changes to that and closes GUI). I use 2.6, so I guess for 2.7 it's something like:

Under sectionstart on_mouse_click:

  if (button == eMouseRight) {   
    gKarma.Visible = true;
    Gui.SetPosition (Karma, mouse.x, mouse.y);
}


And under sectionstart interface_click:

  if (gKarma.Visible == true) {
        if (button == BUTTONNUMBER) {       
         gKarma.Visible == false
         SetCursorMode(CURSORMODE#AFFILIATEDWITHTHATBUTTON);
        }
        if (button == SOMEOTHERBUTTONNUMBER) {       
         gKarma.Visible == false
         SetCursorMode(CURSORMODE#AFFILIATEDWITHTHATBUTTON);
        etc etc

ScottDoom

Whaaaaaaaaaaat. A piece of my code just jumped from one section of the global script to the other and I didn't even touch it. When I moved it back I still get an error.  :D

I mean last time I coded my half-game I had no problem but I just did some basic character and object scripting along with some room-specific scripting. I didn't try creating a custom GUI or anything extra.

Right now I'm trying to get the idle view to work and it's being a pain. I looked at the manual and found the code, but I don't know where to put it.

Ashen

Quote from: largopredatorWouldn't it be easier to close the GUI when you press/select a cursor mode there?
That's what I meant by "you'll have to add gKarma.Visible = false; to every control to get it to switch off when you click one", except I was talking about the GUI Control functions, rather than interface_click.

QuoteI didn't want to use a template because I thought I could learn more from asking for help or doing it myself.
Well, to be honest, you'd probably have to re-write most of that particular template anyway, to get it exactly how you wanted. Like I said, it'd be more a case of getting pointers, so you didn't have to ask for help from absolute scratch.

Quotebut also when you move the mouse over the image icons on the other side the corresponding text still lights up. Is this even possible or am I dreaming?
I don't think it's directly possible, but you can script it in repeatedly_execute(_always), using GUIControl.GetAtScreenXY() to check where the mouse is, and changing the text accordingly (I'd guess using Button.NormalGraphic), e.g. (pseudocode):

Code: ags

if (GUIControl.GetAtScreenXY(mouse.x, mouse.y) == btnLookImg) btnLookTxt.NormalGraphic = LOOKLIT;
else btnLookTxt.NormalGraphic = LOOKDARK;


What do you mean, "trying to get the idle view to work"? By default, that doesn't take any scripting. If you're wanting to change the delay before it activates, then:
Quote from: The BFAQyou need to think of where and when you want this to happen. Do you want this to happen the minute the game starts, before any rooms are loaded? If so, edit the global script (Game -> Edit global script..., or Ctrl-G) and find the definiton for the "game_start" function

Or, if you want the delay, or the view itself for that matter, to change during the game - WHEN do you want it to happen? That's probably where you should put the code.

QuoteWhen I moved it back I still get an error.
What error? What code? Which bits of the global script did it jump between? You don't make it easy to help, do you? ;)
I know what you're thinking ... Don't think that.

ScottDoom

#6
Actually my idle view isn't working by default. It says, by default, it should take 20 seconds but I let my character wait and the idle view never started looping. I tried changed it to 0, because I want it to play as long as the character isn't moving or playing another animation, and it still didn't work. Edit: Ok, figured out the idle view thing and got that working finally.

Also, a part of the script that was already there (mouseClick Left blah blah) jumped up on its own into the keypress blah blah area without warning which was really weird. I have no idea how it happened, but I simply exited my game and reloaded it and it was back to normal. So that's not a problem.

I just read into the scripting tutorials once again and also looked at my old code from my half-complete game and everything made sense and looked easy, so I don't know why I'm having so much trouble now.

What I still need help with: Making the buttons on one side of the interface "light up" although the mouse is scrolling over buttons on the other side. Is this possible? I'm going to play around and see if I can figure it out...

Edit again: Hmm... I've tried a code similar to what you suggested Ashen, and I'm not getting the light-up thing to work. I've got this:
Code: ags
function repeatedly_execute() 
Ã,  { if (gKarma.GetAtScreenXY(mouse.x, mouse.y) == Buttonlook_graphic) Buttonlook_text.MouseOverGraphic = 129;
else Buttonlook_text.NormalGraphic = 134;
}

It says it can't recognize Buttonlook_graphic basically. If I take out Button and just leave look_graphic it says it can't convert *GUI to *BUTTON or something weird... Any ideas? It's not 100% necessary for my GUI to work this way but I'd like it to.

Edit once again: Alright. I tried typing that above code from scratch instead of pasting it in to see what the editor gave me as options, and after typing { if (gKarma. "GetAtScreen" isn't one of the options that pops-up so is that a problem? There's some other options, like X and Y but I'd assume that's a check of the location, and not mouse position on the GUI.

But I understand what we're trying to do... Make a check to see if the mouse is over a certain graphic on the left, thus changing the status of the graphic on the right from normal to mouse-over.

Khris

You'll need this:

Code: ags
function repeatedly_execute() {
Ã,  if (gKarma.visible) {
Ã,  Ã,  GUIControl *myctrl=GUIControl.GetAtScreenXY(mouse.x, mouse.y);
Ã,  Ã,  if (myctrl==testbutton) {
Ã,  Ã,  Ã,  testbutton.NormalGraphic=XX;
Ã,  Ã,  Ã,  // change other buttons
Ã,  Ã,  }
Ã,  Ã,  else {
Ã,  Ã,  Ã,  testbutton.NormalGraphic=YY;
Ã,  Ã,  Ã,  // change other buttons
Ã,  Ã,  }
Ã,  Ã,  if (myctrl==anotherbutton) {
Ã,  Ã,  Ã,  ...
Ã,  Ã,  }
Ã,  }
}


I've tested this, it should work fine, I've noticed though that GetAtScreenXY returns null if the button image's pixel is transparent.

ScottDoom

#8
Thanks a lot khrismuc, that works.

Just out of curiosity, how do you go about figuring that out? I mean I used the Help search function of AGS and typed in things like Button, btn, mouseover, mouse, GUI, etc. to try and find the right keywords to use in the script but I wasn't getting anywhere fast.

Edit: Alright, new problem.Ã,  :) Right now I just simply have it set to pop up at a specified location on the screen after rigth-clicking, rather than popping up where the player right-clicks. Now I've got a question... I already have an extended background that scrolls, so if the player is all the way to the right, will the GUI pop up at the room coordinates x,y (thus being in the left portion where the player can't even see it) or will it pop up x pixels from the left, y pixels from the bottom, thus always popping up in the center of the screen?

If it's going to pop up where the player can't see it, I'm gonna need to fix it. Otherwise I'll leave it as is.

Ashen

#9
In general, a good way to learn the commands is to read the sections. Need to do something to a GUI? Look through the GUI functions and properties. To a GUI Control (buttons, sliders, etc)? GUI Control properties and functions (and the individual sections for GUI Buttons, etc).
(The way I work most things out is trial and error. Start up a blank game so you won't damage your game in progress, and just TRY things. If they don't work, delete them. If they do, you've learnt something.)

EDIT: This next bit is WRONG. Please ignore it.
Spoiler
Yes, if it's a scrolling background it'll try to pop up at the room coordinates rather than the screen coordinates (i.e. it could be off screen). However, that's easily worked around: Instead of mouse.x, mouse.y, use mouse.x - GetViewportX(), mouse.y - GetViewportY(). This will make it account for the scrolled position of the background.
[close]
I know what you're thinking ... Don't think that.

ScottDoom

Alright... I just made it so it pops up where the player right-clicks, even though this sometimes results in the GUI being off screen it's not a huge bug. They'll just have to right-click again and bring it back up in the middle more. I didn't really understand the whole GetViewPortX() thing. Do I need to put a value in there?

Ashen

#11
Sorry, I was having a dumb morning ...
Ignore the GetViewportX/Y stuff - you only need that if you're placing the GUI on a character, object, or something that uses ROOM coordinates. (This is something I was just recently playing with, so it was stuck in my head.)

What you really need to do (honestly, this time) is figure out the maximum X position the GUI can have based on it's width. E.g. if the GUI is 100 pixels wide, the maximum X it can have and still all be visible is: 319 (far right of screen) - 100 (width) = 219. (And, of course, do the same for the maximum Y based on it's height.) So:

Code: ags

  int guix = mouse.x;
  int guiy = mouse.y;
  if (guix > 219) guix = 219;
  if (guiy > 189) guiy = 189;
  gKarma.SetPosition(guix, guiy);
  gKarma.Visible = true;
I know what you're thinking ... Don't think that.

ScottDoom

Thanks, Ashen. I'll try that out after lunch (just got back from class).

Also you have written:
if (guix > 219) guix = 219;
if (guiy > 189) guiy = 289;

The first two numbers match, but those second two numbers don't. Was that a typo or am I not understanding the code?

Ashen

Typo? What typo? ;)

Apparently that Dumb Morning lasted until early afternoon ...
I know what you're thinking ... Don't think that.

strazer

I suggest to use

Code: ags

if (guix > (system.viewport_width - gKarma.Width)) guix = system.viewport_width - gKarma.Width;
if (guiy > (system.viewport_height - gKarma.Height)) guiy = system.viewport_height - gKarma.Height;


instead so you don't have to change the numbers when resizing the GUI.

Khris

Quote from: ScottDoom on Wed 18/01/2006 04:47:21Just out of curiosity, how do you go about figuring that out?

Well, when I first discovered AGS, I read the complete manual and pretty much every thread in the Technical Forums :) It's the hard way, but it worked for me. I used to do this at work while my boss was on the phone or sending mails, and it surely was more productive than browsing through websites with links to funny pictures ;)

ScottDoom

#16
strazer, I don't believe I'll be resizing the GUI at all. What I have drawn is pretty much the final and that's how it's going to stay. Although now I'm wondering once again, since I have it set to pop up at right-click on location except when past the defined points (so it won't go off screen) then what about when it comes to those scrolling screens I mentioned earlier? Will it not go past say mouse.x 209 or is that... like... yeah.Ã,  ???

Anyways, as for right now it works (Ashen's code). At first it didn't work but I threw in a couple of { }'s and erased some others and eventually it got it right. Hah hah. I guess I can go ahead and make a blank scrolling screen in my demo game to check if it'll pop up the right way in scrolling screens...

Edit: The code does work with scrolling backgrounds.  ;D So that's it. I think that's all my GUI questions. Thanks for the help everyone.

Ashen

It should be fine, assuming you've worked out the right max x and y for your GUI (strazer's code takes care of that for you, of course). mouse.x/y uses screen coordinates, as does GUI.SetPosition so it's not possible for mouse.x to be higher than the right most point on the screen, or lower than 0. But don't let that stop you from trying it for youself. Trial and Error.
I know what you're thinking ... Don't think that.

ScottDoom

#18
Alright, new potential problem. Although the game (animation and such) is paused when the GUI is up, I can still click interactions on the game screen outside the GUI. As in, if I select Examine from the GUI and click it on the character the game displays the message even though the game is paused. What's up with that? And I can't just not allow left clicks while game is paused because then the player couldn't even select a new icon.

Edit: Nevermind, I fixed that. I did a check to see if the game was paused and if so a left click defaults to Walk, so clicking Look or something on a character while the GUI is up will not result in the game displaying the message. Although now once the game is un-paused the character walks over to the spot where the player clicked off the GUI, if they did so.

Ashen

Just change the 'Walk' command to  do nothing - on_mouse_click isn't called for GUI clicks, so the button interactions shouldn't be affected. Blocking all clicks while paused, however, would also block the Right click GUI off - which you probably don't want to do..
I know what you're thinking ... Don't think that.

SMF spam blocked by CleanTalk