Author Topic: Question about IUP  (Read 23230 times)

0 Members and 2 Guests are viewing this topic.

Arnold

  • Guest
Question about IUP
« on: March 28, 2015, 11:10:19 AM »
Hi Charles,

I am trying to run some Iup Examples with OxygenBasic, using as much of the original syntax as possible. Some work, some do not.

Am I doing something wrong with this example?

Code: OxygenBasic
  1. /*  IupGetColor: Example in C
  2.     Creates a predefined color selection dialog. The user receives the color in the RGB format.
  3. */
  4.  
  5. $ filename "getcolor.exe"
  6. 'include "$\inc\rtl32.inc"
  7. include "$\inc\console.inc"
  8.  
  9. includepath "iup\"
  10.  
  11. extern lib "iup\iup.dll" cdecl      
  12. include "iup.h"
  13. end extern
  14.  
  15. extern cdecl
  16. #define EXIT_SUCCESS 0
  17.  
  18. int main(int argc, char **argv)
  19. {
  20.   unsigned byte r, g, b;        'char
  21.  
  22.   IupOpen(&argc, &argv);
  23.  
  24.   if(IupGetColor(100, 100, &r, &g, &b)) then
  25.     print("RGB = " r ", " g ", " b) : waitkey()
  26.   end if
  27.  
  28.   IupClose();
  29.   return EXIT_SUCCESS;
  30. }
  31.  
  32. main(0,0)
  33.  

The dialog opens, but I always get 0,0,0 no matter what I try. Is there a way to get the contents of r,g,b?

Roland

JRS

  • Guest
Re: Question about IUP
« Reply #1 on: March 28, 2015, 11:21:54 AM »
Code: C
  1.  IupControlsOpen ();
  2.  


Arnold

  • Guest
Re: Question about IUP
« Reply #2 on: March 28, 2015, 02:57:51 PM »
This I tried at first. To do this I need some dlls of the cd library. But then I get a messagebox: IupControlsOpen() and the dialog does not open. Therefore I thought IupControlsOpen would not be necessary.

Code: OxygenBasic
  1. /*  IupGetColor: Example in C
  2.     Creates a predefined color selection dialog. The user receives the color in the RGB format.
  3. */
  4.  
  5. $ filename "getcolor.exe"
  6. 'include "$\inc\rtl32.inc"
  7. include "$\inc\console.inc"
  8.  
  9. includepath "iup\"
  10.  
  11. extern lib "iup\iup.dll" cdecl      
  12. include "iup.h"
  13. end extern
  14.  
  15. extern lib "iup\iupcontrols.dll" cdecl
  16. extern lib "iup\iupcd.dll" cdecl
  17. extern lib "iup\cd.dll" cdecl
  18. extern lib "iup\freetype6.dll" cdecl
  19. extern lib "iup\zlib1.dll" cdecl
  20. include "iupcontrols.h"  
  21. end extern
  22.  
  23. extern cdecl
  24. #define EXIT_SUCCESS 0
  25.  
  26.  
  27. int main(int argc, char **argv)
  28. {
  29.   unsigned byte r, g, b;     'char
  30.  
  31.   IupOpen(&argc, &argv);
  32.   IupControlsOpen ();
  33.  
  34.   if(IupGetColor(100, 100, &r, &g, &b)) then
  35.     print("RGB = " r ", " g ", " b) : waitkey()
  36.   end if
  37.  
  38.   IupClose();
  39.   return EXIT_SUCCESS;
  40. }
  41.  
  42. main(0,0)
  43.  

Charles Pegge

  • Guest
Re: Question about IUP
« Reply #3 on: March 28, 2015, 06:27:23 PM »
Hi Roland,

I am not familiar with IUP but I recommend one of John's examples as a good starting point, for a GUI frame at least:  projectsb\IUP\jfdemo1.o2bas (thesaurus)

Peter's pwdemo1, in the same folder, with its own self-contained header, demonstrates some graphics. No extra DLLs required. PS: uncomment cdecl in the extern statement.

I dont think one would normally use IUP with a console, except for diagnostics.

Arnold

  • Guest
Re: Question about IUP
« Reply #4 on: May 21, 2015, 03:34:05 PM »
Hi Charles,

may I ask for your help?

The basic principle of the Iup toolkit is rather simple: create a dialog with some controls, add some attributes to the controls and create some callbacks in cdecl for the events. Although I have managed to run many of the Iup test cases with OxygenBasic I am not sure if I could do some things better.

For setting the attributes I use IupSetStrAttribute (old IupStoreAttribute) because IupSetAttribute does not always work correctly. The declarations is:

iup.h:
void      IupSetAttribute   (Ihandle* ih, const char* name, const char* value);

void    IupSetStrAttribute(Ihandle* ih, const char* name, const char* value);
void     IupStoreAttribute(Ihandle* ih, const char* name, const char* value); ' old form

in iup.inc I used:
! IupSetAttribute   (sys ih, string name, string value)

! IupSetStrAttribute (sys ih, string name, string value)
! IupStoreAttribute  (sys ih, string name, string value)   ' old form

