Procedures for ImageGadgets

AmigaOS specific forum
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Roxxler.

Hi,

here a solution for using ImageGadgets in PureBasic Amiga. At
the moment the PC version of PureBasic will offer a function
to use ImageGadgets, anyway now it works also with the Amiga.

Gadtools does not have any function to create something like
an imagegadget, so we have to use the good old intuition gadgets
with an image inside. This is not so difficult as it seems because
every Icon on the WB is just an imagegdaget, easy said.

Ok, to create a gadget we need first of all a gadget structure.
Then we need two image structures (one for the not selected and
one for the selected gadget). Inside the image structure we found
a pointer to the bitplanes of the images and ...... all this is
too difficult to handle (at the moment :) ).

To create imagegadgets we use just normal icons. An icon includes
a diskobject structure and inside this structure we found a
complete gadget structure including the images. All we need.

One word to the used icons: The following procedures using
normal 'oldstyle' icons which comes with OS2/3/3.1. Not NewIcons and
not GlowIcons from OS3.5/3.9. Maybe i will have a look at
using GlowIcons in future. So make sure that you are use the
old icons. If not, the images are not displayed or the program
just crashes.

The following steps we have to do to use imagegadgets:

1. loads some icons
2. install the gadgets with the images of the icon to our window
3. react if the gadgets are clicked
4. free the gadgets
5. free the icons

To load the icon we can use the function GetDiskObject() from the
icon.library, so we have to open this library. For removing the
icons from memory we use icon/FreeDiskObject(). For installing the
gadgets we use the intuition function AddGadget() and for freeing
we use the function RemoveGadget() (also intuition). For that we
must open the intuition.library, too. To deactivate or activate the
gadgets we use the intuition functions OffGadget() and OnGadget().
Last we use intuition/RefreshWindowFrame() for refreshing the
gadgets of a window if nessessary. I have written procedures for
handle this functions, except for GetDiskObject() and FreeDiskObject().
This because this functions are very easy to use and it only will
size the code to put this functions into own procedures.

For further information see the procedures and also the example
for the GetDiskObject() / FreeDiscObject. Here are the procedures:

