How do I implement a side-scrolling custom conversation?

Started by bx83, Mon 03/12/2018 01:05:02

Previous topic - Next topic

bx83

I already have a custom conversatoin tree - see here.

But how do I scroll to the left or right is there are too many icons in the single-line list?



As we can see here, the last item is off the screen and so can't (or can barely) be clicked.

ps. I increased the size of the icons from 64 to 96; just replace all of the 64's with 96's in the code linked to ;)

Cassiebsg

just add a button to scroll left/right at each end. If you load the BASS template you can see how it's done there. ;)

If you want something more "streamline" like if the mouse cursor is over the GUI and is "x pixels from the edge" you could just make it scroll automaticly. Though that'll probably involve more coding and debugging than just a button.
There are those who believe that life here began out there...

bx83


Crimson Wizard

#3
Quote from: Cassiebsg on Mon 03/12/2018 18:12:43
just add a button to scroll left/right at each end. If you load the BASS template you can see how it's done there. ;)

I don't think bx83 can do that, because he is using custom dialog option rendering, not builtin GUI. TBH I don't remember if it's even possible to receive GUI events while dialog options are on screen.



bx83,  First of all, have you ever tried abstauber's module?
http://www.adventuregamestudio.co.uk/forums/index.php?topic=36313.0
I don't know how it is done, but seems to support icons like in your example.

Then, I don't know what kind of scrolling controls you want. I believe when it comes to game or UI design first you plan on how do you want something to work, and then search for the ways to do that in code. Like Cassiebsg said above, it may be done with two "arrow" buttons, or it may be done with some kind of mouse tracking, or else. Since you didn't say anything I will assume the most obvious and give an example of how to add 2 "buttons" at the left and right ends of the GUI. Clicking on these would make icons scroll.
For this you need to:
1. Make sure that icons are drawn not from 0,0 to the end, but with certain margin to let some space for control buttons.
2. Keep track of scrolling position.
3. Draw buttons (sadly AGS does not support placing real controls when you do custom rendering) and handle clicks on them.

Following would be the very crude example of drawing scrolled items based on your code from another thread:

Code: ags

// How much space to leave for scrolling buttons
int DialogOptionsIconMargin = 64;
// The step to add when positioning icons
int DialogOptionsIconStep = 64;
// Current scrolling position
int DialogOptionsScroll = 0;

//----------------------------------------------------------------------------------------------------------------------
// Draw Dialog Options
//
// x_start and x_end - coordinates of icons inside the GUI
// x_scroll - current scrolling position
//
//----------------------------------------------------------------------------------------------------------------------
function DrawDialogOptions(DrawingSurface* ds, DialogOptionsRenderingInfo* info, int x_start, int x_end, int x_scroll)
{
  int i = first, xpos = x_start - x_scroll, ypos;
  int step = DialogOptionsIconStep;
  ds.Clear(COLOR_TRANSPARENT);
  ds.DrawingColor = COLOR_TRANSPARENT;

  while (i <= info.DialogToRender.OptionCount && xpos < xmax)
  {
    if (info.DialogToRender.GetOptionState(i) == eOptionOn)
    {
      String str = info.DialogToRender.GetOptionText(i);
      int cur_img = str.AsInt;
      int sprwidth = Game.SpriteWidth[cur_img];
      int sprheight = Game.SpriteHeight[cur_img];

      if (xpos + sprwidth > x_start)
      {
        // Icon should be visible, at least partially
        ds.DrawImage(xpos, ypos, cur_img);
        // If icon is slightly off-bounds, then clip the loose parts
        if (xpos < x_start)
          ds.DrawRectangle(xpos, ypos, x_start, ypos + sprheight);
        if (xpos + sprwidth > xmax)
          ds.DrawRectangle(xmax, ypos, xpos + sprwidth, ypos + sprheight);
      }
      xpos += step;
    }
    i++;
  }
}

//----------------------------------------------------------------------------------------------------------------------
// Draw scrolling buttons
// This is a new function you will have to code, it draws 2 buttons in the left and right ends of this surface.
//----------------------------------------------------------------------------------------------------------------------

void DrawScrollButtons(DrawingSurface* ds)
{
  // For now just draw 2 colored rectangles
  ds.Color = Game.GetColorFromRGB(255, 0, 0);
  ds.DrawRectangle(0, 0, 64, 64);
  ds.DrawRectangle(ds.Width - 64 - 1, 0, ds.Width - 1, 64);
}

//----------------------------------------------------------------------------------------------------------------------
// Dialog Options Render
//----------------------------------------------------------------------------------------------------------------------
 
function dialog_options_render(DialogOptionsRenderingInfo* info)
{
  DrawDialogOptions(info.Surface, info, DialogOptionsIconMargin, info.Width - DialogOptionsIconMargin, DialogOptionsScroll);
  DrawScrollButtons(info.Surface);
}


Then you'd need to similarily adjust tracking mouse over icons:

Code: ags

//----------------------------------------------------------------------------------------------------------------------
// Dialog Options Repeat Exec
//----------------------------------------------------------------------------------------------------------------------

function dialog_options_repexec(DialogOptionsRenderingInfo* info)
{
  int i = 1, xpos = DialogOptionsIconMargin - DialogOptionsScroll;
  int x_start = DialogOptionsIconMargin;
  int x_end = info.Width - DialogOptionsIconMargin;

  while (i <= info.DialogToRender.OptionCount)
  {
    if (info.DialogToRender.GetOptionState(i) == eOptionOn)
    {
      // First make sure the icon is actually currently visible, and then that the mouse is above it
      if (xpos >= x_start && xpos <= x_end &&
          mouse.y >= info.Y && mouse.x >= xpos && mouse.x <= xpos + DialogOptionsIconStep)
      {
        info.ActiveOptionID = i;
        return;
      }
      xpos += DialogOptionsIconStep;
    }
    i++;
  }
}


Finally, to detect when the mouse has clicked on a scroll button:
Code: ags

//----------------------------------------------------------------------------------------------------------------------
// Dialog Options Mouse Click
//----------------------------------------------------------------------------------------------------------------------
 
function dialog_options_mouse_click(DialogOptionsRenderingInfo* info, MouseButton button)
{
  if (info.ActiveOptionID > 0)
  {
    // do as usual
    // ...
    //

    // probably reset the scroll?
    DialogOptionsScroll = 0;
  }
  else
  {
    if (mouse.y >= info.Y && mouse.x >= 0 && mouse.x <= 64)
    {
       // clicked on left scroll arrow
       DialogOptionsScroll -= 1; // or any other number of pixels
    }
    else if (mouse.y >= info.Y && mouse.x >= info.Width - 64 && mouse.x < info.Width)
    {
       // clicked on right scroll arrow
       DialogOptionsScroll += 1; // or any other number of pixels
    }
  }
}

SMF spam blocked by CleanTalk