How would this function look like using newobject method?

32 posts / 0 new
Last post
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
How would this function look like using newobject method?
Hello, i have this function that open a window with a menu: struct Window *open_window (struct Screen *scr,const char *title,long x,long y,long w,long h,struct NewMenu *newmenu,struct VisualInfo *vi,struct Menu **menuptr) { struct Menu *menu = NULL; struct Window *win; if ((win = OpenWindowTags (NULL, WA_CustomScreen,scr, WA_Title,title, WA_Left,x, WA_Top,y, WA_Width,w, WA_Height,h, WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEGADGET | WFLG_SIZEBBOTTOM | WFLG_ACTIVATE | WFLG_NEWLOOKMENUS | WFLG_NOCAREREFRESH, WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_MENUPICK, WA_MaxWidth,scr->Width, WA_MaxHeight,scr->Height, TAG_END))) { if (vi) if (menu = CreateMenusA (newmenu,NULL)) if (LayoutMenus (menu,vi,GTMN_NewLookMenus,TRUE,TAG_END)) SetMenuStrip (win,menu); } *menuptr = menu; return (win); } how would you change this function to reflect the modern approach described by trixie? thank you very much
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
Here's how i changed the
Here's how i changed the function: Object *open_window (struct Screen *scr,const char *title,long x,long y,long w,long h,Object *tbimg[],int TB_MAX, struct NewMenu *newmenu,struct VisualInfo *vi,struct Menu **menuptr) { Object *winobj; if ((winobj = NewObject (WindowClass,NULL, WA_PubScreen, scr, WA_Title, "ReAction Tool Bar", WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEBBOTTOM | WFLG_SIZEGADGET | WFLG_ACTIVATE, WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_INTUITICKS, WA_Width, scr->Width * 6 / 10, WA_Height, scr->Height * 4 / 10, WINDOW_NewMenu,newmenu, WINDOW_BackFillName, "Sys:Prefs/Presets/Patterns/Chalk/ChalkBlue.brush", WINDOW_Position, WPOS_CENTERSCREEN, WINDOW_ParentGroup, NewObject (LayoutClass,NULL, LAYOUT_Orientation,LAYOUT_ORIENT_VERT, LAYOUT_SpaceOuter, TRUE, LAYOUT_AddChild,ToolBar(tbimg,TB_MAX), LAYOUT_AddChild,NewObject (LayoutClass,NULL, TAG_END), LAYOUT_AddChild,NewObject (LayoutClass,NULL, LAYOUT_SpaceOuter, FALSE, LAYOUT_FixedVert, FALSE, LAYOUT_EvenSize, TRUE, LAYOUT_AddChild, NewObject (ButtonClass,NULL, GA_ID, GID_OK, GA_Text, "Ok", GA_RelVerify, TRUE, TAG_END), LAYOUT_AddChild, NewObject (ButtonClass,NULL, GA_ID, GID_CANCEL, GA_Text, "Cancel", GA_RelVerify, TRUE, TAG_END), TAG_END), TAG_END), TAG_END))) { //if (vi) //if (menu = CreateMenusA (newmenu,NULL)) //if (LayoutMenus (menu,vi,GTMN_NewLookMenus,TRUE,TAG_END)) //SetMenuStrip (win,menu); //} //*menuptr = menu; return (winobj); } } since i don't use the VisualInfo struct anymore in this function, i guess i should remove it from the parameters passed to the function. Or could be usefull to keep for other reason? these parameters are not necessary too: const char *title,long x,long y,long w,long h, struct Menu **menuptr
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter since i don't
@AmigaBlitter
since i don't use the VisualInfo struct anymore in this function, i guess i should remove it from the parameters passed to the function. Or could be usefull to keep for other reason?
If you're using WINDOW_NewMenu, you don't need to LayoutMenus(), so you don't need the VisualInfo - the Window Class handles menu creation and layouting itself. However, be warned that menus created via WINDOW_NewMenu have a side-effect. Any opening (re-opening, uniconifying) of the window will reset the menu strip to the default state as described by your NewMenu structure. Thus, the programmer is responsible for storing the menu state before closing the window, and for restoring the state when the window reopens. So in effect, until Window Class is changed to keep the menu state for closed windows, you may find that WINDOW_NewMenu actually gives you more work than it saves ;-)
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter Here's how i
@AmigaBlitter
Here's how i changed the function:
Look at your function again.
  1. if ((winobj = NewObject (WindowClass,NULL,
  2.  
  3. ...
  4.  
  5. return (winobj);
  6. }
What happens if the NewObject() call fails for some reason? Your function will be left without a valid return value, because you only return in case of success. You need to change your function to something like
  1. if ((winobj = NewObject (WindowClass,NULL,
  2.  
  3. ...
  4.  
  5. return (winobj);
  6. }
  7. else return NULL;
Also note that your function is called open_window() but it doesn't really open the window - it just creates the window object. Such naming does not contribute to a clear and understandable code.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
@trixie Thank you for the
@trixie Thank you for the info. Always using the new methods, how to add a string and a label object? LAYOUT_AddChild, NewObject (ButtonClass,NULL, GA_ID, GID_OK, GA_Text, "Ok", GA_RelVerify, TRUE, TAG_END), This add a button, but a can't find clear references for string, label and other objects via new methods. Thank you
salass00
salass00's picture
Offline
Last seen: 4 days 10 hours ago
Joined: 2011-02-03 11:27
@AmigaBlitter LAYOUT_AddChil
@AmigaBlitter LAYOUT_AddChild, NewObject (StringClass,NULL, TAG_END), CHILD_Label, NewObject (LabelClass,NULL, LABEL_Text, "Label", TAG_END),
YesCop
YesCop's picture
Offline
Last seen: 1 year 9 months ago
Joined: 2011-05-17 15:07
Trixie, You gave a good
Trixie, You gave a good advice when you asked to verifiy if the window pointer is NULL before returning it. I have a question for you. Why do all programmers use newobject in window instantation ? What happens if newobject could not be created ? Do Intuition create nevertheless the window ? Don't we should create all newobjects before creating the window ?
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
@salass00 thank you This is
@salass00 thank you This is what I did before asking, but i've got strange behaviour. The program compiled OK, but i had nothing on screen (i mean no screen, window and gadgets), then, after few seconds, the OS frozen Edit: sorry, i've made two mistake. one of this is fundamental: i forgoto to open the class, first :P It works now. Thank you
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
Now, simply adding the string
Now, simply adding the string in that way LAYOUT_AddChild, NewObject (StringClass,NULL, TAG_END), it is possible to get string events? Or should i give an identifier to the string?
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@YesCop Why do all
@YesCop
Why do all programmers use newobject in window instantation? What happens if newobject could not be created? Do Intuition create nevertheless the window? Don't we should create all newobjects before creating the window?
It's just a matter of technique. If you instantiate the window object in one go together with the contents (i.e. the window's layout), and one of the NewObject() calls in the sequence fails, the window object will not get created (and I believe that Window Class disposes of the objects already created - but you'll have to ask Rigo about that, he maintains the class). Some programmers instantiatate the window and the layout objects separately and then pass the layout to the window object via WINDOW_Layout. But creating all objects individually and then joining them together would be too much of a hassle.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter You must use
@AmigaBlitter You must use GA_ID and assign an identifier to be able to distinguish between events you receive from Intuition. There are plenty of examples that show this in the SDK/Examples/Reaction folder.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
salass00
salass00's picture
Offline
Last seen: 4 days 10 hours ago
Joined: 2011-02-03 11:27
If you instantiate the window
If you instantiate the window object in one go together with the contents (i.e. the window's layout), and one of the NewObject() calls in the sequence fails, the window object will not get created (and I believe that Window Class disposes of the objects already created - but you'll have to ask Rigo about that, he maintains the class).
Window.class only disposes of the WINDOW_Layout object, any objects attached to this are then disposed of by layout.gadget and so on until all the objects are disposed of.
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
@trixie "You must use
@trixie "You must use GA_ID".... the following code comes from the string reaction example. As you can see it uses RA_HandleImput... I don't remember where i read to avoid all RA_. Is this related to old methods? Sorry for the another thread i opened for the string events, btw.
  1. while ( (result = RA_HandleInput(objects[OID_MAIN], &code) ) != WMHI_LASTMSG )
  2. {
  3. switch (result & WMHI_CLASSMASK)
  4. {
  5. case WMHI_CLOSEWINDOW:
  6. windows[WID_MAIN] = NULL;
  7. done = TRUE;
  8. break;
  9.  
  10. case WMHI_GADGETUP:
  11. switch (result & WMHI_GADGETMASK)
  12. {
  13. case GID_STRING1:
  14. printf( "Contents: %s\n", ((struct StringInfo *)(gadgets[GID_STRING1]->SpecialInfo))->Buffer);
  15. break;
  16.  
  17. case GID_STRING2:
  18. printf( "Contents: %s\n", ((struct StringInfo *)(gadgets[GID_STRING2]->SpecialInfo))->Buffer);
  19. break;
  20.  
  21. case GID_QUIT:
  22. done = TRUE;
  23. break;
  24. }
  25. break;
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter RA_HandleImput
@AmigaBlitter
RA_HandleImput... I don't remember where i read to avoid all RA_. Is this related to old methods?
No. RA_HandleInput is a macro, which expands to the WM_HANDLEINPUT method call. See section 4.4 of my tutorial on ReAction programming.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
Yeah! I read it there: "If
Yeah! I read it there: "If you have copied the input handling routine from such a source, make sure to replace the macro with the corresponding method call:" while ( (result = IIntuition->IDoMethod(winObj, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG ) { ... } thank you
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
@trixie Can't intercept the
@trixie Can't intercept the string events. This is the loop code:
  1. ULONG result;
  2. while ((result = DoMethod (winobject, WM_HANDLEINPUT, NULL)) != WMHI_LASTMSG)
  3. {
  4. (result & WMHI_CLASSMASK)
  5. {
  6. WMHI_GADGETUP:
  7. switch (i)
  8. {
  9. case GID_STRING1:
  10. printf( "Contents: %s\n","Hello");
  11. cont = FALSE;
  12. break;
  13. case GID_OK:
  14. case GID_CANCEL:
  15. cont = FALSE;
  16. break;
  17. default:
  18. if (i < TB_MAX)
  19. Printf ("gadget up: %s\n", tbname[i]);
  20. else
  21. Printf ("gadget up: %ld\n", i);
  22. }
  23. break;
What i've forgot this time? Solved: I've add the following: GA_RelVerify, TRUE, GA_TabCycle, TRUE, and now the event get intercepted Btw, how to refer to the string and get the content of the string? if i do: struct Gadget *gadgets[GID_LAST]; printf( "Contents: %s\n", ((struct StringInfo *)(gadgets[GID_STRING1]->SpecialInfo))->Buffer); the program crash and the system freeze soon after thank you
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter GA_RelVerify,
@AmigaBlitter
GA_RelVerify, TRUE,
Yes, all Intuition gadgets whose events you want to listen to must have this set.
Btw, how to refer to the string and get the content of the string?
  1. case GID_STRING1:
  2. {
  3. STRPTR stringContents = NULL;
  4.  
  5. IIntuition->GetAttrs(stringObject, STRINGA_TextVal, (uint32 *)&stringContents, TAG_DONE);
  6. printf("Contents: %s\n", stringContents);
  7.  
  8. /* Remember that the value of stringContents will not be valid
  9.   outside of this block because it's a local variable.
  10.   If you need to keep the contents of the string for some use,
  11.   you must copy it to a permanent buffer.
  12.   */
  13. }
  14. break;
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
Thank you Danjiel, i will
Thank you Danjiel, i will try as soon as back home. As for the freeze problem, i should check if i have disposed all the objects, or disposing the window object dispose all the children too?
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter Disposing of
@AmigaBlitter Disposing of the window object will also dispose of all children objects attached to it.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
@trixie Trying to get the
@trixie Trying to get the string content i get: error: 'struct IntuitionIFace' has no member named 'IIntuition'
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter error: 'struct
@AmigaBlitter
error: 'struct IntuitionIFace' has no member named 'IIntuition'
Looks like you're compiling your code with #define __USE_INLINE__ In that case don't use "IIntuition->" or other interface names in function calls.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
I use __USE_INLINE__ as
I use __USE_INLINE__ as switch on the command line. What should i use instead? Btw, omitting this switch cause me to get tons of warning and undefined reference for my actual code as follow: (.text+0xd08): undefined reference to `Printf' (.text+0xd24): undefined reference to `CreateBackFillHook' (.text+0xd64): undefined reference to `OpenScreenTags' (.text+0xd90): undefined reference to `GetVisualInfoA' (.text+0xfb0): undefined reference to `DoMethod' (.text+0xfdc): undefined reference to `DoMethod' (.text+0x100c): undefined reference to `GetAttr' (.text+0x1028): undefined reference to `Wait' (.text+0x11ac): undefined reference to `Printf' (.text+0x11c4): undefined reference to `Printf' (.text+0x11ec): undefined reference to `GetAttr' (.text+0x1214): undefined reference to `ItemAddress' (.text+0x1244): undefined reference to `Printf' (.text+0x1264): undefined reference to `ItemAddress' (.text+0x12b8): undefined reference to `DoMethod' (.text+0x12e8): undefined reference to `DisposeObject' (.text+0x12f4): undefined reference to `DisposeObject' (.text+0x1344): undefined reference to `DisposeObject' (.text+0x1380): undefined reference to `FreeVisualInfo' (.text+0x139c): undefined reference to `CloseScreen' (.text+0x13a8): undefined reference to `DeleteBackFillHook'
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter Read what I'm
@AmigaBlitter Read what I'm writing and you'll be fine :)
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
"In that case don't use
"In that case don't use "IIntuition->" or other interface names in function calls." Sorry, but i'm not an expert. :(
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter Never
@AmigaBlitter Never mind. You'll use IIntuition->GetAttrs() in code compiled without __USE_INLINE__. The "IIntuition->" prefix refers to the name of the Intuition library interface. As of OS4.x, Amiga libraries can have multiple interfaces ("function groups") inside them, so the interface name specifies where the function comes from. This is what most new code should use. Older code can be compiled with the __USE_INLINE__ switch. In that case, functions are used without interface names, i.e. GetAttrs() in your particular case.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
Hi, thank you for your
Hi, thank you for your patience. I know i'm boring you. Sorry for this. I changed all the prefix in the following way: IDataTypes->NewDTObject IIntuition->IDoMethod IDataTypes->GetDTAttrs ILayers->SetBackFillHookAttrs IDataTypes->DisposeDTObject IIntuition->OpenWindowTags IIntuition->CloseWindow IDOS->AddPart IIntuition->NewObject IIntuition->GetAttr IIntuition->GetAttrs IIntuition->SetAttrs IDOS->Printf ILayers->CreateBackFillHook IIntuition->OpenScreenTags IGadTools->GetVisualInfoA IExec->Wait IIntuition->ItemAddress IGadTools->FreeVisualInfo IIntuition->CloseScreen IIntuition->DeleteBackFillHook i still have this problem: warning: passing argument 2 of 'IIntuition->GetAttrs' makes pointer from integer without a cast error: 'struct IntuitionIFace' has no member named 'DeleteBackFillHook
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter I know i'm
@AmigaBlitter
I know i'm boring you. Sorry for this.
It's no trouble. We all were beginners at some point.
warning: passing argument 2 of 'IIntuition->GetAttrs' makes pointer from integer without a cast
You are passing a wrong or un-cast argument to GetAttrs(). You need to show me the actual function call and how its parameters are declared.
error: 'struct IntuitionIFace' has no member named 'DeleteBackFillHook
DeleteBackFillHook() is a function in layers.library (not Intuition), so you need to open layers library and interface, and then change your code to use ILayers->DeleteBackFillHook().
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
Thank you I used the
Thank you I used the Layers->DeleteBackFillHook() and now it's ok and compile (my mistake, sorry) Here's is the code related to the warning message: "warning: passing argument 2 of 'IIntuition->GetAttrs' makes pointer from integer without a cast" IIntuition->GetAttrs(GID_STRING1, STRINGA_TextVal, (uint32 *)&stringContents, TAG_DONE); Note: the code get compiled, but as soon as i test the string gadget pressing enter, i get a DSI error
trixie
trixie's picture
Offline
Last seen: 1 week 2 days ago
Joined: 2011-02-03 13:58
@AmigaBlitter IIntuition->Ge
@AmigaBlitter
IIntuition->GetAttrs(GID_STRING1, STRINGA_TextVal, (uint32 *)&stringContents, TAG_DONE);
It's because in the first argument, you are passing a numeric identifier, not an actual object pointer. Looking at your GUI definition in post #2, I see that you are adding new objects via LAYOUT_AddChild but without storing the resulting object pointers in particular variables. Having no variables = having no way to manipulate your objects. Let's say your GUI will have three gadgets: a string and two buttons (OK and Cancel). First you need to define a set of identifiers for your gadget objects. They are just a sequence of numbers:
  1. enum
  2. {
  3. GID_STRING,
  4. GID_OK,
  5. GID_CANCEL,
  6. GID_LAST /* dummy ID */
  7. };
Then you need to declare variables to keep your object pointers in. If there are more gadgets than one, we normally declare a field of variables, whose particular items (objects) will subsequently be referred to using the IDs above: Object *gadgets[GID_LAST]; When creating new objects and adding them to the layout, you must assign the resulting object pointer to the particular variable (field item), like this:
  1. ...
  2. LAYOUT_AddChild, gadgets[GID_STRING] = IIntuition->NewObject(LayoutClass, NULL,
  3. GA_ID, GID_STRING,
  4. GA_RelVerify, TRUE,
  5. GA_TabCycle, TRUE,
  6. TAG_END),
  7. ...
Now to make your GetAttr() call work, you need to pass the pointer to the particular string object: IIntuition->GetAttrs(gadgets[GID_STRING], STRINGA_TextVal, (uint32 *)&stringContents, TAG_DONE); Hope it's clearer now. But you should really have a look at some ReAction examples in the SDK/Examples directory - they will give you a lot of insight.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
salass00
salass00's picture
Offline
Last seen: 4 days 10 hours ago
Joined: 2011-02-03 11:27
IIntuition->GetAttrs(gadgets[
IIntuition->GetAttrs(gadgets[GID_STRING], STRINGA_TextVal, (uint32 *)&stringContents, TAG_DONE);
Since only one attribute is being queried it would be simpler to just use GetAttr(): IIntuition->GetAttr(STRINGA_TextVal, gadgets[GID_STRING], (uint32 *)&stringContents);
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2012-02-18 19:55
Thank you Danjiel for the
Thank you Danjiel for the explanations. Now i have understand better Just want to strike a blow for me, cause i completely messed up old and new methods, macro and no macro, Boopsi and so on... Thank you salass00 too and to Hans de Ruiter The code now works!!! @trixie LAYOUT_AddChild, gadgets[GID_STRING] = IIntuition->NewObject(LayoutClass, NULL, GA_ID, GID_STRING, GA_RelVerify, TRUE, GA_TabCycle, TRUE, TAG_END), Did you mean StringClass instead of LayoutClass, didn't you?

Pages

Log in or register to post comments