Procedure.l ImageGadget(gadgetid.w,icon.l,xpos.w,ypos.w,toggle.b,toggleselect.b)
; This procedure installs an ImageGadget to the actual window using the
; intuition function AddGadget(). The image is taken from the given icon
; (exactly: we use the gadget structure inside the DiskObject structure).
; So you can paint your own Imagegadgets with the IconEditor.
; NOTE: Use oldstyle icons (OS 2/3/3.1), not NewIcons or GlowIcons from
; OS 3.5/3.9. If you not use oldstyle icons the images are not displayed
; or the program chrashes. You can use any type of icons (Tool, Project,
; Drawer, Disk etc.)
;
; Parameter: gadgetid.w = the ID of the imagegadget (the same like the first
; parameter of PureBasics gadgets functions).
; Note: PureBasic uses GadTools Gadgets, this procedure
; installs a Intuition gadget. This means that you can
; use a ID "0", even this ID "0" is already used by a
; PureBasic gadget command (see example).
; With the ID we can react to a click to the installed
; imagegadget using the normal PureBasic WaitWindowEvent()
; and EventGadgetID() functions. The function EventGadget()
; returns the ID of the clicked gadget: 0,1,2,3 etc.
; It is nearly the same for our imagegadget:
; ImageGadget 0 will return 65476
; ImageGadget 1 will return 65477
; ImageGadget 2 will return 65478
; ImageGadget 3 will return 65479 and so on ...
; By the way, i don't know why we receive a number starting
; at 65476, but it works and allows to use the gadgets :)
;
; The imagegadget ist installed to the actual window.
; To display the installed imagegadgets can use the PureBasic
; function RefreshGadget(-1 if you use also PureBasic-Gadgets.
; If you only use ImageGadgets you can use this function too,
; but don't forget the InitGadget() command in this case.
; There is also a procedure called RefreshImageGadget()
; which you can use if you don't use other PureBasic gadgets.
; For using this procedure you don't need the InitGadget()
; function.
;
; icon.l = The return from the GetDiskObject() function, it is the pointer
; to the DiskObject structure of the loaded icon
; xpos.w = x position of the gadgets
; ypos.w = y position of the gadgets
; the width and height of the gadget is taken from the
; DiskObject structure (width and height from the icon)
; toggle.b = TRUE = -1 we use a toggle gadget, that means that we can
; switch the gadget on and off (like "Bold" in a wordprocessor)
; = FALSE = 0 normal gadget, like a Buttongadget
; toggleselect.b = TRUE = -1 Only used if toggle.b = TRUE
; the gadget will displayed on, just choosen
; = FALSE = 0 Only used if toggle.b = TRUE
; teh gadget will displayed off, not choosen
;
; Returns : TRUE = -1 = everything went fine
; FALSE = 0 = icon.l contains 0 (no icon loaded)
;
; Note : We must free every imagegadget BEFORE we close the window
; in which they are installed ! Otherwise -> Guru !!
; For this use the procedure FreeImageGadget(icon.l).
;
; Requirements : We have to open the intuition.library (OpenIntuitionLibrary_(version)).
; PureBasic will close it at program end.
;

If icon0 ; icon loaded ?
gadget.l=icon+4 ; Gadget structure is included at offset 4 of DiskObject structure
PokeW(gadget+4,xpos) ; xpos of the gadget is found at offset 4 of gadget struc., so we write the xpos there
PokeW(gadget+6,ypos) ; ypos is found at offset 6, we write our ypos
PokeW(gadget+38,gadgetid) ; gadgetid is found at offset 38, we write our gadgetid
If toggle=-1 ; we need a toggle gadget ?
PokeW(gadget+14,1+256) ; yes, insert the toggle flag to offset 14
If toggleselect=-1 ; gadget should be on, just choosen ?
PokeW(gadget+12,PeekW(gadget+12)+128) ; yes, then we read out the existing flags and add flag for toggleselect and write it back
EndIf
Else
PokeW(gadget+14,1) ; no toggle gadget
EndIf
pos.l=AddGadget_(WindowID(),gadget,0) ; now we can add the gadget to the gadgetlist of the actual window
Else
ProcedureReturn 0
EndIf
ProcedureReturn -1
EndProcedure

Procedure.b FreeImageGadget(icon.l)
; This procedure frees a imagegadget which was installed by the ImageGadget()
; procedure. The gadget will be removed from the gadgetlist of the actual
; window. So make sure that you are accessing the correct window using
; UseWindow(win-nr).
; After freeing you can still see the gadget in the window, we have to
; refresh the window (and the gadgetlist). For refreshing use the PureBasic
; RefreshGadget(-1) function, if you use also PureBasic gadget. You can
; also use the procedure RefreshImageGadget() for that.
;
; Parameter: icon.l = The return from the GetDiskObject() function, it is the pointer
; to the DiskObject structure of the loaded icon
;
; Returns : FALSE= 0 = error on freeing the gadgets
; the gadget was not present in the gadgetlist of the window
; or we have tried to the free the 65553. gadget (max. no. of gadget we can use)
; TRUE = -1 = All went fine and the sun is shining, the gadget is removed
;
; Requirements: We have open the intuition.library (OpenIntuitionLibrary_(version)).
; PureBasic will close it at blah blah blah
;

pos.l=RemoveGadget_(WindowID(),icon+4) ; gadget structure starts at offset 4 of DiskObject structure
If pos-1
ProcedureReturn -1
Else
ProcedureReturn 0
EndIf
EndProcedure

Procedure.b RefreshImageGadget(fensterid.l)
; This procedure refreshes the given window, which means that all system
; and user gadgets will be drawn new.
; This is useful and nessessary after using the PureBasic FreeGadget()
; function or after using FreeImageGadget(), because this functions only
; remove the gadgets from the gadgetslist of the window. To avoid that
; you can still see any gadgets which are already freed, use this procedure.
; example:
; UseWindow(2)
; ; removing some gadgets here
; RefreshWindow(WindowID())
;
; Parameter: fensterid.l = the address of the window (WindowID() will return this address)
;
; Returns : the procedure returns always TRUE = -1
;
; Requirements: We have open the intuition.library (OpenIntuitionLibrary_(version)).
; PureBasic will close it at ... another blah blah blah
;

RefreshWindowFrame_(fensterid)
ProcedureReturn -1
EndProcedure

Procedure.b DisableImageGadget(icon.l,status.b)
; This procedure will deactivate or activate a gadget which was
; created with ImageGadget().
; Make sure that you are accessing the correct window in which the
; imagegadget is installed, otherwise you can open your door because
; someone has knocked. You open the door can drink a cup of coffee
; with Mr. Guru :)
; example:
; UseWindow(2) ; here is our imagegadget installed
; DisableImageGadget(icon,-1) ; now we disable our imagegadget
;
; Parameter: icon.l = The return from the GetDiskObject() function, it is the pointer
; to the DiskObject structure of the loaded icon (and so our gadget)
;
; status.b : TRUE = -1 = we disable our gadget (it is displayed ghosted and we cannot choose it)
; FALSE = 0 = we activate our gadget (again) and we can choose it.
;
; Returns : the procedure returns always TRUE = -1
;
; Requirements: We have open the intuition.library (OpenIntuitionLibrary_(version)).
; PureBasic will close it at ... once again blah blah blah
;

