String gadget: STRINGA_BufferPos not yet implemented?

Online Status

I have a string gadget placed into a window layout:

    ...
    LAYOUT_AddChild, m_ppGadgets[GID_STRING_NAME] = NewObject(STRING_GetClass(), NULL,
      GA_ID, GID_STRING_NAME,
      GA_RelVerify, TRUE,
      STRINGA_TextVal, (ULONG)"[N]",
    TAG_DONE),
    ...

And in my handleGadgetEvents() function for this window I want to get the position of the cursor at the time the user pressed enter in this string gadget:

static void handleGadgets(Application* pApp, ULONG result)
{
  ULONG bufferPos = -1;
  ULONG gotBufferPosAttr;

  switch ((result & WMHI_GADGETMASK))
  {
    case GID_STRING_NAME:
    {
      gotBufferPosAttr = GetAttr(STRINGA_BufferPos, m_ppGadgets[GID_STRING_NAME], &bufferPos);
      if(gotBufferPosAttr == 1)
      {
        printf("Successfully got BufferPosAttr: '%d'\n", bufferPos);
      }
      else
      {
        printf("FAILED to get BufferPosAttr. (bufferPos value is: %d)\n", bufferPos);
      }

      updateNewNames(pApp);
      break;
    }

    // ...
  }
}

But whenever I press enter within the gadget I get the message:

FAILED to get BufferPosAttr. (bufferPos value is: -1)

So could it be that STRINGA_BufferPos is not yet implemented?

Online Status

<intuition/gadgetclass.h> defines STRINGA_BufferPos (STRINGA_Dummy+0x0005), so I guess it is implemented in some way. Not sure about why your event loop fails in that case.

Have you tried to set ULONG gotBufferPosAttr and ULONG bufferPos as global variables for testing purpose?

Online Status

I have just tried it out and made both variables global. Unfortunately, it didn't help.

Online Status

And I've noticed another one: When opening the window and then change some of the string gadgets attributes like:

  SetGadgetAttrs((struct Gadget *) m_ppGadgets[GID_STRING], pIntuiWindow, NULL,
                 STRINGA_TextVal, (ULONG) pStringGadgetText,
                 STRINGA_Mark, (strlen(pStringGadgetText)-1),
                 TAG_DONE);

The STRINGA_TextVal is applied; the string gadget opens with the text.

But the STRINGA_Mark is not applied. As I understand the documentation in string_gc.doc, passing strlen(pStringGadgetText)-1 should mark all characters, from 0 (upper 4 bist are 0) to last position (lower 4 bits are strlen - 1).

Online Status

What's your window refresh? SimpleRefresh? NoCareRefresh?
Does DoMethod(your_windowObject, WM_RETHINK) help?

Online Status

Oops, the 2nd problem, STRINGA_Mark not working, is gone. I just had to call

  ActivateLayoutGadget((struct Gadget*)pMainLayout, pIntuiWindow, NULL, (ULONG)m_ppGadgets[GID_STRING]);

after opening the window.

But the first one, not getting STRINGA_BufferPos from the string gadget still remains.

Or could it be that STRINGA_BufferPos could only be read while the string gadget is active? In my case it is not active because I try to read it in WMHI_GADGETUP after the user left it with enter.

Online Status

I come to a similiar result after setting up a small test application that tries to read STRINGA_BufferPos after string gadget was left using <Enter>. Your assumption about that tag's recent value only being available while gadget is active might be correct, but I don't know that for sure. It also might be that STRINGA_BufferPos is a write-only tag?
Maybe some more seasoned coder than me has an idea about it?

Online Status

Indeed getter of STRINGA_BufferPos is not implemented. Neither is DispPos for that matter.

Online Status

Ah, that explains it. Another attribute I would like to use is: STRINGA_Mark?. Is its getter implemented?

(I have been able to set it in my tests, but so far was not sucessful to read a selection range.)

Online Status

Yes STRINGA_Mark getter is implemented it returns ~0 if there is no selection.

Online Status

Thank you:-)

Online Status

But regarding the STRINGA_Mark - whatever I try I always get -1.

Could it be that asking for STRINGA_Mark in the string gadgets WMHI_GADGETUP never can work, because at this time the string gadget isn't activated anymore and the marking/selection is already gone?

But when WMHI_GADGETUP would be the wrong place to read it - where would be the right one?

Online Status

yes it looses the selection once it looses focus. I must admit I'm not quite sure when you would read it. What are you trying to accomplish?

Online Status

I want to do the following:

From parent window I open a child window that contains only the string gadget and an Ok button. The string gadget is automatically filled with a text at window opening time. Now the user can mark some chars of that text and press the Ok button. At Ok pressing time I want to read the marked range (e.g. that the user has marked from char 3 to char 10) and give this information to parent window. (Which then makes something of this information)