Although the arguments for IupSetAttribute and IupSetStrAttribute seem to be of the same type there must be a difference. The help file indicates:

IupSetAttribute can store only constant strings (like "Title", "30", etc) or application pointers.
IupSetStrAttribute (old IupStoreAttribute) can only store strings. The given string value will be duplicated internally.

I managed to do a lot with IupSetStrAttribute (old IupStoreAttribute) but it would be nice if I could get IupSetAttribute to work too. I suppose that some other functions should be adapted also because they internally call IupSetAttribute. Should I use a different type for IupSetAttribute? Maybe I can create a helper function like this?

! IupSetAttribute_ alias "IupSetAttribute" (sys ih, string name, string(?) value)

sub IupSetAttribute(...
  what to do?
end sub

This is a small example (intended to run in the folder OxygenBasic\ProjectB\Iup) which shows the difference:

Code: [Select]
include "$/inc/console.inc"

typedef sys Icallback

includepath "iup\"     
extern lib "IUP/iup.dll" cdecl     

#define IUP_DEFAULT   -2
#define IUP_CENTER    0xFFFF  /* 65535 */

! IupOpen          (sys argc,argv) as int
! IupClose         ()
! IupMainLoop      () as int
! IupShowXY        (sys ih, int x, int y) as int
! IupSetAttribute   (sys ih, string name, string value)
! IupStoreAttribute(sys ih, string name, string value)
! IupSetFunction(string name, Icallback func) as Icallback
! IupSetCallback (sys ih, string name, Icallback func) as Icallback
! IupCanvas     (string action) as sys
! IupDialog     (sys child) as sys

end extern

extern cdecl       


static int idle_count = 0

function idle()
  print "IDLE_ACTION( count = "  idle_count ")" & cr
  idle_count++

//  if (idle_count == 10000)
//    return IUP_IGNORE

  return IUP_DEFAULT
end function

function motion_cb(sys ih) as int callback
  print "MOTION_CB()" & cr
  if (idle_count > 15000) then
    IupSetFunction ("IDLE_ACTION", NULL)
  end if
  return IUP_DEFAULT
end function

sub IdleTest()

  sys dlg, canvas

  canvas = IupCanvas(NULL)
  IupSetCallback(canvas, "MOTION_CB", @motion_cb)
 
  dlg = IupDialog(canvas)
  IupSetAttribute(dlg, "TITLE", "Idle Test")
  IupSetAttribute(dlg, "RASTERSIZE", "500x500")
'  IupStoreAttribute(dlg, "TITLE", "Idle Test")
'  IupStoreAttribute(dlg, "RASTERSIZE", "500x500")

  IupShowXY(dlg, IUP_CENTER, IUP_CENTER)

  IupSetFunction ("IDLE_ACTION", @idle)
end sub


sub main()

  IupOpen(0,0)
  IdleTest()
  IupMainLoop()
  IupClose()

end sub

main()


With IupSetAttribute the title of the dialog shows "RASTERSIZE" wich should be "Idle Test". But how should I construct and use IupSetAttribute with a pointer to "value"?

Roland

JRS

  • Guest
Re: Question about IUP
« Reply #5 on: May 21, 2015, 06:10:06 PM »
Hi Arnold,

I have found that languages that link dynamically via a a DLL/SO directly to IUP require the str/store method. Script BASIC is linked to IUP via its extension module API interface. This is why the SB and DLLC version get away using the applications strings rather than having to store a copy for IUP. Other than that, everything else should be the same.

Charles Pegge

  • Guest
Re: Question about IUP
« Reply #6 on: May 22, 2015, 12:15:11 AM »
Hi Roland,

I am not at all familiar with IUP. John is the expert :)

But I agree that you can pass in-going string params wherever char* is specified.

This is because bstrings contain char*, and strings reference bstrings.

The actual format of a bstring is:

offset
-04  byte count NB
  00  characters
  NB  null characters (terminator)

(Of course, the called IUP function has no knowledge of a bstring structure, so using such params to return info to the caller should be used with caution.)

I would advise, however that you specify char* in the prototype declarations, rather than string, for precise representation.

I hope this helps.



PS:

In your example, I do not see any corruption of the title: "Idle Test"

Both SetAttribute and StoreAttribute work as expected

Oxygen DLL Update (200k)
http://www.oxygenbasic.org/o2zips/Oxygen.zip
« Last Edit: May 22, 2015, 12:28:28 AM by Charles Pegge »

JRS

  • Guest
Re: Question about IUP
« Reply #7 on: May 22, 2015, 08:33:24 AM »
Quote from: Charles
I am not at all familiar with IUP. John is the expert.

I admit to spending more time with IUP then most in our BASIC circle but far from being an expert. I think we both can agree that IUP is a great cross platform native GUI open source library. Just the fact it's actively being developed and supported says a lot.


Arnold

  • Guest
Re: Question about IUP
« Reply #8 on: May 22, 2015, 10:48:04 AM »
Hi Charles,

many thanks for the update. This really saved me some headaches. I tried IupSetAttribute with some more examples and it now works as expected. And I will follow your advice to use char* instead of string in the prototype declarations.