If status=-1
OffGadget_(icon+4,WindowID(),0) ; gadget is found at offset 4 of diskobject
EndIf
If status=0
OnGadget_(icon+4,WindowID(),0)
EndIf
ProcedureReturn -1
EndProcedure


And now here the example:
NOTE: before start the program just copy two oldstyle icons to ram:, named as
"test1.info" and "test2.info" or change the example to a path where the icons can be found.
It doesn' matter what kind of oldstyle icon (Drawer,Tool etc.) you use. Of course you need
also the procedures :)))



WBStartup() ; you know
If InitGadget(1) And OpenIntuitionLibrary_(36) And OpenIconLibrary_(36) ; open needed libs
If OpenWindow(0,20,20,400,150,#WFLG_DRAGBAR|#WFLG_CLOSEGADGET,"ImageGadget Example") ; open window
UseWindow(0) ; we use our window 0
ActivateWindow() ; what ???
If CreateGadgetList() ; for creating Gadtools (PureBasic) gadgets, if you only use
; Imagegadget you don't need this and the InitGadget()

icon1.l=GetDiskObject_("ram:test1") ;here we load the first icon for our gadgets
;the parameter is the path to the icon, but without the ".info".
; note the "_" after the name of the function. This tells PureBasic
; that we are calling a function from a library
icon2.l=GetDiskObject_("ram:test2") ;the second icon we load
If icon1 And icon2 ;just check if the icons were loaded, GetDiskObject returns
;0 if loading failed.
ImageGadget(0,icon1,30,30,0,0) ;we install imagegadget 0 at xpos 30 and ypos 10, no togglegadget
ImageGadget(1,icon2,30,80,-1,-1) ;imagegadget 1 at xpos 30,ypos 60, it is a togglegadget and it is selected

Else ;the icons are not loaded -> exit
EasyRequester("Error!","Cannot install ImageGadgets!","Exit")
End
EndIf

ButtonGadget(0,200,10,180,14,"PureBasic Gadget") ; we install a gadtools button gadget
ButtonGadget(1,200,30,180,14,"Disable ImageGadget") ; we install another to show how to disable the
; ImageGadgets
disable.b=0 ; just a flag so that we can switch the imagegadgets on and off

RefreshImageGadget(WindowID()) ; Now we refresh the installed gadgets to display them, works also for the
; PureBasicgadgets, so we don't need "RefreshGadget(-1)"

Repeat
Event.l = WaitWindowEvent()
If Event = #IDCMP_GADGETDOWN OR Event = #IDCMP_GADGETUP
EventGadget.l=EventGadgetID()
Select EventGadget
Case 0
EasyRequester("Info","You have clicked on the PureBasic Gadget","Correct")
Case 1
If disable=0 ; we use the flag, gadgets are on
DisableImageGadget(icon1,-1) ; so we can disable them
DisableImageGadget(icon2,-1)
disable=-1 ; set the flag that the gadget are off
Else ; the imagegadgets are already off
DisableImageGadget(icon1,0) ; so we switch them on
DisableImageGadget(icon2,0)
disable=0 ; set flag that the gadgets are on
EndIf
Case 65476
EasyRequester("Info","You have clicked on the ImageGadget 0","Correct")
Case 65477
EasyRequester("Info","You have clicked on the ImageGadget 1, which is a ToggleGadget","Correct")
EndSelect
Endif
Until Event = #IDCMP_CLOSEWINDOW
Else
EasyRequester("Error!","Cannot create Gadtool gadgets!","Exit")
EndIf
Else
EasyRequester("Error!","Cannot open window!","Exit")
Endif
Else
EasyRequester("Error!","Cannot initialize program!","Exit")
EndIf

; before the program ends we first have to free the gadgets and THEN to unload the
; icons, logical !!

FreeImageGadget(icon1) ; we free the first one
FreeImageGadget(icon2) ; the second one

; and now we free the loaded icons
FreeDiskObject_(icon1)
FreeDiskObject_(icon2)
; the icon and intuition.library is closed by PureBasic, we can do it, but it will be done
End


Ok, that all! Puuh, writing a lot. Anyway, hope you find the procedures
useful. Let me know if so.

Greetings ..
Roxxler
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by plouf.

cool :) nice procedures
anyway i believed that since the icon lib has changed all progs that use
old icons can use and glow ones (seems i was wrong :))

