Guia

IUP - Portable User Interface

Guide

Getting Started

IUP has 4 impor

tant concepts that are implemented in a very different way from other toolkits.

First is the control creation timeline. When a control is created it is not immediately mapped to the native system. So some attributes will not work until the control is mapped. The mapping is done when the dialog is shown or manually calling IupMap for the dialog. You can not map a control without inserting it into a dialog.

Second is the attribute system. IUP has only a few functions because it uses string attributes to access the properties of each control. So get used to IupSetAttribute and IupGetAttribute, because you are going to use them a lot.

Third is the abstract layout positioning. IUP controls are never positioned in a specific (x,y) coordinate inside the dialog. The positioning is always calculated dynamically from the abstract layout hierarchy. So get used to the IupFill, IupHbox and IupVbox controls that allows you to position the controls in the dialog.

Fourth is the callback system. Because of the LED resource files IUP has an indirect form to associate a callback to a control. You must associate A C function with a name using IupSetFunction, and you must associate the callback attribute with that name using IupSetAttribute.

LED is the original IUP resource file which has been deprecated in favor of Lua files. But keep in mind that you can use IUP without using LED or Lua, using only the C API.

Building Applications

To compile programs in C, simply include file iup.h. If the application only uses functions from IUP and other portable languages such as C or Lua, with the same prototype for all platforms, then the application immediately becomes platform independent, at least concerning user interface, because the implementation of the IUP functions is different in each platform. The linker is in charge of solving the IUP functions using the library specified in the project/makefile. For further information on how to link your application, please refer to the specific driver documentation.

IUP can also work together with other interface toolkits. The main problem is the IupMainLoop function. If you are going to use only Popup dialogs, then it is very simple. But to use non modal dialogs without the IupMainLoop you must call IupLoopStep from inside your own message loop. Also it is not possible to use Iup controls with dialogs from other toolkits and vice-versa.

The generation of applications is highly dependent on each system, but at least the iup.lib/libiup.a/libiup.so library must be linked.

To use the Lua Binding, you need to link the program with the iuplua.lib/libiuplua.a/libiuplua.so library and with the lua.lib/liblua.a/liblua.so and lualib.lib/liblualib.a/liblualib.so libraries. IupLua is available for Lua 3.2 and Lua 5.0.

The download files list includes the Tecgraf/PUC-Rio Library Download Tips document, with a description of all the available binaries.

Windows

In Windows, you must link also with the libraries ole32.lib and comctl32.lib (provided with the compilers). The iup.rc resource file must be included in the application's project/makefile so that HAND, IUP, PEN and SPLITH cursors can be used.

There is also a guide on using the Dev-C++ IDE Project Options and Visual C++ IDE Project Properties.

Motif

In Motif, IUP uses the Motif (Xm), the Xtoolkit (Xt) and the Xlib (X11) libraries. To link an application to IUP, use the following options in the linker call (in the same order):

-liup -lXm -lXmu -lXt -lX11 -lm

Though these are the minimum requirements, depending on the platform other libraries might be needed. Typically, they are X extensions (Xext), needed in SunOS, and Xpm (needed in Linux only). They must be listed after Xt and before X11. For instance:

-liup -lXm -lXpm -lXmu -lXt -lXext -lX11 -lm

Usually these libraries are placed in default directories, being automatically located by the linker. When the linker warns you about a missing library, add their location directories with option -L. In Tecgraf, some machines require such option:

Standard -L/usr/lib -I/usr/include
Linux -L/usr/X11R6/lib -I/usr/X11R6/include
IRIX -L/usr/lib32 -I/usr/include/X11
Solaris -L/usr/openwin/lib -I/usr/openwin/share/include/X11
AIX -I/usr/include/Motif2.1

Following are some makefile suggestions. All of them can be used in SunOS (Sun), IRIX (Silicon) and AIX (IBM) systems. For Linux, -lXpm must be added at the end of the SYSLIBS variable.

Multithread

User interface is usually not thread safe and IUP is not thread safe. The general recommendation when you want more than one thread is to build the application and the user interface in the main thread, and create secondary threads that communicates with the main thread to update the interface. The secondary threads should not directly update the interface.

Dynamic Loading

Although we have dynamic libraries we do not recommend the dynamic loading of the main IUP library. This is because it depends on Motif and X11, you will have to load these libraries first. So it is easier to build an base application that already includes X11, Motif and the main IUP library than trying to load them all. The IUP secondary libraries can be easily dynamic loaded.

Here is an example in Lua 5:

local init =
{
  {"cd.dll", nil},
  {"iupcontrols.dll", "IupControlsOpen"},
  {"iuplua5.dll", "iuplua_open"},
  {"iupluacontrols5.dll", "iupcontrolslua_open"},
}

local function DllExecute(i,v)
  local name = v[1]
  local func = v[2]
  if not func then func = "" end
  local fnc, err = loadlib(name, func)
  if v[2] then
    if fnc then
      fnc()
    else
      print(v[1]..": "..err)
    end
  end
end

table.foreach(init, DllExecute)

Building The Library

The easiest way to build the library is to install the Tecmake tool into your system. It is easy and helps a lot. The Tecmake configuration files (*.mak) available at the "src" folder are very easy to understand also.

Tecmake is a command line multi compiler build tool available at http://www.tecgraf.puc-rio.br/tecmake. Tecmake is used by all the Tecgraf libraries and many applications.

In IUP's main directory, and in each source directory, there are files named make_uname (make_uname.bat in Windows) that build the libraries using Tecmake. To build the IUP libraries for Windows using Visual C 7.0 for example, just execute make_uname.bat vc7 in the iup root folder.

But we also provide a stand alone makefile for Linux systems and a Visual Studio workspace with the respective projects. The stand alone makefile is created using Premake and a configuration file in lua called "premake.lua".

IUP runs on many different systems and interact with many different libraries such as Motif, OpenGL, Canvas Draw (CD) and Lua (3 and 5). You have to install some these libraries to use the IUP libraries. IUP standalone only depends on the Windows core libraries (alreay installed in the system) and on the Motif 2.x+X11-R6. In Linux you should use Open Motif 2.x. If you only have Motif 1.2 some features will be limited and you must add the file "src/mot/ComboBox1.c".

Using IUP in C++

IUP is a low level API, but at the same time a very simple and intuitive API. That's why it is implemented in C, to keep the API simple. But most of the actual IUP applications today use C++. To use C callbacks in C++ classes, you can declare the callbacks as static members or friend functions, and store the pointer "this" at the "Ihandle*" pointer as an user attribute. For example, you can create your dialog by inheriting from the following dialog.

class iupDialog
{
private:
  Ihandle *hDlg;
  int test;

  static int ResizeCB (Ihandle* self, int w, int h); 
  friend int ShowCB(Ihandle *self, int mode); 

public:
  iupDialog(Ihandle* child)
  { 
    hDlg = IupDialog(child); 
    IupSetAttribute(hDlg, "iupDialog", (char*)this); 
    IupSetAttribute(hDlg, "RESIZE_CB", "iupDialogResizeCB"); 
    IupSetFunction("iupDialogResizeCB", (Icallback)ResizeCB);
    IupSetAttribute(hDlg, "SHOW_CB", "iupDialogShowCB"); 
    IupSetFunction("iupDialogShowCB", (Icallback)ShowCB);
  }

  void ShowXY(int x, int y) { IupShowXY(hDlg, x, y); }

protected:

  // implement this to use your own callbacks
  virtual void Show(int mode) {};
  virtual void Resize (int w, int h){}; 
};

int iupDialog::ResizeCB(Ihandle *self, int w, int h)
{
  iupDialog *d = (iupDialog*)IupGetAttribute(self, "iupDialog");
  d->test = 1; // private members can be accessed in private static members
  d->Resize(w, h);
  return IUP_DEFAULT;
}

int ShowCB(Ihandle *self, int mode)
{
  iupDialog *d = (iupDialog*)IupGetAttribute(self, "iupDialog");
  d->test = 1; // private members can be accessed in private friend functions
  d->Show(mode);
  return IUP_DEFAULT;
}

This is just one possibility on how to write a wrapper class around IUP functions. Some users contributed with C++ wrappers:

RSSGui by Danny Reinhold. Described by his words:

- It works fine with the C++ STL and doesn't define a set of own string, list, vector etc. classes like many other toolkits do (for example wxWidgets).
- It has a really simple event handling mechanism that is much simpler than the system that is used in MFC or in wxWidgets and that doesn't require a preprocessor like Qt. (It could be done type safe using templates as in a signal and slot library but the current way is really, really simple to understand and to write.)
- It has a Widget type for creating wizards.
- It is not complete, some things are missing. It was tested only on the Windows platform.

For more see the documentation page of RSSGui.

IupTreeUtil by Sergio Maffra and Frederico Abraham. It is an utility wrapper for the IupTree control.

The code available here uses the same license terms of the IUP license.