Online Status

You better listend to the STRINGA_Mark updates then. Store them somewhere and then use the stored values when pressing OK.

By listening I mean use ICA_TARGET

Online Status

I tried it with ICA_TARGET by creating the string gadget this way:

LAYOUT_AddChild, m_ppGadgets[GID_STRING] = NewObject(STRING_GetClass(), NULL,
  GA_ID, GID_STRING,
  GA_RelVerify, TRUE,
  GA_TabCycle, TRUE,
  ICA_TARGET, ICTARGET_IDCMP,

and then having the event handling function for the window like that:

while ((result = DoMethod(pRangeSelectWindow->pWinObject , WM_HANDLEINPUT, &code)))
{
  switch (result & WMHI_CLASSMASK)
  {
    case WMHI_CLOSEWINDOW:
    {
      // ...
    }
    case WMHI_GADGETUP:
    {
      // ...
    }
    case IDCMP_IDCMPUPDATE:
    {
      printf("IDCMP_IDCMPUPDATE\n");
      if(!GetAttr(STRINGA_Mark,
                  m_ppGadgets[GID_STRING],
                  &pRangeSelectWindow->Marked))
      {
        pRangeSelectWindow->Marked = 666;
      }
      break;
    }
  }
}

But the IDCMP_IDCMPUPDATE is never received / the printf() is not called. I feel I did it the wrong way. But how would it be right?

Online Status

Yes you don't wait for IDCMP_xxx like that. You have to set up an IDCMP hook on the windowobject. In that hook you will get the idcmp.

Online Status

Sorry for my ongoing questions about this topic. But I'm a newbie to BOOPSI objects..

So I have the window with the string gadget. For the window I set WINDOW_IDCMPHook, WINDOW_IDCMPHookBits and for the string gadget ICA_TARGET:

pRangeSelectWindow->pWinObject = NewObject(WINDOW_GetClass(), NULL,
  WA_Title, "MultiRename: Select name part",
  // ...
  WINDOW_IDCMPHook, &m_IDCMPHook,
  WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE,
  // ...
  WINDOW_Layout, pMainLayout = NewObject(LAYOUT_GetClass(), NULL,
    // ...
    LAYOUT_AddChild, m_ppGadgets[GID_STRING] = NewObject(STRING_GetClass(), NULL,
      GA_ID, GID_STRING,
      GA_RelVerify, TRUE,
      GA_TabCycle, TRUE,
      ICA_TARGET, ICTARGET_IDCMP,
    TAG_DONE),
  // ...

To show what really was done (or not done) inside the function, I initialized my desired global variable my_marked_range to 0, and the code of the hook function sets the "marker values" 666 if GetAttr() should fail:

// Global variable for hook function result
ULONG my_marked_range = 0;

// Hook function
  ULONG __ASM__ __SAVE_DS__ IDCMPFunc(__REG__(a0, struct Hook *pHook),
                                      __REG__(a2, Object *pWinObj),
                                      __REG__(a1, struct IntuiMessage *pMsg))
  {
    if(pMsg->Class != IDCMP_IDCMPUPDATE)
    {
      return 0;
    }

    if(!GetAttr(STRINGA_Mark, m_ppGadgets[GID_STRING],  &my_marked_range))
    {
      if(my_marked_range == 0)
      {
        my_marked_range = 666;
      }
    }

  return 0;
}

When Ok of the window is pressed, the value of my_marked_range is ouput with printf: I always get -1. So, it seems, that the hook is called but GetAttr() returns -1 for the variable.

What else could I try to get the STRINGA_Mark value?

Online Status

Okay I just had an actual look at the code. STRINGA_Mark is indeed not sent out as an update. So please forget about IDCMP_IDCMPUPDATE.

Even so the STRINGA_Mark is not available except when the gadget is active. And since it is gone when the gadgetup is received I don't think there is any way for you to get this.

It is supposed mainly to be a way to select, and not as a way read the selection.Also what you are trying to do does sound very non-standard

Still, Why do we have a getter that is most of the time not providing a meaningful value. I can't give you a good answer right now.

I would suggest you try and find a more standard way (for the user too) of getting som subtext

Online Status

You are right, using the marking ability of String Gadget this way might not be Styleguide compliant. But in this very application it seems to be the smartest solution: The user marks a range of characters. When the window is closed with Ok, it returns the marked range to parent. Parent interprets the range and generates a mask from it, e.g. something like "[N3-7]".

But I think I’ll find a solution, probably with 2 sliders to define the range.

(I lent the marking of the text to query the desired area from the user from Windows tool TotalCommander whose MultiRename tool I would like to replicate here for the Amiga.)