the prob with purecompiler still exist (sedond exe don't crash?
also compile/run crash) maybe its only when open external libs as
i have not notice that wtih internal commands ?????

Christos
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Roxxler.
cool :) nice procedures
anyway i believed that since the icon lib has changed all progs that use
old icons can use and glow ones (seems i was wrong :))

the prob with purecompiler still exist (sedond exe don't crash?
also compile/run crash) maybe its only when open external libs as
i have not notice that wtih internal commands ?????

Christos
Hi,
yes, the same i thought too, but it will not work. Just test it :)
Since OS 3.5 there are many new functions in the icon.library. I will
have a look at this.

You are right: strange thing the crash. On my machines (A1000/030 OS3.1
and A4000/060-PPC OS3.9) it will crash if i compile it ones and use this
executable. After compiling a second time the executable will run without
probs. I don´t believe that the reason is that external libs are used,
because we use this also e.g. with the ImageGadgets and all works fine.

Greetings ..
Roxxler
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by tinman.
here a solution for using ImageGadgets in PureBasic Amiga. At
Nice work. Have you considered using GUIGfx.library though - it would allow you to create ImageGadgets from any kind of image using datatypes, and automatically do things like resize and remap.

There was some code posted to the Blitz mailing list recently if you want somewhere to start.


It's not minimalist - I'm increasing efficiency by reducing input effort.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Roxxler.
Nice work. Have you considered using GUIGfx.library though - it would allow you to create ImageGadgets from any kind of image using datatypes, and automatically do things like resize and remap.
There was some code posted to the Blitz mailing list recently if you want somewhere to start.

It's not minimalist - I'm increasing efficiency by reducing input effort.
Hi,
thanx for the tip. I will have a look at it.

Greetings ..
Roxxler
Post Reply