BTW I noticed that you added a folder \tests in the latest OxygenBasic.zip. Was this done intentionally?

Roland

JRS

  • Guest
Re: Question about IUP
« Reply #9 on: May 22, 2015, 10:55:18 AM »
Quote
BTW I noticed that you added a folder \tests in the latest OxygenBasic.zip. Was this done intentionally?

Maybe Charles is planting a new IUP garden.  :)

Charles Pegge

  • Guest
Re: Question about IUP
« Reply #10 on: May 22, 2015, 10:00:01 PM »

The new tests directory is a place for any code that is experimental, or that checks Oxygen's functionality. It makes sense to keep them separate from the other examples.

Arnold

  • Guest
Re: Question about IUP
« Reply #11 on: May 26, 2015, 11:46:02 PM »
Hi Charles,

may I ask for your helping hand one more time? I have a problem with variadic functions using char *format, ... and although I tried a lot I do not find a solution which certainly does exist.

I try to run a demo with the IupScanf dialog (not recommended by the author, but shows the principle). This is the code of scanf.o2bas intended to run in ProjectsB/Iup:

Code: [Select]

includepath "iup\"     
extern lib "IUP/iup.dll" cdecl
     
! IupOpen      (sys argc,argv) as int
! IupClose     ()
! IupMessage   (char *title, char *msg)
! IupMessagef  (char *title, char *format, ...)
! IupScanf     (char *format, ...) as int

end extern

/*
includepath "iup/"     
extern lib "IUP/iup.dll" cdecl     
include "iup.h"
*/

extern cdecl       


% lf   = chr(10)    '\n' ??
% crlf = chr(13,10)

sub ScanfTest()

  int result
  int integr = 12
  float real = 0.001f    ' 1e-3f
  char text[300]="This is a vector of characters"
  char *fmt =
'  {
'   "IupScanf Example\n"  &
'   "Text: %300.5%s\n"    & 
'   "Real: %20.10%g\n"    & 
'   "Integer: %20.10%d\n"
'  }

   "IupScanf Example\nText: %300.5%s\nReal: %20.10%g\nInteger: %20.10%d\n"
'   "IupScanf Example" lf "Text: %300.5%s" lf "Real: %20.10%g" lf "Integer: %20.10%d" lf
   
' does not work? 
  IupMessagef("Before IupScanf","Text: %s" lf "Real: %f" lf "Integer: %d" ,
                  text, real, integr )

' does not work?
  result = IupScanf(fmt, text, &real, &integr)

  if result = -1 then
    IupMessage("IupScanf","Operation canceled")
  else
'    IupMessagef("IupScanf","Text: %s\nReal: %f\nInteger: %d\nFields read successfully: %d",text,real,integr,result)
    IupMessagef("IupScanf","Text: %s" lf "Real: %f" lf "Integer: %d" lf "Fields read successfully: %d",
                  text,real,integr,result)
  end if
end sub


sub main()

  IupOpen(0,0)
  ScanfTest()
  IupClose()

end sub

main()


IupMessagef and IupScanf somehow work and somehow wrong. IupMessagef seems to do some formating but does not show values, only the text vector. IupScanf does not show the dialog, but it also does not return an error (-1). Must I use different types with the arguments? Should the format string be adapted in some way?

If I try to use iup.h directly I get a strange error message (line points to int result):

ERROR:  direct void type not usable: ihandle: _retval
WORD:   [
LINE:   27
FILE:   main source
PASS:   1

Does this message refer somehow to IupMessagef or IupScanf too? If IupScanf with char *format, ... could be used, then a more powerful dialog IupGetParam would probably work too. I think almost all of the functions in the Iup library should work then.

I have attached the source code of iup_scanf.c (implementation of IupScanf). Unfortunately I do not know enough of the C language to decide how I should treat e.g "\n" or how to treat the pointers and types of the values in OxygenBasic.

Roland


.

Arnold

  • Guest
Re: Question about IUP
« Reply #12 on: May 26, 2015, 11:49:02 PM »
I noticed that you added a nice demo using iupgl.dll. With me iupgl.dll did not work (because I forgot "extern cdecl"). By reading the code I also noticed that the appendix "as sys callback" might not be mandatory and could be omitted. But this must be checked. And if it is possible to use the header files directly I will do this in the examples provided with Iup3.14 too.

JRS

  • Guest
Re: Question about IUP
« Reply #13 on: May 26, 2015, 11:54:45 PM »
Roland,

Great to see that you got theming working.

I'm really happy you have taken an interest in IUP and O2. I believe your efforts will set the standard on Windows using IUP.

Charles Pegge

  • Guest
Re: Question about IUP
« Reply #14 on: May 27, 2015, 06:26:10 AM »
Hi Roland,

It expects a byval double.

You can pass a double directly, or explicitly convert the float to a double

Code: OxygenBasic
  1.    IupMessagef("Before IupScanf" , "Text: %s" lf "Real: %f" lf "Integer: %d", text,convert double real,integr)
  2.  

PS: Yes, o2 will accept IUP headers undoctored :)