diff --git a/iup/COPYRIGHT b/iup/COPYRIGHT index dd31d6c..0061f2d 100755 --- a/iup/COPYRIGHT +++ b/iup/COPYRIGHT @@ -7,7 +7,7 @@ and commercial purposes at absolutely no cost.  ===============================================================================  -Copyright (C) 1994-2009 Tecgraf, PUC-Rio. +Copyright (C) 1994-2010 Tecgraf, PUC-Rio.  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/iup/etc/iup.rc b/iup/etc/iup.rc index eab8cf5..49c324d 100755 --- a/iup/etc/iup.rc +++ b/iup/etc/iup.rc @@ -12,7 +12,7 @@ BEGIN VALUE "CompanyName", "Tecgraf/PUC-Rio\0" VALUE "FileDescription", "IUP - Portable User Interface\0" VALUE "FileVersion", "3.0.0\0" - VALUE "LegalCopyright", "Copyright © 1994-2009 Tecgraf, PUC-Rio.\0" + VALUE "LegalCopyright", "Copyright © 1994-2010 Tecgraf, PUC-Rio.\0" VALUE "OriginalFilename", "iup.dll\0" VALUE "ProductName", "IUP for Windows\0" VALUE "ProductVersion", "3.0.0\0" diff --git a/iup/include/iup.h b/iup/include/iup.h index 9913329..2d33b98 100755 --- a/iup/include/iup.h +++ b/iup/include/iup.h @@ -19,11 +19,11 @@ extern "C" {   #define IUP_NAME "IUP - Portable User Interface" -#define IUP_COPYRIGHT "Copyright (C) 1994-2009 Tecgraf, PUC-Rio." +#define IUP_COPYRIGHT "Copyright (C) 1994-2010 Tecgraf, PUC-Rio." #define IUP_DESCRIPTION "Portable toolkit for building graphical user interfaces." -#define IUP_VERSION "3.0" /* bug fixes are reported only by IupVersion functions */ -#define IUP_VERSION_NUMBER 300000 -#define IUP_VERSION_DATE "2009/10/02" +#define IUP_VERSION "3.1" /* bug fixes are reported only by IupVersion functions */ +#define IUP_VERSION_NUMBER 301000 +#define IUP_VERSION_DATE "2010/04/22"  typedef struct Ihandle_ Ihandle; typedef int (*Icallback)(Ihandle*); @@ -38,6 +38,7 @@ void IupImageLibOpen (void);  int IupMainLoop (void); int IupLoopStep (void); +int IupLoopStepWait (void); int IupMainLoopLevel (void); void IupFlush (void); void IupExitLoop (void); @@ -148,6 +149,7 @@ Ihandle* IupNormalizerv(Ihandle* *ih_list); Ihandle* IupCbox (Ihandle* child, ...); Ihandle* IupCboxv (Ihandle* *children); Ihandle* IupSbox (Ihandle *child); +Ihandle* IupSplit (Ihandle* child1, Ihandle* child2);  Ihandle* IupFrame (Ihandle* child);  @@ -197,12 +199,13 @@ int IupTreeSetUserId(Ihandle* ih, int id, void* userid); void* IupTreeGetUserId(Ihandle* ih, int id); int IupTreeGetId(Ihandle* ih, void *userid);  -void IupTreeSetAttribute (Ihandle* ih, const char* name, int id, char* value); -void IupTreeStoreAttribute(Ihandle* ih, const char* name, int id, char* value); +void IupTreeSetAttribute (Ihandle* ih, const char* name, int id, const char* value); +void IupTreeStoreAttribute(Ihandle* ih, const char* name, int id, const char* value); char* IupTreeGetAttribute (Ihandle* ih, const char* name, int id); int IupTreeGetInt (Ihandle* ih, const char* name, int id); float IupTreeGetFloat (Ihandle* ih, const char* name, int id); -void IupTreeSetfAttribute (Ihandle* ih, const char* name, int id, char* format, ...); +void IupTreeSetfAttribute (Ihandle* ih, const char* name, int id, const char* format, ...); +void IupTreeSetAttributeHandle(Ihandle* ih, const char* a, int id, Ihandle* ih_named);   /************************************************************************/ @@ -338,7 +341,7 @@ int IupMain (int argc, char** argv); /* In C++ we have to declare the prototype #endif  /****************************************************************************** -* Copyright (C) 1994-2009 Tecgraf, PUC-Rio. +* Copyright (C) 1994-2010 Tecgraf, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/iup/include/iupcbs.h b/iup/include/iupcbs.h index f33166b..70d117f 100755 --- a/iup/include/iupcbs.h +++ b/iup/include/iupcbs.h @@ -24,7 +24,7 @@ typedef int (*IFnnii)(Ihandle*, Ihandle*, int, int); /* drop_cb */ typedef int (*IFnnn)(Ihandle*, Ihandle*, Ihandle*); /* tabchange_cb */ typedef int (*IFnss)(Ihandle*, char *, char *); /* file_cb */ typedef int (*IFns)(Ihandle*, char *); /* multiselect_cb */ -typedef int (*IFnis)(Ihandle*, int, char *); /* text_action, multiline_action, edit_cb, renamenode_cb, rename_cb */ +typedef int (*IFnis)(Ihandle*, int, char *); /* text_action, multiline_action, edit_cb, rename_cb */ typedef int (*IFnsii)(Ihandle*, char*, int, int); /* list_action */ typedef int (*IFnsiii)(Ihandle*, char*, int, int, int); /* dropfiles_cb */ typedef int (*IFniis)(Ihandle*, int, int, char*); /* motion_cb, click_cb, value_edit_cb */ diff --git a/iup/include/iupcontrols.h b/iup/include/iupcontrols.h index c7bc566..a30d407 100755 --- a/iup/include/iupcontrols.h +++ b/iup/include/iupcontrols.h @@ -15,9 +15,6 @@ extern "C" { int IupControlsOpen(void); void IupControlsClose(void); /* for backward compatibility only, does nothing since IUP 3 */  -void IupOldValOpen(void); -void IupOldTabsOpen(void); - Ihandle* IupColorbar(void); Ihandle* IupCells(void); Ihandle *IupColorBrowser(void); diff --git a/iup/include/iuplua.h b/iup/include/iuplua.h index dc660b5..854a858 100755 --- a/iup/include/iuplua.h +++ b/iup/include/iuplua.h @@ -23,7 +23,7 @@ int iuplua_dofile (char *filename);  #ifdef LUA_TNONE /* Lua 5 */ int iuplua_open(lua_State *L); -int iupkey_open(lua_State *L); +int iupkey_open(lua_State *L); /* does nothing, kept for backward compatibility */ int iuplua_close(lua_State * L);  /* utilities */ diff --git a/iup/mak.vc8/iupgtk.vcproj b/iup/mak.vc8/iupgtk.vcproj index 5d0a8e2..9fccbb2 100755 --- a/iup/mak.vc8/iupgtk.vcproj +++ b/iup/mak.vc8/iupgtk.vcproj @@ -143,6 +143,10 @@ >   +  +   diff --git a/iup/mak.vc8/iuplua5.vcproj b/iup/mak.vc8/iuplua5.vcproj index 0c62f76..1245e86 100755 --- a/iup/mak.vc8/iuplua5.vcproj +++ b/iup/mak.vc8/iuplua5.vcproj @@ -123,6 +123,10 @@ >   +  +   @@ -307,6 +311,10 @@ >   +  +   diff --git a/iup/mak.vc8/iupmot.vcproj b/iup/mak.vc8/iupmot.vcproj index aedd67e..d2d1780 100755 --- a/iup/mak.vc8/iupmot.vcproj +++ b/iup/mak.vc8/iupmot.vcproj @@ -161,6 +161,10 @@ >   +  +   diff --git a/iup/mak.vc8/iupsample.vcproj b/iup/mak.vc8/iupsample.vcproj index bddc4f6..dde33fd 100755 --- a/iup/mak.vc8/iupsample.vcproj +++ b/iup/mak.vc8/iupsample.vcproj @@ -616,6 +616,13 @@  +  +  +    +  +  +        +  +   @@ -255,6 +259,14 @@ >   +  +  +  +   @@ -298,6 +310,10 @@ RelativePath="..\test\vbox.c" >  +  +     diff --git a/iup/mak.vc8/iuptestgtk.vcproj b/iup/mak.vc8/iuptestgtk.vcproj index 46d9e49..017bb69 100755 --- a/iup/mak.vc8/iuptestgtk.vcproj +++ b/iup/mak.vc8/iuptestgtk.vcproj @@ -154,6 +154,10 @@ >   +  +   @@ -246,6 +250,14 @@ >   +  +  +  +   @@ -289,6 +301,10 @@ RelativePath="..\test\vbox.c" >  +  +     diff --git a/iup/mak.vc8/iupwin.vcproj b/iup/mak.vc8/iupwin.vcproj index c1e2434..cf53df8 100755 --- a/iup/mak.vc8/iupwin.vcproj +++ b/iup/mak.vc8/iupwin.vcproj @@ -176,6 +176,10 @@ >   +  +   diff --git a/iup/mak.vc9/iup.sln b/iup/mak.vc9/iup.sln index 898c75f..47e2076 100755 --- a/iup/mak.vc9/iup.sln +++ b/iup/mak.vc9/iup.sln @@ -95,6 +95,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iuplua5_exe", "iupluaexe5.v {1EBC7A53-4677-AAAA-1234-49D301F17D85} = {1EBC7A53-4677-AAAA-1234-49D301F17D85} {1EBC7A53-4677-75D7-8D4A-49D301F17D85} = {1EBC7A53-4677-75D7-8D4A-49D301F17D85} {1EBC7A53-4677-ADF1-8D4A-49D301F17D85} = {1EBC7A53-4677-ADF1-8D4A-49D301F17D85} + {1EBC7A53-4677-FFFF-1234-49D301F17D85} = {1EBC7A53-4677-FFFF-1234-49D301F17D85} {B4823266-DF8C-4EFB-91C0-C7688C234EAC} = {B4823266-DF8C-4EFB-91C0-C7688C234EAC} {5EEFE977-C56D-462F-BDEE-12A5452EB8CC} = {5EEFE977-C56D-462F-BDEE-12A5452EB8CC} {5EEFE977-C56D-462F-BDEE-12A5452EB8CC} = {5EEFE977-C56D-462F-BDEE-12A5452EB8CC} @@ -196,6 +197,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iuplua5gtk_exe", "iupluaexe {E251B4F4-0B0A-482B-BA18-2509ADC4B6AA} = {E251B4F4-0B0A-482B-BA18-2509ADC4B6AA} EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{B24D8E0A-2EB5-4C49-A146-C0AABEF81788}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -285,7 +288,6 @@ Global {2F92EC58-D94C-40BF-8C82-77607C72E1E3} = {FC52B7B5-744E-45D6-815C-3502F9D965E7} {9462FDEA-3E53-4250-8710-DD50AF48607C} = {FC52B7B5-744E-45D6-815C-3502F9D965E7} {C684B76D-52EC-49CE-84F2-B031509419A5} = {FC52B7B5-744E-45D6-815C-3502F9D965E7} - {A60D658D-766C-40DB-BAFF-59AB884D86FB} = {11041D08-354A-4300-9624-41277E67DE34} {1EBC7A53-4677-4C3A-8DFF-269001F17D85} = {11041D08-354A-4300-9624-41277E67DE34} {1EBC7A53-4677-4C3A-8DFF-49DFF4417D85} = {11041D08-354A-4300-9624-41277E67DE34} {1EBC7A53-33FF-4C3A-8DFF-49D301F17D85} = {11041D08-354A-4300-9624-41277E67DE34} @@ -293,7 +295,6 @@ Global {1EBC7A53-4677-1234-DDDD-49DFF4417D85} = {11041D08-354A-4300-9624-41277E67DE34} {B4823266-DF8C-4EFB-91C0-C7E78C234EAC} = {11041D08-354A-4300-9624-41277E67DE34} {1EBC7A53-4677-4C3A-8DFF-49D301F17D85} = {11041D08-354A-4300-9624-41277E67DE34} - {A60D658D-766C-40DB-BAE4-59AB884D86FB} = {1CBEAA34-BA34-497D-A775-B9AF6F905696} {1EBC7A53-4677-ADF1-8D4A-49D301F17D85} = {1CBEAA34-BA34-497D-A775-B9AF6F905696} {1EBC7A53-4677-75D7-8D4A-49D301F17D85} = {1CBEAA34-BA34-497D-A775-B9AF6F905696} {1EBC7A53-4677-4C3A-8D4A-49D301157985} = {1CBEAA34-BA34-497D-A775-B9AF6F905696} @@ -302,7 +303,12 @@ Global {B4823266-DF8C-4EFB-91C0-C7688C234EAC} = {1CBEAA34-BA34-497D-A775-B9AF6F905696} {1EBC7A53-4677-4C3A-8D4A-49D301F17D85} = {1CBEAA34-BA34-497D-A775-B9AF6F905696} {1EBC7A53-4677-FFFF-1234-49D301F17D85} = {1CBEAA34-BA34-497D-A775-B9AF6F905696} - {389DF3C9-A628-4F6D-8C52-8924FA01DE66} = {1CBEAA34-BA34-497D-A775-B9AF6F905696} + {A60D658D-766C-40DB-BAFF-59AB884D86FB} = {B24D8E0A-2EB5-4C49-A146-C0AABEF81788} + {A60D658D-766C-40DB-BAE4-59AB884D86FB} = {B24D8E0A-2EB5-4C49-A146-C0AABEF81788} + {389DF3C9-A628-4F6D-8C52-8924FA01DE66} = {B24D8E0A-2EB5-4C49-A146-C0AABEF81788} + {2F92EC58-D94C-40BF-4444-77607C72E1E3} = {B24D8E0A-2EB5-4C49-A146-C0AABEF81788} + {E7D19356-B0AB-44AD-ACCB-5FFFCC4837BE} = {B24D8E0A-2EB5-4C49-A146-C0AABEF81788} + {0F789DF8-22CC-4392-98DB-AC3960FAD4EA} = {B24D8E0A-2EB5-4C49-A146-C0AABEF81788} EndGlobalSection GlobalSection(DevPartner) = postSolution EndGlobalSection diff --git a/iup/mak.vc9/iupcontrols.vcproj b/iup/mak.vc9/iupcontrols.vcproj index 6a452af..2a7875c 100755 --- a/iup/mak.vc9/iupcontrols.vcproj +++ b/iup/mak.vc9/iupcontrols.vcproj @@ -311,14 +311,6 @@ >   -  -  -  -     +  +   @@ -583,17 +587,6 @@ >   -  -  -  -  -     diff --git a/iup/mak.vc9/iupgtk.vcproj b/iup/mak.vc9/iupgtk.vcproj index 17281f1..a84dd4a 100755 --- a/iup/mak.vc9/iupgtk.vcproj +++ b/iup/mak.vc9/iupgtk.vcproj @@ -95,6 +95,10 @@ >   +  +   diff --git a/iup/mak.vc9/iuplua3.vcproj b/iup/mak.vc9/iuplua3.vcproj index 9993c1c..e46f316 100755 --- a/iup/mak.vc9/iuplua3.vcproj +++ b/iup/mak.vc9/iuplua3.vcproj @@ -116,6 +116,10 @@ >   +  +   @@ -164,6 +168,10 @@ >   +  +   diff --git a/iup/mak.vc9/iuplua5.vcproj b/iup/mak.vc9/iuplua5.vcproj index 17d9a55..ad13650 100755 --- a/iup/mak.vc9/iuplua5.vcproj +++ b/iup/mak.vc9/iuplua5.vcproj @@ -231,6 +231,10 @@ >   +  +   @@ -407,6 +411,10 @@ >   +  +   diff --git a/iup/mak.vc9/iupluaexe5.vcproj b/iup/mak.vc9/iupluaexe5.vcproj index db6804a..39d15f2 100755 --- a/iup/mak.vc9/iupluaexe5.vcproj +++ b/iup/mak.vc9/iupluaexe5.vcproj @@ -72,7 +72,7 @@ OutputFile="$(OutDir)/iuplua51.exe" LinkIncremental="1" SuppressStartupBanner="true" - AdditionalLibraryDirectories="..\..\im\lib;..\..\cd\lib;..\lib;..\..\lua5.1\lib\vc9;..\..\luagl\lib\static" + AdditionalLibraryDirectories="..\..\im\lib;..\..\cd\lib;..\lib;..\..\lua5.1\lib\vc9;..\..\luagl\lib\static;..\..\lfs\lib\vc9" GenerateManifest="false" GenerateDebugInformation="true" SubSystem="1" diff --git a/iup/mak.vc9/iupmot.vcproj b/iup/mak.vc9/iupmot.vcproj index 9bbfa5c..5c40695 100755 --- a/iup/mak.vc9/iupmot.vcproj +++ b/iup/mak.vc9/iupmot.vcproj @@ -109,6 +109,10 @@ >   +  +   diff --git a/iup/mak.vc9/iupsample.vcproj b/iup/mak.vc9/iupsample.vcproj index 144f3ba..0e10bb6 100755 --- a/iup/mak.vc9/iupsample.vcproj +++ b/iup/mak.vc9/iupsample.vcproj @@ -45,7 +45,7 @@ Optimization="0" AdditionalIncludeDirectories="..\include;..\..\cd\include" PreprocessorDefinitions="WIN32;_DEBUG;_WIN32_WINNT=0x0500;_WIN32_IE=0x0500;_CRT_SECURE_NO_DEPRECATE;__IUPDEF_H" - ExceptionHandling="0" + ExceptionHandling="1" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" diff --git a/iup/mak.vc9/iupsamplegtk.vcproj b/iup/mak.vc9/iupsamplegtk.vcproj index 24da672..485b773 100755 --- a/iup/mak.vc9/iupsamplegtk.vcproj +++ b/iup/mak.vc9/iupsamplegtk.vcproj @@ -617,7 +617,6 @@ >       +  +   diff --git a/iup/mak.vc9/iuptestgtk.vcproj b/iup/mak.vc9/iuptestgtk.vcproj index 4cbc9da..d8c092c 100755 --- a/iup/mak.vc9/iuptestgtk.vcproj +++ b/iup/mak.vc9/iuptestgtk.vcproj @@ -73,6 +73,7 @@ LinkIncremental="1" SuppressStartupBanner="true" AdditionalLibraryDirectories="..\lib;d:\lng\gtk\lib;..\..\cd\lib;D:\LNG\vld\lib" + GenerateManifest="false" GenerateDebugInformation="true" ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb" SubSystem="1" @@ -262,6 +263,10 @@ >   +  +   diff --git a/iup/mak.vc9/iupwin.vcproj b/iup/mak.vc9/iupwin.vcproj index 15578a9..94ef390 100755 --- a/iup/mak.vc9/iupwin.vcproj +++ b/iup/mak.vc9/iupwin.vcproj @@ -248,6 +248,10 @@ >   +  +     diff --git a/iup/src/Makefile b/iup/src/Makefile index 028047f..e666555 100755 --- a/iup/src/Makefile +++ b/iup/src/Makefile @@ -1,9 +1,12 @@  -.PHONY: do_all iup iupgtk -do_all: iup iupgtk +.PHONY: do_all iup iupgtk iupmot +do_all: iup  iup: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak   iupgtk: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak USE_GTK=Yes + @$(MAKE) --no-print-directory -f ../tecmake.mak USE_GTK=Yes + +iupmot: + @$(MAKE) --no-print-directory -f ../tecmake.mak USE_MOTIF=Yes diff --git a/iup/src/config.mak b/iup/src/config.mak index e857643..82b8452 100755 --- a/iup/src/config.mak +++ b/iup/src/config.mak @@ -2,9 +2,31 @@ PROJNAME = iup LIBNAME = iup OPT = YES  -#ifdef DBG +ifdef GTK_DEFAULT + ifdef USE_MOTIF + # Build Motif version in Linux,Darwin,FreeBSD + LIBNAME = iupmot + else + ifeq ($(findstring Win, $(TEC_SYSNAME)), ) + # Force definition if not in Windows + USE_GTK = Yes + endif + endif +else  + ifdef USE_GTK + # Build GTK version in IRIX,SunOS,AIX,Win32 + LIBNAME = iupgtk + else + ifeq ($(findstring Win, $(TEC_SYSNAME)), ) + # Force definition if not in Windows + USE_MOTIF = Yes + endif + endif +endif + +ifdef DBG DEFINES += IUP_ASSERT -#endif  +endif   INCLUDES = ../include .  @@ -17,19 +39,14 @@ SRC = iup_array.c iup_callback.c iup_dlglist.c iup_attrib.c iup_focus.c iup_font iup_user.c iup_button.c iup_radio.c iup_toggle.c iup_progressbar.c iup_text.c iup_val.c \ iup_box.c iup_hbox.c iup_vbox.c iup_cbox.c iup_class.c iup_classbase.c iup_maskmatch.c \ iup_mask.c iup_maskparse.c iup_tabs.c iup_spin.c iup_list.c iup_getparam.c \ - iup_sbox.c iup_normalizer.c iup_tree.c + iup_sbox.c iup_normalizer.c iup_tree.c iup_split.c  ifdef USE_GTK - ifndef GTK_DEFAULT - # Build GTK version in IRIX,SunOS,AIX,Win32 - LIBNAME := iupgtk - endif - DEFINES += GTK_DISABLE_DEPRECATED INCLUDES += gtk SRC += gtk/iupgtk_common.c gtk/iupgtk_focus.c gtk/iupgtk_font.c gtk/iupgtk_clipboard.c \ gtk/iupgtk_globalattrib.c gtk/iupgtk_key.c gtk/iupgtk_tips.c \ - gtk/iupgtk_loop.c gtk/iupgtk_open.c gtk/iupgtk_messagedlg.c \ + gtk/iupgtk_loop.c gtk/iupgtk_open.c gtk/iupgtk_messagedlg.c gtk/iupgtk_draw.c \ gtk/iupgtk_dialog.c gtk/iupgtk_timer.c gtk/iupgtk_image.c gtk/iupgtk_label.c \ gtk/iupgtk_colordlg.c gtk/iupgtk_fontdlg.c gtk/iupgtk_filedlg.c \ gtk/iupgtk_button.c gtk/iupgtk_toggle.c gtk/iupgtk_progressbar.c \ @@ -40,7 +57,11 @@ ifdef USE_GTK DEFINES += _WIN32_WINNT=0x0500 _WIN32_IE=0x0500 WINVER=0x0500 NOTREEVIEW SRC += win/iupwindows_main.c win/iupwindows_help.c win/iupwindows_info.c else - SRC += gtk/iupgtk_help.c mot/iupunix_info.c + ifdef GTK_MAC + SRC += gtk/iupmac_help.c gtk/iupmac_info.c + else + SRC += gtk/iupgtk_help.c mot/iupunix_info.c + endif endif  ifdef USE_HILDON @@ -49,42 +70,35 @@ ifdef USE_GTK LIBS += hildon-1 endif else - ifneq ($(findstring Win, $(TEC_SYSNAME)), ) -  - SRC += win/iupwin_common.c win/iupwin_brush.c win/iupwin_focus.c win/iupwin_font.c \ - win/iupwin_globalattrib.c win/iupwin_handle.c win/iupwin_key.c \ - win/iupwin_loop.c win/iupwin_open.c win/iupwin_tips.c win/iupwin_info.c \ - win/iupwin_dialog.c win/iupwin_messagedlg.c win/iupwin_timer.c \ - win/iupwin_image.c win/iupwin_label.c win/iupwin_canvas.c win/iupwin_frame.c \ - win/iupwin_colordlg.c win/iupwin_fontdlg.c win/iupwin_filedlg.c \ - win/iupwin_button.c win/iupwin_draw.c win/iupwin_toggle.c win/iupwin_clipboard.c \ - win/iupwin_progressbar.c win/iupwin_text.c win/iupwin_val.c \ - win/iupwin_tabs.c win/iupwin_menu.c win/iupwin_list.c win/iupwin_tree.c -  - SRC += win/iupwindows_main.c win/iupwindows_help.c win/iupwindows_info.c -  - INCLUDES += win - DEFINES += _WIN32_WINNT=0x0500 _WIN32_IE=0x0500 WINVER=0x0500 NOTREEVIEW - else - ifdef GTK_DEFAULT - # Build Motif version in Linux,Darwin,FreeBSD - LIBNAME := iupmot - endif  -  - SRC += mot/iupmot_common.c mot/iupmot_color.c mot/iupmot_focus.c mot/iupmot_font.c \ - mot/iupmot_key.c mot/iupmot_loop.c mot/iupmot_open.c mot/iupmot_tips.c \ - mot/iupmot_globalattrib.c mot/iupmot_dialog.c mot/iupmot_messagedlg.c \ - mot/iupmot_timer.c mot/iupmot_image.c mot/iupmot_label.c mot/iupmot_canvas.c \ - mot/iupmot_colordlg.c mot/iupmot_fontdlg.c mot/iupmot_filedlg.c mot/iupmot_frame.c \ - mot/iupmot_button.c mot/iupmot_toggle.c mot/iupmot_progressbar.c mot/iupmot_clipboard.c \ - mot/iupmot_text.c mot/iupmot_val.c mot/iupmot_tabs.c mot/iupmot_menu.c \ - mot/iupmot_list.c mot/iupmot_tree.c -  - SRC += mot/iupunix_help.c mot/iupunix_info.c -  - INCLUDES += mot - USE_MOTIF=Yes  - endif +ifdef USE_MOTIF + SRC += mot/iupmot_common.c mot/iupmot_color.c mot/iupmot_focus.c mot/iupmot_font.c \ + mot/iupmot_key.c mot/iupmot_loop.c mot/iupmot_open.c mot/iupmot_tips.c \ + mot/iupmot_globalattrib.c mot/iupmot_dialog.c mot/iupmot_messagedlg.c mot/iupmot_draw.c \ + mot/iupmot_timer.c mot/iupmot_image.c mot/iupmot_label.c mot/iupmot_canvas.c \ + mot/iupmot_colordlg.c mot/iupmot_fontdlg.c mot/iupmot_filedlg.c mot/iupmot_frame.c \ + mot/iupmot_button.c mot/iupmot_toggle.c mot/iupmot_progressbar.c mot/iupmot_clipboard.c \ + mot/iupmot_text.c mot/iupmot_val.c mot/iupmot_tabs.c mot/iupmot_menu.c \ + mot/iupmot_list.c mot/iupmot_tree.c +  + SRC += mot/iupunix_help.c mot/iupunix_info.c + + INCLUDES += mot +else + SRC += win/iupwin_common.c win/iupwin_brush.c win/iupwin_focus.c win/iupwin_font.c \ + win/iupwin_globalattrib.c win/iupwin_handle.c win/iupwin_key.c \ + win/iupwin_loop.c win/iupwin_open.c win/iupwin_tips.c win/iupwin_info.c \ + win/iupwin_dialog.c win/iupwin_messagedlg.c win/iupwin_timer.c \ + win/iupwin_image.c win/iupwin_label.c win/iupwin_canvas.c win/iupwin_frame.c \ + win/iupwin_colordlg.c win/iupwin_fontdlg.c win/iupwin_filedlg.c \ + win/iupwin_button.c win/iupwin_draw.c win/iupwin_toggle.c win/iupwin_clipboard.c \ + win/iupwin_progressbar.c win/iupwin_text.c win/iupwin_val.c \ + win/iupwin_tabs.c win/iupwin_menu.c win/iupwin_list.c win/iupwin_tree.c +  + SRC += win/iupwindows_main.c win/iupwindows_help.c win/iupwindows_info.c + + INCLUDES += win + DEFINES += _WIN32_WINNT=0x0500 _WIN32_IE=0x0500 WINVER=0x0500 NOTREEVIEW +endif endif  ifeq "$(TEC_SYSNAME)" "SunOS" @@ -113,6 +127,6 @@ ifeq "$(TEC_UNAME)" "dll" endif  ifeq "$(TEC_UNAME)" "owc1" - # Necessary or IUP will not work in Open Watcom + # Necessary or IUP 3 will not work in Open Watcom DBG=Yes endif diff --git a/iup/src/gtk/iupgtk_button.c b/iup/src/gtk/iupgtk_button.c index 18be87c..f8474ae 100755 --- a/iup/src/gtk/iupgtk_button.c +++ b/iup/src/gtk/iupgtk_button.c @@ -150,8 +150,10 @@ static int gtkButtonSetPaddingAttrib(Ihandle* ih, const char* value) gtk_alignment_set_padding(alignment, ih->data->vert_padding, ih->data->vert_padding,  ih->data->horiz_padding, ih->data->horiz_padding); } + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  #ifdef WIN32 @@ -366,12 +368,12 @@ static int gtkButtonMapMethod(Ihandle* ih) ih->data->type = IUP_BUTTON_IMAGE;  value = iupAttribGet(ih, "TITLE"); - if (value) + if (value && *value!=0) { GtkSettings* settings = gtk_widget_get_settings(ih->handle); g_object_set(settings, "gtk-button-images", (int)TRUE, NULL);  - gtk_button_set_label((GtkButton*)ih->handle, value); + gtk_button_set_label((GtkButton*)ih->handle, iupgtkStrConvertToUTF8(value)); ih->data->type |= IUP_BUTTON_TEXT;  #if GTK_CHECK_VERSION(2, 10, 0) @@ -397,7 +399,7 @@ static int gtkButtonMapMethod(Ihandle* ih) #endif } else - gtk_button_set_label((GtkButton*)ih->handle, title); + gtk_button_set_label((GtkButton*)ih->handle, iupgtkStrConvertToUTF8(title)); ih->data->type = IUP_BUTTON_TEXT; }  diff --git a/iup/src/gtk/iupgtk_canvas.c b/iup/src/gtk/iupgtk_canvas.c index daae4ad..3af48a4 100755 --- a/iup/src/gtk/iupgtk_canvas.c +++ b/iup/src/gtk/iupgtk_canvas.c @@ -537,8 +537,8 @@ static int gtkCanvasMapMethod(Ihandle* ih)  /* To receive mouse events on a drawing area, you will need to enable them. */ gtk_widget_add_events(ih->handle, GDK_EXPOSURE_MASK| - GDK_POINTER_MOTION_MASK|GDK_BUTTON_MOTION_MASK| - GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK| + GDK_POINTER_MOTION_MASK|GDK_POINTER_MOTION_HINT_MASK| + GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_MOTION_MASK| GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK| GDK_ENTER_NOTIFY_MASK|GDK_LEAVE_NOTIFY_MASK| GDK_FOCUS_CHANGE_MASK|GDK_STRUCTURE_MASK); @@ -611,14 +611,15 @@ void iupdrvCanvasInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "YAUTOHIDE", NULL, gtkCanvasSetYAutoHideAttrib, "YES", NULL, IUPAF_DEFAULT); /* force new default value */  iupClassRegisterAttribute(ic, "DRAWABLE", gtkCanvasGetDrawableAttrib, NULL, NULL, NULL, IUPAF_NO_STRING); - //iupClassRegisterAttribute(ic, "CD_GDK", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT);  /* IupCanvas Windows or X only */ -#ifdef WIN32  - iupClassRegisterAttribute(ic, "HWND", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_STRING|IUPAF_NO_INHERIT); -#else - iupClassRegisterAttribute(ic, "XWINDOW", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_INHERIT|IUPAF_NO_STRING); - iupClassRegisterAttribute(ic, "XDISPLAY", (IattribGetFunc)iupdrvGetDisplay, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT|IUPAF_NO_STRING); +#ifndef GTK_MAC + #ifdef WIN32  + iupClassRegisterAttribute(ic, "HWND", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_STRING|IUPAF_NO_INHERIT); + #else + iupClassRegisterAttribute(ic, "XWINDOW", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_INHERIT|IUPAF_NO_STRING); + iupClassRegisterAttribute(ic, "XDISPLAY", (IattribGetFunc)iupdrvGetDisplay, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT|IUPAF_NO_STRING); + #endif #endif }  diff --git a/iup/src/gtk/iupgtk_common.c b/iup/src/gtk/iupgtk_common.c index 40368f2..d84c1c8 100755 --- a/iup/src/gtk/iupgtk_common.c +++ b/iup/src/gtk/iupgtk_common.c @@ -91,13 +91,13 @@ void iupdrvBaseUnMapMethod(Ihandle* ih) gtk_widget_destroy(widget); /* To match the call to gtk_*****_new */ }  -void iupdrvDisplayUpdate(Ihandle *ih) +void iupdrvPostRedraw(Ihandle *ih) { /* Post a REDRAW */ gtk_widget_queue_draw(ih->handle); }  -void iupdrvDisplayRedraw(Ihandle *ih) +void iupdrvRedrawNow(Ihandle *ih) { GdkWindow* window = ih->handle->window; /* Post a REDRAW */ @@ -202,7 +202,11 @@ void iupdrvSetVisible(Ihandle* ih, int visible)  int iupdrvIsVisible(Ihandle* ih) { +#if GTK_CHECK_VERSION(2, 18, 0) + if (gtk_widget_get_visible(ih->handle)) +#else if (GTK_WIDGET_VISIBLE(ih->handle)) +#endif { /* if marked as visible, since we use gtk_widget_hide and NOT gtk_widget_hide_all must check its parents. */ @@ -211,7 +215,11 @@ int iupdrvIsVisible(Ihandle* ih) { if (parent->iclass->nativetype != IUP_TYPEVOID) { +#if GTK_CHECK_VERSION(2, 18, 0) + if (!gtk_widget_get_visible(parent->handle)) +#else if (!GTK_WIDGET_VISIBLE(parent->handle)) +#endif return 0; }  @@ -225,7 +233,11 @@ int iupdrvIsVisible(Ihandle* ih)  int iupdrvIsActive(Ihandle *ih) { - return (GTK_WIDGET_IS_SENSITIVE(ih->handle)); +#if GTK_CHECK_VERSION(2, 18, 0) + return gtk_widget_is_sensitive(ih->handle); +#else + return GTK_WIDGET_IS_SENSITIVE(ih->handle); +#endif }  void iupdrvSetActive(Ihandle* ih, int enable) @@ -424,9 +436,11 @@ static GdkCursor* gtkGetCursor(Ihandle* ih, const char* name) { "RESIZE_N", GDK_TOP_SIDE}, { "RESIZE_S", GDK_BOTTOM_SIDE}, { "RESIZE_NS", GDK_SB_V_DOUBLE_ARROW}, + { "SPLITTER_HORIZ", GDK_SB_V_DOUBLE_ARROW}, { "RESIZE_W", GDK_LEFT_SIDE}, { "RESIZE_E", GDK_RIGHT_SIDE}, { "RESIZE_WE", GDK_SB_H_DOUBLE_ARROW}, + { "SPLITTER_VERT", GDK_SB_H_DOUBLE_ARROW}, { "RESIZE_NE", GDK_TOP_RIGHT_CORNER}, { "RESIZE_SE", GDK_BOTTOM_RIGHT_CORNER}, { "RESIZE_NW", GDK_TOP_LEFT_CORNER}, @@ -571,18 +585,24 @@ void iupdrvDrawFocusRect(Ihandle* ih, void* _gc, int x, int y, int w, int h) { GdkWindow* window = ih->handle->window; GtkStyle *style = gtk_widget_get_style(ih->handle); +#if GTK_CHECK_VERSION(2, 18, 0) + GtkStateType state = gtk_widget_get_state(ih->handle); +#else + GtkStateType state = GTK_WIDGET_STATE(ih->handle); +#endif + gtk_paint_focus(style, window, state, NULL, ih->handle, NULL, x, y, w, h); (void)_gc; - - gtk_paint_focus(style, window, GTK_WIDGET_STATE(ih->handle), NULL, ih->handle, NULL, x, y, w, h); }  void iupdrvBaseRegisterCommonAttrib(Iclass* ic) { +#ifndef GTK_MAC #ifdef WIN32  iupClassRegisterAttribute(ic, "HFONT", iupgtkGetFontIdAttrib, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT|IUPAF_NO_STRING); #else iupClassRegisterAttribute(ic, "XFONTID", iupgtkGetFontIdAttrib, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT|IUPAF_NO_STRING); #endif +#endif iupClassRegisterAttribute(ic, "PANGOFONTDESC", iupgtkGetPangoFontDescAttrib, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT|IUPAF_NO_STRING); }  @@ -789,7 +809,17 @@ char* iupgtkStrConvertFromFilename(const char* str) /* From Filename to IUP */  gboolean iupgtkMotionNotifyEvent(GtkWidget *widget, GdkEventMotion *evt, Ihandle *ih) { - IFniis cb = (IFniis)IupGetCallback(ih,"MOTION_CB"); + IFniis cb; + + if (evt->is_hint) + { + int x, y; + gdk_window_get_pointer(widget->window, &x, &y, NULL); + evt->x = x; + evt->y = y; + } + + cb = (IFniis)IupGetCallback(ih,"MOTION_CB"); if (cb) { char status[IUPKEY_STATUS_SIZE] = IUPKEY_STATUS_INIT; @@ -818,6 +848,23 @@ gboolean iupgtkButtonEvent(GtkWidget *widget, GdkEventButton *evt, Ihandle *ih)  iupgtkButtonKeySetStatus(evt->state, evt->button, status, doubleclick);  + if (doubleclick) + { + /* Must compensate the fact that in GTK there is an extra button press event  + when occours a double click, we compensate that completing the event  + with a button release before the double click. */ + + status[5] = ' '; /* clear double click */ + + ret = cb(ih, b, 0, (int)evt->x, (int)evt->y, status); /* release */ + if (ret==IUP_CLOSE) + IupExitLoop(); + else if (ret==IUP_IGNORE) + return TRUE; + + status[5] = 'D'; /* restore double click */ + } + ret = cb(ih, b, press, (int)evt->x, (int)evt->y, status); if (ret==IUP_CLOSE) IupExitLoop(); diff --git a/iup/src/gtk/iupgtk_dialog.c b/iup/src/gtk/iupgtk_dialog.c index 46c0ce1..ff0d8f2 100755 --- a/iup/src/gtk/iupgtk_dialog.c +++ b/iup/src/gtk/iupgtk_dialog.c @@ -120,12 +120,13 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu static int native_border = 0; static int native_caption = 0;  - int has_caption = iupAttribGetBoolean(ih, "MAXBOX") || - iupAttribGetBoolean(ih, "MINBOX") || - iupAttribGetBoolean(ih, "MENUBOX") ||  - IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */ + int has_titlebar = iupAttribGetBoolean(ih, "RESIZE") || /* GTK and Motif only */ + iupAttribGetBoolean(ih, "MAXBOX") || + iupAttribGetBoolean(ih, "MINBOX") || + iupAttribGetBoolean(ih, "MENUBOX") ||  + IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */  - int has_border = has_caption || + int has_border = has_titlebar || iupAttribGetBoolean(ih, "RESIZE") || iupAttribGetBoolean(ih, "BORDER");  @@ -147,7 +148,7 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu *border = win_border;  *caption = 0; - if (has_caption) + if (has_titlebar) *caption = win_caption;  if (!native_border && *border) @@ -171,7 +172,7 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu }  *caption = 0; - if (has_caption) + if (has_titlebar) { if (native_caption) *caption = native_caption; @@ -429,6 +430,7 @@ static int gtkDialogMapMethod(Ihandle* ih) int functions = 0; InativeHandle* parent; GtkWidget* fixed; + int has_titlebar = 0;  #ifdef HILDON if (iupAttribGetBoolean(ih, "HILDONWINDOW"))  @@ -494,33 +496,41 @@ static int gtkDialogMapMethod(Ihandle* ih) iupAttribSetStr(ih, "MINBOX", "NO"); }  - if (IupGetAttribute(ih, "TITLE")) { /* must use IupGetAttribute to check from the native implementation */ - functions |= GDK_FUNC_MOVE; - decorations |= GDK_DECOR_TITLE; - } - - if (iupAttribGetBoolean(ih, "MENUBOX")) { + if (iupAttribGet(ih, "TITLE")) + has_titlebar = 1; + if (iupAttribGetBoolean(ih, "MENUBOX"))  + { functions |= GDK_FUNC_CLOSE; decorations |= GDK_DECOR_MENU; + has_titlebar = 1; } - - if (iupAttribGetBoolean(ih, "MINBOX")) { + if (iupAttribGetBoolean(ih, "MINBOX"))  + { functions |= GDK_FUNC_MINIMIZE; decorations |= GDK_DECOR_MINIMIZE; + has_titlebar = 1; } - - if (iupAttribGetBoolean(ih, "MAXBOX")) { + if (iupAttribGetBoolean(ih, "MAXBOX"))  + { functions |= GDK_FUNC_MAXIMIZE; decorations |= GDK_DECOR_MAXIMIZE; + has_titlebar = 1; } - - if (iupAttribGetBoolean(ih, "RESIZE")) { + if (iupAttribGetBoolean(ih, "RESIZE"))  + { functions |= GDK_FUNC_RESIZE; decorations |= GDK_DECOR_RESIZEH; - }  - if (iupAttribGetBoolean(ih, "BORDER")) - decorations |= GDK_DECOR_BORDER; + decorations |= GDK_DECOR_BORDER; /* has_border */ + } + if (has_titlebar) + { + functions |= GDK_FUNC_MOVE; + decorations |= GDK_DECOR_TITLE; + gtk_window_set_title((GtkWindow*)ih->handle, ""); + } + if (iupAttribGetBoolean(ih, "BORDER") || has_titlebar) + decorations |= GDK_DECOR_BORDER; /* has_border */  if (decorations == 0) gtk_window_set_decorated((GtkWindow*)ih->handle, FALSE); @@ -980,11 +990,12 @@ void iupdrvDialogInitClass(Iclass* ic) iupClassRegisterCallback(ic, "TRAYCLICK_CB", "iii");  /* Driver Dependent Attribute functions */ - -#ifdef WIN32  - iupClassRegisterAttribute(ic, "HWND", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_STRING|IUPAF_NO_INHERIT); -#else - iupClassRegisterAttribute(ic, "XWINDOW", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_INHERIT|IUPAF_NO_STRING); +#ifndef GTK_MAC + #ifdef WIN32  + iupClassRegisterAttribute(ic, "HWND", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_STRING|IUPAF_NO_INHERIT); + #else + iupClassRegisterAttribute(ic, "XWINDOW", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_INHERIT|IUPAF_NO_STRING); + #endif #endif  /* Visual */ diff --git a/iup/src/gtk/iupgtk_drv.h b/iup/src/gtk/iupgtk_drv.h index ade2a4a..bf567d6 100755 --- a/iup/src/gtk/iupgtk_drv.h +++ b/iup/src/gtk/iupgtk_drv.h @@ -59,8 +59,8 @@ void iupgtkFontUpdateObjectPangoLayout(Ihandle* ih, gpointer object); /* There are PANGO_SCALE Pango units in one device unit.  For an output backend where a device unit is a pixel,  a size value of 10 * PANGO_SCALE gives 10 pixels. */ -#define IUPGTK_PANGOUNITS2PIXELS(_x) (((_x) + PANGO_SCALE/2) / PANGO_SCALE) -#define IUPGTK_PIXELS2PANGOUNITS(_x) ((_x) * PANGO_SCALE) +#define iupGTK_PANGOUNITS2PIXELS(_x) (((_x) + PANGO_SCALE/2) / PANGO_SCALE) +#define iupGTK_PIXELS2PANGOUNITS(_x) ((_x) * PANGO_SCALE)   /* open */ diff --git a/iup/src/gtk/iupgtk_filedlg.c b/iup/src/gtk/iupgtk_filedlg.c index 5426910..a326c72 100755 --- a/iup/src/gtk/iupgtk_filedlg.c +++ b/iup/src/gtk/iupgtk_filedlg.c @@ -77,6 +77,8 @@ static void gtkFileDlgGetMultipleFiles(Ihandle* ih, GSList* list) cur_len = iupArrayCount(names_array); all_names = iupArrayAdd(names_array, dir_len+1); memcpy(all_names+cur_len, filename, dir_len); + all_names[cur_len+dir_len] = '0'; + iupAttribStoreStr(ih, "DIRECTORY", all_names); all_names[cur_len+dir_len] = '|';  dir_len++; /* skip separator */ @@ -101,10 +103,14 @@ static void gtkFileDlgGetMultipleFiles(Ihandle* ih, GSList* list) iupArrayDestroy(names_array); }  -#ifdef WIN32 -#include  +#ifdef GTK_MAC + #include  #else -#include  + #ifdef WIN32 + #include  + #else + #include  + #endif #endif  static void gtkFileDlgUpdatePreviewGLCanvas(Ihandle* ih) @@ -112,10 +118,12 @@ static void gtkFileDlgUpdatePreviewGLCanvas(Ihandle* ih) Ihandle* glcanvas = IupGetAttributeHandle(ih, "PREVIEWGLCANVAS"); if (glcanvas) { -#ifdef WIN32  - iupAttribSetStr(glcanvas, "HWND", iupAttribGet(ih, "HWND")); -#else - iupAttribSetStr(glcanvas, "XWINDOW", iupAttribGet(ih, "XWINDOW")); +#ifndef GTK_MAC + #ifdef WIN32  + iupAttribSetStr(glcanvas, "HWND", iupAttribGet(ih, "HWND")); + #else + iupAttribSetStr(glcanvas, "XWINDOW", iupAttribGet(ih, "XWINDOW")); + #endif #endif glcanvas->iclass->Map(glcanvas); } @@ -126,12 +134,15 @@ static void gtkFileDlgPreviewRealize(GtkWidget *widget, Ihandle *ih) iupAttribSetStr(ih, "PREVIEWDC", iupgtkGetNativeGraphicsContext(widget)); iupAttribSetStr(ih, "WID", (char*)widget);  -#ifdef WIN32  - iupAttribSetStr(ih, "HWND", (char*)GDK_WINDOW_HWND(widget->window)); -#else - iupAttribSetStr(ih, "XWINDOW", (char*)GDK_WINDOW_XID(widget->window)); - iupAttribSetStr(ih, "XDISPLAY", (char*)iupdrvGetDisplay()); +#ifndef GTK_MAC + #ifdef WIN32  + iupAttribSetStr(ih, "HWND", (char*)GDK_WINDOW_HWND(widget->window)); + #else + iupAttribSetStr(ih, "XWINDOW", (char*)GDK_WINDOW_XID(widget->window)); + iupAttribSetStr(ih, "XDISPLAY", (char*)iupdrvGetDisplay()); + #endif #endif + gtkFileDlgUpdatePreviewGLCanvas(ih); }  @@ -174,11 +185,11 @@ static void gtkFileDlgUpdatePreview(GtkFileChooser *file_chooser, Ihandle* ih) { char *filename = gtk_file_chooser_get_preview_filename(file_chooser);  + IFnss cb = (IFnss)IupGetCallback(ih, "FILE_CB"); if (iupdrvIsFile(filename)) - { - IFnss cb = (IFnss)IupGetCallback(ih, "FILE_CB"); cb(ih, iupgtkStrConvertFromFilename(filename), "SELECT"); - } + else + cb(ih, iupgtkStrConvertFromFilename(filename), "OTHER");  g_free (filename);  @@ -469,6 +480,13 @@ static int gtkFileDlgPopup(Ihandle* ih, int x, int y) char* filename = (char*)file_list->data; iupAttribStoreStr(ih, "VALUE", iupgtkStrConvertFromFilename(filename)); g_free(filename); + + /* store the DIRECTORY */ + { + char* dir = iupStrFileGetPath(iupAttribGet(ih, "VALUE")); + iupAttribStoreStr(ih, "DIRECTORY", dir); + free(dir); + } }  g_slist_free(file_list); @@ -481,6 +499,14 @@ static int gtkFileDlgPopup(Ihandle* ih, int x, int y) iupAttribStoreStr(ih, "VALUE", iupgtkStrConvertFromFilename(filename)); file_exist = iupdrvIsFile(filename); dir_exist = iupdrvIsDirectory(filename); + + if (file_exist) + { + char* dir = iupStrFileGetPath(filename); + iupAttribStoreStr(ih, "DIRECTORY", dir); + free(dir); + } + g_free(filename); }  @@ -507,8 +533,11 @@ static int gtkFileDlgPopup(Ihandle* ih, int x, int y) { /* GtkFileChooser does not change the current directory */ char* dir = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); - if (dir) iupdrvSetCurrentDirectory(dir); - g_free(dir); + if (dir)  + { + iupdrvSetCurrentDirectory(dir); + g_free(dir); + } } } else diff --git a/iup/src/gtk/iupgtk_font.c b/iup/src/gtk/iupgtk_font.c index f7ff348..1139f62 100755 --- a/iup/src/gtk/iupgtk_font.c +++ b/iup/src/gtk/iupgtk_font.c @@ -132,9 +132,9 @@ static IgtkFont* gtkFindFont(const char *standardfont)  metrics = pango_context_get_metrics(gtk_fonts_context, fontdesc, pango_context_get_language(gtk_fonts_context)); fonts[i].charheight = pango_font_metrics_get_ascent(metrics) + pango_font_metrics_get_descent(metrics); - fonts[i].charheight = IUPGTK_PANGOUNITS2PIXELS(fonts[i].charheight); + fonts[i].charheight = iupGTK_PANGOUNITS2PIXELS(fonts[i].charheight); fonts[i].charwidth = pango_font_metrics_get_approximate_char_width(metrics); - fonts[i].charwidth = IUPGTK_PANGOUNITS2PIXELS(fonts[i].charwidth); + fonts[i].charwidth = iupGTK_PANGOUNITS2PIXELS(fonts[i].charwidth); pango_font_metrics_unref(metrics);   gtkFontUpdate(&(fonts[i])); diff --git a/iup/src/gtk/iupgtk_fontdlg.c b/iup/src/gtk/iupgtk_fontdlg.c index 5769cbc..dca0232 100755 --- a/iup/src/gtk/iupgtk_fontdlg.c +++ b/iup/src/gtk/iupgtk_fontdlg.c @@ -24,7 +24,7 @@ static int gtkFontDlgPopup(Ihandle* ih, int x, int y) InativeHandle* parent = iupDialogGetNativeParent(ih); GtkFontSelectionDialog* dialog; int response; - char* preview_text; + char* preview_text, *standardfont;  iupAttribSetInt(ih, "_IUPDLG_X", x); /* used in iupDialogUpdatePosition */ iupAttribSetInt(ih, "_IUPDLG_Y", y); @@ -36,7 +36,10 @@ static int gtkFontDlgPopup(Ihandle* ih, int x, int y) if (parent) gtk_window_set_transient_for((GtkWindow*)dialog, (GtkWindow*)parent);  - gtk_font_selection_dialog_set_font_name(dialog, iupAttribGet(ih, "VALUE")); + standardfont = iupAttribGet(ih, "VALUE"); + if (!standardfont) + standardfont = IupGetGlobal("DEFAULTFONT"); + gtk_font_selection_dialog_set_font_name(dialog, standardfont);  preview_text = iupAttribGet(ih, "PREVIEWTEXT"); if (preview_text) diff --git a/iup/src/gtk/iupgtk_frame.c b/iup/src/gtk/iupgtk_frame.c index 022c6c7..25595be 100755 --- a/iup/src/gtk/iupgtk_frame.c +++ b/iup/src/gtk/iupgtk_frame.c @@ -41,8 +41,11 @@ static char* gtkFrameGetTitleAttrib(Ihandle* ih)  static int gtkFrameSetTitleAttrib(Ihandle* ih, const char* value) { - GtkFrame* frame = (GtkFrame*)ih->handle; - gtk_frame_set_label(frame, iupgtkStrConvertToUTF8(value)); + if (iupAttribGetStr(ih, "_IUPFRAME_HAS_TITLE")) + { + GtkFrame* frame = (GtkFrame*)ih->handle; + gtk_frame_set_label(frame, iupgtkStrConvertToUTF8(value)); + } return 0; }  @@ -57,7 +60,11 @@ static int gtkFrameSetBgColorAttrib(Ihandle* ih, const char* value) if (label) iupgtkBaseSetBgColor(label, r, g, b);  - iupgtkBaseSetBgColor(ih->handle, r, g, b); + if (iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR")) + { + GtkWidget* fixed = gtk_bin_get_child((GtkBin*)ih->handle); + iupgtkBaseSetBgColor(fixed, r, g, b); + }  return 1; } @@ -120,10 +127,19 @@ static int gtkFrameMapMethod(Ihandle* ih) gtk_frame_set_shadow_type((GtkFrame*)ih->handle, GTK_SHADOW_IN); else gtk_frame_set_shadow_type((GtkFrame*)ih->handle, GTK_SHADOW_ETCHED_IN); + + if (iupAttribGet(ih, "BGCOLOR")) + iupAttribSetStr(ih, "_IUPFRAME_HAS_BGCOLOR", "1"); }  /* the container that will receive the child element. */ fixed = gtk_fixed_new(); + if (iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR")) +#if GTK_CHECK_VERSION(2, 18, 0) + gtk_widget_set_has_window(fixed, TRUE); +#else + gtk_fixed_set_has_window((GtkFixed*)fixed, TRUE); +#endif gtk_container_add((GtkContainer*)ih->handle, fixed); gtk_widget_show(fixed);  diff --git a/iup/src/gtk/iupgtk_key.c b/iup/src/gtk/iupgtk_key.c index 5aec919..ed485a7 100755 --- a/iup/src/gtk/iupgtk_key.c +++ b/iup/src/gtk/iupgtk_key.c @@ -316,9 +316,9 @@ gboolean iupgtkKeyPressEvent(GtkWidget *widget, GdkEventKey *evt, Ihandle *ih) if (code == 0)  return FALSE;  - /* Avoid duplicate calls if a child of the dialog contains the focus. - GTK will call the callback for the child and for the dialog */ - if (ih->iclass->nativetype == IUP_TYPEDIALOG && ih != IupGetFocus()) + /* Avoid duplicate calls if a child of a native container contains the focus. + GTK will call the callback for the child and for the container. */ + if (ih->iclass->childtype != IUP_CHILDNONE && ih != IupGetFocus()) return FALSE;  result = iupKeyCallKeyCb(ih, code); @@ -390,33 +390,33 @@ gboolean iupgtkKeyReleaseEvent(GtkWidget *widget, GdkEventKey *evt, Ihandle *ih) void iupgtkButtonKeySetStatus(guint state, unsigned int but, char* status, int doubleclick) { if (state & GDK_SHIFT_MASK) - iupKEYSETSHIFT(status); + iupKEY_SETSHIFT(status);  if (state & GDK_CONTROL_MASK) - iupKEYSETCONTROL(status);  + iupKEY_SETCONTROL(status);   if ((state & GDK_BUTTON1_MASK) || but==1) - iupKEYSETBUTTON1(status); + iupKEY_SETBUTTON1(status);  if ((state & GDK_BUTTON2_MASK) || but==2) - iupKEYSETBUTTON2(status); + iupKEY_SETBUTTON2(status);  if ((state & GDK_BUTTON3_MASK) || but==3) - iupKEYSETBUTTON3(status); + iupKEY_SETBUTTON3(status);  if ((state & GDK_BUTTON4_MASK) || but==4) - iupKEYSETBUTTON4(status); + iupKEY_SETBUTTON4(status);  if ((state & GDK_BUTTON5_MASK) || but==5) - iupKEYSETBUTTON5(status); + iupKEY_SETBUTTON5(status);  if (state & GDK_MOD1_MASK || state & GDK_MOD5_MASK) /* Alt */ - iupKEYSETALT(status); + iupKEY_SETALT(status);  if (state & GDK_MOD4_MASK) /* Apple/Win */ - iupKEYSETSYS(status); + iupKEY_SETSYS(status);  if (doubleclick) - iupKEYSETDOUBLE(status); + iupKEY_SETDOUBLE(status); }  diff --git a/iup/src/gtk/iupgtk_label.c b/iup/src/gtk/iupgtk_label.c index 49d5c6d..f95f576 100755 --- a/iup/src/gtk/iupgtk_label.c +++ b/iup/src/gtk/iupgtk_label.c @@ -133,8 +133,10 @@ static int gtkLabelSetPaddingAttrib(Ihandle* ih, const char* value) { GtkMisc* misc = (GtkMisc*)ih->handle; gtk_misc_set_padding(misc, ih->data->horiz_padding, ih->data->vert_padding); + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static char* gtkLabelGetPangoLayoutAttrib(Ihandle* ih) diff --git a/iup/src/gtk/iupgtk_list.c b/iup/src/gtk/iupgtk_list.c index 80f6cce..48fa88e 100755 --- a/iup/src/gtk/iupgtk_list.c +++ b/iup/src/gtk/iupgtk_list.c @@ -113,6 +113,8 @@ void iupdrvListInsertItem(Ihandle* ih, int pos, const char* value) GtkTreeIter iter; gtk_list_store_insert(GTK_LIST_STORE(model), &iter, pos); gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, iupgtkStrConvertToUTF8(value), -1); + + iupListUpdateOldValue(ih, pos, 0); }  void iupdrvListRemoveItem(Ihandle* ih, int pos) @@ -127,14 +129,24 @@ void iupdrvListRemoveItem(Ihandle* ih, int pos) int curpos = gtk_combo_box_get_active((GtkComboBox*)ih->handle); if (pos == curpos) { - if (curpos > 0) curpos--; - else curpos++; + if (curpos > 0)  + curpos--; + else  + { + curpos=1; + if (iupdrvListGetCount(ih)==1) + curpos = -1; /* remove the selection */ + }  + g_signal_handlers_block_by_func(G_OBJECT(ih->handle), G_CALLBACK(gtkListComboBoxChanged), ih); gtk_combo_box_set_active((GtkComboBox*)ih->handle, curpos); + g_signal_handlers_unblock_by_func(G_OBJECT(ih->handle), G_CALLBACK(gtkListComboBoxChanged), ih); } }  gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + + iupListUpdateOldValue(ih, pos, 1); } }  @@ -177,7 +189,7 @@ static int gtkListSetStandardFontAttrib(Ihandle* ih, const char* value) static char* gtkListGetIdValueAttrib(Ihandle* ih, const char* name_id) { int pos = iupListGetPos(ih, name_id); - if (pos != -1) + if (pos >= 0) { GtkTreeIter iter; GtkTreeModel* model = gtkListGetModel(ih); @@ -349,7 +361,7 @@ static int gtkListSetValueAttrib(Ihandle* ih, const char* value) GtkTreeModel *model = gtkListGetModel(ih); g_signal_handlers_block_by_func(G_OBJECT(ih->handle), G_CALLBACK(gtkListComboBoxChanged), ih); if (iupStrToInt(value, &pos)==1 &&  - (pos>0 && pos0 && pos<=gtk_tree_model_iter_n_children(model, NULL))) { gtk_combo_box_set_active((GtkComboBox*)ih->handle, pos-1); /* IUP starts at 1 */ iupAttribSetInt(ih, "_IUPLIST_OLDVALUE", pos); @@ -788,9 +800,10 @@ static int gtkListSetNCAttrib(Ihandle* ih, const char* value) { GtkEntry* entry = (GtkEntry*)iupAttribGet(ih, "_IUPGTK_ENTRY"); gtk_entry_set_max_length(entry, ih->data->nc); + return 0; } - - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int gtkListSetClipboardAttrib(Ihandle *ih, const char *value) @@ -1364,9 +1377,9 @@ static int gtkListMapMethod(Ihandle* ih) if (!ih->data->has_editbox && ih->data->is_multiple) { gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); -#if GTK_CHECK_VERSION(2, 10, 0) + #if GTK_CHECK_VERSION(2, 10, 0) gtk_tree_view_set_rubber_banding(GTK_TREE_VIEW(ih->handle), TRUE); -#endif + #endif } else gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); diff --git a/iup/src/gtk/iupgtk_loop.c b/iup/src/gtk/iupgtk_loop.c index e349a45..704923e 100755 --- a/iup/src/gtk/iupgtk_loop.c +++ b/iup/src/gtk/iupgtk_loop.c @@ -69,6 +69,13 @@ int IupMainLoop(void) return IUP_NOERROR; }  +int IupLoopStepWait(void) +{ + if (gtk_main_iteration_do(TRUE)) + return IUP_CLOSE; + return IUP_DEFAULT; +} + int IupLoopStep(void) { if (gtk_main_iteration_do(FALSE)) diff --git a/iup/src/gtk/iupgtk_menu.c b/iup/src/gtk/iupgtk_menu.c index c12fbea..772f4cf 100755 --- a/iup/src/gtk/iupgtk_menu.c +++ b/iup/src/gtk/iupgtk_menu.c @@ -245,11 +245,19 @@ static int gtkMenuMapMethod(Ihandle* ih) return IUP_NOERROR; }  +static void gtkMenuUnMapMethod(Ihandle* ih) +{ + if (iupMenuIsMenuBar(ih)) + ih->parent = NULL; + + iupdrvBaseUnMapMethod(ih); +} + void iupdrvMenuInitClass(Iclass* ic) { /* Driver Dependent Class functions */ ic->Map = gtkMenuMapMethod; - ic->UnMap = iupdrvBaseUnMapMethod; + ic->UnMap = gtkMenuUnMapMethod;  /* Used by iupdrvMenuGetMenuBarSize */ iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, NULL, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_DEFAULT); /* use inheritance to retrieve standard fonts */ @@ -337,15 +345,10 @@ static int gtkItemSetValueAttrib(Ihandle* ih, const char* value)  static char* gtkItemGetValueAttrib(Ihandle* ih) { - if (GTK_IS_CHECK_MENU_ITEM(ih->handle)) - { - if (gtk_check_menu_item_get_active((GtkCheckMenuItem*)ih->handle)) - return "ON"; - else - return "OFF"; - } + if (GTK_IS_CHECK_MENU_ITEM(ih->handle) && gtk_check_menu_item_get_active((GtkCheckMenuItem*)ih->handle)) + return "ON"; else - return NULL; + return "OFF"; }  static int gtkItemMapMethod(Ihandle* ih) diff --git a/iup/src/gtk/iupgtk_open.c b/iup/src/gtk/iupgtk_open.c index 66e46e8..962f760 100755 --- a/iup/src/gtk/iupgtk_open.c +++ b/iup/src/gtk/iupgtk_open.c @@ -20,7 +20,52 @@  #include "iupgtk_drv.h"  +#ifdef GTK_MAC +#include   +char* iupgtkGetNativeWindowHandle(Ihandle* ih) +{ + GdkWindow* window = ih->handle->window; + if (window) + return (char*)window; + else + return NULL; +} + +void* iupgtkGetNativeGraphicsContext(GtkWidget* widget) +{ + return (void*)gdk_gc_new((GdkDrawable*)widget->window); +} + +void iupgtkReleaseNativeGraphicsContext(GtkWidget* widget, void* gc) +{ + g_object_unref(gc); + (void)widget; +} + +void* iupdrvGetDisplay(void) +{ + GdkDisplay* display = gdk_display_get_default(); + return display; +} + +void iupgtkPushVisualAndColormap(void* visual, void* colormap) +{ + GdkColormap* gdk_colormap; + GdkVisual *gdk_visual = gdk_visual_get_best(); + + gdk_colormap = gdk_colormap_new(gdk_visual, FALSE); + + gtk_widget_push_colormap(gdk_colormap); + + /* gtk_widget_push_visual is now deprecated */ +} + +static void gtkSetDrvGlobalAttrib(void) +{ +} + +#else #ifdef WIN32 /******************************** WIN32 ************************************/ #include   @@ -115,6 +160,8 @@ static void gtkSetDrvGlobalAttrib(void)  #endif  +#endif + static void gtkSetGlobalColorAttrib(const char* name, GdkColor *color) { iupGlobalSetDefaultColorAttrib(name, (int)iupCOLOR16TO8(color->red),  diff --git a/iup/src/gtk/iupgtk_tabs.c b/iup/src/gtk/iupgtk_tabs.c index 8029826..6b5aa66 100755 --- a/iup/src/gtk/iupgtk_tabs.c +++ b/iup/src/gtk/iupgtk_tabs.c @@ -76,13 +76,13 @@ static void gtkTabsUpdatePageBgColor(Ihandle* ih, unsigned char r, unsigned char  for (child = ih->firstchild; child; child = child->brother) { - GtkWidget* tab_page = (GtkWidget*)iupAttribGet(child, "_IUPTAB_CONTAINER"); - if (tab_page) + GtkWidget* tab_container = (GtkWidget*)iupAttribGet(child, "_IUPTAB_CONTAINER"); + if (tab_container) { GtkWidget* tab_label = (GtkWidget*)iupAttribGet(child, "_IUPGTK_TABLABEL"); if (tab_label) iupgtkBaseSetBgColor(tab_label, r, g, b); - iupgtkBaseSetBgColor(tab_page, r, g, b); + iupgtkBaseSetBgColor(tab_container, r, g, b); } } } @@ -121,15 +121,18 @@ static int gtkTabsSetPaddingAttrib(Ihandle* ih, const char* value) iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');  if (ih->handle) + { gtkTabsUpdatePagePadding(ih); - return 0; + return 0; + } + else + return 1; /* store until not mapped, when mapped will be set again */ }  static void gtkTabsUpdateTabType(Ihandle* ih) { - GtkNotebook* tab_page = (GtkNotebook*)ih->handle; int iup2gtk[4] = {GTK_POS_TOP, GTK_POS_BOTTOM, GTK_POS_LEFT, GTK_POS_RIGHT}; - gtk_notebook_set_tab_pos(tab_page, iup2gtk[ih->data->type]); + gtk_notebook_set_tab_pos((GtkNotebook*)ih->handle, iup2gtk[ih->data->type]); }  static int gtkTabsSetTabTypeAttrib(Ihandle* ih, const char* value) @@ -144,7 +147,7 @@ static int gtkTabsSetTabTypeAttrib(Ihandle* ih, const char* value) ih->data->type = ITABS_TOP;  if (ih->handle) - gtkTabsUpdateTabType(ih); + gtkTabsUpdateTabType(ih); /* for this to work must be updated in map */  return 0; } @@ -171,7 +174,7 @@ static int gtkTabsSetTabTitleAttrib(Ihandle* ih, const char* name_id, const char GtkWidget* tab_label = (GtkWidget*)iupAttribGet(child, "_IUPGTK_TABLABEL"); if (tab_label) { - GtkWidget* tab_page = (GtkWidget*)iupAttribGet(child, "_IUPTAB_CONTAINER"); + GtkWidget* tab_page = (GtkWidget*)iupAttribGet(child, "_IUPTAB_PAGE"); gtk_label_set_text((GtkLabel*)tab_label, iupgtkStrConvertToUTF8(value)); gtk_notebook_set_menu_label_text((GtkNotebook*)ih->handle, tab_page, gtk_label_get_text((GtkLabel*)tab_label)); } @@ -238,8 +241,10 @@ void gtkTabSwitchPage(GtkNotebook* notebook, GtkNotebookPage *page, int pos, Iha IFnnn cb; Ihandle* child = IupGetChild(ih, pos); Ihandle* prev_child = IupGetChild(ih, iupdrvTabsGetCurrentTab(ih)); - IupSetAttribute(child, "VISIBLE", "YES"); - IupSetAttribute(prev_child, "VISIBLE", "NO"); + GtkWidget* tab_container = (GtkWidget*)iupAttribGet(child, "_IUPTAB_CONTAINER"); + GtkWidget* prev_tab_container = (GtkWidget*)iupAttribGet(prev_child, "_IUPTAB_CONTAINER"); + if (tab_container) gtk_widget_show(tab_container); + if (prev_tab_container) gtk_widget_hide(prev_tab_container);  if (iupAttribGet(ih, "_IUPGTK_IGNORE_CHANGE")) return; @@ -263,7 +268,7 @@ static void gtkTabsChildAddedMethod(Ihandle* ih, Ihandle* child)  if (ih->handle) { - GtkWidget* tab_page; + GtkWidget *tab_page, *tab_container; GtkWidget *tab_label = NULL, *tab_image = NULL; char *tabtitle, *tabimage; int pos; @@ -271,9 +276,13 @@ static void gtkTabsChildAddedMethod(Ihandle* ih, Ihandle* child)  pos = IupGetChildPos(ih, child);  - tab_page = gtk_fixed_new(); + tab_page = gtk_vbox_new(FALSE, 0); gtk_widget_show(tab_page);  + tab_container = gtk_fixed_new(); + gtk_widget_show(tab_container); + gtk_container_add((GtkContainer*)tab_page, tab_container); + tabtitle = iupAttribGet(child, "TABTITLE"); if (!tabtitle) tabtitle = iupTabsAttribGetStrId(ih, "TABTITLE", pos); tabimage = iupAttribGet(child, "TABIMAGE"); @@ -327,9 +336,10 @@ static void gtkTabsChildAddedMethod(Ihandle* ih, Ihandle* child)  iupAttribSetStr(child, "_IUPGTK_TABIMAGE", (char*)tab_image); /* store it even if its NULL */ iupAttribSetStr(child, "_IUPGTK_TABLABEL", (char*)tab_label); - iupAttribSetStr(child, "_IUPTAB_CONTAINER", (char*)tab_page); + iupAttribSetStr(child, "_IUPTAB_CONTAINER", (char*)tab_container); + iupAttribSetStr(child, "_IUPTAB_PAGE", (char*)tab_page); iupStrToRGB(IupGetAttribute(ih, "BGCOLOR"), &r, &g, &b); - iupgtkBaseSetBgColor(tab_page, r, g, b); + iupgtkBaseSetBgColor(tab_container, r, g, b);  if (tabtitle) { @@ -354,10 +364,8 @@ static void gtkTabsChildAddedMethod(Ihandle* ih, Ihandle* child)  iupAttribSetStr(ih, "_IUPGTK_IGNORE_CHANGE", NULL);  - if (pos == iupdrvTabsGetCurrentTab(ih)) - IupSetAttribute(child, "VISIBLE", "YES"); - else - IupSetAttribute(child, "VISIBLE", "NO"); + if (pos != iupdrvTabsGetCurrentTab(ih)) + gtk_widget_hide(tab_container); } }  @@ -365,10 +373,11 @@ static void gtkTabsChildRemovedMethod(Ihandle* ih, Ihandle* child) { if (ih->handle) { - GtkWidget* tab_page = (GtkWidget*)iupAttribGet(child, "_IUPTAB_CONTAINER"); + GtkWidget* tab_page = (GtkWidget*)iupAttribGet(child, "_IUPTAB_PAGE"); if (tab_page) { int pos = gtk_notebook_page_num((GtkNotebook*)ih->handle, tab_page); + iupTabsTestRemoveTab(ih, pos);  iupAttribSetStr(ih, "_IUPGTK_IGNORE_CHANGE", "1"); gtk_notebook_remove_page((GtkNotebook*)ih->handle, pos); @@ -377,6 +386,7 @@ static void gtkTabsChildRemovedMethod(Ihandle* ih, Ihandle* child) iupAttribSetStr(child, "_IUPGTK_TABIMAGE", NULL); iupAttribSetStr(child, "_IUPGTK_TABLABEL", NULL); iupAttribSetStr(child, "_IUPTAB_CONTAINER", NULL); + iupAttribSetStr(child, "_IUPTAB_PAGE", NULL); } } } @@ -440,5 +450,5 @@ void iupdrvTabsInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "TABORIENTATION", iupTabsGetTabOrientationAttrib, gtkTabsSetTabOrientationAttrib, IUPAF_SAMEASSYSTEM, "HORIZONTAL", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TABTITLE", NULL, gtkTabsSetTabTitleAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TABIMAGE", NULL, gtkTabsSetTabImageAttrib, IUPAF_NO_INHERIT); - iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, gtkTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, gtkTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); } diff --git a/iup/src/gtk/iupgtk_text.c b/iup/src/gtk/iupgtk_text.c index 4c2906a..d0909d7 100755 --- a/iup/src/gtk/iupgtk_text.c +++ b/iup/src/gtk/iupgtk_text.c @@ -101,7 +101,7 @@ static void gtkTextParseParagraphFormat(Ihandle* formattag, GtkTextTag* tag) align = PANGO_TAB_LEFT; free(str);  - pango_tab_array_set_tab(tabs, i, align, IUPGTK_PIXELS2PANGOUNITS(pos)); + pango_tab_array_set_tab(tabs, i, align, iupGTK_PIXELS2PANGOUNITS(pos)); i++; if (i == 32) break; } @@ -171,7 +171,7 @@ static void gtkTextParseCharacterFormat(Ihandle* formattag, GtkTextTag* tag) else  iupStrToInt(format, &val);  - val = IUPGTK_PIXELS2PANGOUNITS(val); + val = iupGTK_PIXELS2PANGOUNITS(val); g_object_set(G_OBJECT(tag), "rise", val, NULL); }  @@ -214,7 +214,7 @@ static void gtkTextParseCharacterFormat(Ihandle* formattag, GtkTextTag* tag) { if (val < 0) /* in pixels */ { - val = IUPGTK_PIXELS2PANGOUNITS(-val); + val = iupGTK_PIXELS2PANGOUNITS(-val); g_object_set(G_OBJECT(tag), "size", val, NULL); } else /* in points */ @@ -387,8 +387,8 @@ static int gtkTextConvertXYToPos(Ihandle* ih, int x, int y)  /* transform to Layout coordinates */ gtk_entry_get_layout_offsets(GTK_ENTRY(ih->handle), &off_x, &off_y); - x = IUPGTK_PIXELS2PANGOUNITS(x - off_x);  - y = IUPGTK_PIXELS2PANGOUNITS(y - off_y); + x = iupGTK_PIXELS2PANGOUNITS(x - off_x);  + y = iupGTK_PIXELS2PANGOUNITS(y - off_y);  pango_layout_xy_to_index(gtk_entry_get_layout(GTK_ENTRY(ih->handle)), x, y, &pos, &trailing); return pos; @@ -851,7 +851,7 @@ static char* gtkTextGetValueAttrib(Ihandle* ih)  static int gtkTextSetInsertAttrib(Ihandle* ih, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (!value) return 0; @@ -875,7 +875,8 @@ static int gtkTextSetInsertAttrib(Ihandle* ih, const char* value)  static int gtkTextSetAppendAttrib(Ihandle* ih, const char* value) { - if (!ih->handle) /* do not store the action before map */ + gint pos; + if (!ih->handle) /* do not do the action before map */ return 0; /* disable callbacks */ iupAttribSetStr(ih, "_IUPGTK_DISABLE_TEXT_CB", "1"); @@ -884,13 +885,18 @@ static int gtkTextSetAppendAttrib(Ihandle* ih, const char* value) GtkTextIter iter; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(ih->handle)); gtk_text_buffer_get_end_iter(buffer, &iter); - if (ih->data->append_newline) + pos = gtk_text_buffer_get_char_count(buffer); + if (ih->data->append_newline && pos!=0) gtk_text_buffer_insert(buffer, &iter, "\n", 1); gtk_text_buffer_insert(buffer, &iter, iupgtkStrConvertToUTF8(value), -1); } else { - gint pos = strlen(gtk_entry_get_text(GTK_ENTRY(ih->handle)))+1; +#if GTK_CHECK_VERSION(2, 14, 0) + pos = gtk_entry_get_text_length(GTK_ENTRY(ih->handle))+1; +#else + pos = strlen(gtk_entry_get_text(GTK_ENTRY(ih->handle)))+1; +#endif gtk_editable_insert_text(GTK_EDITABLE(ih->handle), iupgtkStrConvertToUTF8(value), -1, &pos); } iupAttribSetStr(ih, "_IUPGTK_DISABLE_TEXT_CB", NULL); @@ -946,8 +952,10 @@ static int gtkTextSetPaddingAttrib(Ihandle* ih, const char* value) gtk_entry_set_inner_border(GTK_ENTRY(ih->handle), &border); #endif } + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int gtkTextSetNCAttrib(Ihandle* ih, const char* value) @@ -955,10 +963,14 @@ static int gtkTextSetNCAttrib(Ihandle* ih, const char* value) if (!iupStrToInt(value, &ih->data->nc)) ih->data->nc = INT_MAX;  - if (!ih->data->is_multiline && ih->handle) - gtk_entry_set_max_length(GTK_ENTRY(ih->handle), ih->data->nc); - - return 0; + if (ih->handle) + { + if (!ih->data->is_multiline) + gtk_entry_set_max_length(GTK_ENTRY(ih->handle), ih->data->nc); + return 0; + } + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int gtkTextSetClipboardAttrib(Ihandle *ih, const char *value) diff --git a/iup/src/gtk/iupgtk_toggle.c b/iup/src/gtk/iupgtk_toggle.c index 8ff7df5..040beda 100755 --- a/iup/src/gtk/iupgtk_toggle.c +++ b/iup/src/gtk/iupgtk_toggle.c @@ -213,8 +213,10 @@ static int gtkToggleSetPaddingAttrib(Ihandle* ih, const char* value) GtkButton* button = (GtkButton*)ih->handle; GtkMisc* misc = (GtkMisc*)gtk_button_get_image(button); gtk_misc_set_padding(misc, ih->data->horiz_padding, ih->data->vert_padding); + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int gtkToggleSetFgColorAttrib(Ihandle* ih, const char* value) diff --git a/iup/src/gtk/iupgtk_tree.c b/iup/src/gtk/iupgtk_tree.c index d408f27..9595ada 100755 --- a/iup/src/gtk/iupgtk_tree.c +++ b/iup/src/gtk/iupgtk_tree.c @@ -31,33 +31,50 @@ #include "iup_drvinfo.h" #include "iupgtk_drv.h"  + +/* IMPORTANT:  + + GtkTreeStore uses the "user_data" field of the GtkTreeIter  + to store the node pointer that is position independent. + So we use it as a reference to the node in the cache, just like in Motif and Windows. + + BUT if GTK change its implementation this must be changed also. See "gtk_tree_store.c". + + ABOUT SELECTIONS: + + From the GTK documentation on GtkTreeSelection + + "Additionally, you cannot change the selection of a row on the model  + that is not currently displayed by the view without expanding its parents first." +*/ + enum { - IUPGTK_TREE_IMAGE, + IUPGTK_TREE_IMAGE, /* "pixbuf", "pixbuf-expander-closed" */ IUPGTK_TREE_HAS_IMAGE, - IUPGTK_TREE_IMAGE_EXPANDED, + IUPGTK_TREE_IMAGE_EXPANDED, /* "pixbuf-expander-open" */ IUPGTK_TREE_HAS_IMAGE_EXPANDED, - IUPGTK_TREE_TITLE, - IUPGTK_TREE_KIND, - IUPGTK_TREE_COLOR, - IUPGTK_TREE_FONT, - IUPGTK_TREE_USERDATA + IUPGTK_TREE_TITLE, /* "text" */ + IUPGTK_TREE_KIND, /* "is-expander" */ + IUPGTK_TREE_COLOR, /* "foreground-gdk" */ + IUPGTK_TREE_FONT, /* "font-desc" */ + IUPGTK_TREE_SELECT, + IUPGTK_TREE_LAST_DATA /* used as a count */ };  -static GtkTreeIter gtkTreeInvalidIter = {0,0,0,0}; +static void gtkTreeRebuildNodeCache(Ihandle* ih, int id, GtkTreeIter iterItem);  /*****************************************************************************/ /* COPYING ITEMS (Branches and its children) */ /*****************************************************************************/ /* Insert the copied item in a new location. Returns the new item. */ -static void gtkTreeCopyItem(GtkTreeModel* model, GtkTreeIter* iterItem, GtkTreeIter* iterParent, int position, GtkTreeIter *iterNewItem, int full_copy) +static void gtkTreeCopyItem(Ihandle* ih, GtkTreeModel* model, GtkTreeIter* iterItem, GtkTreeIter* iterParent, int position, GtkTreeIter *iterNewItem) { GtkTreeStore* store = GTK_TREE_STORE(model); int kind; char* title; gboolean has_image, has_image_expanded; PangoFontDescription* font; - void* userdata; GdkColor *color; GdkPixbuf* image, *image_expanded;  @@ -69,9 +86,10 @@ static void gtkTreeCopyItem(GtkTreeModel* model, GtkTreeIter* iterItem, GtkTreeI IUPGTK_TREE_KIND, &kind, IUPGTK_TREE_COLOR, &color,  IUPGTK_TREE_FONT, &font,  - IUPGTK_TREE_USERDATA, &userdata, -1);  + /* Add the new node */ + ih->data->node_count++; if (position == 2) gtk_tree_store_append(store, iterNewItem, iterParent); else if (position == 1) /* copy as first child of expanded branch */ @@ -79,9 +97,6 @@ static void gtkTreeCopyItem(GtkTreeModel* model, GtkTreeIter* iterItem, GtkTreeI else /* copy as next brother of item or collapsed branch */ gtk_tree_store_insert_after(store, iterNewItem, NULL, iterParent); /* iterParent is sibling of the new item */  - if (full_copy) /* during a full copy the userdata reference is not copied */ - userdata = NULL; - gtk_tree_store_set(store, iterNewItem, IUPGTK_TREE_IMAGE, image, IUPGTK_TREE_HAS_IMAGE, has_image, IUPGTK_TREE_IMAGE_EXPANDED, image_expanded, @@ -90,21 +105,21 @@ static void gtkTreeCopyItem(GtkTreeModel* model, GtkTreeIter* iterItem, GtkTreeI IUPGTK_TREE_KIND, kind, IUPGTK_TREE_COLOR, color,  IUPGTK_TREE_FONT, font, - IUPGTK_TREE_USERDATA, userdata, + IUPGTK_TREE_SELECT, 0, -1); }  -static void gtkTreeCopyChildren(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItemSrc, GtkTreeIter *iterItemDst, int full_copy) +static void gtkTreeCopyChildren(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItemSrc, GtkTreeIter *iterItemDst) { GtkTreeIter iterChildSrc; int hasItem = gtk_tree_model_iter_children(model, &iterChildSrc, iterItemSrc); /* get the firstchild */ while(hasItem) { GtkTreeIter iterNewItem; - gtkTreeCopyItem(model, &iterChildSrc, iterItemDst, 2, &iterNewItem, full_copy); /* append always */ + gtkTreeCopyItem(ih, model, &iterChildSrc, iterItemDst, 2, &iterNewItem); /* append always */  /* Recursively transfer all the items */ - gtkTreeCopyChildren(ih, model, &iterChildSrc, &iterNewItem, full_copy);  + gtkTreeCopyChildren(ih, model, &iterChildSrc, &iterNewItem);   /* Go to next sibling item */ hasItem = gtk_tree_model_iter_next(model, &iterChildSrc); @@ -112,9 +127,17 @@ static void gtkTreeCopyChildren(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *i }  /* Copies all items in a branch to a new location. Returns the new branch node. */ -static void gtkTreeCopyNode(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItemSrc, GtkTreeIter *iterItemDst, GtkTreeIter* iterNewItem, int full_copy) +static void gtkTreeCopyMoveNode(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItemSrc, GtkTreeIter *iterItemDst, GtkTreeIter* iterNewItem, int is_copy) { int kind, position = 0; /* insert after iterItemDst */ + int id_new, count, id_src, id_dst; + + int old_count = ih->data->node_count; + + id_src = iupTreeFindNodeId(ih, iterItemSrc); + id_dst = iupTreeFindNodeId(ih, iterItemDst); + id_new = id_dst+1; /* contains the position for a copy operation */ + gtk_tree_model_get(model, iterItemDst, IUPGTK_TREE_KIND, &kind, -1);  if (kind == ITREE_BRANCH) @@ -122,346 +145,311 @@ static void gtkTreeCopyNode(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterI GtkTreePath* path = gtk_tree_model_get_path(model, iterItemDst); if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path)) position = 1; /* insert as first child of iterItemDst */ + else + { + int child_count = iupdrvTreeTotalChildCount(ih, iterItemDst); + id_new += child_count; + } gtk_tree_path_free(path); }  - gtkTreeCopyItem(model, iterItemSrc, iterItemDst, position, iterNewItem, full_copy);  + /* move to the same place does nothing */ + if (!is_copy && id_new == id_src) + { + iterNewItem->stamp = 0; + return; + }  - gtkTreeCopyChildren(ih, model, iterItemSrc, iterNewItem, full_copy); -} + gtkTreeCopyItem(ih, model, iterItemSrc, iterItemDst, position, iterNewItem);   -/*****************************************************************************/ -/* FINDING ITEMS */ -/*****************************************************************************/ + gtkTreeCopyChildren(ih, model, iterItemSrc, iterNewItem);  -static void gtkTreeInvertAllNodeMarking(Ihandle* ih, GtkTreeModel* model, GtkTreeSelection* selection, GtkTreeIter* iterItem) -{ - GtkTreeIter iterChild; - int hasItem = TRUE; + count = ih->data->node_count - old_count; + iupTreeCopyMoveCache(ih, id_src, id_new, count, is_copy);  - while(hasItem) + if (!is_copy) { - if(gtk_tree_selection_iter_is_selected(selection, iterItem)) - gtk_tree_selection_unselect_iter(selection, iterItem); - else - gtk_tree_selection_select_iter(selection, iterItem); + /* Deleting the node of its old position */ + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + gtk_tree_store_remove(GTK_TREE_STORE(model), iterItemSrc); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);  - /* Check whether we have child items */ - if(gtk_tree_model_iter_has_child(model, iterItem)) - { - gtk_tree_model_iter_children(model, &iterChild, iterItem); /* get the firstchild */ - gtkTreeInvertAllNodeMarking(ih, model, selection, &iterChild); - } + /* restore count, because we remove src */ + ih->data->node_count = old_count;  - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, iterItem); + /* compensate position for a move */ + if (id_new > id_src) + id_new -= count; } + + gtkTreeRebuildNodeCache(ih, id_new, *iterNewItem); }  -static GtkTreeIter gtkTreeFindVisibleNodeId(Ihandle* ih, GtkTreeModel* model, GtkTreeIter iterItem, GtkTreeIter iterNode) +/*****************************************************************************/ +/* FINDING ITEMS */ +/*****************************************************************************/ + +static void gtkTreeIterInit(Ihandle* ih, GtkTreeIter* iterItem, InodeHandle* node_handle) { - GtkTreeIter iterChild; - GtkTreePath* path; - int hasItem = TRUE; + iterItem->stamp = ih->data->stamp; + iterItem->user_data = node_handle; + iterItem->user_data2 = NULL; + iterItem->user_data3 = NULL; +}  - while(hasItem) - { - /* ID control to traverse items */ - ih->data->id_control++; /* not the real id since it counts only the visible ones */ +static int gtkTreeIsNodeSelected(GtkTreeModel* model, GtkTreeIter *iterItem) +{ + gboolean selected = 0; + gtk_tree_model_get(model, iterItem, IUPGTK_TREE_SELECT, &selected, -1); + return selected; +}  - /* StateID founded! */ - if(iterItem.user_data == iterNode.user_data) - return iterItem; +static void gtkTreeSelectNodeRaw(GtkTreeModel* model, GtkTreeIter *iterItem, int select) +{ + /* Cannot change the selection of a row on the model that is not currently displayed.  + So we store the selection state here. And update the actual state when the node becames visible. */ + gtk_tree_store_set(GTK_TREE_STORE(model), iterItem, IUPGTK_TREE_SELECT, select, -1); +}  - path = gtk_tree_model_get_path(model, &iterItem); +static void gtkTreeSelectNode(GtkTreeModel* model, GtkTreeSelection* selection, GtkTreeIter *iterItem, int select) +{ + if (select == -1) + select = !gtkTreeIsNodeSelected(model, iterItem); /* toggle */  - /* Check whether we have child items and it is expanded (visible) */ - if (gtk_tree_model_iter_has_child(model, &iterItem) && gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path)) - { - gtk_tree_model_iter_children(model, &iterChild, &iterItem); /* get the firstchild */ - iterChild = gtkTreeFindVisibleNodeId(ih, model, iterChild, iterNode); + gtkTreeSelectNodeRaw(model, iterItem, select);  - /* StateID founded! */ - if(iterChild.user_data) - { - gtk_tree_path_free(path); - return iterChild; - } - } + if (select) + gtk_tree_selection_select_iter(selection, iterItem); + else + gtk_tree_selection_unselect_iter(selection, iterItem); +}  - gtk_tree_path_free(path); - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, &iterItem); +static void gtkTreeSelectAll(Ihandle* ih, GtkTreeModel* model, GtkTreeSelection* selection, int selected) +{ + int i; + GtkTreeIter iterItem; + + for (i = 0; i < ih->data->node_count; i++) + { + gtkTreeIterInit(ih, &iterItem, ih->data->node_cache[i].node_handle); + gtkTreeSelectNodeRaw(model, &iterItem, selected); }  - return gtkTreeInvalidIter; /* invalid since gtk_tree_model_iter_next returned false */ + if (selected) + gtk_tree_selection_select_all(selection); + else + gtk_tree_selection_unselect_all(selection); }  -static GtkTreeIter gtkTreeFindVisibleNodeFromId(Ihandle* ih, GtkTreeModel* model, GtkTreeIter iterItem) +static void gtkTreeInvertAllNodeMarking(Ihandle* ih, GtkTreeModel* model, GtkTreeSelection* selection) { - GtkTreeIter iterChild; - GtkTreePath* path; - int hasItem = TRUE; + int i; + GtkTreeIter iterItem;  - while(hasItem) + for (i = 0; i < ih->data->node_count; i++) { - /* ID control to traverse items */ - ih->data->id_control--; /* not the real id since it counts only the visible ones */ + gtkTreeIterInit(ih, &iterItem, ih->data->node_cache[i].node_handle); + gtkTreeSelectNode(model, selection, &iterItem, -1); + } +}  - /* StateID founded! */ - if(ih->data->id_control < 0) - return iterItem; +static void gtkTreeSelectRange(Ihandle* ih, GtkTreeModel* model, GtkTreeSelection* selection, GtkTreeIter *iterItem1, GtkTreeIter *iterItem2, int clear) +{ + int i; + int id1 = iupTreeFindNodeId(ih, iterItem1->user_data); + int id2 = iupTreeFindNodeId(ih, iterItem2->user_data); + GtkTreeIter iterItem;  - path = gtk_tree_model_get_path(model, &iterItem); + if (id1 > id2) + { + int tmp = id1; + id1 = id2; + id2 = tmp; + }  - /* Check whether we have child items and it is expanded (visible) */ - if(gtk_tree_model_iter_has_child(model, &iterItem) && gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path)) + for (i = 0; i < ih->data->node_count; i++) + { + gtkTreeIterInit(ih, &iterItem, ih->data->node_cache[i].node_handle); + if (i < id1 || i > id2) { - gtk_tree_model_iter_children(model, &iterChild, &iterItem); /* get the firstchild */ - iterChild = gtkTreeFindVisibleNodeFromId(ih, model, iterChild); - - /* StateID founded! */ - if(ih->data->id_control < 0) - { - gtk_tree_path_free(path); - return iterChild; - } + if (clear) + gtkTreeSelectNode(model, selection, &iterItem, 0); } - - gtk_tree_path_free(path); - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, &iterItem); + else + gtkTreeSelectNode(model, selection, &iterItem, 1); } - - return gtkTreeInvalidIter; /* invalid since gtk_tree_model_iter_next returned false */ }  -static GtkTreeIter gtkTreeGetLastVisibleNode(Ihandle* ih, GtkTreeModel* model, GtkTreeIter iterItem) +static int gtkTreeIsNodeVisible(Ihandle* ih, GtkTreeModel* model, InodeHandle* node_handle, InodeHandle* *nodeLastParent) { - GtkTreeIter iterChild, iterPrev = gtkTreeInvalidIter; - GtkTreePath* path = gtk_tree_model_get_path(model, &iterItem); - - /* Check whether we have child items and it is expanded (visible) */ - if(gtk_tree_model_iter_has_child(model, &iterItem) && gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path)) - { - int hasItem = TRUE; - gtk_tree_model_iter_children(model, &iterChild, &iterItem); /* get the firstchild */ + GtkTreeIter iterItem, iterParent; + GtkTreePath* path; + int is_visible;  - while(hasItem) - { - iterPrev = iterChild; + gtkTreeIterInit(ih, &iterItem, node_handle);  - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, &iterChild); - } + if (!gtk_tree_model_iter_parent(model, &iterParent, &iterItem) || + iterParent.user_data == *nodeLastParent) + return 1;  - iterItem = gtkTreeGetLastVisibleNode(ih, model, iterPrev); - } + path = gtk_tree_model_get_path(model, &iterParent); + is_visible = gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path); gtk_tree_path_free(path);  - return iterItem; + if (!is_visible) + return 0; + + /* save last parent */ + *nodeLastParent = iterParent.user_data; + return 1; }  -static GtkTreeIter gtkTreeFindNodeID(Ihandle* ih, GtkTreeModel* model, GtkTreeIter iterItem, GtkTreeIter iterNode) +static void gtkTreeGetLastVisibleNode(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItem) { - GtkTreeIter iterChild; - int hasItem = TRUE; + int i; + InodeHandle* nodeLastParent = NULL;  - while(hasItem) + for (i = ih->data->node_count-1; i >= 0; i--) { - /* ID control to traverse items */ - ih->data->id_control++; - - /* StateID founded! */ - if (iterItem.user_data == iterNode.user_data) - return iterItem; - - /* Check whether we have child items */ - if (gtk_tree_model_iter_has_child(model, &iterItem)) + if (gtkTreeIsNodeVisible(ih, model, ih->data->node_cache[i].node_handle, &nodeLastParent)) { - gtk_tree_model_iter_children(model, &iterChild, &iterItem); /* get the firstchild */ - iterChild = gtkTreeFindNodeID(ih, model, iterChild, iterNode); - - /* StateID founded! */ - if(iterChild.user_data) - return iterChild; + gtkTreeIterInit(ih, iterItem, ih->data->node_cache[i].node_handle); + return; } - - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, &iterItem); }  - return gtkTreeInvalidIter; /* invalid since gtk_tree_model_iter_next returned false */ + gtkTreeIterInit(ih, iterItem, ih->data->node_cache[0].node_handle); /* root is always visible */ }  -static int gtkTreeGetNodeId(Ihandle* ih, GtkTreeIter iterItem) +static void gtkTreeGetNextVisibleNode(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItem, int count) { - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - GtkTreeIter iterRoot; - gtk_tree_model_get_iter_first(model, &iterRoot); - - ih->data->id_control = -1; - iterItem = gtkTreeFindNodeID(ih, model, iterRoot, iterItem); - if (iterItem.user_data) - return ih->data->id_control; - else - return -1; -} + int i, id; + InodeHandle* nodeLastParent = NULL;  -static GtkTreeIter gtkTreeFindUserData(Ihandle* ih, GtkTreeModel* model, GtkTreeIter iterItem, void* userdata) -{ - GtkTreeIter iterChild; - int hasItem = TRUE; - void* node_userdata; + id = iupTreeFindNodeId(ih, iterItem->user_data); + id += count;  - while(hasItem) + for (i = id; i < ih->data->node_count; i++) { - /* ID control to traverse items */ - ih->data->id_control++; + if (gtkTreeIsNodeVisible(ih, model, ih->data->node_cache[i].node_handle, &nodeLastParent)) + { + gtkTreeIterInit(ih, iterItem, ih->data->node_cache[i].node_handle); + return; + } + }  - gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_USERDATA, &node_userdata, -1); + gtkTreeIterInit(ih, iterItem, ih->data->node_cache[0].node_handle); /* root is always visible */ +}  - /* userdata founded! */ - if (node_userdata == userdata) - return iterItem; +static void gtkTreeGetPreviousVisibleNode(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItem, int count) +{ + int i, id; + InodeHandle* nodeLastParent = NULL;  - /* Check whether we have child items */ - if (gtk_tree_model_iter_has_child(model, &iterItem)) - { - gtk_tree_model_iter_children(model, &iterChild, &iterItem); /* get the firstchild */ - iterChild = gtkTreeFindUserData(ih, model, iterChild, userdata); + id = iupTreeFindNodeId(ih, iterItem->user_data); + id -= count;  - /* userdata founded! */ - if (iterChild.user_data) - return iterChild; + for (i = id; i >= 0; i--) + { + if (gtkTreeIsNodeVisible(ih, model, ih->data->node_cache[i].node_handle, &nodeLastParent)) + { + gtkTreeIterInit(ih, iterItem, ih->data->node_cache[i].node_handle); + return; } - - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, &iterItem); }  - return gtkTreeInvalidIter; /* invalid since gtk_tree_model_iter_next returned false */ + gtkTreeGetLastVisibleNode(ih, model, iterItem); }  -static int gtkTreeGetUserDataId(Ihandle* ih, GtkTreeModel* model, void* userdata) +static int gtkTreeFindNodeId(Ihandle* ih, GtkTreeIter* iterItem) { - GtkTreeIter iterRoot, iterItem; - gtk_tree_model_get_iter_first(model, &iterRoot); - - ih->data->id_control = -1; - iterItem = gtkTreeFindUserData(ih, model, iterRoot, userdata); - if (iterItem.user_data) - return ih->data->id_control; - else - return -1; + return iupTreeFindNodeId(ih, iterItem->user_data); }  -static void gtkTreeCallNodeRemovedRec(Ihandle* ih, GtkTreeModel* model, GtkTreeIter iterItem, IFnis cb) +static void gtkTreeCallNodeRemovedRec(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItem, IFns cb, int *id) { GtkTreeIter iterChild; - int hasItem = TRUE; - void* node_userdata; + int hasItem; + int old_id = *id;  + /* Check whether we have child items */ + /* remove from children first */ + hasItem = gtk_tree_model_iter_children(model, &iterChild, iterItem); /* get the firstchild */ while(hasItem) { - /* ID control to traverse items */ - ih->data->id_control++; - - gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_USERDATA, &node_userdata, -1); - - cb(ih, ih->data->id_control, (char*)node_userdata); - - /* Check whether we have child items */ - if (gtk_tree_model_iter_has_child(model, &iterItem)) - { - gtk_tree_model_iter_children(model, &iterChild, &iterItem); /* get the firstchild */ - gtkTreeCallNodeRemovedRec(ih, model, iterChild, cb); - } + /* go recursive to children */ + gtkTreeCallNodeRemovedRec(ih, model, &iterChild, cb, id);  /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, &iterItem); + hasItem = gtk_tree_model_iter_next(model, &iterChild); } + + /* actually do it for the node */ + ih->data->node_count--; + (*id)++; + + cb(ih, (char*)ih->data->node_cache[old_id].userdata); }  static void gtkTreeCallNodeRemoved(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItem) { - IFnis cb = (IFnis)IupGetCallback(ih, "NODEREMOVED_CB"); + int old_count = ih->data->node_count; + int id = iupTreeFindNodeId(ih, iterItem->user_data); + int old_id = id; + + IFns cb = (IFns)IupGetCallback(ih, "NODEREMOVED_CB"); if (cb)  + gtkTreeCallNodeRemovedRec(ih, model, iterItem, cb, &id); + else { - ih->data->id_control = gtkTreeGetNodeId(ih, *iterItem)-1; - gtkTreeCallNodeRemovedRec(ih, model, *iterItem, cb); + int removed_count = iupdrvTreeTotalChildCount(ih, iterItem->user_data)+1; + ih->data->node_count -= removed_count; } + + iupTreeDelFromCache(ih, old_id, old_count-ih->data->node_count); }  -static gboolean gtkTreeFindNodeFromID(Ihandle* ih, GtkTreeModel* model, GtkTreeIter *iterItem, int *id) +static void gtkTreeCallNodeRemovedAll(Ihandle* ih) { - GtkTreeIter iterChild; - int hasItem = TRUE; + IFns cb = (IFns)IupGetCallback(ih, "NODEREMOVED_CB"); + int i, old_count = ih->data->node_count;  - while(hasItem) + if (cb) { - /* ID control to traverse items */ - (*id)--; - - /* StateID founded! */ - if (*id < 0) - return TRUE; - - /* Check whether we have child items */ - if (gtk_tree_model_iter_has_child(model, iterItem)) + for (i = 0; i < ih->data->node_count; i++) { - gtk_tree_model_iter_children(model, &iterChild, iterItem); /* get the firstchild */ -  - if (gtkTreeFindNodeFromID(ih, model, &iterChild, id)) - { - *iterItem = iterChild; - return TRUE; - } + cb(ih, (char*)ih->data->node_cache[i].userdata); } - - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, iterItem); }  - return FALSE; + ih->data->node_count = 0; + + iupTreeDelFromCache(ih, 0, old_count); }  -static gboolean gtkTreeFindNodeFromString(Ihandle* ih, GtkTreeModel* model, const char* name_id, GtkTreeIter *iterItem) +static gboolean gtkTreeFindNodeFromString(Ihandle* ih, const char* name_id, GtkTreeIter *iterItem) { - if (name_id[0]) - { - int id; - if (iupStrToInt(name_id, &id)) - { - gtk_tree_model_get_iter_first(model, iterItem); - return gtkTreeFindNodeFromID(ih, model, iterItem, &id); - } - } - else - { - GtkTreePath* path = NULL; - gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &path, NULL); - if (path) - { - gtk_tree_model_get_iter(model, iterItem, path); - gtk_tree_path_free(path); - return TRUE; - } - } - return FALSE; + InodeHandle* node_handle = iupTreeGetNodeFromString(ih, name_id); + if (!node_handle) + return FALSE; + + gtkTreeIterInit(ih, iterItem, node_handle); + return TRUE; }  /*****************************************************************************/ /* MANIPULATING IMAGES */ /*****************************************************************************/ -static void gtkTreeUpdateImages(Ihandle* ih, GtkTreeModel* model, GtkTreeIter iterItem, int mode) +static void gtkTreeUpdateImages(Ihandle* ih, int mode) { - GtkTreeIter iterChild; - int hasItem = TRUE; - int kind; + GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + GtkTreeIter iterItem; + int i, kind;  - while(hasItem) + for (i=0; idata->node_count; i++) { + gtkTreeIterInit(ih, &iterItem, ih->data->node_cache[i].node_handle); + gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_KIND, &kind, -1);  if (kind == ITREE_BRANCH) @@ -480,14 +468,6 @@ static void gtkTreeUpdateImages(Ihandle* ih, GtkTreeModel* model, GtkTreeIter it if (!has_image) gtk_tree_store_set(GTK_TREE_STORE(model), &iterItem, IUPGTK_TREE_IMAGE, ih->data->def_image_collapsed, -1); } - - if (gtk_tree_model_iter_has_child(model, &iterItem)) - { - - /* Recursively traverse child items */ - gtk_tree_model_iter_children(model, &iterChild, &iterItem); - gtkTreeUpdateImages(ih, model, iterChild, mode); - } } else  { @@ -499,9 +479,6 @@ static void gtkTreeUpdateImages(Ihandle* ih, GtkTreeModel* model, GtkTreeIter it gtk_tree_store_set(GTK_TREE_STORE(model), &iterItem, IUPGTK_TREE_IMAGE, ih->data->def_image_leaf, -1); } } - - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, &iterItem); } }  @@ -536,26 +513,49 @@ void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* t GtkTreeIter iterPrev, iterNewItem, iterParent; GtkTreePath* path; GdkColor color = {0L,0,0,0}; - int kindPrev; - - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), name_id, &iterPrev)) - return; + int kindPrev = -1;  - gtk_tree_model_get(GTK_TREE_MODEL(store), &iterPrev, IUPGTK_TREE_KIND, &kindPrev, -1); + if (!gtkTreeFindNodeFromString(ih, name_id, &iterPrev)) + { + /* check if the root was really specified */ + int id = 0; + if (!iupStrToInt(name_id, &id) || id != -1) + return; + } + else + gtk_tree_model_get(GTK_TREE_MODEL(store), &iterPrev, IUPGTK_TREE_KIND, &kindPrev, -1);  - if (kindPrev == ITREE_BRANCH && add) - gtk_tree_store_insert(store, &iterNewItem, &iterPrev, 0); /* iterPrev is parent of the new item (firstchild of it) */ + if (kindPrev != -1) + { + /* Add the new node */ + if (kindPrev == ITREE_BRANCH && add) + gtk_tree_store_insert(store, &iterNewItem, &iterPrev, 0); /* iterPrev is parent of the new item (firstchild of it) */ + else + gtk_tree_store_insert_after(store, &iterNewItem, NULL, &iterPrev); /* iterPrev is sibling of the new item */ + iupTreeAddToCache(ih, add, kindPrev, iterPrev.user_data, iterNewItem.user_data); + } else - gtk_tree_store_insert_after(store, &iterNewItem, NULL, &iterPrev); /* iterPrev is sibling of the new item */ + { + gtk_tree_store_append(store, &iterNewItem, NULL); /* root node */ + iupTreeAddToCache(ih, 0, 0, NULL, iterNewItem.user_data); + + /* store the stamp for the tree */ + ih->data->stamp = iterNewItem.stamp; + }  iupgtkGetColor(iupAttribGetStr(ih, "FGCOLOR"), &color);  + if (!title) + title = ""; + /* set the attributes of the new node */ gtk_tree_store_set(store, &iterNewItem, IUPGTK_TREE_HAS_IMAGE, FALSE, IUPGTK_TREE_HAS_IMAGE_EXPANDED, FALSE, IUPGTK_TREE_TITLE, iupgtkStrConvertToUTF8(title), IUPGTK_TREE_KIND, kind, - IUPGTK_TREE_COLOR, &color, -1); + IUPGTK_TREE_COLOR, &color,  + IUPGTK_TREE_SELECT, 0, + -1);  if (kind == ITREE_LEAF) gtk_tree_store_set(store, &iterNewItem, IUPGTK_TREE_IMAGE, ih->data->def_image_leaf, -1); @@ -563,56 +563,113 @@ void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* t gtk_tree_store_set(store, &iterNewItem, IUPGTK_TREE_IMAGE, ih->data->def_image_collapsed, IUPGTK_TREE_IMAGE_EXPANDED, ih->data->def_image_expanded, -1);  - if (kindPrev == ITREE_BRANCH && add) - iterParent = iterPrev; - else - gtk_tree_model_iter_parent(GTK_TREE_MODEL(store), &iterParent, &iterNewItem); + if (kindPrev != -1) + { + if (kindPrev == ITREE_BRANCH && add) + iterParent = iterPrev; + else if (!gtk_tree_model_iter_parent(GTK_TREE_MODEL(store), &iterParent, &iterNewItem)) + return;  - /* If this is the first child of the parent, then handle the ADDEXPANDED attribute */ - if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), &iterParent) == 1) + /* If this is the first child of the parent, then handle the ADDEXPANDED attribute */ + if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), &iterParent) == 1) + { + path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iterParent); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", "1"); + if (ih->data->add_expanded) + gtk_tree_view_expand_row(GTK_TREE_VIEW(ih->handle), path, FALSE); + else + gtk_tree_view_collapse_row(GTK_TREE_VIEW(ih->handle), path); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", NULL); + gtk_tree_path_free(path); + } + } + else { - int depth; - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iterParent); - depth = gtk_tree_path_get_depth(path)-1; - if (ih->data->add_expanded || depth==0) /* if this is the first child of the root, expand always */ + if (ih->data->node_count == 1) { - iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCHOPEN_CB", "1"); - gtk_tree_view_expand_row(GTK_TREE_VIEW(ih->handle), path, FALSE); + /* MarkStart node */ + iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)iterNewItem.user_data); + + /* Set the default VALUE */ + path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iterNewItem); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(ih->handle), path, NULL, FALSE); + gtk_tree_path_free(path); } - else - gtk_tree_view_collapse_row(GTK_TREE_VIEW(ih->handle), path); - gtk_tree_path_free(path); } }  -static void gtkTreeAddRootNode(Ihandle* ih) + +/*****************************************************************************/ +/* AUXILIAR FUNCTIONS */ +/*****************************************************************************/ + + +static void gtkTreeChildRebuildCacheRec(Ihandle* ih, GtkTreeModel *model, GtkTreeIter *iterItem, int *id) { - GtkTreeStore* store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle))); - GtkTreePath* path; - GtkTreeIter iterRoot; - GdkColor color = {0L,0,0,0}; + GtkTreeIter iterChild; + int hasItem = gtk_tree_model_iter_children(model, &iterChild, iterItem); /* get the firstchild */ + while(hasItem) + { + (*id)++; + ih->data->node_cache[*id].node_handle = iterChild.user_data;  - iupgtkGetColor(iupAttribGetStr(ih, "FGCOLOR"), &color); + /* go recursive to children */ + gtkTreeChildRebuildCacheRec(ih, model, &iterChild, id); + + /* Go to next sibling item */ + hasItem = gtk_tree_model_iter_next(model, &iterChild); + } +}  - gtk_tree_store_append(store, &iterRoot, NULL); /* root node */ - gtk_tree_store_set(store, &iterRoot, IUPGTK_TREE_IMAGE, ih->data->def_image_collapsed, - IUPGTK_TREE_HAS_IMAGE, FALSE, - IUPGTK_TREE_IMAGE_EXPANDED, ih->data->def_image_expanded, - IUPGTK_TREE_HAS_IMAGE_EXPANDED, FALSE, - IUPGTK_TREE_KIND, ITREE_BRANCH, - IUPGTK_TREE_COLOR, &color, -1); +static void gtkTreeRebuildNodeCache(Ihandle* ih, int id, GtkTreeIter iterItem) +{ + GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + ih->data->node_cache[id].node_handle = iterItem.user_data; + gtkTreeChildRebuildCacheRec(ih, model, &iterItem, &id); +} + +static void gtkTreeChildCountRec(GtkTreeModel *model, GtkTreeIter *iterItem, int *count) +{ + GtkTreeIter iterChild; + int hasItem = gtk_tree_model_iter_children(model, &iterChild, iterItem); /* get the firstchild */ + while(hasItem) + { + (*count)++;  - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iterRoot); - /* MarkStart node */ - iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)path); + /* go recursive to children */ + gtkTreeChildCountRec(model, &iterChild, count);  - /* Set the default VALUE */ - gtk_tree_view_set_cursor(GTK_TREE_VIEW(ih->handle), path, NULL, FALSE); + /* Go to next sibling item */ + hasItem = gtk_tree_model_iter_next(model, &iterChild); + } +} + +int iupdrvTreeTotalChildCount(Ihandle* ih, InodeHandle* node_handle) +{ + int count = 0; + GtkTreeIter iterItem; + GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + gtkTreeIterInit(ih, &iterItem, node_handle); + gtkTreeChildCountRec(model, &iterItem, &count); + return count; +} + +InodeHandle* iupdrvTreeGetFocusNode(Ihandle* ih) +{ + GtkTreePath* path = NULL; + gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &path, NULL); + if (path) + { + GtkTreeIter iterItem; + GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + gtk_tree_model_get_iter(model, &iterItem, path); + gtk_tree_path_free(path); + return iterItem.user_data; + } + + return NULL; }  -/*****************************************************************************/ -/* AUXILIAR FUNCTIONS */ -/*****************************************************************************/ static void gtkTreeOpenCloseEvent(Ihandle* ih) { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); @@ -620,7 +677,7 @@ static void gtkTreeOpenCloseEvent(Ihandle* ih) GtkTreePath* path; int kind;  - if (!gtkTreeFindNodeFromString(ih, model, "", &iterItem)) + if (!gtkTreeFindNodeFromString(ih, "", &iterItem)) return;  path = gtk_tree_model_get_path(model, &iterItem); @@ -637,27 +694,22 @@ static void gtkTreeOpenCloseEvent(Ihandle* ih) } }  -static gboolean gtkTreeSelected_Foreach_Func(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, GList **rowref_list) +typedef struct _gtkTreeSelectMinMax { - GtkTreeRowReference *rowref; - - rowref = gtk_tree_row_reference_new(model, path); - *rowref_list = g_list_append(*rowref_list, rowref); + Ihandle* ih; + int id1, id2; +} gtkTreeSelectMinMax;  - (void)iter; - return FALSE; /* do not stop walking the store, call us with next row */ -} - -static gboolean gtkTreeSelected_Iter_Func(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, GList **rowref_list) +static gboolean gtkTreeSelected_Foreach_Func(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iterItem, gtkTreeSelectMinMax *minmax) { - GtkTreeRowReference *rowref; - GtkTreeIter iterParent; - if (!gtk_tree_model_iter_parent(model, &iterParent, iter)) /* the root node can't be deleted */ - return FALSE; /* do not stop walking the store, call us with next row */ - - rowref = gtk_tree_row_reference_new(model, path); - *rowref_list = g_list_append(*rowref_list, rowref); + int id = iupTreeFindNodeId(minmax->ih, iterItem->user_data); + if (id < minmax->id1) + minmax->id1 = id; + if (id > minmax->id2) + minmax->id2 = id;  + (void)model; + (void)path; return FALSE; /* do not stop walking the store, call us with next row */ }  @@ -672,45 +724,48 @@ static void gtkTreeCallMultiSelectionCb(Ihandle* ih) { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle)); - GtkTreeIter iterRoot; - GList *rr_list = NULL; - GList *node; - int* id_rowItem; - int count_selected_rows, i = 0; + GtkTreeIter iterItem; + int i = 0, countItems; + gtkTreeSelectMinMax minmax;  - gtk_tree_model_get_iter_first(model, &iterRoot); + minmax.ih = ih; + minmax.id1 = ih->data->node_count; + minmax.id2 = -1;  - gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc)gtkTreeSelected_Foreach_Func, &rr_list); - count_selected_rows = g_list_length(rr_list); - id_rowItem = malloc(sizeof(int) * count_selected_rows); + gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc)gtkTreeSelected_Foreach_Func, &minmax); + if (minmax.id2 == -1) + return;  - for(node = rr_list; node != NULL; node = node->next) + /* interactive selection of several nodes will NOT select hidden nodes, + so make sure that they are selected. */ + for(i = minmax.id1; i <= minmax.id2; i++) { - GtkTreePath* path = gtk_tree_row_reference_get_path(node->data); - if (path) - { - GtkTreeIter iterItem; - gtk_tree_model_get_iter(model, &iterItem, path); - - id_rowItem[i] = gtkTreeGetNodeId(ih, iterItem); - i++; - - gtk_tree_path_free(path); - } + gtkTreeIterInit(ih, &iterItem, ih->data->node_cache[i].node_handle); + if (!gtkTreeIsNodeSelected(model, &iterItem)) + gtkTreeSelectNodeRaw(model, &iterItem, 1); }  - g_list_foreach(rr_list, (GFunc) gtk_tree_row_reference_free, NULL); - g_list_free(rr_list); + /* if last selected item is a branch, then select its children */ + iupTreeSelectLastCollapsedBranch(ih, &(minmax.id2)); + + countItems = minmax.id2-minmax.id1+1;  if (cbMulti) - cbMulti(ih, id_rowItem, count_selected_rows); - else { - for (i=0; ihandle))); GtkTreeIter iterItem; GtkTreePath* path; + int kind;  - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), value, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, value, &iterItem)) return 0;  path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iterItem);  - if (!gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path)) + gtk_tree_model_get(GTK_TREE_MODEL(store), &iterItem, IUPGTK_TREE_KIND, &kind, -1); + if (kind == ITREE_LEAF) + gtk_tree_view_expand_to_path(GTK_TREE_VIEW(ih->handle), path); + else + { + int expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path); gtk_tree_view_expand_to_path(GTK_TREE_VIEW(ih->handle), path); + if (!expanded) gtk_tree_view_collapse_row(GTK_TREE_VIEW(ih->handle), path); + }  gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(ih->handle), path, NULL, FALSE, 0, 0); /* scroll to visible */  @@ -788,34 +851,23 @@ static int gtkTreeSetExpandAllAttrib(Ihandle* ih, const char* value) if (iupStrBoolean(value)) gtk_tree_view_expand_all(GTK_TREE_VIEW(ih->handle)); else - { - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - GtkTreeIter iterRoot; - GtkTreePath* pathRoot; - gtk_tree_view_collapse_all(GTK_TREE_VIEW(ih->handle));  - /* The root node is always expanded */ - gtk_tree_model_get_iter_first(model, &iterRoot); - pathRoot = gtk_tree_model_get_path(model, &iterRoot); - gtk_tree_view_expand_row(GTK_TREE_VIEW(ih->handle), pathRoot, FALSE); - gtk_tree_path_free(pathRoot); - } - return 0; }  static char* gtkTreeGetDepthAttrib(Ihandle* ih, const char* name_id) { - char* depth; + char* str; GtkTreeStore* store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle))); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), name_id, &iterItem)) + + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return NULL;  - depth = iupStrGetMemory(10); - sprintf(depth, "%d", gtk_tree_store_iter_depth(store, &iterItem)); - return depth; + str = iupStrGetMemory(10); + sprintf(str, "%d", gtk_tree_store_iter_depth(store, &iterItem)); + return str; }  static int gtkTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char* value) @@ -824,14 +876,14 @@ static int gtkTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char GtkTreeIter iterItemSrc, iterItemDst, iterNewItem; GtkTreeIter iterParent, iterNextParent;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0;  model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItemSrc)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItemSrc)) return 0;  - if (!gtkTreeFindNodeFromString(ih, model, value, &iterItemDst)) + if (!gtkTreeFindNodeFromString(ih, value, &iterItemDst)) return 0;  /* If Drag item is an ancestor of Drop item then return */ @@ -843,12 +895,8 @@ static int gtkTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char iterParent = iterNextParent; }  - /* Copying the node and its children to the new position */ - gtkTreeCopyNode(ih, model, &iterItemSrc, &iterItemDst, &iterNewItem, 0); /* not a full copy, preserve user data */ - - /* Deleting the node of its old position */ - /* do not delete the user data, we copy the references in CopyNode */ - gtk_tree_store_remove(GTK_TREE_STORE(model), &iterItemSrc); + /* Move the node and its children to the new position */ + gtkTreeCopyMoveNode(ih, model, &iterItemSrc, &iterItemDst, &iterNewItem, 0);  return 0; } @@ -859,14 +907,14 @@ static int gtkTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char GtkTreeIter iterItemSrc, iterItemDst, iterNewItem; GtkTreeIter iterParent, iterNextParent;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0;  model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItemSrc)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItemSrc)) return 0;  - if (!gtkTreeFindNodeFromString(ih, model, value, &iterItemDst)) + if (!gtkTreeFindNodeFromString(ih, value, &iterItemDst)) return 0;  /* If Drag item is an ancestor of Drop item then return */ @@ -878,8 +926,8 @@ static int gtkTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char iterParent = iterNextParent; }  - /* Copying the node and its children to the new position */ - gtkTreeCopyNode(ih, model, &iterItemSrc, &iterItemDst, &iterNewItem, 1); + /* Copy the node and its children to the new position */ + gtkTreeCopyMoveNode(ih, model, &iterItemSrc, &iterItemDst, &iterNewItem, 1);  return 0; } @@ -891,7 +939,7 @@ static char* gtkTreeGetColorAttrib(Ihandle* ih, const char* name_id) GtkTreeIter iterItem; GdkColor *color;  - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return NULL;  gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_COLOR, &color, -1); @@ -912,7 +960,7 @@ static int gtkTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* v GdkColor color; unsigned char r, g, b;  - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  if (!iupStrToRGB(value, &r, &g, &b)) @@ -931,14 +979,14 @@ static char* gtkTreeGetParentAttrib(Ihandle* ih, const char* name_id) GtkTreeIter iterParent; char* str;  - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return NULL;  if (!gtk_tree_model_iter_parent(model, &iterParent, &iterItem)) return NULL;  str = iupStrGetMemory(10); - sprintf(str, "%d", gtkTreeGetNodeId(ih, iterParent)); + sprintf(str, "%d", gtkTreeFindNodeId(ih, &iterParent)); return str; }  @@ -948,7 +996,7 @@ static char* gtkTreeGetChildCountAttrib(Ihandle* ih, const char* name_id) GtkTreeIter iterItem; char* str;  - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return NULL;  str = iupStrGetMemory(10); @@ -956,40 +1004,13 @@ static char* gtkTreeGetChildCountAttrib(Ihandle* ih, const char* name_id) return str; }  -static int gtkTreeCount(GtkTreeModel* model, GtkTreeIter iterBranch) -{ - GtkTreeIter iterChild; - int count = 0; - int hasItem = gtk_tree_model_iter_children(model, &iterChild, &iterBranch); /* get the firstchild */ - count++; - while(hasItem) - { - count += gtkTreeCount(model, iterChild); - - /* Go to next sibling item */ - hasItem = gtk_tree_model_iter_next(model, &iterChild); - } - - return count; -} - -static char* gtkTreeGetCountAttrib(Ihandle* ih) -{ - GtkTreeIter iterRoot; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - char* str = iupStrGetMemory(10); - gtk_tree_model_get_iter_first(model, &iterRoot); - sprintf(str, "%d", gtkTreeCount(model, iterRoot)); - return str; -} - static char* gtkTreeGetKindAttrib(Ihandle* ih, const char* name_id) { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeIter iterItem; int kind;  - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return NULL;  gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_KIND, &kind, -1); @@ -1005,7 +1026,7 @@ static char* gtkTreeGetStateAttrib(Ihandle* ih, const char* name_id) GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeIter iterItem;  - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return NULL;  if (gtk_tree_model_iter_has_child(model, &iterItem)) @@ -1028,13 +1049,20 @@ static int gtkTreeSetStateAttrib(Ihandle* ih, const char* name_id, const char* v GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeIter iterItem; GtkTreePath* path; + int kind;  - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  - path = gtk_tree_model_get_path(model, &iterItem); - gtkTreeExpandItem(ih, path, iupStrEqualNoCase(value, "EXPANDED")); - gtk_tree_path_free(path); + gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_KIND, &kind, -1); + if (kind == ITREE_BRANCH) + { + path = gtk_tree_model_get_path(model, &iterItem); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", "1"); + gtkTreeExpandItem(ih, path, iupStrEqualNoCase(value, "EXPANDED")); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", NULL); + gtk_tree_path_free(path); + }  return 0; } @@ -1050,7 +1078,7 @@ static char* gtkTreeGetTitleAttrib(Ihandle* ih, const char* name_id) { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return NULL; return gtkTreeGetTitle(model, iterItem); } @@ -1059,8 +1087,10 @@ static int gtkTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* v { GtkTreeStore* store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle))); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0; + if (!value) + value = ""; gtk_tree_store_set(store, &iterItem, IUPGTK_TREE_TITLE, iupgtkStrConvertToUTF8(value), -1); return 0; } @@ -1070,7 +1100,7 @@ static int gtkTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const cha PangoFontDescription* fontdesc = NULL; GtkTreeStore* store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle))); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0; if (value) fontdesc = iupgtkGetPangoFontDesc(value); @@ -1083,49 +1113,12 @@ static char* gtkTreeGetTitleFontAttrib(Ihandle* ih, const char* name_id) PangoFontDescription* fontdesc; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return NULL; gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_FONT, &fontdesc, -1); return pango_font_description_to_string(fontdesc); }  -static char* gtkTreeGetFindUserDataAttrib(Ihandle* ih, const char* name_id) -{ - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - int id; - char* str = (char*)(name_id+1); /* skip ':' */ - void* userdata = NULL; - if (sscanf(str, "%p", &userdata)!=1) - return NULL; - id = gtkTreeGetUserDataId(ih, model, userdata); - if (id == -1) - return NULL; - str = iupStrGetMemory(16); - sprintf(str, "%d", id); - return str; -} - -static char* gtkTreeGetUserDataAttrib(Ihandle* ih, const char* name_id) -{ - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - GtkTreeIter iterItem; - char* userdata; - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) - return NULL; - gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_USERDATA, &userdata, -1); - return userdata; -} - -static int gtkTreeSetUserDataAttrib(Ihandle* ih, const char* name_id, const char* value) -{ - GtkTreeStore* store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle))); - GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), name_id, &iterItem)) - return 0; - gtk_tree_store_set(store, &iterItem, IUPGTK_TREE_USERDATA, value, -1); - return 0; -} - static char* gtkTreeGetValueAttrib(Ihandle* ih) { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); @@ -1140,67 +1133,117 @@ static char* gtkTreeGetValueAttrib(Ihandle* ih) gtk_tree_path_free(path);  str = iupStrGetMemory(16); - sprintf(str, "%d", gtkTreeGetNodeId(ih, iterItem)); + sprintf(str, "%d", gtkTreeFindNodeId(ih, &iterItem)); return str; }  - return "0"; /* default VALUE is root */ + if (ih->data->node_count) + return "0"; /* default VALUE is root */ + else + return "-1"; +} + +static char* gtkTreeGetMarkedNodesAttrib(Ihandle* ih) +{ + char* str = iupStrGetMemory(ih->data->node_count+1); + GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + GtkTreeIter iterItem; + int i; + + for (i=0; idata->node_count; i++) + { + gtkTreeIterInit(ih, &iterItem, ih->data->node_cache[i].node_handle); + if (gtkTreeIsNodeSelected(model, &iterItem)) + str[i] = '+'; + else + str[i] = '-'; + } + + str[ih->data->node_count] = 0; + return str; +} + +static int gtkTreeSetMarkedNodesAttrib(Ihandle* ih, const char* value) +{ + int count, i; + GtkTreeModel* model; + GtkTreeIter iterItem; + GtkTreeSelection* selection; + + if (ih->data->mark_mode==ITREE_MARK_SINGLE || !value) + return 0; + + count = strlen(value); + if (count > ih->data->node_count) + count = ih->data->node_count; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle)); + model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + + for (i=0; idata->node_cache[i].node_handle); + if (value[i] == '+') + gtkTreeSelectNode(model, selection, &iterItem, 1); + else + gtkTreeSelectNode(model, selection, &iterItem, 0); + } + + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); + + return 0; }  static int gtkTreeSetMarkAttrib(Ihandle* ih, const char* value) { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle)); - GtkTreeIter iterRoot;  if (ih->data->mark_mode==ITREE_MARK_SINGLE) return 0;  - gtk_tree_model_get_iter_first(model, &iterRoot); - if(iupStrEqualNoCase(value, "BLOCK")) { + GtkTreeIter iterItem1, iterItem2; GtkTreePath* pathFocus; gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &pathFocus, NULL); - gtk_tree_selection_select_range(selection, (GtkTreePath*)iupAttribGet(ih, "_IUPTREE_MARKSTART_NODE"), pathFocus); + gtk_tree_model_get_iter(model, &iterItem1, pathFocus); gtk_tree_path_free(pathFocus); + + gtkTreeIterInit(ih, &iterItem2, iupAttribGet(ih, "_IUPTREE_MARKSTART_NODE")); + + gtkTreeSelectRange(ih, model, selection, &iterItem1, &iterItem2, 0); } else if(iupStrEqualNoCase(value, "CLEARALL")) - gtk_tree_selection_unselect_all(selection); + gtkTreeSelectAll(ih, model, selection, 0); else if(iupStrEqualNoCase(value, "MARKALL")) - gtk_tree_selection_select_all(selection); + gtkTreeSelectAll(ih, model, selection, 1); else if(iupStrEqualNoCase(value, "INVERTALL")) /* INVERTALL *MUST* appear before INVERT, or else INVERTALL will never be called. */ - gtkTreeInvertAllNodeMarking(ih, model, selection, &iterRoot); + gtkTreeInvertAllNodeMarking(ih, model, selection); else if(iupStrEqualPartial(value, "INVERT")) { /* iupStrEqualPartial allows the use of "INVERTid" form */ GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, model, &value[strlen("INVERT")], &iterItem)) + if (!gtkTreeFindNodeFromString(ih, &value[strlen("INVERT")], &iterItem)) return 0;  - if(gtk_tree_selection_iter_is_selected(selection, &iterItem)) - gtk_tree_selection_unselect_iter(selection, &iterItem); - else - gtk_tree_selection_select_iter(selection, &iterItem); + gtkTreeSelectNode(model, selection, &iterItem, -1); /* toggle */ } else { - GtkTreePath *path1, *path2; GtkTreeIter iterItem1, iterItem2; char str1[50], str2[50]; if (iupStrToStrStr(value, str1, str2, '-')!=2) return 0;  - if (!gtkTreeFindNodeFromString(ih, model, str1, &iterItem1)) + if (!gtkTreeFindNodeFromString(ih, str1, &iterItem1)) return 0; - if (!gtkTreeFindNodeFromString(ih, model, str2, &iterItem2)) + if (!gtkTreeFindNodeFromString(ih, str2, &iterItem2)) return 0;  - path1 = gtk_tree_model_get_path(model, &iterItem1); - path2 = gtk_tree_model_get_path(model, &iterItem2); - gtk_tree_selection_select_range(selection, path1, path2); - gtk_tree_path_free(path1); - gtk_tree_path_free(path2); + gtkTreeSelectRange(ih, model, selection, &iterItem1, &iterItem2, 0); }  return 1; @@ -1210,148 +1253,112 @@ static int gtkTreeSetValueAttrib(Ihandle* ih, const char* value) { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle)); - GtkTreeIter iterRoot, iterItem; + GtkTreeIter iterItem; GtkTreePath* path; + int kind;  if (gtkTreeSetMarkAttrib(ih, value)) return 0;  - gtk_tree_model_get_iter_first(model, &iterRoot); - - if (iupStrEqualNoCase(value, "ROOT")) - iterItem = iterRoot; + if (iupStrEqualNoCase(value, "ROOT") || iupStrEqualNoCase(value, "FIRST")) + gtk_tree_model_get_iter_first(model, &iterItem); else if(iupStrEqualNoCase(value, "LAST")) - iterItem = gtkTreeGetLastVisibleNode(ih, model, iterRoot); + gtkTreeGetLastVisibleNode(ih, model, &iterItem); else if(iupStrEqualNoCase(value, "PGUP")) { - GtkTreeIter iterPrev; - GtkTreePath* pathFocus; gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &pathFocus, NULL); - gtk_tree_model_get_iter(model, &iterPrev, pathFocus); + gtk_tree_model_get_iter(model, &iterItem, pathFocus); gtk_tree_path_free(pathFocus);  - ih->data->id_control = -1; - gtkTreeFindVisibleNodeId(ih, model, iterRoot, iterPrev); - ih->data->id_control -= 10; /* less 10 visible nodes */ - - if(ih->data->id_control < 0) - ih->data->id_control = 0; /* Begin of tree = Root id */ - - iterItem = gtkTreeFindVisibleNodeFromId(ih, model, iterRoot); + gtkTreeGetPreviousVisibleNode(ih, model, &iterItem, 10); } else if(iupStrEqualNoCase(value, "PGDN")) { - GtkTreeIter iterNext; - GtkTreePath* pathFocus; gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &pathFocus, NULL); - gtk_tree_model_get_iter(model, &iterNext, pathFocus); + gtk_tree_model_get_iter(model, &iterItem, pathFocus); gtk_tree_path_free(pathFocus);  - ih->data->id_control = -1; - gtkTreeFindVisibleNodeId(ih, model, iterRoot, iterNext); - ih->data->id_control += 10; /* more 10 visible nodes */ - - iterNext = gtkTreeFindVisibleNodeFromId(ih, model, iterRoot); - - if (ih->data->id_control >= 0) - iterNext = gtkTreeGetLastVisibleNode(ih, model, iterRoot); - - iterItem = iterNext; + gtkTreeGetNextVisibleNode(ih, model, &iterItem, 10); } else if(iupStrEqualNoCase(value, "NEXT")) { - GtkTreeIter iterNext; - GtkTreePath* pathFocus; gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &pathFocus, NULL); - gtk_tree_model_get_iter(model, &iterNext, pathFocus); + gtk_tree_model_get_iter(model, &iterItem, pathFocus); gtk_tree_path_free(pathFocus);  - ih->data->id_control = -1; - gtkTreeFindVisibleNodeId(ih, model, iterRoot, iterNext); - ih->data->id_control++; /* more 1 visible node */ - - iterNext = gtkTreeFindVisibleNodeFromId(ih, model, iterRoot); - - if (ih->data->id_control >= 0) - iterNext = gtkTreeGetLastVisibleNode(ih, model, iterRoot); - - iterItem = iterNext; + gtkTreeGetNextVisibleNode(ih, model, &iterItem, 1); } else if(iupStrEqualNoCase(value, "PREVIOUS")) { - GtkTreeIter iterPrev; - GtkTreePath* pathFocus; gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &pathFocus, NULL); - gtk_tree_model_get_iter(model, &iterPrev, pathFocus); + gtk_tree_model_get_iter(model, &iterItem, pathFocus); gtk_tree_path_free(pathFocus);  - ih->data->id_control = -1; - gtkTreeFindVisibleNodeId(ih, model, iterRoot, iterPrev); - ih->data->id_control--; /* less 1 visible node */ - - if (ih->data->id_control < 0) - ih->data->id_control = 0; - - iterItem = gtkTreeFindVisibleNodeFromId(ih, model, iterRoot); - if (!iterItem.user_data) - return 0; + gtkTreeGetPreviousVisibleNode(ih, model, &iterItem, 1); } else { - if (!gtkTreeFindNodeFromString(ih, model, value, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, value, &iterItem)) return 0; }  /* select */ if (ih->data->mark_mode==ITREE_MARK_SINGLE) { - iupAttribSetStr(ih, "_IUP_IGNORE_SELECTION", "1"); - gtk_tree_selection_select_iter(selection, &iterItem); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + gtkTreeSelectNode(model, selection, &iterItem, 1); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); }  path = gtk_tree_model_get_path(model, &iterItem); + + /* make it visible */ + gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_KIND, &kind, -1); + if (kind == ITREE_LEAF) + gtk_tree_view_expand_to_path(GTK_TREE_VIEW(ih->handle), path); + else + { + int expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path); + gtk_tree_view_expand_to_path(GTK_TREE_VIEW(ih->handle), path); + if (!expanded) gtk_tree_view_collapse_row(GTK_TREE_VIEW(ih->handle), path); + } + gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(ih->handle), path, NULL, FALSE, 0, 0); /* scroll to visible */ + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); gtk_tree_view_set_cursor(GTK_TREE_VIEW(ih->handle), path, NULL, FALSE); /* set focus */ + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); + gtk_tree_path_free(path);  - iupAttribSetInt(ih, "_IUPTREE_OLDVALUE", gtkTreeGetNodeId(ih, iterItem)); + iupAttribSetInt(ih, "_IUPTREE_OLDVALUE", gtkTreeFindNodeId(ih, &iterItem));  return 0; }   static int gtkTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id) { - GtkTreePath *pathMarkStart, *pathMarkStartPrev; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  - pathMarkStart = gtk_tree_model_get_path(model, &iterItem); - - pathMarkStartPrev = (GtkTreePath*)iupAttribGet(ih, "_IUPTREE_MARKSTART_NODE"); - if (pathMarkStartPrev) - gtk_tree_path_free(pathMarkStartPrev); - - iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)pathMarkStart); + iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)iterItem.user_data);  return 1; }  static char* gtkTreeGetMarkedAttrib(Ihandle* ih, const char* name_id) { - GtkTreeSelection* selection; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + GtkTreeModel* model; GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle)); - if (gtk_tree_selection_iter_is_selected(selection, &iterItem)) + model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + if (gtkTreeIsNodeSelected(model, &iterItem)) return "YES"; else return "NO"; @@ -1359,87 +1366,99 @@ static char* gtkTreeGetMarkedAttrib(Ihandle* ih, const char* name_id)  static int gtkTreeSetMarkedAttrib(Ihandle* ih, const char* name_id, const char* value) { + GtkTreeModel* model; GtkTreeSelection* selection; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  - iupAttribSetStr(ih, "_IUP_IGNORE_SELECTION", "1"); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle)); + model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); if (iupStrBoolean(value)) - gtk_tree_selection_select_iter(selection, &iterItem); + gtkTreeSelectNode(model, selection, &iterItem, 1); else - gtk_tree_selection_unselect_iter(selection, &iterItem); + gtkTreeSelectNode(model, selection, &iterItem, 0); + + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);  return 0; }  static int gtkTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; - if (iupStrEqualNoCase(value, "SELECTED")) /* selected here means the specified one */ + if (iupStrEqualNoCase(value, "ALL")) { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - GtkTreeIter iterItem; - GtkTreeIter iterParent; + gtkTreeCallNodeRemovedAll(ih);  - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) - return 0; + /* deleting the reference node (and it's children) */ + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + gtk_tree_store_clear(GTK_TREE_STORE(model)); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); + return 0; + } + if (iupStrEqualNoCase(value, "SELECTED")) /* selected here means the reference node */ + { + GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + GtkTreeIter iterItem;  - if (!gtk_tree_model_iter_parent(model, &iterParent, &iterItem)) /* the root node can't be deleted */ + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  gtkTreeCallNodeRemoved(ih, model, &iterItem);  - /* deleting the specified node (and it's children) */ + /* deleting the reference node (and it's children) */ + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); gtk_tree_store_remove(GTK_TREE_STORE(model), &iterItem); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); } - else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the specified one */ + else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the reference node */ { GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); GtkTreeIter iterItem, iterChild; int hasChildren;  - if (!gtkTreeFindNodeFromString(ih, model, name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  hasChildren = gtk_tree_model_iter_children(model, &iterChild, &iterItem);  - /* deleting the selected node's children */ + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + + /* deleting the reference node children */ while(hasChildren) { gtkTreeCallNodeRemoved(ih, model, &iterChild); hasChildren = gtk_tree_store_remove(GTK_TREE_STORE(model), &iterChild); } + + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); } else if(iupStrEqualNoCase(value, "MARKED")) /* Delete the array of marked nodes */ { + int i; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle)); - GList *rr_list = NULL; - GList *node; + GtkTreeIter iterItem;  - gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc)gtkTreeSelected_Iter_Func, &rr_list); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");  - for(node = rr_list; node != NULL; node = node->next) + for(i = 1; i < ih->data->node_count; /* increment only if not removed */) { - GtkTreePath* path = gtk_tree_row_reference_get_path(node->data); - if (path) + gtkTreeIterInit(ih, &iterItem, ih->data->node_cache[i].node_handle); + if (gtkTreeIsNodeSelected(model, &iterItem)) { - GtkTreeIter iterItem; - if (gtk_tree_model_get_iter(model, &iterItem, path)) - { - gtkTreeCallNodeRemoved(ih, model, &iterItem); - gtk_tree_store_remove(GTK_TREE_STORE(model), &iterItem); - } - gtk_tree_path_free(path); + gtkTreeCallNodeRemoved(ih, model, &iterItem); + gtk_tree_store_remove(GTK_TREE_STORE(model), &iterItem); } - gtk_tree_row_reference_free(node->data); + else + i++; } - g_list_free(rr_list); + + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); }  return 0; @@ -1450,36 +1469,11 @@ static int gtkTreeSetRenameAttrib(Ihandle* ih, const char* value) if (ih->data->show_rename) { GtkTreePath* path; - IFni cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB"); GtkTreeViewColumn *focus_column; - gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &path, &focus_column); - - if (cbShowRename) - { - GtkTreeIter iterItem; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - gtk_tree_model_get_iter(model, &iterItem, path); - cbShowRename(ih, gtkTreeGetNodeId(ih, iterItem)); - } - gtk_tree_view_set_cursor(GTK_TREE_VIEW(ih->handle), path, focus_column, TRUE); gtk_tree_path_free(path); } - else - { - IFnis cbRenameNode = (IFnis)IupGetCallback(ih, "RENAMENODE_CB"); - if (cbRenameNode) - { - GtkTreePath* path; - GtkTreeIter iterItem; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &path, NULL); - gtk_tree_model_get_iter(model, &iterItem, path); - gtk_tree_path_free(path); - cbRenameNode(ih, gtkTreeGetNodeId(ih, iterItem), gtkTreeGetTitle(model, iterItem));  - } - }  (void)value; return 0; @@ -1491,7 +1485,7 @@ static int gtkTreeSetImageExpandedAttrib(Ihandle* ih, const char* name_id, const GtkTreeStore* store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle))); GdkPixbuf* pixExpand = iupImageGetImage(value, ih, 0); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  gtk_tree_model_get(GTK_TREE_MODEL(store), &iterItem, IUPGTK_TREE_KIND, &kind, -1); @@ -1514,7 +1508,7 @@ static int gtkTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v GtkTreeStore* store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle))); GdkPixbuf* pixImage = iupImageGetImage(value, ih, 0); GtkTreeIter iterItem; - if (!gtkTreeFindNodeFromString(ih, GTK_TREE_MODEL(store), name_id, &iterItem)) + if (!gtkTreeFindNodeFromString(ih, name_id, &iterItem)) return 0;  if (pixImage) @@ -1539,42 +1533,30 @@ static int gtkTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v  static int gtkTreeSetImageBranchExpandedAttrib(Ihandle* ih, const char* value) { - GtkTreeIter iterRoot; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); ih->data->def_image_expanded = iupImageGetImage(value, ih, 0);  - gtk_tree_model_get_iter_first(model, &iterRoot); - - /* Update all images, starting at root node */ - gtkTreeUpdateImages(ih, model, iterRoot, ITREE_UPDATEIMAGE_EXPANDED); + /* Update all images */ + gtkTreeUpdateImages(ih, ITREE_UPDATEIMAGE_EXPANDED);  return 1; }  static int gtkTreeSetImageBranchCollapsedAttrib(Ihandle* ih, const char* value) { - GtkTreeIter iterRoot; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); ih->data->def_image_collapsed = iupImageGetImage(value, ih, 0);  - gtk_tree_model_get_iter_first(model, &iterRoot); - - /* Update all images, starting at root node */ - gtkTreeUpdateImages(ih, model, iterRoot, ITREE_UPDATEIMAGE_COLLAPSED); + /* Update all images */ + gtkTreeUpdateImages(ih, ITREE_UPDATEIMAGE_COLLAPSED);  return 1; }  static int gtkTreeSetImageLeafAttrib(Ihandle* ih, const char* value) { - GtkTreeIter iterRoot; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); ih->data->def_image_leaf = iupImageGetImage(value, ih, 0);  - gtk_tree_model_get_iter_first(model, &iterRoot); - - /* Update all images, starting at root node */ - gtkTreeUpdateImages(ih, model, iterRoot, ITREE_UPDATEIMAGE_LEAF); + /* Update all images */ + gtkTreeUpdateImages(ih, ITREE_UPDATEIMAGE_LEAF);  return 1; } @@ -1655,6 +1637,7 @@ void iupdrvTreeUpdateMarkMode(Ihandle *ih) if (ih->data->mark_mode==ITREE_MARK_MULTIPLE && !ih->data->show_dragdrop) { #if GTK_CHECK_VERSION(2, 10, 0) + if (iupAttribGetInt(ih, "RUBBERBAND")) gtk_tree_view_set_rubber_banding(GTK_TREE_VIEW(ih->handle), TRUE); #endif } @@ -1704,6 +1687,19 @@ static void gtkTreeCellTextEditingStarted(GtkCellRenderer *cell, GtkCellEditable PangoFontDescription* fontdesc = NULL; GdkColor *color = NULL; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + IFni cbShowRename; + + gtk_tree_model_get_iter_from_string(model, &iterItem, path_string); + + cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB"); + if (cbShowRename && cbShowRename(ih, gtkTreeFindNodeId(ih, &iterItem))==IUP_IGNORE) + { + /* TODO: non of these worked: + gtk_cell_renderer_stop_editing(cell, TRUE); + gtk_cell_editable_editing_done(editable); */ + gtk_editable_set_editable(GTK_EDITABLE(editable), FALSE); + return; + }  value = iupAttribGetStr(ih, "RENAMECARET"); if (value) @@ -1713,7 +1709,6 @@ static void gtkTreeCellTextEditingStarted(GtkCellRenderer *cell, GtkCellEditable if (value) gtkTreeSetRenameSelectionPos(editable, value);  - gtk_tree_model_get_iter_from_string(model, &iterItem, path_string); gtk_tree_model_get(model, &iterItem, IUPGTK_TREE_FONT, &fontdesc, -1); if (fontdesc) gtk_widget_modify_font(GTK_WIDGET(editable), fontdesc); @@ -1732,7 +1727,7 @@ static void gtkTreeCellTextEdited(GtkCellRendererText *cell, gchar *path_string, IFnis cbRename;  if (!new_text) - return; + new_text = "";  model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); if (!gtk_tree_model_get_iter_from_string(model, &iterItem, path_string)) @@ -1741,7 +1736,7 @@ static void gtkTreeCellTextEdited(GtkCellRendererText *cell, gchar *path_string, cbRename = (IFnis)IupGetCallback(ih, "RENAME_CB"); if (cbRename) { - if (cbRename(ih, gtkTreeGetNodeId(ih, iterItem), iupgtkStrConvertFromUTF8(new_text)) == IUP_IGNORE) + if (cbRename(ih, gtkTreeFindNodeId(ih, &iterItem), iupgtkStrConvertFromUTF8(new_text)) == IUP_IGNORE) return; }  @@ -1766,8 +1761,8 @@ static int gtkTreeCallDragDropCb(Ihandle* ih, GtkTreeIter *iterDrag, GtkTreeIter  if (cbDragDrop) { - int drag_id = gtkTreeGetNodeId(ih, *iterDrag); - int drop_id = gtkTreeGetNodeId(ih, *iterDrop); + int drag_id = gtkTreeFindNodeId(ih, iterDrag); + int drop_id = gtkTreeFindNodeId(ih, iterDrop); return cbDragDrop(ih, drag_id, drop_id, is_shift, *is_ctrl); }  @@ -1804,22 +1799,17 @@ static void gtkTreeDragDataReceived(GtkWidget *widget, GdkDragContext *context, { GtkTreeIter iterNewItem;  - /* Copy the dragged item to the new position. */ - gtkTreeCopyNode(ih, model, &iterDrag, &iterDrop, &iterNewItem, is_ctrl); - - if (!is_ctrl) - { - /* do not delete the user data, we copy the references in CopyNode */ - gtk_tree_store_remove(GTK_TREE_STORE(model), &iterDrag); - } + /* Copy or move the dragged item to the new position. */ + gtkTreeCopyMoveNode(ih, model, &iterDrag, &iterDrop, &iterNewItem, is_ctrl);  /* set focus and selection */ + if (iterNewItem.stamp) { GtkTreePath *pathNew; GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle));  pathNew = gtk_tree_model_get_path(model, &iterNewItem); - gtk_tree_selection_select_path(selection, pathNew); + gtkTreeSelectNode(model, selection, &iterNewItem, 1);  gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(ih->handle), pathNew, NULL, FALSE, 0, 0); gtk_tree_view_set_cursor(GTK_TREE_VIEW(ih->handle), pathNew, NULL, FALSE); @@ -1927,10 +1917,24 @@ static void gtkTreeDragBegin(GtkWidget *widget, GdkDragContext *context, Ihandle (void)widget; }  +static gboolean gtkTreeSelectionFunc(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean selected, Ihandle* ih) +{ + GtkTreeIter iterItem; + gtk_tree_model_get_iter(model, &iterItem, path); + gtkTreeSelectNodeRaw(model, &iterItem, !selected); + (void)ih; + (void)selection; + return TRUE; +} + static void gtkTreeSelectionChanged(GtkTreeSelection* selection, Ihandle* ih) { IFnii cbSelec; int is_ctrl = 0; + (void)selection; + + if (iupAttribGet(ih, "_IUPTREE_IGNORE_SELECTION_CB")) + return;  if (ih->data->mark_mode == ITREE_MARK_MULTIPLE) { @@ -1953,25 +1957,17 @@ static void gtkTreeSelectionChanged(GtkTreeSelection* selection, Ihandle* ih) if (cbSelec) { int curpos = -1, is_selected = 0; + GtkTreeIter iterFocus; + GtkTreePath* pathFocus; + GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle));  - if (iupAttribGet(ih, "_IUP_IGNORE_SELECTION")) - { - iupAttribSetStr(ih, "_IUP_IGNORE_SELECTION", NULL); - return; - } - + gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &pathFocus, NULL); + if (pathFocus) { - GtkTreeIter iterFocus; - GtkTreePath* pathFocus; - GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); - gtk_tree_view_get_cursor(GTK_TREE_VIEW(ih->handle), &pathFocus, NULL); - if (pathFocus) - { - gtk_tree_model_get_iter(model, &iterFocus, pathFocus); - gtk_tree_path_free(pathFocus); - curpos = gtkTreeGetNodeId(ih, iterFocus); - is_selected = gtk_tree_selection_iter_is_selected(selection, &iterFocus); - } + gtk_tree_model_get_iter(model, &iterFocus, pathFocus); + gtk_tree_path_free(pathFocus); + curpos = gtkTreeFindNodeId(ih, &iterFocus); + is_selected = gtkTreeIsNodeSelected(model, &iterFocus); }  if (curpos == -1) @@ -1993,18 +1989,52 @@ static void gtkTreeSelectionChanged(GtkTreeSelection* selection, Ihandle* ih) } }  +static void gtkTreeUpdateSelectionChildren(Ihandle* ih, GtkTreeModel* model, GtkTreeSelection* selection, GtkTreeIter *iterItem) +{ + int expanded; + GtkTreeIter iterChild; + int hasItem = gtk_tree_model_iter_children(model, &iterChild, iterItem); /* get the firstchild */ + while(hasItem) + { + if (gtkTreeIsNodeSelected(model, &iterChild)) + gtk_tree_selection_select_iter(selection, &iterChild); + + expanded = 0; + if (gtk_tree_model_iter_has_child(model, &iterChild)) + { + GtkTreePath* path = gtk_tree_model_get_path(model, &iterChild); + expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(ih->handle), path); + gtk_tree_path_free(path); + } + + /* Recursive only if expanded */ + if (expanded) + gtkTreeUpdateSelectionChildren(ih, model, selection, &iterChild);  + + /* Go to next sibling item */ + hasItem = gtk_tree_model_iter_next(model, &iterChild); + } +} + +static void gtkTreeRowExpanded(GtkTreeView* tree_view, GtkTreeIter *iterItem, GtkTreePath *path, Ihandle* ih) +{ + GtkTreeSelection* selection = gtk_tree_view_get_selection(tree_view); + GtkTreeModel* model = gtk_tree_view_get_model(tree_view); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + gtkTreeUpdateSelectionChildren(ih, model, selection, iterItem); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); + (void)path; +} + static gboolean gtkTreeTestExpandRow(GtkTreeView* tree_view, GtkTreeIter *iterItem, GtkTreePath *path, Ihandle* ih) { IFni cbBranchOpen = (IFni)IupGetCallback(ih, "BRANCHOPEN_CB"); if (cbBranchOpen) { - if (iupAttribGet(ih, "_IUPTREE_IGNORE_BRANCHOPEN_CB")) - { - iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCHOPEN_CB", NULL); + if (iupAttribGet(ih, "_IUPTREE_IGNORE_BRANCH_CB")) return FALSE; - }  - if (cbBranchOpen(ih, gtkTreeGetNodeId(ih, *iterItem)) == IUP_IGNORE) + if (cbBranchOpen(ih, gtkTreeFindNodeId(ih, iterItem)) == IUP_IGNORE) return TRUE; /* prevent the change */ }  @@ -2018,7 +2048,10 @@ static gboolean gtkTreeTestCollapseRow(GtkTreeView* tree_view, GtkTreeIter *iter IFni cbBranchClose = (IFni)IupGetCallback(ih, "BRANCHCLOSE_CB"); if (cbBranchClose) { - if (cbBranchClose(ih, gtkTreeGetNodeId(ih, *iterItem)) == IUP_IGNORE) + if (iupAttribGet(ih, "_IUPTREE_IGNORE_BRANCH_CB")) + return FALSE; + + if (cbBranchClose(ih, gtkTreeFindNodeId(ih, iterItem)) == IUP_IGNORE) return TRUE; }  @@ -2042,7 +2075,7 @@ static void gtkTreeRowActived(GtkTreeView* tree_view, GtkTreePath *path, GtkTree  /* just to leaf nodes */ if(gtk_tree_model_iter_has_child(model, &iterItem) == 0 && kind == ITREE_LEAF) - cbExecuteLeaf(ih, gtkTreeGetNodeId(ih, iterItem)); + cbExecuteLeaf(ih, gtkTreeFindNodeId(ih, &iterItem));  (void)column; (void)tree_view; @@ -2057,11 +2090,57 @@ static int gtkTreeConvertXYToPos(Ihandle* ih, int x, int y) GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); gtk_tree_model_get_iter(model, &iterItem, path); gtk_tree_path_free (path); - return gtkTreeGetNodeId(ih, iterItem); + return gtkTreeFindNodeId(ih, &iterItem); } return -1; }  +static Iarray* gtkTreeGetSelectedArrayId(Ihandle* ih) +{ + Iarray* selarray = iupArrayCreate(1, sizeof(int)); + int i; + GtkTreeIter iterItem; + GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(ih->handle)); + + for (i = 0; i < ih->data->node_count; i++) + { + gtkTreeIterInit(ih, &iterItem, ih->data->node_cache[i].node_handle); + if (gtkTreeIsNodeSelected(model, &iterItem)) + { + int* id_hitem = (int*)iupArrayInc(selarray); + int j = iupArrayCount(selarray); + id_hitem[j-1] = i; + } + } + + return selarray; +} + +static void gtkTreeCallMultiUnSelectionCb(Ihandle* ih) +{ + IFnIi cbMulti = (IFnIi)IupGetCallback(ih, "MULTIUNSELECTION_CB"); + IFnii cbSelec = (IFnii)IupGetCallback(ih, "SELECTION_CB"); + if (cbSelec || cbMulti) + { + Iarray* markedArray = gtkTreeGetSelectedArrayId(ih); + int* id_hitem = (int*)iupArrayGetData(markedArray); + int i, count = iupArrayCount(markedArray); + + if (count > 1) + { + if (cbMulti) + cbMulti(ih, id_hitem, iupArrayCount(markedArray)); + else + { + for (i=0; itype == GDK_BUTTON_PRESS && evt->button == 1) /* left single press */ + { + iupAttribSetInt(ih, "_IUPTREE_DRAG_X", (int)evt->x); + iupAttribSetInt(ih, "_IUPTREE_DRAG_Y", (int)evt->y); + + if (ih->data->mark_mode==ITREE_MARK_MULTIPLE &&  + !(evt->state & GDK_SHIFT_MASK) && !(evt->state & GDK_CONTROL_MASK)) + { + gtkTreeCallMultiUnSelectionCb(ih); + iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", "1"); + } + } else if (evt->type == GDK_BUTTON_RELEASE && evt->button == 1) /* left single release */ { if (ih->data->mark_mode==ITREE_MARK_MULTIPLE && (evt->state & GDK_SHIFT_MASK)) @@ -2109,16 +2200,7 @@ static gboolean gtkTreeButtonEvent(GtkWidget *treeview, GdkEventButton *evt, Iha iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", "2"); } } - else if (evt->type == GDK_BUTTON_PRESS && evt->button == 1) /* left single press */ - { - iupAttribSetInt(ih, "_IUPTREE_DRAG_X", (int)evt->x); - iupAttribSetInt(ih, "_IUPTREE_DRAG_Y", (int)evt->y);  - if (ih->data->mark_mode==ITREE_MARK_MULTIPLE &&  - !(evt->state & GDK_SHIFT_MASK) && !(evt->state & GDK_CONTROL_MASK)) - iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", "1"); - } -  return FALSE; }  @@ -2159,29 +2241,14 @@ static void gtkTreeEnableDragDrop(Ihandle* ih) { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, 0 } };  - if (iupAttribGetBoolean(ih, "AUTODRAGDROP")) - { - gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW(ih->handle), - GDK_BUTTON1_MASK, - row_targets, - G_N_ELEMENTS(row_targets), - GDK_ACTION_MOVE|GDK_ACTION_COPY); - gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW(ih->handle), - row_targets, - G_N_ELEMENTS(row_targets), - GDK_ACTION_MOVE|GDK_ACTION_COPY); - } - else - { - gtk_drag_source_set(ih->handle, GDK_BUTTON1_MASK, row_targets, G_N_ELEMENTS(row_targets), GDK_ACTION_MOVE|GDK_ACTION_COPY); - gtk_drag_dest_set(ih->handle, GDK_BUTTON1_MASK, row_targets, G_N_ELEMENTS(row_targets), GDK_ACTION_MOVE|GDK_ACTION_COPY); + gtk_drag_source_set(ih->handle, GDK_BUTTON1_MASK, row_targets, G_N_ELEMENTS(row_targets), GDK_ACTION_MOVE|GDK_ACTION_COPY); + gtk_drag_dest_set(ih->handle, GDK_BUTTON1_MASK, row_targets, G_N_ELEMENTS(row_targets), GDK_ACTION_MOVE|GDK_ACTION_COPY);  - g_signal_connect(G_OBJECT(ih->handle), "drag-begin", G_CALLBACK(gtkTreeDragBegin), ih); - g_signal_connect(G_OBJECT(ih->handle), "drag-motion", G_CALLBACK(gtkTreeDragMotion), ih); - g_signal_connect(G_OBJECT(ih->handle), "drag-leave", G_CALLBACK(gtkTreeDragLeave), NULL); - g_signal_connect(G_OBJECT(ih->handle), "drag-drop", G_CALLBACK(gtkTreeDragDrop), ih); - g_signal_connect(G_OBJECT(ih->handle), "drag-data-received", G_CALLBACK(gtkTreeDragDataReceived), ih); - } + g_signal_connect(G_OBJECT(ih->handle), "drag-begin", G_CALLBACK(gtkTreeDragBegin), ih); + g_signal_connect(G_OBJECT(ih->handle), "drag-motion", G_CALLBACK(gtkTreeDragMotion), ih); + g_signal_connect(G_OBJECT(ih->handle), "drag-leave", G_CALLBACK(gtkTreeDragLeave), NULL); + g_signal_connect(G_OBJECT(ih->handle), "drag-drop", G_CALLBACK(gtkTreeDragDrop), ih); + g_signal_connect(G_OBJECT(ih->handle), "drag-data-received", G_CALLBACK(gtkTreeDragDataReceived), ih); }  /*****************************************************************************/ @@ -2194,8 +2261,16 @@ static int gtkTreeMapMethod(Ihandle* ih) GtkTreeSelection* selection; GtkTreeViewColumn *column;  - store = gtk_tree_store_new(9, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, - G_TYPE_STRING, G_TYPE_INT, GDK_TYPE_COLOR, PANGO_TYPE_FONT_DESCRIPTION, G_TYPE_POINTER); + store = gtk_tree_store_new(IUPGTK_TREE_LAST_DATA,  + GDK_TYPE_PIXBUF, /* IUPGTK_TREE_IMAGE */ + G_TYPE_BOOLEAN, /* IUPGTK_TREE_HAS_IMAGE */ + GDK_TYPE_PIXBUF, /* IUPGTK_TREE_IMAGE_EXPANDED */ + G_TYPE_BOOLEAN, /* IUPGTK_TREE_HAS_IMAGE_EXPANDED */ + G_TYPE_STRING, /* IUPGTK_TREE_TITLE */ + G_TYPE_INT, /* IUPGTK_TREE_KIND */ + GDK_TYPE_COLOR, /* IUPGTK_TREE_COLOR */ + PANGO_TYPE_FONT_DESCRIPTION, /* IUPGTK_TREE_FONT */ + G_TYPE_BOOLEAN); /* IUPGTK_TREE_SELECT */  ih->handle = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));  @@ -2262,8 +2337,9 @@ static int gtkTreeMapMethod(Ihandle* ih) gtk_scrolled_window_set_policy(scrolled_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ih->handle)); -  gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + gtk_tree_selection_set_select_function(selection, (GtkTreeSelectionFunc)gtkTreeSelectionFunc, ih, NULL); + gtk_tree_view_set_reorderable(GTK_TREE_VIEW(ih->handle), FALSE);  /* callbacks */ @@ -2279,6 +2355,7 @@ static int gtkTreeMapMethod(Ihandle* ih) g_signal_connect(G_OBJECT(ih->handle), "show-help", G_CALLBACK(iupgtkShowHelp), ih); g_signal_connect(G_OBJECT(ih->handle), "motion-notify-event",G_CALLBACK(iupgtkMotionNotifyEvent), ih);  + g_signal_connect(G_OBJECT(ih->handle), "row-expanded", G_CALLBACK(gtkTreeRowExpanded), ih); g_signal_connect(G_OBJECT(ih->handle), "test-expand-row", G_CALLBACK(gtkTreeTestExpandRow), ih); g_signal_connect(G_OBJECT(ih->handle), "test-collapse-row", G_CALLBACK(gtkTreeTestCollapseRow), ih); g_signal_connect(G_OBJECT(ih->handle), "row-activated", G_CALLBACK(gtkTreeRowActived), ih); @@ -2301,7 +2378,8 @@ static int gtkTreeMapMethod(Ihandle* ih) ih->data->def_image_collapsed = iupImageGetImage("IMGCOLLAPSED", ih, 0); ih->data->def_image_expanded = iupImageGetImage("IMGEXPANDED", ih, 0);  - gtkTreeAddRootNode(ih); + if (iupAttribGetInt(ih, "ADDROOT")) + iupdrvTreeAddNode(ih, "-1", ITREE_BRANCH, "", 0);  /* configure for DRAG&DROP of files */ if (IupGetCallback(ih, "DROPFILES_CB")) @@ -2309,13 +2387,23 @@ static int gtkTreeMapMethod(Ihandle* ih)  IupSetCallback(ih, "_IUP_XY2POS_CB", (Icallback)gtkTreeConvertXYToPos);  + iupdrvTreeUpdateMarkMode(ih); + return IUP_NOERROR; }  +static void gtkTreeUnMapMethod(Ihandle* ih) +{ + ih->data->node_count = 0; + + iupdrvBaseUnMapMethod(ih); +} + void iupdrvTreeInitClass(Iclass* ic) { /* Driver Dependent Class functions */ ic->Map = gtkTreeMapMethod; + ic->UnMap = gtkTreeUnMapMethod;  /* Visual */ iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkTreeSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_DEFAULT); @@ -2324,7 +2412,6 @@ void iupdrvTreeInitClass(Iclass* ic) /* IupTree Attributes - GENERAL */ iupClassRegisterAttribute(ic, "EXPANDALL", NULL, gtkTreeSetExpandAllAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "INDENTATION", gtkTreeGetIndentationAttrib, gtkTreeSetIndentationAttrib, NULL, NULL, IUPAF_DEFAULT); - iupClassRegisterAttribute(ic, "COUNT", gtkTreeGetCountAttrib, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_READONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAGDROP", NULL, iupgtkSetDragDropAttrib, NULL, NULL, IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SPACING", iupTreeGetSpacingAttrib, gtkTreeSetSpacingAttrib, NULL, NULL, IUPAF_NOT_MAPPED); iupClassRegisterAttribute(ic, "TOPITEM", NULL, gtkTreeSetTopItemAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); @@ -2345,7 +2432,6 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttributeId(ic, "COLOR", gtkTreeGetColorAttrib, gtkTreeSetColorAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "NAME", gtkTreeGetTitleAttrib, gtkTreeSetTitleAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TITLE", gtkTreeGetTitleAttrib, gtkTreeSetTitleAttrib, IUPAF_NO_INHERIT); - iupClassRegisterAttributeId(ic, "USERDATA", gtkTreeGetUserDataAttrib, gtkTreeSetUserDataAttrib, IUPAF_NO_STRING|IUPAF_NO_INHERIT);  iupClassRegisterAttributeId(ic, "CHILDCOUNT", gtkTreeGetChildCountAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TITLEFONT", gtkTreeGetTitleFontAttrib, gtkTreeSetTitleFontAttrib, IUPAF_NO_INHERIT); @@ -2355,6 +2441,7 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttribute (ic, "MARK", NULL, gtkTreeSetMarkAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute (ic, "STARTING", NULL, gtkTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); iupClassRegisterAttribute (ic, "MARKSTART", NULL, gtkTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + iupClassRegisterAttribute (ic, "MARKEDNODES", gtkTreeGetMarkedNodesAttrib, gtkTreeSetMarkedNodesAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);  iupClassRegisterAttribute (ic, "VALUE", gtkTreeGetValueAttrib, gtkTreeSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);  @@ -2363,7 +2450,7 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "RENAME", NULL, gtkTreeSetRenameAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "MOVENODE", NULL, gtkTreeSetMoveNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "COPYNODE", NULL, gtkTreeSetCopyNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); - iupClassRegisterAttributeId(ic, "FINDUSERDATA", gtkTreeGetFindUserDataAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);  - iupClassRegisterAttribute (ic, "AUTODRAGDROP", NULL, NULL, NULL, NULL, IUPAF_DEFAULT); + /* IupTree Attributes - GTK Only */ + iupClassRegisterAttribute (ic, "RUBBERBAND", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT); } diff --git a/iup/src/iup.c b/iup/src/iup.c index df4bf34..d103af5 100755 --- a/iup/src/iup.c +++ b/iup/src/iup.c @@ -36,8 +36,10 @@ * \subsection com File Comments (at start) * - Check an existant file for example. *  - * \subsection inc Include Defines - * - __IUPXXX_H (same file name, upper case, "__" preffix and replace "." by "_") + * \subsection def Defines + * - __IUPXXX_H (for include file, same file name, upper case, "__" preffix and replace "." by "_") + * - IUP_XXX (for enumerations) + * - iupXXX (for macros, complement with Function Names rules) *  * \subsection doc Documentation * - In the header, using Doxygen commands. @@ -58,7 +60,7 @@ #include "iup.h"  /* This appears only here to avoid changing the iup.h header fo bug fixes */ -#define IUP_VERSION_FIX " RC3" +#define IUP_VERSION_FIX "" #define IUP_VERSION_FIX_NUMBER 0  const char iup_ident[] =  diff --git a/iup/src/iup.def b/iup/src/iup.def index d0dcfbd..56e7225 100755 --- a/iup/src/iup.def +++ b/iup/src/iup.def @@ -27,6 +27,8 @@ IupGetFunction IupGetGlobal IupGetHandle IupGetInt +IupGetInt2 +IupGetIntInt IupGetLanguage IupGetName IupHbox @@ -40,6 +42,7 @@ IupListDialog IupLoad IupLoadBuffer IupLoopStep +IupLoopStepWait IupMainLoop IupMap IupMapFont @@ -68,6 +71,7 @@ IupShowXY IupStoreAttribute IupStoreGlobal IupSubmenu +IupSplit IupText IupToggle IupUnMapFont @@ -135,6 +139,7 @@ IupTextConvertLinColToPos IupTextConvertPosToLinCol IupUpdateChildren IupTreeSetAttribute  +IupTreeSetAttributeHandle IupTreeStoreAttribute IupTreeGetAttribute  IupTreeGetInt  @@ -175,8 +180,8 @@ iupdrvFontGetStringWidth iupdrvFontGetMultiLineStringSize iupdrvFontGetCharSize iupdrvDrawFocusRect -iupdrvDisplayUpdate -iupdrvDisplayRedraw +iupdrvPostRedraw +iupdrvRedrawNow iupdrvBaseUnMapMethod iupdrvBaseSetZorderAttrib iupdrvBaseSetTipVisibleAttrib @@ -351,3 +356,17 @@ iupArrayCreate iupArrayCount iupArrayAdd iupSaveImageAsText +iupDrawCreateCanvas +iupDrawKillCanvas +iupDrawFlush +iupDrawGetSize +iupDrawParentBackground +iupDrawRectangle +iupDrawLine +iupDrawArc +iupDrawPolygon +iupDrawResetClip +iupDrawSetClipRect +iupDrawText +iupDrawUpdateSize +iupDrawImage diff --git a/iup/src/iup_attrib.c b/iup/src/iup_attrib.c index 2bbb80a..bf9576e 100755 --- a/iup/src/iup_attrib.c +++ b/iup/src/iup_attrib.c @@ -63,7 +63,7 @@ char* IupGetAttributes(Ihandle *ih) name = iupTableFirst(ih->attrib); while (name) { - if (!iupAttribIsInternal(name)) + if (!iupATTRIB_ISINTERNAL(name)) { if (buffer[0] != 0) strcat(buffer,","); @@ -115,6 +115,14 @@ void iupAttribUpdateFromParent(Ihandle* ih) } }  +static int iAttribIsInherit(Ihandle* ih, const char* name) +{ + int inherit; + char *def_value; + iupClassObjectGetAttributeInfo(ih, name, &def_value, &inherit); + return inherit; +} + static void iAttribNotifyChildren(Ihandle *ih, const char* name, const char *value) { int inherit; @@ -123,17 +131,36 @@ static void iAttribNotifyChildren(Ihandle *ih, const char* name, const char *val { if (!iupTableGet(child->attrib, name)) { - /* set on the class */ - iupClassObjectSetAttribute(child, name, value, &inherit); + /* set only if an inheritable attribute at the child */ + if (iAttribIsInherit(child, name)) + { + /* set on the class */ + iupClassObjectSetAttribute(child, name, value, &inherit);  - if (inherit) /* inherit can be different for the child */ iAttribNotifyChildren(child, name, value); + } }  child = child->brother; } }  +void iupAttribUpdateChildren(Ihandle* ih) +{ + char *name = iupTableFirst(ih->attrib); + while (name) + { + if (!iupATTRIB_ISINTERNAL(name) && iAttribIsInherit(ih, name)) + { + /* retrieve from the table */ + char* value = iupTableGet(ih->attrib, name); + iAttribNotifyChildren(ih, name, value); + } + + name = iupTableNext(ih->attrib); + } +} + void iupAttribUpdate(Ihandle* ih) { char** name_array; @@ -159,7 +186,7 @@ void iupAttribUpdate(Ihandle* ih) for (i = 0; i < count; i++) { name = name_array[i]; - if (!iupAttribIsInternal(name)) + if (!iupATTRIB_ISINTERNAL(name)) { /* retrieve from the table */ value = iupTableGet(ih->attrib, name); @@ -196,7 +223,7 @@ void IupSetAttribute(Ihandle *ih, const char* name, const char *value) if (!iupObjectCheck(ih)) return;  - if (iupAttribIsInternal(name)) + if (iupATTRIB_ISINTERNAL(name)) iupAttribSetStr(ih, name, value); else { @@ -225,7 +252,7 @@ void IupStoreAttribute(Ihandle *ih, const char* name, const char *value) if (!iupObjectCheck(ih)) return;  - if (iupAttribIsInternal(name)) + if (iupATTRIB_ISINTERNAL(name)) iupAttribStoreStr(ih, name, value); else { @@ -257,7 +284,7 @@ char* IupGetAttribute(Ihandle *ih, const char* name) if (!value) value = iupAttribGet(ih, name);  - if (!value && !iupAttribIsInternal(name)) + if (!value && !iupATTRIB_ISINTERNAL(name)) { if (inherit) { @@ -346,6 +373,16 @@ void iupAttribSetHandleName(Ihandle *ih) IupSetHandle(str_name, ih); }  +char* iupAttribGetHandleName(Ihandle *ih) +{ + char str_name[100]; + sprintf(str_name, "_IUP_NAME(%p)", ih); + if (IupGetHandle(str_name)==ih) + return iupStrGetMemoryCopy(str_name); + else + return NULL; +} + void IupSetAttributeHandle(Ihandle *ih, const char* name, Ihandle *ih_named) { int inherit; @@ -426,7 +463,7 @@ void iupAttribSetInt(Ihandle *ih, const char* name, int num)  void iupAttribSetFloat(Ihandle *ih, const char* name, float num) { - iupAttribSetStrf(ih, name, "%f", (double)num); + iupAttribSetStrf(ih, name, "%g", (double)num); }  int iupAttribGetBoolean(Ihandle* ih, const char* name) @@ -479,7 +516,7 @@ char* iupAttribGetStr(Ihandle* ih, const char* name)  value = iupTableGet(ih->attrib, name);  - if (!value && !iupAttribIsInternal(name)) + if (!value && !iupATTRIB_ISINTERNAL(name)) { int inherit; char *def_value; @@ -555,6 +592,15 @@ static void iAttribCapture(char* env_buffer, char* dlm) env_buffer[i-1]='\0'; /* discard delimiter */ }  +static void iAttribSkipComment(void) +{ + int c; + do + { + c = *env_str; ++env_str; + } while ((c > 0) && (c != '\n')); +} + static int iAttribToken(char* env_buffer) { for (;;) @@ -565,6 +611,11 @@ static int iAttribToken(char* env_buffer) case 0: return IUPLEX_TK_END;  + case '#': /* Skip comment */ + case '%': /* Skip comment */ + iAttribSkipComment(); + continue; + case ' ': /* ignore whitespace */ case '\t': case '\n': @@ -609,7 +660,7 @@ static void iAttribParse(Ihandle *ih, const char* str) { switch (iAttribToken(env_buffer)) { - case IUPLEX_TK_END: /* procedimento igual ao IUPLEX_TK_COMMA */ + case IUPLEX_TK_END: /* same as IUPLEX_TK_COMMA */ end = 1; case IUPLEX_TK_COMMA: if (name) diff --git a/iup/src/iup_attrib.h b/iup/src/iup_attrib.h index 993dd3c..8593d6e 100755 --- a/iup/src/iup_attrib.h +++ b/iup/src/iup_attrib.h @@ -28,7 +28,7 @@ extern "C" {  /** Returns true if the attribute name if in the internal format "_IUP...". * \ingroup attrib */ -#define iupAttribIsInternal(_name) ((_name[0] == '_' && _name[1] == 'I' && _name[2] == 'U' && _name[3] == 'P')? 1: 0) +#define iupATTRIB_ISINTERNAL(_name) ((_name[0] == '_' && _name[1] == 'I' && _name[2] == 'U' && _name[3] == 'P')? 1: 0)  /** Returns true if the attribute name is a known pointer. * \ingroup attrib */ @@ -102,16 +102,23 @@ float iupAttribGetFloat(Ihandle* ih, const char* name); * \ingroup attrib */ void iupAttribSetHandleName(Ihandle *ih);  +/** Returns the internal name if set. + * \ingroup attrib */ +char* iupAttribGetHandleName(Ihandle *ih); +  /* For all attributes in the evironment, call the class SetAttribute only. - * Called only after the element is mapped. */ + * Called only after the element is mapped, but before the children are mapped. */ void iupAttribUpdate(Ihandle* ih);   /* For all registered inherited attributes, checks the parent tree and  * call the class SetAttribute if the attribute is defined. - * Called only after the element is mapped. */ + * Called only after the element is mapped, but before the children are mapped. */ void iupAttribUpdateFromParent(Ihandle* ih);  +/* For all attributes in the evironment, call the class SetAttribute only for the children. + * Called only after the element is mapped, and after the children are mapped. */ +void iupAttribUpdateChildren(Ihandle* ih);   /* Other functions declared in and implemented here.  diff --git a/iup/src/iup_box.c b/iup/src/iup_box.c index 54e56d9..111cab4 100755 --- a/iup/src/iup_box.c +++ b/iup/src/iup_box.c @@ -172,9 +172,9 @@ static int iBoxSetCMarginAttrib(Ihandle* ih, const char* value) iupdrvFontGetCharSize(ih, &charwidth, &charheight); iupStrToIntInt(value, &cmargin_x, &cmargin_y, 'x'); if (cmargin_x!=-1) - ih->data->margin_x = iupHEIGHT2RASTER(cmargin_x, charheight); + ih->data->margin_x = iupWIDTH2RASTER(cmargin_x, charwidth); if (cmargin_y!=-1) - ih->data->margin_x = iupWIDTH2RASTER(cmargin_y, charwidth); + ih->data->margin_y = iupHEIGHT2RASTER(cmargin_y, charheight); return 0; }  @@ -227,8 +227,12 @@ Iclass* iupBoxClassBase(void) /* boxes only */ iupClassRegisterAttribute(ic, "GAP", iBoxGetGapAttrib, iBoxSetGapAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED); iupClassRegisterAttribute(ic, "CGAP", iBoxGetCGapAttrib, iBoxSetCGapAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "NGAP", iBoxGetGapAttrib, iBoxSetGapAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "NCGAP", iBoxGetCGapAttrib, iBoxSetCGapAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "MARGIN", iBoxGetMarginAttrib, iBoxSetMarginAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED); iupClassRegisterAttribute(ic, "CMARGIN", iBoxGetCMarginAttrib, iBoxSetCMarginAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "NMARGIN", iBoxGetMarginAttrib, iBoxSetMarginAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "NCMARGIN", iBoxGetCMarginAttrib, iBoxSetCMarginAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);  iupClassRegisterAttribute(ic, "EXPANDCHILDREN", iBoxGetExpandChildrenAttrib, iBoxSetExpandChildrenAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "HOMOGENEOUS", iBoxGetHomogeneousAttrib, iBoxSetHomogeneousAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); diff --git a/iup/src/iup_button.c b/iup/src/iup_button.c index 7719663..56befe2 100755 --- a/iup/src/iup_button.c +++ b/iup/src/iup_button.c @@ -100,8 +100,9 @@ static void iButtonComputeNaturalSizeMethod(Ihandle* ih, int *w, int *h, int *ex char* value = iupAttribGet(ih, "IMAGE"); if (value) { + char* title = iupAttribGet(ih, "TITLE"); type = IUP_BUTTON_IMAGE; - if (iupAttribGet(ih, "TITLE")) + if (title && *title!=0) type |= IUP_BUTTON_TEXT; } else diff --git a/iup/src/iup_canvas.c b/iup/src/iup_canvas.c index 5eda988..46fefd9 100755 --- a/iup/src/iup_canvas.c +++ b/iup/src/iup_canvas.c @@ -55,14 +55,14 @@ void iupCanvasCalcScrollRealPos(double min, double max, double *pos, char* iupCanvasGetPosXAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->posx); + sprintf(str, "%g", ih->data->posx); return str; }  char* iupCanvasGetPosYAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->posy); + sprintf(str, "%g", ih->data->posy); return str; }  diff --git a/iup/src/iup_classattrib.c b/iup/src/iup_classattrib.c index df8f873..3ac780c 100755 --- a/iup/src/iup_classattrib.c +++ b/iup/src/iup_classattrib.c @@ -55,7 +55,7 @@ static const char* iClassFindId(const char* name) { if (*name >= '0' && *name <= '9') return name; - if (*name == '*' || *name == ':') + if (*name == '*' || *name == ':' || *name == '-') return name;  name++; @@ -94,7 +94,6 @@ int iupClassObjectSetAttribute(Ihandle* ih, const char* name, const char * value const char* name_id = iClassFindId(name); if (name_id) { - IattribFunc* afunc; const char* partial_name = iClassCutNameId(name, name_id); if (!partial_name) partial_name = "IDVALUE"; /* pure numbers are used as attributes in IupList and IupMatrix,  @@ -474,8 +473,12 @@ void iupClassObjectEnsureDefaultAttributes(Ihandle* ih) (afunc->call_global_default && iupGlobalDefaultColorChanged(afunc->default_value))) { if ((!ih->handle && (afunc->flags & IUPAF_NOT_MAPPED)) || - (ih->handle && !(afunc->flags & IUPAF_NOT_MAPPED) && !iupAttribGet(ih, name))) - afunc->set(ih, iClassGetDefaultValue(afunc)); + (ih->handle && !(afunc->flags & IUPAF_NOT_MAPPED))) + { + char* value = iupAttribGet(ih, name); + if (!value) /* if set will be updated later */ + afunc->set(ih, iClassGetDefaultValue(afunc)); + } } }  diff --git a/iup/src/iup_classbase.c b/iup/src/iup_classbase.c index 9cb9e63..03a98d1 100755 --- a/iup/src/iup_classbase.c +++ b/iup/src/iup_classbase.c @@ -164,8 +164,7 @@ static char* iBaseGetPositionAttrib(Ihandle* ih)  static int iBaseSetPositionAttrib(Ihandle* ih, const char* value) { - if (ih->is_floating) - iupStrToIntInt(value, &ih->x, &ih->y, ','); + iupStrToIntInt(value, &ih->x, &ih->y, ','); return 0; }  @@ -211,7 +210,7 @@ char* iupBaseGetVisibleAttrib(Ihandle* ih) int iupBaseSetVisibleAttrib(Ihandle* ih, const char* value) { iupdrvSetVisible(ih, iupStrBoolean(value)); - return 0; + return 1; /* must be 1 to mark when set at the element */ }  char* iupBaseNativeParentGetBgColorAttrib(Ihandle* ih) @@ -410,15 +409,19 @@ void iupBaseRegisterCommonAttrib(Iclass* ic) iupClassRegisterAttribute(ic, "FLOATING", iBaseGetFloatingAttrib, iBaseSetFloatingAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "EXPAND", iBaseGetExpandAttrib, iBaseSetExpandAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "NORMALIZERGROUP", NULL, iBaseSetNormalizerGroupAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "EXPANDWEIGTH", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);  /* make sure everyone has the correct default value */ - iupClassRegisterAttribute(ic, "VISIBLE", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT); iupClassRegisterAttribute(ic, "ACTIVE", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT); if (ic->is_interactive) iupClassRegisterAttribute(ic, "CANFOCUS", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT); else iupClassRegisterAttribute(ic, "CANFOCUS", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NO_INHERIT);  + /* if not native container, must set at children, + native container will automatically hide its children. */ + iupClassRegisterAttribute(ic, "VISIBLE", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT); /* let the attribute to be propagated to children */ + iupClassRegisterAttribute(ic, "SIZE", iupBaseGetSizeAttrib, iupBaseSetSizeAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "RASTERSIZE", iupBaseGetRasterSizeAttrib, iupBaseSetRasterSizeAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CHARSIZE", iupBaseGetCharSizeAttrib, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); @@ -439,7 +442,7 @@ void iupBaseRegisterCommonAttrib(Iclass* ic)  void iupBaseRegisterVisualAttrib(Iclass* ic) { - iupClassRegisterAttribute(ic, "VISIBLE", iupBaseGetVisibleAttrib, iupBaseSetVisibleAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT); /* VISIBLE inheritance comes from the native system */ + iupClassRegisterAttribute(ic, "VISIBLE", iupBaseGetVisibleAttrib, iupBaseSetVisibleAttrib, "YES", "NO", IUPAF_DEFAULT); iupClassRegisterAttribute(ic, "ACTIVE", iupBaseGetActiveAttrib, iupBaseSetActiveAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT);  iupClassRegisterAttribute(ic, "ZORDER", NULL, iupdrvBaseSetZorderAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); diff --git a/iup/src/iup_dialog.c b/iup/src/iup_dialog.c index d70e12c..1aaf095 100755 --- a/iup/src/iup_dialog.c +++ b/iup/src/iup_dialog.c @@ -220,11 +220,19 @@ static void iDialogDestroyMethod(Ihandle* ih) iupDlgListRemove(ih); }  +static int iDialogSetMenuAttrib(Ihandle* ih, const char* value); + static void iDialogComputeNaturalSizeMethod(Ihandle* ih, int *w, int *h, int *expand) { int decorwidth, decorheight; Ihandle* child = ih->firstchild;  + /* if does not have a menu, but the attribute is defined, + try to update the menu before retrieving the decoration. */ + char* value = iupAttribGet(ih, "MENU"); + if (!ih->data->menu && value) + iDialogSetMenuAttrib(ih, value); + iupDialogGetDecorSize(ih, &decorwidth, &decorheight); *w = decorwidth; *h = decorheight; @@ -278,20 +286,22 @@ static void iDialogAfterShow(Ihandle* ih) { Ihandle* old_focus; IFni show_cb; + int show_state;  /* process all pending messages */ IupFlush();  old_focus = IupGetFocus(); + show_state = ih->data->show_state;  show_cb = (IFni)IupGetCallback(ih, "SHOW_CB"); - if (show_cb && show_cb(ih, ih->data->show_state) == IUP_CLOSE) + if (show_cb && show_cb(ih, show_state) == IUP_CLOSE) { IupExitLoop(); return; }  - if (ih->data->show_state == IUP_SHOW) + if (show_state == IUP_SHOW) { if (show_cb) IupFlush(); /* again to update focus */ @@ -718,7 +728,8 @@ Iclass* iupDialogGetClass(void) iupBaseRegisterVisualAttrib(ic);  /* Overwrite Visual */ - iupClassRegisterAttribute(ic, "VISIBLE", iupBaseGetVisibleAttrib, iDialogSetVisibleAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NO_INHERIT); /* the only case where VISIBLE default is NO */ + /* the only case where VISIBLE default is NO, and must not be propagated to the dialog children */ + iupClassRegisterAttribute(ic, "VISIBLE", iupBaseGetVisibleAttrib, iDialogSetVisibleAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NO_INHERIT);   /* IupDialog only */ iupClassRegisterAttribute(ic, "MENU", NULL, iDialogSetMenuAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); diff --git a/iup/src/iup_drv.h b/iup/src/iup_drv.h index 5cdb8e7..1071347 100755 --- a/iup/src/iup_drv.h +++ b/iup/src/iup_drv.h @@ -60,11 +60,11 @@ void iupdrvSetActive(Ihandle* ih, int enable);  /** Post a redraw of a control. * \ingroup drv */ -void iupdrvDisplayUpdate(Ihandle *ih); +void iupdrvPostRedraw(Ihandle *ih);  /** Force a redraw of a control. * \ingroup drv */ -void iupdrvDisplayRedraw(Ihandle *ih); +void iupdrvRedrawNow(Ihandle *ih);  /** Reparent the native control. * \ingroup drv */ diff --git a/iup/src/iup_focus.c b/iup/src/iup_focus.c index be54b75..fc0579c 100755 --- a/iup/src/iup_focus.c +++ b/iup/src/iup_focus.c @@ -220,15 +220,25 @@ void iupFocusPrevious(Ihandle *ih) /* local variables */ static Ihandle* iup_current_focus = NULL;  +Ihandle* IupGetFocus(void) +{ + return iup_current_focus; +} + +void iupSetCurrentFocus(Ihandle *ih) +{ + iup_current_focus = ih; +} + Ihandle *IupSetFocus(Ihandle *ih) { - Ihandle* old_focus = iup_current_focus; + Ihandle* old_focus = IupGetFocus();  iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return old_focus;  - /* iup_current_focus is NOT set here,  + /* Current focus is NOT set here,  only in the iupCallGetFocusCb */  if (iupFocusCanAccept(ih))  @@ -237,16 +247,11 @@ Ihandle *IupSetFocus(Ihandle *ih) return old_focus; }  -Ihandle *IupGetFocus(void) -{ - return iup_current_focus; -} - void iupCallGetFocusCb(Ihandle *ih) { Icallback cb;  - if (ih == iup_current_focus) /* avoid duplicate messages */ + if (ih == IupGetFocus()) /* avoid duplicate messages */ return;  cb = (Icallback)IupGetCallback(ih, "GETFOCUS_CB"); @@ -258,14 +263,14 @@ void iupCallGetFocusCb(Ihandle *ih) if (cb2) cb2(ih, 1); }  - iup_current_focus = ih; + iupSetCurrentFocus(ih); }  void iupCallKillFocusCb(Ihandle *ih) { Icallback cb;  - if (ih != iup_current_focus) /* avoid duplicate messages */ + if (ih != IupGetFocus()) /* avoid duplicate messages */ return;  cb = IupGetCallback(ih, "KILLFOCUS_CB"); @@ -277,5 +282,5 @@ void iupCallKillFocusCb(Ihandle *ih) if (cb2) cb2(ih, 0); }  - iup_current_focus = NULL; + iupSetCurrentFocus(NULL); } diff --git a/iup/src/iup_focus.h b/iup/src/iup_focus.h index 239e233..9fb4e58 100755 --- a/iup/src/iup_focus.h +++ b/iup/src/iup_focus.h @@ -39,6 +39,7 @@ Ihandle* iupFocusNextInteractive(Ihandle *ih); void iupFocusNext(Ihandle *ih); void iupFocusPrevious(Ihandle *ih);  +void iupSetCurrentFocus(Ihandle *ih);  /* Other functions declared in and implemented here.  IupPreviousField diff --git a/iup/src/iup_getparam.c b/iup/src/iup_getparam.c index 1418aa5..7fd6a94 100755 --- a/iup/src/iup_getparam.c +++ b/iup/src/iup_getparam.c @@ -45,6 +45,14 @@ static int iParamButtonCancel_CB(Ihandle* self) return IUP_CLOSE; }  +static int iParamButtonHelp_CB(Ihandle* self) +{ + Ihandle* dlg = IupGetDialog(self); + Iparamcb cb = (Iparamcb)IupGetCallback(dlg, "PARAM_CB"); + if (cb) cb(dlg, -4, (void*)iupAttribGet(dlg, "USER_DATA")); + return IUP_DEFAULT; +} + static int iParamToggleAction_CB(Ihandle *self, int v) { Ihandle* param = (Ihandle*)iupAttribGetInherit(self, "_IUPGP_PARAM"); @@ -288,7 +296,7 @@ static int iParamColorButton_CB(Ihandle *self, int button, int pressed)  IupPopup(dlg, IUP_CENTER, IUP_CENTER);  - if (IupGetInt(dlg, "STATUS") != -1) + if (IupGetInt(dlg, "STATUS")==1) { char* value = IupGetAttribute(dlg, "VALUE"); IupSetAttribute(textbox, "VALUE", value); @@ -381,11 +389,13 @@ static int iParamSpinInt_CB(Ihandle *self, int pos) static Ihandle* iParamCreateBox(Ihandle* param) { Ihandle *box, *ctrl = NULL, *label; - char *type; + char *type = iupAttribGet(param, "TYPE"); + + if (iupStrEqual(type, "BUTTONNAMES")) + return NULL;  label = IupLabel(iupAttribGet(param, "TITLE"));  - type = iupAttribGet(param, "TYPE"); if (iupStrEqual(type, "SEPARATOR")) { box = IupHbox(label, NULL); @@ -563,7 +573,7 @@ static Ihandle* iParamCreateBox(Ihandle* param) float step = iupAttribGetFloat(param, "STEP"); float val = iupAttribGetFloat(param, "VALUE"); if (step == 0) step = (max-min)/20.0f; - IupSetfAttribute(ctrl, "MASKFLOAT", "%f:%f", (double)min, (double)max); + IupSetfAttribute(ctrl, "MASKFLOAT", "%g:%g", (double)min, (double)max);  /* here spin is always [0-spinmax] converted to [min-max] */  @@ -584,7 +594,7 @@ static Ihandle* iParamCreateBox(Ihandle* param) if (min == 0) IupSetAttribute(ctrl, "MASK", IUP_MASK_UFLOAT); else - IupSetfAttribute(ctrl, "MASKFLOAT", "%f:%f", (double)min, (double)1.0e10); + IupSetfAttribute(ctrl, "MASKFLOAT", "%g:%g", (double)min, (double)1.0e10); IupAppend(box, ctrl); } else @@ -620,6 +630,7 @@ static Ihandle* iParamCreateBox(Ihandle* param) } IupSetfAttribute(ctrl, "SPINMAX", "%d", max); IupSetfAttribute(ctrl, "SPINMIN", "%d", min); + IupSetfAttribute(ctrl, "MASKINT", "%d:%d", min, max); } else if (iupAttribGetInt(param, "PARTIAL")) { @@ -696,7 +707,7 @@ static Ihandle* iParamCreateBox(Ihandle* param)  static Ihandle* IupParamDlgP(Ihandle** params) { - Ihandle *dlg, *button_ok, *button_cancel,  + Ihandle *dlg, *button_ok, *button_cancel, *button_help=NULL,  *dlg_box, *button_box, *param_box; int i, lbl_width, p, expand;  @@ -713,7 +724,23 @@ static Ihandle* IupParamDlgP(Ihandle** params) i = 0; expand = 0; while (params[i] != NULL) { - IupAppend(param_box, iParamCreateBox(params[i])); + Ihandle* box = iParamCreateBox(params[i]); + if (box) + IupAppend(param_box, box); + else /* buttonnames */ + { + char* value = iupAttribGet(params[i], "_IUPGP_OK"); + if (value && *value) IupSetAttribute(button_ok, "TITLE", value); + value = iupAttribGet(params[i], "_IUPGP_CANCEL"); + if (value && *value) IupSetAttribute(button_cancel, "TITLE", value); + value = iupAttribGet(params[i], "_IUPGP_HELP"); + if (value && *value)  + { + button_help = IupButton(value, NULL); + IupSetAttribute(button_help, "PADDING", "20x0"); + IupSetCallback(button_help, "ACTION", (Icallback)iParamButtonHelp_CB); + } + }  if (IupGetInt(params[i], "EXPAND")) expand = 1; @@ -725,6 +752,7 @@ static Ihandle* IupParamDlgP(Ihandle** params) IupFill(), button_ok, button_cancel, + button_help, NULL); IupSetAttribute(button_box,"MARGIN","0x0"); IupSetAttribute(button_box, "NORMALIZESIZE", "HORIZONTAL"); @@ -926,6 +954,23 @@ static void iParamSetFileOptions(char* extra, Ihandle* param) iupAttribStoreStr(param, "_IUPGP_NOOVERWRITEPROMPT", nooverwriteprompt); }  +static void iParamSetButtonNames(char* extra, Ihandle* param) +{ + char *ok, *cancel, *help; + int count; + + if (!extra) + return; + + ok = iParamGetNextStrItem(extra, ',', &count); extra += count; + cancel = iParamGetNextStrItem(extra, ',', &count); extra += count; + help = iParamGetNextStrItem(extra, ',', &count); extra += count; + + iupAttribStoreStr(param, "_IUPGP_OK", ok); + iupAttribStoreStr(param, "_IUPGP_CANCEL", cancel); + iupAttribStoreStr(param, "_IUPGP_HELP", help); +} + static void iParamSetListItems(char* extra, Ihandle* param) { int d = 1, count; @@ -1082,6 +1127,12 @@ static Ihandle *IupParamf(const char* format, int *line_size) iupAttribSetStr(param, "TYPE", "SEPARATOR"); iupAttribSetStr(param, "DATA_TYPE", "-1"); /* NONE */ break; + case 'u': + iupAttribSetStr(param, "TYPE", "BUTTONNAMES"); + iupAttribSetStr(param, "DATA_TYPE", "-1"); /* NONE */ + extra = iParamGetStrExtra(line_ptr, '[', ']', &count); line_ptr += count; + iParamSetButtonNames(extra, param); + break; default: return NULL; } @@ -1099,7 +1150,7 @@ static Ihandle *IupParamf(const char* format, int *line_size)  int iupGetParamCount(const char *format, int *param_extra) { - int param_count = 0, sep = 0; + int param_count = 0, extra = 0; const char* s = format;  *param_extra = 0; @@ -1107,14 +1158,20 @@ int iupGetParamCount(const char *format, int *param_extra) { if (*s == '%' && *(s+1) == 't') /* do not count separator lines */ { - sep = 1; + extra = 1; + (*param_extra)++; + } + + if (*s == '%' && *(s+1) == 'u') /* do not count button names lines */ + { + extra = 1; (*param_extra)++; }  if (*s == '\n') { - if (sep) - sep = 0; + if (extra) + extra = 0; else param_count++; } @@ -1154,21 +1211,21 @@ int IupGetParamv(const char* title, Iparamcb action, void* user_data, const char return 0;  data_type = IupGetInt(params[i], "DATA_TYPE"); - if (data_type == 1) - { - int *data_int = (int*)(param_data[p]); - if (!data_int) return 0; - iupAttribSetStrf(params[i], "VALUE", "%d", *data_int); - p++; - } - else if (data_type == 2) + if (data_type == 2) /* float */ { float *data_float = (float*)(param_data[p]); if (!data_float) return 0; iupAttribSetStrf(params[i], "VALUE", "%g", *data_float); p++; } - else if (data_type == 0) + else if (data_type == 1) /* integer */ + { + int *data_int = (int*)(param_data[p]); + if (!data_int) return 0; + iupAttribSetStrf(params[i], "VALUE", "%d", *data_int); + p++; + } + else if (data_type == 0) /* string */ { char *data_str = (char*)(param_data[p]); if (!data_str) return 0; diff --git a/iup/src/iup_globalattrib.c b/iup/src/iup_globalattrib.c index 00586fb..d1a2584 100755 --- a/iup/src/iup_globalattrib.c +++ b/iup/src/iup_globalattrib.c @@ -129,12 +129,14 @@ int iupGlobalIsPointer(const char* name) static struct { const char *name; } ptr_table[] = { -#ifdef WIN32 +#ifndef GTK_MAC + #ifdef WIN32 {"HINSTANCE"}, -#else + #else {"XDISPLAY"}, {"XSCREEN"}, {"APPSHELL"}, + #endif #endif }; #define PTR_TABLE_SIZE ((sizeof ptr_table)/(sizeof ptr_table[0])) diff --git a/iup/src/iup_hbox.c b/iup/src/iup_hbox.c index e790636..a8a93a3 100755 --- a/iup/src/iup_hbox.c +++ b/iup/src/iup_hbox.c @@ -213,6 +213,13 @@ static void iHboxSetChildrenCurrentSizeMethod(Ihandle* ih, int shrink) else { int empty = (child->expand & IUP_EXPAND_W1)? empty_w1: ((child->expand & IUP_EXPAND_W0)? empty_w0: 0); + char* weigth_str = iupAttribGet(child, "EXPANDWEIGTH"); + if (weigth_str) + { + float weigth;  + if (iupStrToFloat(weigth_str, &weigth)) + empty = iupROUND(empty * weigth); + } iupBaseSetCurrentSize(child, child->naturalwidth+empty, client_height, shrink); }  diff --git a/iup/src/iup_key.h b/iup/src/iup_key.h index 37d6c9d..9b30bc4 100755 --- a/iup/src/iup_key.h +++ b/iup/src/iup_key.h @@ -51,16 +51,16 @@ void iupKeyInit(void);  #define IUPKEY_STATUS_SIZE 11 /* 10 chars + null */ #define IUPKEY_STATUS_INIT " " /* 10 spaces */ -#define iupKEYSETSHIFT(_s) (_s[0]='S') -#define iupKEYSETCONTROL(_s) (_s[1]='C') -#define iupKEYSETBUTTON1(_s) (_s[2]='1') -#define iupKEYSETBUTTON2(_s) (_s[3]='2') -#define iupKEYSETBUTTON3(_s) (_s[4]='3') -#define iupKEYSETDOUBLE(_s) (_s[5]='D') -#define iupKEYSETALT(_s) (_s[6]='A') -#define iupKEYSETSYS(_s) (_s[7]='Y') -#define iupKEYSETBUTTON4(_s) (_s[8]='4') -#define iupKEYSETBUTTON5(_s) (_s[9]='5') +#define iupKEY_SETSHIFT(_s) (_s[0]='S') +#define iupKEY_SETCONTROL(_s) (_s[1]='C') +#define iupKEY_SETBUTTON1(_s) (_s[2]='1') +#define iupKEY_SETBUTTON2(_s) (_s[3]='2') +#define iupKEY_SETBUTTON3(_s) (_s[4]='3') +#define iupKEY_SETDOUBLE(_s) (_s[5]='D') +#define iupKEY_SETALT(_s) (_s[6]='A') +#define iupKEY_SETSYS(_s) (_s[7]='Y') +#define iupKEY_SETBUTTON4(_s) (_s[8]='4') +#define iupKEY_SETBUTTON5(_s) (_s[9]='5')   #ifdef __cplusplus diff --git a/iup/src/iup_layout.c b/iup/src/iup_layout.c index b96293c..0ccd496 100755 --- a/iup/src/iup_layout.c +++ b/iup/src/iup_layout.c @@ -43,7 +43,7 @@ static void iLayoutDisplayUpdateChildren(Ihandle *ih) iLayoutDisplayUpdateChildren(child);  if (child->handle && child->iclass->nativetype != IUP_TYPEVOID) - iupdrvDisplayUpdate(child); + iupdrvPostRedraw(child); } }  @@ -54,7 +54,7 @@ void IupUpdate(Ihandle* ih) return;  if (ih->handle && ih->iclass->nativetype != IUP_TYPEVOID) - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih); }  void IupUpdateChildren(Ihandle* ih) @@ -74,7 +74,7 @@ static void iLayoutDisplayRedrawChildren(Ihandle *ih) iLayoutDisplayRedrawChildren(child);  if (child->handle && child->iclass->nativetype != IUP_TYPEVOID) - iupdrvDisplayRedraw(child); + iupdrvRedrawNow(child); } }  @@ -85,7 +85,7 @@ void IupRedraw(Ihandle* ih, int children) return;  if (ih->handle && ih->iclass->nativetype != IUP_TYPEVOID) - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih);  if (children) iLayoutDisplayRedrawChildren(ih); @@ -136,7 +136,7 @@ void iupLayoutCompute(Ihandle* ih) iupBaseSetPosition(ih, 0, 0); }  -static void iLayoutSetMinMaxSize(Ihandle* ih, int *w, int *h) +void iupLayoutSetMinMaxSize(Ihandle* ih, int *w, int *h) { if (ih->has_minsize) { @@ -163,7 +163,8 @@ void iupBaseComputeNaturalSize(Ihandle* ih) ih->naturalwidth = ih->userwidth; ih->naturalheight = ih->userheight;  - if (ih->iclass->childtype!=IUP_CHILDNONE || ih->iclass->nativetype == IUP_TYPEDIALOG) + if (ih->iclass->childtype!=IUP_CHILDNONE ||  + ih->iclass->nativetype == IUP_TYPEDIALOG) /* pre-defined dialogs can restrict the number of children */ { int w=0, h=0, children_expand;  @@ -190,7 +191,7 @@ void iupBaseComputeNaturalSize(Ihandle* ih) ih->naturalheight = iupMAX(ih->naturalheight, h);  /* crop the natural size */ - iLayoutSetMinMaxSize(ih, &(ih->naturalwidth), &(ih->naturalheight)); + iupLayoutSetMinMaxSize(ih, &(ih->naturalwidth), &(ih->naturalheight)); } } else  @@ -198,15 +199,15 @@ void iupBaseComputeNaturalSize(Ihandle* ih) /* for non-container only compute if user size is not defined */ if (ih->naturalwidth <= 0 || ih->naturalheight <= 0) { - int w=0, h=0; - iupClassObjectComputeNaturalSize(ih, &w, &h, NULL); + int w=0, h=0, children_expand; + iupClassObjectComputeNaturalSize(ih, &w, &h, &children_expand);  if (ih->naturalwidth <= 0) ih->naturalwidth = w; if (ih->naturalheight <= 0) ih->naturalheight = h; }  /* crop the natural size */ - iLayoutSetMinMaxSize(ih, &(ih->naturalwidth), &(ih->naturalheight)); + iupLayoutSetMinMaxSize(ih, &(ih->naturalwidth), &(ih->naturalheight)); } }  @@ -259,7 +260,7 @@ void iupBaseSetCurrentSize(Ihandle* ih, int w, int h, int shrink)  /* crop the current size if expanded */ if (ih->expand & IUP_EXPAND_WIDTH || ih->expand & IUP_EXPAND_HEIGHT) - iLayoutSetMinMaxSize(ih, &(ih->currentwidth), &(ih->currentheight)); + iupLayoutSetMinMaxSize(ih, &(ih->currentwidth), &(ih->currentheight)); } }  diff --git a/iup/src/iup_layout.h b/iup/src/iup_layout.h index a2a0c29..775e5a2 100755 --- a/iup/src/iup_layout.h +++ b/iup/src/iup_layout.h @@ -16,6 +16,8 @@ extern "C" { void iupLayoutCompute(Ihandle* ih); /* can be called before map */ void iupLayoutUpdate(Ihandle* ih); /* called only after map */  +void iupLayoutSetMinMaxSize(Ihandle* ih, int *w, int *h); + /* Other functions declared in and implemented here.  IupRefresh */ diff --git a/iup/src/iup_ledlex.c b/iup/src/iup_ledlex.c index 3283a43..5cf8640 100755 --- a/iup/src/iup_ledlex.c +++ b/iup/src/iup_ledlex.c @@ -35,7 +35,7 @@ static struct /* lexical variables */ static int iLexGetChar (void); static int iLexToken(int *erro); static int iLexCapture (char* dlm); -static int iLexSkip (char* dlm); +static void iLexSkipComment (void); static int iLexCaptureAttr (void);  int iupLexStart(const char* filename, int is_file) /* initialize lexical analysis */ @@ -186,9 +186,9 @@ static int iLexToken(int *erro) case ']': return IUPLEX_TK_ENDATTR;  - case '#': /* iLexSkip comment */ - case '%': /* iLexSkip comment */ - iLexSkip ("\n\r"); + case '#': /* Skip comment */ + case '%': /* Skip comment */ + iLexSkipComment(); continue;  case ' ': /* ignore whitespace */ @@ -276,14 +276,13 @@ static int iLexCaptureAttr (void) return c; /* return delimiter */ }  -static int iLexSkip (char* dlm) +static void iLexSkipComment (void) { int c; do { - c = iLexGetChar (); - } while ((c > 0) && !strchr (dlm,c)); - return c; /* return delimiter */ + c = iLexGetChar(); + } while ((c > 0) && (c != '\n')); }  static int iLexGetChar (void) diff --git a/iup/src/iup_list.c b/iup/src/iup_list.c index 5965665..1077d98 100755 --- a/iup/src/iup_list.c +++ b/iup/src/iup_list.c @@ -53,6 +53,37 @@ static void iListCallActionCallback(Ihandle* ih, IFnsii cb, int pos, int state) IupExitLoop(); }  +void iupListUpdateOldValue(Ihandle* ih, int pos, int removed) +{ + if (!ih->data->has_editbox) + { + char* old_value = iupAttribGet(ih, "_IUPLIST_OLDVALUE"); + if (old_value) + { + int old_pos = atoi(old_value)-1; /* was in IUP reference, starting at 1 */ + if (ih->data->is_dropdown || !ih->data->is_multiple) + { + if (old_pos >= pos) + { + if (removed && old_pos == pos) + { + /* when the current item is removed nothing remains selected */ + iupAttribSetStr(ih, "_IUPLIST_OLDVALUE", NULL); + } + else + iupAttribSetInt(ih, "_IUPLIST_OLDVALUE", removed? old_pos-1: old_pos+1); + } + } + else + { + /* multiple selection on a non drop-down list. */ + char* value = IupGetAttribute(ih, "VALUE"); + iupAttribStoreStr(ih, "_IUPLIST_OLDVALUE", value); + } + } + } +} + void iupListSingleCallActionCallback(Ihandle* ih, IFnsii cb, int pos) { char* old_str = iupAttribGet(ih, "_IUPLIST_OLDVALUE"); @@ -77,7 +108,7 @@ void iupListMultipleCallActionCallback(Ihandle* ih, IFnsii cb, IFns multi_cb, in char* old_str = iupAttribGet(ih, "_IUPLIST_OLDVALUE"); int old_count = old_str? strlen(old_str): 0;  - char* str = iupStrGetMemory(count+1); + char* str = malloc(count+1); memset(str, '-', count); str[count]=0; for (i=0; i count-1) return -1; + if (pos == count) return -2; + if (pos > count) return -1;  return pos; } @@ -217,7 +254,10 @@ int iupListSetIdValueAttrib(Ihandle* ih, const char* name_id, const char* value) if (pos >= 0 && pos <= count-1) { if (pos == 0) + { iupdrvListRemoveAllItems(ih); + iupAttribSetStr(ih, "_IUPLIST_OLDVALUE", NULL); + } else { int i = pos; @@ -245,7 +285,7 @@ int iupListSetIdValueAttrib(Ihandle* ih, const char* name_id, const char* value)  static int iListSetAppendItemAttrib(Ihandle* ih, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (value) iupdrvListAppendItem(ih, value); @@ -254,27 +294,32 @@ static int iListSetAppendItemAttrib(Ihandle* ih, const char* value)  static int iListSetInsertItemAttrib(Ihandle* ih, const char* name_id, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (value) { int pos = iupListGetPos(ih, name_id); - if (pos!=-1) + if (pos >= 0) iupdrvListInsertItem(ih, pos, value); + else if (pos == -2) + iupdrvListAppendItem(ih, value); } return 0; }  static int iListSetRemoveItemAttrib(Ihandle* ih, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (!value) + { iupdrvListRemoveAllItems(ih); + iupAttribSetStr(ih, "_IUPLIST_OLDVALUE", NULL); + } else { int pos = iupListGetPos(ih, value); - if (pos!=-1) + if (pos >= 0) iupdrvListRemoveItem(ih, pos); } return 0; diff --git a/iup/src/iup_list.h b/iup/src/iup_list.h index 045116b..05fe9f8 100755 --- a/iup/src/iup_list.h +++ b/iup/src/iup_list.h @@ -30,6 +30,7 @@ char* iupListGetNCAttrib(Ihandle* ih); char* iupListGetPaddingAttrib(Ihandle* ih); char* iupListGetSpacingAttrib(Ihandle* ih); void iupListSingleCallDblClickCallback(Ihandle* ih, IFnis cb, int pos); +void iupListUpdateOldValue(Ihandle* ih, int pos, int removed);  struct _IcontrolData  { diff --git a/iup/src/iup_names.c b/iup/src/iup_names.c index 9ec01a6..18ca3ef 100755 --- a/iup/src/iup_names.c +++ b/iup/src/iup_names.c @@ -14,11 +14,41 @@ #include "iup_object.h" #include "iup_class.h" #include "iup_assert.h" +#include "iup_attrib.h" #include "iup_str.h"   static Itable *inames_strtable = NULL; /* table indexed by name containing Ihandle* address */ -static Itable *inames_ihtable = NULL; /* table indexed by Ihandle* address containing names */ + +void iupNamesInit(void) +{ + inames_strtable = iupTableCreate(IUPTABLE_STRINGINDEXED); +} + +void iupNamesFinish(void) +{ + iupTableDestroy(inames_strtable); + inames_strtable = NULL; +} + +static Ihandle* iNameGetTopParent(Ihandle* ih) +{ + Ihandle* parent = ih; + while (parent->parent) + parent = parent->parent; + return parent; +} + +static int iNameCheckArray(Ihandle** ih_array, int count, Ihandle* ih) +{ + int i; + for (i = 0; i < count; i++) + { + if (ih_array[i] == ih) + return 0; + } + return 1; +}  void iupNamesDestroyHandles(void) { @@ -37,10 +67,14 @@ void iupNamesDestroyHandles(void) while (name) { ih = (Ihandle*)iupTableGetCurr(inames_strtable); - if (iupObjectCheck(ih)) + if (iupObjectCheck(ih)) /* here must be a handle */ { - ih_array[i] = ih; - i++; + ih = iNameGetTopParent(ih); + if (iNameCheckArray(ih_array, i, ih)) + { + ih_array[i] = ih; + i++; + } } name = iupTableNext(inames_strtable); } @@ -48,44 +82,28 @@ void iupNamesDestroyHandles(void) count = i; for (i = 0; i < count; i++) { - if (iupObjectCheck(ih_array[i])) + if (iupObjectCheck(ih_array[i])) /* here must be a handle */ IupDestroy(ih_array[i]); }  free(ih_array); }  -void iupNamesInit(void) -{ - inames_strtable = iupTableCreate(IUPTABLE_STRINGINDEXED); - inames_ihtable = iupTableCreate(IUPTABLE_POINTERINDEXED); -} - -void iupNamesFinish(void) -{ - iupTableDestroy(inames_strtable); - inames_strtable = NULL; - - iupTableDestroy(inames_ihtable); - inames_ihtable = NULL; -} - -void iupRemoveAllNames(Ihandle* ih) +void iupRemoveNames(Ihandle* ih) { char *name; - Ihandle *cur_ih;  - name = iupTableFirst(inames_strtable); - while (name) - { - cur_ih = (Ihandle*)iupTableGetCurr(inames_strtable); - if (iupObjectCheck(cur_ih) && cur_ih == ih) - iupTableRemoveCurr(inames_strtable); + /* clear the cache */ + name = iupAttribGet(ih, "_IUP_LASTHANDLENAME"); + if (name) + iupTableRemove(inames_strtable, name);  - name = iupTableNext(inames_strtable); - } + /* check for an internal name */ + name = iupAttribGetHandleName(ih); + if (name) + iupTableRemove(inames_strtable, name);  - iupTableRemove(inames_ihtable, (char*)ih); + /* Do NOT search for other names */ }  Ihandle *IupGetHandle(const char *name) @@ -104,22 +122,24 @@ Ihandle* IupSetHandle(const char *name, Ihandle *ih) return NULL;  old_ih = iupTableGet(inames_strtable, name); + if (ih != NULL) { iupTableSet(inames_strtable, name, ih, IUPTABLE_POINTER); - iupTableSet(inames_ihtable, (char*)ih, (char*)name, IUPTABLE_STRING); /* keep only the last name set */ + + /* save the name in the cache if it is a valid handle */ + if (iupObjectCheck(ih)) + iupAttribStoreStr(ih, "_IUP_LASTHANDLENAME", name); } else { - ih = iupTableGet(inames_strtable, name); iupTableRemove(inames_strtable, name); - if (ih)  - { - char* cur_name = iupTableGet(inames_ihtable, (char*)ih); - if (iupStrEqualNoCase(cur_name, name)) - iupTableRemove(inames_ihtable, (char*)ih); - } + + /* clear the name from the cache if it is a valid handle */ + if (iupObjectCheck(old_ih)) + iupAttribSetStr(old_ih, "_IUP_LASTHANDLENAME", NULL); } + return old_ih; }  @@ -151,7 +171,8 @@ static int iNamesCountDialogs(void) while (name) { Ihandle* dlg = (Ihandle*)iupTableGetCurr(inames_strtable); - if (iupObjectCheck(dlg) && dlg->iclass->nativetype == IUP_TYPEDIALOG) + if (iupObjectCheck(dlg) && /* here must be a handle */ + dlg->iclass->nativetype == IUP_TYPEDIALOG) i++;  name = iupTableNext(inames_strtable); @@ -171,7 +192,8 @@ int IupGetAllDialogs(char** names, int n) while (name) { Ihandle* dlg = (Ihandle*)iupTableGetCurr(inames_strtable); - if (iupObjectCheck(dlg) && dlg->iclass->nativetype == IUP_TYPEDIALOG) + if (iupObjectCheck(dlg) && /* here must be a handle */ + dlg->iclass->nativetype == IUP_TYPEDIALOG) { names[i] = name; i++; @@ -186,8 +208,32 @@ int IupGetAllDialogs(char** names, int n)  char* IupGetName(Ihandle* ih) { - iupASSERT(iupObjectCheck(ih)); - if (!iupObjectCheck(ih)) + char *name; + if (!ih) /* no iupASSERT needed here */ return NULL; - return iupTableGet(inames_ihtable, (char*)ih); + + if (iupObjectCheck(ih)) + { + /* check the cache first, but must be a handle */ + name = iupAttribGet(ih, "_IUP_LASTHANDLENAME"); + if (name) + return name; + } + + /* check for an internal name */ + name = iupAttribGetHandleName(ih); + if (name) + return name; +  + /* search for the name */ + name = iupTableFirst(inames_strtable); + while (name) + { + if ((Ihandle*)iupTableGetCurr(inames_strtable) == ih) + return name; + + name = iupTableNext(inames_strtable); + } + + return NULL; } diff --git a/iup/src/iup_names.h b/iup/src/iup_names.h index 9d3adc7..d652594 100755 --- a/iup/src/iup_names.h +++ b/iup/src/iup_names.h @@ -17,7 +17,7 @@ void iupNamesFinish(void); void iupNamesDestroyHandles(void);  /* called from IupDestroy */ -void iupRemoveAllNames(Ihandle* ih); +void iupRemoveNames(Ihandle* ih);  /* Other functions declared in and implemented here. IupGetName diff --git a/iup/src/iup_object.c b/iup/src/iup_object.c index 7f4ce23..f0d5dc9 100755 --- a/iup/src/iup_object.c +++ b/iup/src/iup_object.c @@ -148,6 +148,8 @@ Ihandle* IupCreate(const char *name)  void IupDestroy(Ihandle *ih) { + Icallback cb; + iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; @@ -156,6 +158,9 @@ void IupDestroy(Ihandle *ih) if (ih->iclass->nativetype == IUP_TYPEDIALOG) IupHide(ih);  + cb = IupGetCallback(ih, "DESTROY_CB"); + if (cb) cb(ih); + /* Destroy all its children. Just need to remove the first child, IupDetach will update firstchild. */ @@ -165,6 +170,9 @@ void IupDestroy(Ihandle *ih) /* unmap if mapped and remove from its parent child list */ IupDetach(ih);  + /* removes names associated with the element */ + iupRemoveNames(ih); + /* destroy the element */ iupClassObjectDestroy(ih);  @@ -172,9 +180,6 @@ void IupDestroy(Ihandle *ih) if (ih->data) free(ih->data);  - /* removes all the names associated with the element */ - iupRemoveAllNames(ih); - /* destroy the base handle structure */ iHandleDestroy(ih); } diff --git a/iup/src/iup_object.h b/iup/src/iup_object.h index 6f6b668..a69edc0 100755 --- a/iup/src/iup_object.h +++ b/iup/src/iup_object.h @@ -113,6 +113,7 @@ Ihandle* iupObjectCreate(Iclass* ic, void** params); void** iupObjectGetParamList(void* first, va_list arglist);  /** Checks if the handle is still valid based on the signature. + * But if the handle was destroyed still can access invalid memory. * \ingroup object */ int iupObjectCheck(Ihandle* ih);  diff --git a/iup/src/iup_open.c b/iup/src/iup_open.c index e02561e..bce5c5c 100755 --- a/iup/src/iup_open.c +++ b/iup/src/iup_open.c @@ -101,8 +101,8 @@ void IupClose(void)  iupdrvSetIdleFunction(NULL); /* stop any idle */  - iupDlgListDestroyAll(); /* destroy all dialogs */ - iupNamesDestroyHandles(); /* destroy everything else that have names */ + iupDlgListDestroyAll(); /* destroy all dialogs and their children */ + iupNamesDestroyHandles(); /* destroy everything that do not belong to a dialog */ iupImageStockFinish(); /* release stock images hash table and the images */  iupRegisterFinish(); /* release native classes */ diff --git a/iup/src/iup_register.c b/iup/src/iup_register.c index 4c58038..2e9954a 100755 --- a/iup/src/iup_register.c +++ b/iup/src/iup_register.c @@ -99,6 +99,7 @@ void iupRegisterInternalClasses(void) iupRegisterClass(iupCboxGetClass()); iupRegisterClass(iupSboxGetClass()); iupRegisterClass(iupNormalizerGetClass()); + iupRegisterClass(iupSplitGetClass());  iupRegisterClass(iupMenuGetClass()); iupRegisterClass(iupItemGetClass()); diff --git a/iup/src/iup_sbox.c b/iup/src/iup_sbox.c index 5a71d33..9998481 100755 --- a/iup/src/iup_sbox.c +++ b/iup/src/iup_sbox.c @@ -57,6 +57,7 @@ static void iSboxSaveDimension(Ihandle* ih, int w, int h) { ih->data->w = w; ih->data->h = h; + iupLayoutSetMinMaxSize(ih, &(ih->data->w), &(ih->data->h)); }  static void iSboxAddDecorOffset(Ihandle* ih, int *x, int *y) diff --git a/iup/src/iup_show.c b/iup/src/iup_show.c index 9ea1408..b42975e 100755 --- a/iup/src/iup_show.c +++ b/iup/src/iup_show.c @@ -53,35 +53,6 @@ void IupUnmap(Ihandle *ih) ih->handle = NULL; }  -static char* iShowGetVisible(Ihandle* ih) -{ - char* value = iupAttribGet(ih, "VISIBLE"); /* Check on the element first */ - while (!value) - { - ih = ih->parent; /* iheritance here independs on the attribute */ - if (!ih) - return NULL; - - value = iupAttribGet(ih, "VISIBLE"); - - /* only recursive up to the native parent */  - if (ih->iclass->nativetype != IUP_TYPEVOID) - return value; /* can be NULL */ - } - - return value; -} - -static void iShowUpdateVisible(Ihandle* ih) -{ - int inherit; - /* although default is VISIBLE=YES,  - when mapped the element is still hidden.  - So we must manually update the visible state. */ - char* value = iShowGetVisible(ih); - iupClassObjectSetAttribute(ih, "VISIBLE", value, &inherit); -} - int IupMap(Ihandle* ih) { iupASSERT(iupObjectCheck(ih)); @@ -108,7 +79,7 @@ int IupMap(Ihandle* ih) return IUP_ERROR; }  - /* update FONT, must be the before several others */ + /* update FONT, must be the before several others, so we do it here */ if (ih->iclass->nativetype != IUP_TYPEVOID && ih->iclass->nativetype != IUP_TYPEIMAGE && ih->iclass->nativetype != IUP_TYPEMENU) @@ -117,18 +88,13 @@ int IupMap(Ihandle* ih) /* ensure attributes default values, at this time only the ones that need to be set after map */ iupClassObjectEnsureDefaultAttributes(ih);  - /* check visible state if not a dialog */ - if (ih->iclass->nativetype == IUP_TYPECANVAS ||  - ih->iclass->nativetype == IUP_TYPECONTROL) - iShowUpdateVisible(ih); - - /* updates the defined attributes in the native system. */ + /* updates the defined attributes from the hash table to the native system. */ iupAttribUpdate(ih);   - /* updates attributes defined in the parent tree */ + /* updates inheritable attributes defined in the parent tree */ iupAttribUpdateFromParent(ih);  - /* map children */ + /* map children independent from childtype */ { Ihandle* child = ih->firstchild; while (child) @@ -140,6 +106,10 @@ int IupMap(Ihandle* ih) } }  + /* updates the defined attributes from the hash table to the native system. */ + if (ih->iclass->childtype!=IUP_CHILDNONE) + iupAttribUpdateChildren(ih); + /* moves and resizes the elements to reflect the layout computation */ /* if the dialog is visible will be reflected in the user interface */ if (ih->iclass->nativetype == IUP_TYPEDIALOG) diff --git a/iup/src/iup_spin.c b/iup/src/iup_spin.c index 6fadab4..514703f 100755 --- a/iup/src/iup_spin.c +++ b/iup/src/iup_spin.c @@ -175,7 +175,7 @@ static int iSpinCreateMethod(Ihandle* ih, void** params)  static int iSpinboxCreateMethod(Ihandle* ih, void** params) { - Ihandle *spin, *ctrl; + Ihandle *spin;  if (!params || !(params[0])) return IUP_ERROR; @@ -184,8 +184,7 @@ static int iSpinboxCreateMethod(Ihandle* ih, void** params) IupSetAttribute(ih, "MARGIN", "0x0"); IupSetAttribute(ih, "ALIGNMENT", "ACENTER");  - ctrl = (Ihandle*)(params[0]); - iupChildTreeAppend(ih, ctrl); + /* IupText is already a child of Spinbox because of the IupHbox Create method */  spin = IupSpin(); iupChildTreeAppend(ih, spin); @@ -249,7 +248,7 @@ Iclass* iupSpinboxGetClass(void) ic->name = "spinbox"; ic->format = "h"; /* one Ihandle */ ic->nativetype = IUP_TYPEVOID; - ic->childtype = IUP_CHILDNONE; + ic->childtype = IUP_CHILD_ONE; /* fake value to define it as a container */ ic->is_interactive = 0;  iupClassRegisterCallback(ic, "SPIN_CB", "i"); @@ -267,7 +266,7 @@ Iclass* iupSpinGetClass(void) ic->name = "spin"; ic->format = NULL; /* no parameters */ ic->nativetype = IUP_TYPEVOID; - ic->childtype = IUP_CHILDNONE; + ic->childtype = IUP_CHILD_ONE; /* fake value to define it as a container */ ic->is_interactive = 0;  /* Class functions */ diff --git a/iup/src/iup_stdcontrols.h b/iup/src/iup_stdcontrols.h index 11499ae..0f3deb9 100755 --- a/iup/src/iup_stdcontrols.h +++ b/iup/src/iup_stdcontrols.h @@ -46,6 +46,7 @@ Iclass* iupZboxGetClass(void); Iclass* iupCboxGetClass(void); Iclass* iupSboxGetClass(void); Iclass* iupNormalizerGetClass(void); +Iclass* iupSplitGetClass(void);  Iclass* iupTimerGetClass(void); Iclass* iupImageGetClass(void); diff --git a/iup/src/iup_str.c b/iup/src/iup_str.c index 68976f1..5f5b85d 100755 --- a/iup/src/iup_str.c +++ b/iup/src/iup_str.c @@ -147,8 +147,9 @@ char *iupStrCopyUntil(char **str, int c) return NULL;  p_str=strchr(*str,c); - if (!p_str) return NULL; - + if (!p_str)  + return NULL; + else { int i; int sl=(int)(p_str - (*str)); @@ -160,10 +161,10 @@ char *iupStrCopyUntil(char **str, int c) new_str[i] = (*str)[i];  new_str[sl] = 0; - }  - *str = p_str+1; - return new_str; + *str = p_str+1; + return new_str; + } }  char *iupStrCopyUntilNoCase(char **str, int c) @@ -174,11 +175,12 @@ char *iupStrCopyUntilNoCase(char **str, int c)  p_str=strchr(*str,c); /* usually the lower case is enough */ if (!p_str && isalpha(c))  - { p_str=strchr(*str, toupper(c)); /* but check also for upper case */ - if (!p_str) return NULL; - }  + /* if both fail, then abort */ + if (!p_str)  + return NULL; + else { int i; int sl=(int)(p_str - (*str)); @@ -190,10 +192,10 @@ char *iupStrCopyUntilNoCase(char **str, int c) new_str[i] = (*str)[i];  new_str[sl] = 0; - }  - *str = p_str+1; - return new_str; + *str = p_str+1; + return new_str; + } }  char *iupStrGetMemory(int size) diff --git a/iup/src/iup_table.c b/iup/src/iup_table.c index 9e97ff5..a873191 100755 --- a/iup/src/iup_table.c +++ b/iup/src/iup_table.c @@ -19,12 +19,12 @@ /* Adjust these parameters for optimal performance and memory usage */ static const unsigned int itable_maxTableSizeIndex = 8; static const unsigned int itable_hashTableSize[] = { 31, 101, 401, 1601, 4001, 8009, 16001, 32003, 64007 }; -static const float itable_resizeLimit = 2; +static const unsigned int itable_resizeLimit = 2; static const unsigned int itable_itemGrow = 5;  /* Iteration context. */ -typedef struct ItableContext +typedef struct _ItableContext { unsigned int entryIndex; /* index at the Itable::entries array */ unsigned int itemIndex; /* index at the ItableEntry::items array */ @@ -41,7 +41,7 @@ typedef struct ItableContext * this is simply the pointer (in this case keyIndex * and keyStr are equal). */ -typedef struct ItableKey +typedef struct _ItableKey { unsigned long keyIndex; /* the secondary hash number */ const char *keyStr; @@ -52,11 +52,11 @@ ItableKey; * Such an item is stored in the item list of * an entry. */ -typedef struct ItableItem +typedef struct _ItableItem { Itable_Types itemType; - ItableKey key; - void *value; + ItableKey key; + void* value; } ItableItem;  @@ -67,29 +67,28 @@ ItableItem; * in nextItemIndex. * size is the current size of the items array. */ -typedef struct ItableEntry +typedef struct _ItableEntry { unsigned int nextItemIndex; - unsigned int size; - ItableItem *items; + unsigned int itemsSize; + ItableItem* items; } ItableEntry;   /* A hash table. - * indexType is the type of the index. * entries is an array of entries. Select an * entry by its index. * size is the number of entries in the hash table... */ -struct Itable +struct _Itable { - unsigned int size; - unsigned int numberOfEntries; - unsigned int tableSizeIndex; /* index into itable_hashTableSize array */ - Itable_IndexTypes indexType; - ItableEntry *entries; - ItableContext context; + unsigned int entriesSize; + unsigned int numberOfEntries; + unsigned int tableSizeIndex; /* index into itable_hashTableSize array */ + Itable_IndexTypes indexType; /* type of the index: string or pointer. */ + ItableEntry *entries; + ItableContext context; };   @@ -121,8 +120,7 @@ Itable *iupTableCreate(Itable_IndexTypes indexType)  Itable *iupTableCreateSized(Itable_IndexTypes indexType, unsigned int initialSizeIndex) { - Itable *it = (Itable *)malloc(sizeof(struct Itable)); - + Itable *it = (Itable *)malloc(sizeof(Itable)); iupASSERT(it!=NULL); if (!it) return 0; @@ -130,12 +128,12 @@ Itable *iupTableCreateSized(Itable_IndexTypes indexType, unsigned int initialSiz if (initialSizeIndex > itable_maxTableSizeIndex) initialSizeIndex = itable_maxTableSizeIndex;  - it->size = itable_hashTableSize[initialSizeIndex]; + it->entriesSize = itable_hashTableSize[initialSizeIndex]; it->tableSizeIndex = initialSizeIndex; it->numberOfEntries = 0; it->indexType = indexType;  - it->entries = (ItableEntry *)malloc(it->size * sizeof(ItableEntry)); + it->entries = (ItableEntry *)malloc(it->entriesSize * sizeof(ItableEntry)); iupASSERT(it->entries!=NULL); if (!it->entries) { @@ -143,7 +141,7 @@ Itable *iupTableCreateSized(Itable_IndexTypes indexType, unsigned int initialSiz return 0; }  - memset(it->entries, 0, it->size * sizeof(ItableEntry)); + memset(it->entries, 0, it->entriesSize * sizeof(ItableEntry));  it->context.entryIndex = (unsigned int)-1; it->context.itemIndex = (unsigned int)-1; @@ -158,16 +156,19 @@ void iupTableClear(Itable *it) if (!it) return;  - for (i = 0; i < it->size; i++) + for (i = 0; i < it->entriesSize; i++) { ItableEntry *entry = &(it->entries[i]); if (entry->items) + { iTableFreeItemArray(it->indexType, entry->nextItemIndex, entry->items); + entry->items = NULL; + } }  it->numberOfEntries = 0;  - memset(it->entries, 0, it->size * sizeof(ItableEntry)); + memset(it->entries, 0, it->entriesSize * sizeof(ItableEntry));  it->context.entryIndex = (unsigned int)-1; it->context.itemIndex = (unsigned int)-1; @@ -185,7 +186,10 @@ void iupTableDestroy(Itable *it) iupTableClear(it);  if (it->entries) + { free(it->entries); + it->entries = NULL; + }  free(it); } @@ -288,17 +292,23 @@ static void iTableRemoveItem(Itable *it, ItableEntry *entry, unsigned int itemIn item = &(entry->items[itemIndex]);  if (it->indexType == IUPTABLE_STRINGINDEXED) + { free((void *)item->key.keyStr); + item->key.keyStr = NULL; + }  if (item->itemType == IUPTABLE_STRING) + { free(item->value); + item->value = NULL; + }  - /* order the remaining items */ + /* re-order the remaining items */ for (i = itemIndex; i < entry->nextItemIndex-1; i++) entry->items[i] = entry->items[i+1];  - /* clear the non used item */ - memset(entry->items + entry->nextItemIndex, 0, sizeof (ItableItem)); + /* clear the released item */ + memset(entry->items + entry->nextItemIndex-1, 0, sizeof (ItableItem));  entry->nextItemIndex--; it->numberOfEntries--; @@ -398,7 +408,7 @@ char *iupTableFirst(Itable *it) it->context.itemIndex = (unsigned int)-1;  /* find the first used entry */ - for (entryIndex = 0; entryIndex < it->size; entryIndex++) + for (entryIndex = 0; entryIndex < it->entriesSize; entryIndex++) { if (it->entries[entryIndex].nextItemIndex > 0) { @@ -430,7 +440,7 @@ char *iupTableNext(Itable *it) else { /* find the next used entry */ - for (entryIndex = it->context.entryIndex+1; entryIndex < it->size; entryIndex++) + for (entryIndex = it->context.entryIndex+1; entryIndex < it->entriesSize; entryIndex++) { if (it->entries[entryIndex].nextItemIndex > 0) { @@ -471,7 +481,7 @@ char *iupTableRemoveCurr(Itable *it) else { /* find the next used entry */ - for (entryIndex = it->context.entryIndex+1; entryIndex < it->size; entryIndex++) + for (entryIndex = it->context.entryIndex+1; entryIndex < it->entriesSize; entryIndex++) { if (it->entries[entryIndex].nextItemIndex > 0) { @@ -498,6 +508,8 @@ static void iTableFreeItemArray(Itable_IndexTypes indexType, unsigned int nextFr { unsigned int i;  + /* Used only in iupTableClear */ + iupASSERT(items!=NULL); if (!items) return; @@ -505,13 +517,19 @@ static void iTableFreeItemArray(Itable_IndexTypes indexType, unsigned int nextFr if (indexType == IUPTABLE_STRINGINDEXED) { for (i = 0; i < nextFreeIndex; i++) + { free((void *)(items[i].key.keyStr)); + items[i].key.keyStr = NULL; + } }  for (i = 0; i < nextFreeIndex; i++) { if (items[i].itemType == IUPTABLE_STRING) + { free(items[i].value); + items[i].value = NULL; + } }  free(items); @@ -545,7 +563,7 @@ static unsigned int iTableGetEntryIndex(Itable *it, const char *key, unsigned lo *keyIndex = (unsigned long)key; /* this could NOT be dependent from table size */ }  - return (unsigned int)((*keyIndex) % it->size); + return (unsigned int)((*keyIndex) % it->entriesSize); }  #ifdef DEBUGTABLE @@ -603,25 +621,24 @@ static unsigned int iTableFindItem(Itable *it, const char *key, ItableEntry **en  static void iTableUpdateArraySize(ItableEntry *entry) { - if (entry->nextItemIndex >= entry->size) + if (entry->nextItemIndex >= entry->itemsSize) { /* we have to expand the item array */ unsigned int newSize;  - newSize = entry->size + itable_itemGrow; + newSize = entry->itemsSize + itable_itemGrow;  entry->items = (ItableItem *)realloc(entry->items, newSize * sizeof(ItableItem)); iupASSERT(entry->items!=NULL); if (!entry->items) return;  - memset(entry->items + entry->size, 0, itable_itemGrow * sizeof(ItableItem)); + memset(entry->items + entry->itemsSize, 0, itable_itemGrow * sizeof(ItableItem));  - entry->size = newSize; + entry->itemsSize = newSize; } }  - static void iTableAdd(Itable *it, ItableKey *key, void *value, Itable_Types itemType) { unsigned int entryIndex; @@ -657,7 +674,7 @@ static unsigned int iTableResize(Itable *it) /* check if we do not need to resize the hash table */ if (it->numberOfEntries == 0 || it->tableSizeIndex >= itable_maxTableSizeIndex || - it->size / it->numberOfEntries >= itable_resizeLimit) + it->entriesSize / it->numberOfEntries >= itable_resizeLimit) return 0;  /* create a new hash table and copy the contents of @@ -666,7 +683,7 @@ static unsigned int iTableResize(Itable *it) newSizeIndex = it->tableSizeIndex + 1; newTable = iupTableCreateSized(it->indexType, newSizeIndex);  - for (entryIndex = 0; entryIndex < it->size; entryIndex++) + for (entryIndex = 0; entryIndex < it->entriesSize; entryIndex++) { entry = &(it->entries[entryIndex]);  @@ -680,12 +697,13 @@ static unsigned int iTableResize(Itable *it) }   free(entry->items); + entry->items = NULL; } }  free(it->entries);  - it->size = newTable->size; + it->entriesSize = newTable->entriesSize; it->tableSizeIndex = newTable->tableSizeIndex; it->numberOfEntries = newTable->numberOfEntries; it->entries = newTable->entries; @@ -712,11 +730,11 @@ static void iTableShowStatistics(Itable *it) return; }  - nofSlots = it->size; + nofSlots = it->entriesSize; nofKeys = it->numberOfEntries; optimalNofKeysPerSlot = (double)nofKeys / (double)nofSlots;  - for (entryIndex = 0; entryIndex < it->size; entryIndex++) + for (entryIndex = 0; entryIndex < it->entriesSize; entryIndex++) { ItableEntry *entry = &(it->entries[entryIndex]);  diff --git a/iup/src/iup_table.h b/iup/src/iup_table.h index 5222160..f2ff2c7 100755 --- a/iup/src/iup_table.h +++ b/iup/src/iup_table.h @@ -42,8 +42,8 @@ typedef enum _Itable_Types  typedef void (*Ifunc)(void);  -struct Itable; -typedef struct Itable Itable; +struct _Itable; +typedef struct _Itable Itable;   /** Creates a hash table with an initial default size. @@ -63,7 +63,7 @@ Itable *iupTableCreateSized(Itable_IndexTypes indexType, unsigned int initialSiz /** Destroys the Itable. * Calls \ref iupTableClear. * \ingroup table */ -void iupTableDestroy(Itable *n); +void iupTableDestroy(Itable *it);  /** Removes all items in the table. * This function does also free the memory of strings contained in the table!!!! @@ -76,33 +76,33 @@ int iupTableCount(Itable *it);  /** Store an element in the table. * \ingroup table */ -void iupTableSet(Itable *n, const char *key, void *value, Itable_Types itemType); +void iupTableSet(Itable *it, const char *key, void *value, Itable_Types itemType);  /** Store a function pointer in the table. * Type is set to IUPTABLE_FUNCPOINTER. * \ingroup table */ -void iupTableSetFunc(Itable *n, const char *key, Ifunc func); +void iupTableSetFunc(Itable *it, const char *key, Ifunc func);  /** Retrieves an element from the table. * Returns NULL if not found. * \ingroup table */ -void *iupTableGet(Itable *n, const char *key); +void *iupTableGet(Itable *it, const char *key);  /** Retrieves a function pointer from the table.  * If not a function or not found returns NULL. * value always contains the element pointer. * \ingroup table */ -Ifunc iupTableGetFunc(Itable *n, const char *key, void **value); +Ifunc iupTableGetFunc(Itable *it, const char *key, void **value);  /** Retrieves an element from the table and its type. * \ingroup table */ -void *iupTableGetTyped(Itable *n, const char *key, Itable_Types *itemType); +void *iupTableGetTyped(Itable *it, const char *key, Itable_Types *itemType);  /** Removes the entry at the specified key from the * hash table and frees the memory used by it if * it is a string... * \ingroup table */ -void iupTableRemove(Itable *n, const char *key); +void iupTableRemove(Itable *it, const char *key);  /** Key iteration function. Returns a key. * To iterate over all keys call iupTableFirst at the first diff --git a/iup/src/iup_tabs.c b/iup/src/iup_tabs.c index 77b2cf5..2907371 100755 --- a/iup/src/iup_tabs.c +++ b/iup/src/iup_tabs.c @@ -307,6 +307,25 @@ static char* iTabsGetClientSizeAttrib(Ihandle* ih) return str; }  +void iupTabsTestRemoveTab(Ihandle* ih, int pos) +{ + int cur_pos = iupdrvTabsGetCurrentTab(ih); + if (cur_pos == pos) + { + if (cur_pos == 0) + { + Ihandle* child = IupGetChild(ih, 1); + if (!child) /* not found child, means only one child, do nothing */ + return; + + cur_pos = 1; + } + else + cur_pos--; + + iupdrvTabsSetCurrentTab(ih, cur_pos); + } +}  /* ------------------------------------------------------------------------- */ /* TABS - Methods */ diff --git a/iup/src/iup_tabs.h b/iup/src/iup_tabs.h index 7f5df2e..fd0edf4 100755 --- a/iup/src/iup_tabs.h +++ b/iup/src/iup_tabs.h @@ -16,6 +16,7 @@ char* iupTabsGetTabOrientationAttrib(Ihandle* ih); char* iupTabsGetTabTypeAttrib(Ihandle* ih); char* iupTabsAttribGetStrId(Ihandle* ih, const char* name, int pos); char* iupTabsGetPaddingAttrib(Ihandle* ih); +void iupTabsTestRemoveTab(Ihandle* ih, int pos);  int iupdrvTabsExtraDecor(Ihandle* ih); int iupdrvTabsGetLineCountAttrib(Ihandle* ih); diff --git a/iup/src/iup_tree.c b/iup/src/iup_tree.c index c06e573..b5344f5 100755 --- a/iup/src/iup_tree.c +++ b/iup/src/iup_tree.c @@ -200,6 +200,240 @@ void iupTreeUpdateImages(Ihandle *ih) iupClassObjectSetAttribute(ih, "IMAGEBRANCHEXPANDED", value, &inherit); }  +void iupTreeSelectLastCollapsedBranch(Ihandle* ih, int *last_id) +{ + /* if last selected item is a branch, then select its children */ + if (iupStrEqual(IupTreeGetAttribute(ih, "KIND", *last_id), "BRANCH") &&  + iupStrEqual(IupTreeGetAttribute(ih, "STATE", *last_id), "COLLAPSED")) + { + int childcount = IupTreeGetInt(ih, "CHILDCOUNT", *last_id); + if (childcount > 0) + { + int start = *last_id + 1; + int end = *last_id + childcount; + IupSetfAttribute(ih, "MARK", "%d-%d", start, end); + *last_id = *last_id + childcount; + } + } +} + +int iupTreeForEach(Ihandle* ih, iupTreeNodeFunc func, void* userdata) +{ + int i; + for (i = 0; i < ih->data->node_count; i++) + { + if (!func(ih, ih->data->node_cache[i].node_handle, i, userdata)) + return 0; + } + + return 1; +} + +int iupTreeFindNodeId(Ihandle* ih, InodeHandle* node_handle) +{ + /* Unoptimized version: + int i; + for (i = 0; i < ih->data->node_count; i++) + { + if (ih->data->node_cache[i].node_handle == node_handle) + return i; + } + */ + InodeData *node_cache = ih->data->node_cache; + while(node_cache->node_handle != node_handle &&  + node_cache->node_handle != NULL) /* the cache always have zeros at the end */ + node_cache++; + + if (node_cache->node_handle != NULL) + return node_cache - ih->data->node_cache; + else + return -1; +} + +static int iTreeFindUserDataId(Ihandle* ih, void* userdata) +{ + /* Unoptimized version: + int i; + for (i = 0; i < ih->data->node_count; i++) + { + if (ih->data->node_cache[i].node_handle == node_handle) + return i; + } + */ + InodeData *node_cache = ih->data->node_cache; + while(node_cache->userdata != userdata &&  + node_cache->node_handle != NULL) /* the cache always have zeros at the end */ + node_cache++; + + if (node_cache->node_handle != NULL) + return node_cache - ih->data->node_cache; + else + return -1; +} + +static int iTreeGetIdFromString(const char* name_id) +{ + if (name_id && name_id[0]) + { + int id = -1; + iupStrToInt(name_id, &id); + return id; + } + else + return -2; +} + +InodeHandle* iupTreeGetNode(Ihandle* ih, int id) +{ + if (id >= 0 && id < ih->data->node_count) + return ih->data->node_cache[id].node_handle; + else if (id == -2) + return iupdrvTreeGetFocusNode(ih); + else + return NULL; +} + +InodeHandle* iupTreeGetNodeFromString(Ihandle* ih, const char* name_id) +{ + return iupTreeGetNode(ih, iTreeGetIdFromString(name_id)); +} + +static void iTreeAddToCache(Ihandle* ih, int id, InodeHandle* node_handle) +{ + iupASSERT(id >= 0 && id < ih->data->node_count); + if (id < 0 || id >= ih->data->node_count) + return; + + /* node_count here already contains the final count */ + + if (id == ih->data->node_count-1) + ih->data->node_cache[id].node_handle = node_handle; + else + { + /* open space for the new id */ + int remain_count = ih->data->node_count-id; + memmove(ih->data->node_cache+id+1, ih->data->node_cache+id, remain_count*sizeof(InodeData)); + ih->data->node_cache[id].node_handle = node_handle; + } + + ih->data->node_cache[id].userdata = NULL; +} + +static void iTreeIncCacheMem(Ihandle* ih) +{ + /* node_count here already contains the final count */ + + if (ih->data->node_count+10 > ih->data->node_cache_max) + { + int old_node_cache_max = ih->data->node_cache_max; + ih->data->node_cache_max += 20; + ih->data->node_cache = realloc(ih->data->node_cache, ih->data->node_cache_max*sizeof(InodeData)); + memset(ih->data->node_cache+old_node_cache_max, 0, 20*sizeof(InodeData)); + } +} + +void iupTreeAddToCache(Ihandle* ih, int add, int kindPrev, InodeHandle* prevNode, InodeHandle* node_handle) +{ + int new_id = 0; + + ih->data->node_count++; + + /* node_count here already contains the final count */ + iTreeIncCacheMem(ih); + + if (prevNode) + { + if (add || kindPrev == ITREE_LEAF) + { + /* ADD implies always that id=prev_id+1 */ + /* INSERT after a leaf implies always that new_id=prev_id+1 */ + int prev_id = iupTreeFindNodeId(ih, prevNode); + new_id = prev_id+1; + } + else + { + /* INSERT after a branch implies always that new_id=prev_id+1+child_count */ + int prev_id = iupTreeFindNodeId(ih, prevNode); + int child_count = iupdrvTreeTotalChildCount(ih, prevNode); + new_id = prev_id+1+child_count; + } + } + + iTreeAddToCache(ih, new_id, node_handle); + iupAttribSetInt(ih, "LASTADDNODE", new_id); +} + +void iupTreeDelFromCache(Ihandle* ih, int id, int count) +{ + int remain_count; + + /* id can be the last node, actually==node_count becase node_count is already updated */ + iupASSERT(id >= 0 && id <= ih->data->node_count);  + if (id < 0 || id > ih->data->node_count) + return; + + /* node_count here already contains the final count */ + + /* remove id+count */ + remain_count = ih->data->node_count-id; + memmove(ih->data->node_cache+id, ih->data->node_cache+id+count, remain_count*sizeof(InodeData)); + + /* clear the remaining space */ + memset(ih->data->node_cache+ih->data->node_count, 0, count*sizeof(InodeData)); +} + +void iupTreeCopyMoveCache(Ihandle* ih, int id_src, int id_dst, int count, int is_copy) +{ + int remain_count; + + iupASSERT(id_src >= 0 && id_src < ih->data->node_count); + if (id_src < 0 || id_src >= ih->data->node_count) + return; + + iupASSERT(id_dst >= 0 && id_dst < ih->data->node_count); + if (id_dst < 0 || id_dst >= ih->data->node_count) + return; + + iupASSERT(id_dst < id_src || id_dst > id_src+count); + if (id_dst >= id_src && id_dst <= id_src+count) + return; + + /* id_dst here points to the final position for a copy operation */ + + /* node_count here contains the final count for a copy operation */ + iTreeIncCacheMem(ih); + + /* add space for new nodes */ + remain_count = ih->data->node_count - (id_dst + count); + memmove(ih->data->node_cache+id_dst+count, ih->data->node_cache+id_dst, remain_count*sizeof(InodeData)); + + /* compensate because we add space for new nodes */ + if (id_src > id_dst) + id_src += count; + + if (is_copy)  + { + /* during a copy, the userdata is not reused, so clear it */ + memset(ih->data->node_cache+id_dst, 0, count*sizeof(InodeData)); + } + else /* move = copy + delete */ + { + /* copy userdata from src to dst */ + memcpy(ih->data->node_cache+id_dst, ih->data->node_cache+id_src, count*sizeof(InodeData)); + + /* remove the src */ + remain_count = ih->data->node_count - (id_src + count); + memmove(ih->data->node_cache+id_src, ih->data->node_cache+id_src+count, remain_count*sizeof(InodeData)); + + /* clear the remaining space */ + memset(ih->data->node_cache+ih->data->node_count-count, 0, count*sizeof(InodeData)); + } +} + + +/*************************************************************************/ + + char* iupTreeGetSpacingAttrib(Ihandle* ih) { char *str = iupStrGetMemory(50); @@ -221,8 +455,10 @@ static int iTreeSetMarkModeAttrib(Ihandle* ih, const char* value) ih->data->mark_mode = ITREE_MARK_MULTIPLE;  else  ih->data->mark_mode = ITREE_MARK_SINGLE; + if (ih->handle) - iupdrvTreeUpdateMarkMode(ih); + iupdrvTreeUpdateMarkMode(ih); /* for this to work, must update during map */ + return 0; }  @@ -290,7 +526,7 @@ static int iTreeSetShowDragDropAttrib(Ihandle* ih, const char* value)  static int iTreeSetAddLeafAttrib(Ihandle* ih, const char* name_id, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; iupdrvTreeAddNode(ih, name_id, ITREE_LEAF, value, 1); return 0; @@ -298,7 +534,7 @@ static int iTreeSetAddLeafAttrib(Ihandle* ih, const char* name_id, const char* v  static int iTreeSetAddBranchAttrib(Ihandle* ih, const char* name_id, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; iupdrvTreeAddNode(ih, name_id, ITREE_BRANCH, value, 1); return 0; @@ -306,7 +542,7 @@ static int iTreeSetAddBranchAttrib(Ihandle* ih, const char* name_id, const char*  static int iTreeSetInsertLeafAttrib(Ihandle* ih, const char* name_id, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; iupdrvTreeAddNode(ih, name_id, ITREE_LEAF, value, 0); return 0; @@ -314,7 +550,7 @@ static int iTreeSetInsertLeafAttrib(Ihandle* ih, const char* name_id, const char  static int iTreeSetInsertBranchAttrib(Ihandle* ih, const char* name_id, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; iupdrvTreeAddNode(ih, name_id, ITREE_BRANCH, value, 0); return 0; @@ -338,6 +574,74 @@ static int iTreeSetAddExpandedAttrib(Ihandle* ih, const char* value) return 0; }  +static char* iTreeGetCountAttrib(Ihandle* ih) +{ + char* str = iupStrGetMemory(10); + sprintf(str, "%d", ih->data->node_count); + return str; +} + +static char* iTreeGetTotalChildCountAttrib(Ihandle* ih, const char* name_id) +{ + char* str; + InodeHandle* node_handle = iupTreeGetNodeFromString(ih, name_id); + if (!node_handle) + return NULL; + + str = iupStrGetMemory(10); + sprintf(str, "%d", iupdrvTreeTotalChildCount(ih, node_handle)); + return str; +} + + +static char* iTreeGetFindUserDataAttrib(Ihandle* ih, const char* name_id) +{ + int id; + char* str = (char*)(name_id+1); /* skip ':' */ + void* userdata = NULL; + if (sscanf(str, "%p", &userdata)!=1) + return NULL; + id = iTreeFindUserDataId(ih, userdata); + if (id == -1) + return NULL; + str = iupStrGetMemory(16); + sprintf(str, "%d", id); + return str; +} + +static char* iTreeGetUserDataAttrib(Ihandle* ih, const char* name_id) +{ + int id = iTreeGetIdFromString(name_id); + if (id >= 0 && id < ih->data->node_count) + return ih->data->node_cache[id].userdata; + else if (id == -2) + { + InodeHandle* node_handle = iupdrvTreeGetFocusNode(ih); + id = iupTreeFindNodeId(ih, node_handle); + if (id >= 0 && id < ih->data->node_count) + return ih->data->node_cache[id].userdata; + } + return NULL; +} + +static int iTreeSetUserDataAttrib(Ihandle* ih, const char* name_id, const char* value) +{ + int id = iTreeGetIdFromString(name_id); + if (id >= 0 && id < ih->data->node_count) + ih->data->node_cache[id].userdata = (void*)value; + else if (id == -2) + { + InodeHandle* node_handle = iupdrvTreeGetFocusNode(ih); + id = iupTreeFindNodeId(ih, node_handle); + if (id >= 0 && id < ih->data->node_count) + ih->data->node_cache[id].userdata = (void*)value; + } + return 0; +} + + +/*************************************************************************/ + static int iTreeCreateMethod(Ihandle* ih, void **params) { (void)params; @@ -348,10 +652,20 @@ static int iTreeCreateMethod(Ihandle* ih, void **params) IupSetAttribute(ih, "EXPAND", "YES");  ih->data->add_expanded = 1; + ih->data->node_cache_max = 20; + ih->data->node_cache = calloc(ih->data->node_cache_max, sizeof(InodeData));  return IUP_NOERROR; }  +static void iTreeDestroyMethod(Ihandle* ih) +{ + if (ih->data->node_cache) + free(ih->data->node_cache); +} + +/*************************************************************************/ + Ihandle* IupTree(void) { return IupCreate("tree"); @@ -371,15 +685,15 @@ Iclass* iupTreeGetClass(void) /* Class functions */ ic->Create = iTreeCreateMethod; ic->LayoutUpdate = iupdrvBaseLayoutUpdateMethod; - ic->UnMap = iupdrvBaseUnMapMethod; + ic->Destroy = iTreeDestroyMethod;  /* Callbacks */ iupClassRegisterCallback(ic, "SELECTION_CB", "ii"); iupClassRegisterCallback(ic, "MULTISELECTION_CB", "Ii"); + iupClassRegisterCallback(ic, "MULTIUNSELECTION_CB", "Ii"); iupClassRegisterCallback(ic, "BRANCHOPEN_CB", "i"); iupClassRegisterCallback(ic, "BRANCHCLOSE_CB", "i"); iupClassRegisterCallback(ic, "EXECUTELEAF_CB", "i"); - iupClassRegisterCallback(ic, "RENAMENODE_CB", "is"); iupClassRegisterCallback(ic, "SHOWRENAME_CB", "i"); iupClassRegisterCallback(ic, "RENAME_CB", "is"); iupClassRegisterCallback(ic, "DRAGDROP_CB", "iiii"); @@ -392,9 +706,12 @@ Iclass* iupTreeGetClass(void) iupBaseRegisterVisualAttrib(ic);  /* IupTree Attributes - GENERAL */ - iupClassRegisterAttribute(ic, "SHOWDRAGDROP", iTreeGetShowDragDropAttrib, iTreeSetShowDragDropAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); - iupClassRegisterAttribute(ic, "SHOWRENAME", iTreeGetShowRenameAttrib, iTreeSetShowRenameAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); - iupClassRegisterAttribute(ic, "ADDEXPANDED", iTreeGetAddExpandedAttrib, iTreeSetAddExpandedAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "SHOWDRAGDROP", iTreeGetShowDragDropAttrib, iTreeSetShowDragDropAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "SHOWRENAME", iTreeGetShowRenameAttrib, iTreeSetShowRenameAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "ADDEXPANDED", iTreeGetAddExpandedAttrib, iTreeSetAddExpandedAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "COUNT", iTreeGetCountAttrib, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_READONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "LASTADDNODE", NULL, NULL, IUPAF_SAMEASSYSTEM, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "ADDROOT", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT);  /* IupTree Attributes - MARKS */ iupClassRegisterAttribute(ic, "CTRL", NULL, iTreeSetCtrlAttrib, NULL, NULL, IUPAF_NOT_MAPPED); @@ -406,6 +723,11 @@ Iclass* iupTreeGetClass(void) iupClassRegisterAttributeId(ic, "ADDBRANCH", NULL, iTreeSetAddBranchAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "INSERTLEAF", NULL, iTreeSetInsertLeafAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "INSERTBRANCH", NULL, iTreeSetInsertBranchAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); + + /* IupTree Attributes - NODES */ + iupClassRegisterAttributeId(ic, "TOTALCHILDCOUNT", iTreeGetTotalChildCountAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttributeId(ic, "FINDUSERDATA", iTreeGetFindUserDataAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttributeId(ic, "USERDATA", iTreeGetUserDataAttrib, iTreeSetUserDataAttrib, IUPAF_NO_STRING|IUPAF_NO_INHERIT);  /* Default node images */ iTreeInitializeImages(); @@ -415,18 +737,23 @@ Iclass* iupTreeGetClass(void) return ic; }  - /********************************************************************************************/  - -void IupTreeSetAttribute(Ihandle* ih, const char* a, int id, char* v) +void IupTreeSetAttribute(Ihandle* ih, const char* a, int id, const char* v) { char* attr = iupStrGetMemory(50); sprintf(attr, "%s%d", a, id); IupSetAttribute(ih, attr, v); }  -void IupTreeStoreAttribute(Ihandle* ih, const char* a, int id, char* v) +void IupTreeSetAttributeHandle(Ihandle* ih, const char* a, int id, Ihandle* ih_named) +{ + char* attr = iupStrGetMemory(50); + sprintf(attr, "%s%d", a, id); + IupSetAttributeHandle(ih, attr, ih_named); +} + +void IupTreeStoreAttribute(Ihandle* ih, const char* a, int id, const char* v) { char* attr = iupStrGetMemory(50); sprintf(attr, "%s%d", a, id); @@ -454,7 +781,7 @@ float IupTreeGetFloat(Ihandle* ih, const char* a, int id) return IupGetFloat(ih, attr); }  -void IupTreeSetfAttribute(Ihandle* ih, const char* a, int id, char* f, ...) +void IupTreeSetfAttribute(Ihandle* ih, const char* a, int id, const char* f, ...) { static char v[SHRT_MAX]; char* attr = iupStrGetMemory(50); @@ -466,34 +793,40 @@ void IupTreeSetfAttribute(Ihandle* ih, const char* a, int id, char* f, ...) IupStoreAttribute(ih, attr, v); }  - /************************************************************************************/  - int IupTreeSetUserId(Ihandle* ih, int id, void* userdata) { - char attr[30]; - sprintf(attr,"USERDATA%d",id); - IupSetAttribute(ih, attr, userdata); - return IupGetAttribute(ih, attr)? 1: 0; + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return 0; + + if (id >= 0 && id < ih->data->node_count) + { + ih->data->node_cache[id].userdata = userdata; + return 1; + } + + return 0; }  int IupTreeGetId(Ihandle* ih, void *userdata) { - int id = -1; - char* value; - char attr[30]; - sprintf(attr,"FINDUSERDATA:%p",userdata); - value = IupGetAttribute(ih, attr); - if (!value) return -1; + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return -1;  - iupStrToInt(value, &id); - return id; + return iTreeFindUserDataId(ih, userdata); }  void* IupTreeGetUserId(Ihandle* ih, int id) { - char attr[30]; - sprintf(attr,"USERDATA%d",id); - return IupGetAttribute(ih, attr); + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return NULL; + + if (id >= 0 && id < ih->data->node_count) + return ih->data->node_cache[id].userdata; + + return NULL; } diff --git a/iup/src/iup_tree.h b/iup/src/iup_tree.h index f96a698..44acc83 100755 --- a/iup/src/iup_tree.h +++ b/iup/src/iup_tree.h @@ -29,6 +29,36 @@ void iupdrvTreeUpdateMarkMode(Ihandle *ih);  char* iupTreeGetSpacingAttrib(Ihandle* ih);  +#if defined(GTK_MAJOR_VERSION) +typedef void InodeHandle; +#elif defined(XmVERSION) +typedef struct _WidgetRec InodeHandle; +#elif defined(WINVER) +typedef struct _TREEITEM InodeHandle; +#else +typedef struct _InodeData InodeHandle; +#endif + +typedef struct _InodeData +{ + InodeHandle* node_handle; + void* userdata; +} InodeData; + +typedef int (*iupTreeNodeFunc)(Ihandle* ih, InodeHandle* node_handle, int id, void* userdata); +int iupTreeForEach(Ihandle* ih, iupTreeNodeFunc func, void* userdata); +InodeHandle* iupTreeGetNode(Ihandle* ih, int id); +InodeHandle* iupTreeGetNodeFromString(Ihandle* ih, const char* name_id); +int iupTreeFindNodeId(Ihandle* ih, InodeHandle* node_handle); + +InodeHandle* iupdrvTreeGetFocusNode(Ihandle* ih); +int iupdrvTreeTotalChildCount(Ihandle* ih, InodeHandle* node_handle); +void iupTreeSelectLastCollapsedBranch(Ihandle* ih, int *last_id); + +void iupTreeDelFromCache(Ihandle* ih, int id, int count); +void iupTreeAddToCache(Ihandle* ih, int add, int kindPrev, InodeHandle* prevNode, InodeHandle* node_handle); +void iupTreeCopyMoveCache(Ihandle* ih, int id_src, int id_dst, int count, int is_copy); + /* Structure of the tree */ struct _IcontrolData { @@ -36,6 +66,7 @@ struct _IcontrolData add_expanded, show_dragdrop, show_rename, + stamp, /* GTK only */ spacing;  void* def_image_leaf; /* Default image leaf */ @@ -44,9 +75,10 @@ struct _IcontrolData  void* def_image_leaf_mask; /* Motif Only */ void* def_image_collapsed_mask;  - void* def_image_expanded_mask;  + void* def_image_expanded_mask;   - int id_control; /* auxiliary variable for computing or finding the id of a node */ + InodeData *node_cache; + int node_cache_max, node_count; };   diff --git a/iup/src/iup_vbox.c b/iup/src/iup_vbox.c index f71aa51..23e8e3a 100755 --- a/iup/src/iup_vbox.c +++ b/iup/src/iup_vbox.c @@ -215,6 +215,13 @@ static void iVboxSetChildrenCurrentSizeMethod(Ihandle* ih, int shrink) else { int empty = (child->expand & IUP_EXPAND_H1)? empty_h1: ((child->expand & IUP_EXPAND_H0)? empty_h0: 0); + char* weigth_str = iupAttribGet(child, "EXPANDWEIGTH"); + if (weigth_str) + { + float weigth;  + if (iupStrToFloat(weigth_str, &weigth)) + empty = iupROUND(empty * weigth); + } iupBaseSetCurrentSize(child, client_width, child->naturalheight+empty, shrink); }  diff --git a/iup/src/iup_zbox.c b/iup/src/iup_zbox.c index 3f79892..dd4a0e4 100755 --- a/iup/src/iup_zbox.c +++ b/iup/src/iup_zbox.c @@ -210,7 +210,7 @@ static int iZboxSetVisibleAttrib(Ihandle* ih, const char* value) { if (iupObjectCheck(ih->data->value_handle)) IupSetAttribute(ih->data->value_handle, "VISIBLE", (char*)value); - return 0; + return 1; /* must be 1 to mark when set at the element */ }  static void iZboxComputeNaturalSizeMethod(Ihandle* ih, int *w, int *h, int *expand) @@ -368,8 +368,8 @@ Iclass* iupZboxGetClass(void) iupClassRegisterAttribute(ic, "VALUEPOS", iZboxGetValuePosAttrib, iZboxSetValuePosAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "VALUE_HANDLE", NULL, iZboxSetValueHandleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT|IUPAF_NO_STRING);  - /* Intercept VISIBLE since ZBOX works showing and hidding its children */ - iupClassRegisterAttribute(ic, "VISIBLE", NULL, iZboxSetVisibleAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + /* Intercept VISIBLE since ZBOX works by showing and hidding its children */ + iupClassRegisterAttribute(ic, "VISIBLE", NULL, iZboxSetVisibleAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED);  return ic; } diff --git a/iup/src/make_uname b/iup/src/make_uname index 7fec9f8..6542234 100755 --- a/iup/src/make_uname +++ b/iup/src/make_uname @@ -1,4 +1,4 @@ #This builds all the libraries of the folder for 1 uname  -tecmake $1 $2 $3 $4 $5 $6 $7 +tecmake USE_MOTIF=Yes $1 $2 $3 $4 $5 $6 $7 tecmake USE_GTK=Yes $1 $2 $3 $4 $5 $6 $7 diff --git a/iup/src/mot/iupmot_button.c b/iup/src/mot/iupmot_button.c index 2d93588..f6e383f 100755 --- a/iup/src/mot/iupmot_button.c +++ b/iup/src/mot/iupmot_button.c @@ -112,8 +112,10 @@ static int motButtonSetPaddingAttrib(Ihandle* ih, const char* value) { XtVaSetValues(ih->handle, XmNmarginHeight, ih->data->vert_padding, XmNmarginWidth, ih->data->horiz_padding, NULL); + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int motButtonSetBgColorAttrib(Ihandle* ih, const char* value) @@ -189,43 +191,43 @@ static int motButtonMapMethod(Ihandle* ih) if (value) { ih->data->type = IUP_BUTTON_IMAGE; - iupmotSetArg(args, num_args, XmNlabelType, XmPIXMAP); + iupMOT_SETARG(args, num_args, XmNlabelType, XmPIXMAP); } else { ih->data->type = IUP_BUTTON_TEXT; - iupmotSetArg(args, num_args, XmNlabelType, XmSTRING); + iupMOT_SETARG(args, num_args, XmNlabelType, XmSTRING); }  /* Core */ - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */ /* Label */ - iupmotSetArg(args, num_args, XmNrecomputeSize, False); /* no automatic resize from text */ - iupmotSetArg(args, num_args, XmNmarginHeight, 0); /* default padding */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); - iupmotSetArg(args, num_args, XmNmarginTop, 0); /* no extra margins */ - iupmotSetArg(args, num_args, XmNmarginLeft, 0); - iupmotSetArg(args, num_args, XmNmarginBottom, 0); - iupmotSetArg(args, num_args, XmNmarginRight, 0); + iupMOT_SETARG(args, num_args, XmNrecomputeSize, False); /* no automatic resize from text */ + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); /* default padding */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNmarginTop, 0); /* no extra margins */ + iupMOT_SETARG(args, num_args, XmNmarginLeft, 0); + iupMOT_SETARG(args, num_args, XmNmarginBottom, 0); + iupMOT_SETARG(args, num_args, XmNmarginRight, 0); /* PushButton */ - iupmotSetArg(args, num_args, XmNfillOnArm, False); + iupMOT_SETARG(args, num_args, XmNfillOnArm, False);  /* Primitive */ if (iupAttribGetBoolean(ih, "FOCUSONCLICK")) { if (iupAttribGetBoolean(ih, "CANFOCUS")) - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); else - iupmotSetArg(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False); } else - iupmotSetArg(args, num_args, XmNtraversalOn, False); - iupmotSetArg(args, num_args, XmNhighlightThickness, 2); - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 2); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP);  ih->handle = XtCreateManagedWidget( iupDialogGetChildIdStr(ih), /* child identifier */ diff --git a/iup/src/mot/iupmot_canvas.c b/iup/src/mot/iupmot_canvas.c index 7777cf3..299bbcd 100755 --- a/iup/src/mot/iupmot_canvas.c +++ b/iup/src/mot/iupmot_canvas.c @@ -434,6 +434,10 @@ static void motCanvasLayoutUpdateMethod(Ihandle *ih)  XtVaGetValues(sb_win, XmNborderWidth, &border, NULL);  + /* avoid abort in X */ + if (ih->currentwidth <= 2*border) ih->currentwidth = 2*border+1; + if (ih->currentheight <= 2*border) ih->currentheight = 2*border+1; + XtVaSetValues(sb_win, XmNx, (XtArgVal)ih->x, XmNy, (XtArgVal)ih->y, @@ -458,19 +462,19 @@ static int motCanvasMapMethod(Ihandle* ih) /* Create the scrolled window */ /******************************/  - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNscrollingPolicy, XmAPPLICATION_DEFINED); - iupmotSetArg(args, num_args, XmNvisualPolicy, XmVARIABLE); - iupmotSetArg(args, num_args, XmNspacing, 0); /* no space between scrollbars and draw area */ - iupmotSetArg(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNscrollingPolicy, XmAPPLICATION_DEFINED); + iupMOT_SETARG(args, num_args, XmNvisualPolicy, XmVARIABLE); + iupMOT_SETARG(args, num_args, XmNspacing, 0); /* no space between scrollbars and draw area */ + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0);  if (iupAttribGetBoolean(ih, "BORDER")) { - iupmotSetArg(args, num_args, XmNborderWidth, 1); - iupmotSetArg(args, num_args, XmNborderColor, iupmotColorGetPixelStr("0 0 0")); + iupMOT_SETARG(args, num_args, XmNborderWidth, 1); + iupMOT_SETARG(args, num_args, XmNborderColor, iupmotColorGetPixelStr("0 0 0")); } else - iupmotSetArg(args, num_args, XmNborderWidth, 0); + iupMOT_SETARG(args, num_args, XmNborderWidth, 0);  sb_win = XtCreateManagedWidget( iupDialogGetChildIdStr(ih), /* child identifier */ @@ -488,36 +492,36 @@ static int motCanvasMapMethod(Ihandle* ih) /****************************/  num_args = 0; - iupmotSetArg(args, num_args, XmNmarginHeight, 0); /* no shadow margins */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); /* no shadow margins */ - iupmotSetArg(args, num_args, XmNshadowThickness, 0); - iupmotSetArg(args, num_args, XmNresizePolicy, XmRESIZE_NONE); /* no automatic resize of children */ + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); /* no shadow margins */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); /* no shadow margins */ + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNresizePolicy, XmRESIZE_NONE); /* no automatic resize of children */ if (ih->iclass->is_interactive) { - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); /* include in navigation */ + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); /* include in navigation */  if (iupAttribGetBoolean(ih, "CANFOCUS")) - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); else - iupmotSetArg(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False); } else { - iupmotSetArg(args, num_args, XmNnavigationType, XmNONE); - iupmotSetArg(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmNONE); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False); }  - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */  visual = IupGetAttribute(ih, "VISUAL"); /* defined by the OpenGL Canvas or NULL */ if (visual) { Colormap colormap = (Colormap)iupAttribGet(ih, "COLORMAP"); if (colormap) - iupmotSetArg(args, num_args, XmNcolormap,colormap); + iupMOT_SETARG(args, num_args, XmNcolormap,colormap);  iupmotDialogSetVisual(ih, visual); } diff --git a/iup/src/mot/iupmot_common.c b/iup/src/mot/iupmot_common.c index 7b3f8b7..286e075 100755 --- a/iup/src/mot/iupmot_common.c +++ b/iup/src/mot/iupmot_common.c @@ -167,6 +167,10 @@ void iupdrvBaseLayoutUpdateMethod(Ihandle *ih) Widget widget = (Widget)iupAttribGet(ih, "_IUP_EXTRAPARENT"); if (!widget) widget = ih->handle;  + /* avoid abort in X */ + if (ih->currentwidth == 0) ih->currentwidth = 1; + if (ih->currentheight == 0) ih->currentheight = 1; + XtVaSetValues(widget, XmNx, (XtArgVal)ih->x, XmNy, (XtArgVal)ih->y, @@ -184,7 +188,7 @@ void iupdrvBaseUnMapMethod(Ihandle* ih) XtDestroyWidget(widget); /* To match the call to XtCreateManagedWidget */ }  -void iupdrvDisplayUpdate(Ihandle *ih) +void iupdrvPostRedraw(Ihandle *ih) { XExposeEvent evt; Dimension w, h; @@ -209,12 +213,12 @@ void iupdrvDisplayUpdate(Ihandle *ih) XSendEvent(iupmot_display, XtWindow(ih->handle), False, ExposureMask, (XEvent*)&evt); }  -void iupdrvDisplayRedraw(Ihandle *ih) +void iupdrvRedrawNow(Ihandle *ih) { Widget w;  /* POST a Redraw */ - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih);  /* if this element has an inner native parent (like IupTabs),  then redraw that native parent if different from the element. */ @@ -223,7 +227,7 @@ void iupdrvDisplayRedraw(Ihandle *ih) { Widget handle = ih->handle; ih->handle = w; - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih); ih->handle = handle; }  @@ -276,10 +280,11 @@ int iupdrvBaseSetZorderAttrib(Ihandle* ih, const char* value) { if (iupdrvIsVisible(ih)) { + Widget widget = (Widget)iupAttribGet(ih, "_IUP_EXTRAPARENT"); if (iupStrEqualNoCase(value, "TOP")) - XRaiseWindow(iupmot_display, XtWindow(ih->handle)); + XRaiseWindow(iupmot_display, XtWindow(widget)); else - XLowerWindow(iupmot_display, XtWindow(ih->handle)); + XLowerWindow(iupmot_display, XtWindow(widget)); }  return 0; @@ -455,9 +460,11 @@ static Cursor motGetCursor(Ihandle* ih, const char* name) { "RESIZE_N", XC_top_side}, { "RESIZE_S", XC_bottom_side}, { "RESIZE_NS", XC_sb_v_double_arrow}, + { "SPLITTER_HORIZ", XC_sb_v_double_arrow}, { "RESIZE_W", XC_left_side}, { "RESIZE_E", XC_right_side}, { "RESIZE_WE", XC_sb_h_double_arrow}, + { "SPLITTER_VERT", XC_sb_h_double_arrow}, { "RESIZE_NE", XC_top_right_corner}, { "RESIZE_SE", XC_bottom_right_corner}, { "RESIZE_NW", XC_top_left_corner}, diff --git a/iup/src/mot/iupmot_dialog.c b/iup/src/mot/iupmot_dialog.c index 4eeb834..7a27d74 100755 --- a/iup/src/mot/iupmot_dialog.c +++ b/iup/src/mot/iupmot_dialog.c @@ -134,12 +134,13 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu static int native_border = 0; static int native_caption = 0;  - int has_caption = iupAttribGetBoolean(ih, "MAXBOX") || - iupAttribGetBoolean(ih, "MINBOX") || - iupAttribGetBoolean(ih, "MENUBOX") ||  - IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */ + int has_titlebar = iupAttribGetBoolean(ih, "RESIZE") || /* GTK and Motif only */ + iupAttribGetBoolean(ih, "MAXBOX") || + iupAttribGetBoolean(ih, "MINBOX") || + iupAttribGetBoolean(ih, "MENUBOX") ||  + IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */  - int has_border = has_caption || + int has_border = has_titlebar || iupAttribGetBoolean(ih, "RESIZE") || iupAttribGetBoolean(ih, "BORDER");  @@ -155,7 +156,7 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu *border = win_border;  *caption = 0; - if (has_caption) + if (has_titlebar) *caption = win_caption;  if (!native_border && *border) @@ -181,7 +182,7 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu }  *caption = 0; - if (has_caption) + if (has_titlebar) { if (native_caption) *caption = native_caption; @@ -853,6 +854,7 @@ static int motDialogMapMethod(Ihandle* ih) InativeHandle* parent; int mwm_decor = 0; int num_args = 0; + int has_titlebar = 0; Arg args[20];  if (iupAttribGetBoolean(ih, "DIALOGFRAME"))  @@ -867,32 +869,46 @@ static int motDialogMapMethod(Ihandle* ih) /****************************/  if (iupAttribGet(ih, "TITLE")) - mwm_decor |= MWM_DECOR_TITLE; + has_titlebar = 1; if (iupAttribGetBoolean(ih, "MENUBOX")) - mwm_decor |= MWM_DECOR_MENU; + { + mwm_decor |= MWM_DECOR_MENU; + has_titlebar = 1; + } if (iupAttribGetBoolean(ih, "MINBOX")) - mwm_decor |= MWM_DECOR_MINIMIZE; + { + mwm_decor |= MWM_DECOR_MINIMIZE; + has_titlebar = 1; + } if (iupAttribGetBoolean(ih, "MAXBOX")) - mwm_decor |= MWM_DECOR_MAXIMIZE; + { + mwm_decor |= MWM_DECOR_MAXIMIZE; + has_titlebar = 1; + } if (iupAttribGetBoolean(ih, "RESIZE")) - mwm_decor |= MWM_DECOR_RESIZEH; - if (iupAttribGetBoolean(ih, "BORDER")) - mwm_decor |= MWM_DECOR_BORDER; - - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* so XtRealizeWidget will not show the dialog */ - iupmotSetArg(args, num_args, XmNdeleteResponse, XmDO_NOTHING); - iupmotSetArg(args, num_args, XmNallowShellResize, True); /* Used so the BulletinBoard can control the shell size */ - iupmotSetArg(args, num_args, XmNtitle, ""); - iupmotSetArg(args, num_args, XmNvisual, iupmot_visual); + { + mwm_decor |= MWM_DECOR_RESIZEH; + mwm_decor |= MWM_DECOR_BORDER; /* has_border */ + } + if (has_titlebar) + mwm_decor |= MWM_DECOR_TITLE; + if (iupAttribGetBoolean(ih, "BORDER") || has_titlebar)  + mwm_decor |= MWM_DECOR_BORDER; /* has_border */ + + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* so XtRealizeWidget will not show the dialog */ + iupMOT_SETARG(args, num_args, XmNdeleteResponse, XmDO_NOTHING); + iupMOT_SETARG(args, num_args, XmNallowShellResize, True); /* Used so the BulletinBoard can control the shell size */ + iupMOT_SETARG(args, num_args, XmNtitle, ""); + iupMOT_SETARG(args, num_args, XmNvisual, iupmot_visual);  if (iupmotColorMap())  - iupmotSetArg(args, num_args, XmNcolormap, iupmotColorMap()); + iupMOT_SETARG(args, num_args, XmNcolormap, iupmotColorMap());  if (mwm_decor != 0x7E)  - iupmotSetArg(args, num_args, XmNmwmDecorations, mwm_decor); + iupMOT_SETARG(args, num_args, XmNmwmDecorations, mwm_decor);  if (iupAttribGetBoolean(ih, "SAVEUNDER")) - iupmotSetArg(args, num_args, XmNsaveUnder, True); + iupMOT_SETARG(args, num_args, XmNsaveUnder, True);  parent = iupDialogGetNativeParent(ih); if (parent) diff --git a/iup/src/mot/iupmot_drv.h b/iup/src/mot/iupmot_drv.h index 8a536ef..424ae9f 100755 --- a/iup/src/mot/iupmot_drv.h +++ b/iup/src/mot/iupmot_drv.h @@ -65,7 +65,7 @@ void iupmotGetWindowSize(Ihandle *ih, int *width, int *height);  char* iupmotGetXWindowAttrib(Ihandle *ih);  -#define iupmotSetArg(_a, _i, _n, _d) ((_a)[(_i)].name = (_n), (_a)[(_i)].value = (XtArgVal)(_d), (_i)++) +#define iupMOT_SETARG(_a, _i, _n, _d) ((_a)[(_i)].name = (_n), (_a)[(_i)].value = (XtArgVal)(_d), (_i)++)   #ifdef __cplusplus diff --git a/iup/src/mot/iupmot_filedlg.c b/iup/src/mot/iupmot_filedlg.c index 768dd2b..0be6319 100755 --- a/iup/src/mot/iupmot_filedlg.c +++ b/iup/src/mot/iupmot_filedlg.c @@ -17,6 +17,7 @@ #include  #include  #include  +#include   #include "iup.h" #include "iupcbs.h" @@ -28,6 +29,7 @@ #include "iup_dialog.h" #include "iup_strmessage.h" #include "iup_drvinfo.h" +#include "iup_array.h"  #include "iupmot_drv.h"  @@ -87,14 +89,14 @@ static int motFileDlgCheckValue(Ihandle* ih, Widget w) return 0; } } - else + else if (!iupAttribGetBoolean(ih, "MULTIPLEFILES")) { if (iupdrvIsDirectory(value)) /* selected a directory */ { iupStrMessageShowError(ih, "IUP_INVALIDDIR"); return 0; } - else if (!iupdrvIsFile(value)) /* new file */ + else if (!iupdrvIsFile(value)) /* not a file == new file */ { value = iupAttribGet(ih, "ALLOWNEW"); if (!value) @@ -132,6 +134,51 @@ static void motFileDlgCBclose(Widget w, XtPointer client_data, XtPointer call_da iupAttribSetStr(ih, "_IUP_WM_DELETE", "1"); }  +static int motFileDlgGetMultipleFiles(Ihandle* ih, const char* dir, Widget wList) +{ + int *pos, sel_count, dir_len; + int i, len, cur_len; + char *filename, *all_names; + Iarray* names_array; + XmString* items; + + if (!XmListGetSelectedPos(wList, &pos, &sel_count)) + return 0; + + names_array = iupArrayCreate(1024, 1); /* just set an initial size, but count is 0 */ + XtVaGetValues(wList, XmNitems, &items, NULL); + + cur_len = strlen(dir); + + all_names = iupArrayAdd(names_array, cur_len+1); + memcpy(all_names, dir, cur_len); + all_names[cur_len] = '|'; + dir_len = cur_len; + cur_len++; /* skip separator */ + + for (i = 0; iitem, XmSTRING_DEFAULT_CHARSET, &filename);  + cb = (IFnss)IupGetCallback(ih, "FILE_CB"); if (iupdrvIsFile(filename)) - { - IFnss cb = (IFnss)IupGetCallback(ih, "FILE_CB"); cb(ih, filename, "SELECT"); - } + else + cb(ih, filename, "OTHER");  XtFree(filename); (void)w; @@ -417,6 +488,13 @@ static int motFileDlgPopup(Ihandle* ih, int x, int y) if (dialogtype == IUP_DIALOGDIR) XtVaSetValues(filebox, XmNfileTypeMask, XmFILE_DIRECTORY, NULL);  + if (iupAttribGetBoolean(ih, "MULTIPLEFILES")) + { + Widget wList = XmFileSelectionBoxGetChild(filebox, XmDIALOG_LIST); + XtVaSetValues(wList, XmNselectionPolicy, XmEXTENDED_SELECT, NULL); + XtAddCallback(wList, XmNextendedSelectionCallback, (XtCallbackProc)motFileDlgBrowseSelectionCallback, (XtPointer)ih); + } + /* just check for the path inside FILE */ value = iupAttribGet(ih, "FILE"); if (value && value[0] == '/') @@ -501,8 +579,10 @@ static int motFileDlgPopup(Ihandle* ih, int x, int y) file_cb = (IFnss)IupGetCallback(ih, "FILE_CB"); if (file_cb) { - Widget file_list = XmFileSelectionBoxGetChild(filebox, XmDIALOG_LIST); - XtAddCallback(file_list, XmNbrowseSelectionCallback, (XtCallbackProc)motFileDlgBrowseSelectionCallback, (XtPointer)ih); + Widget list = XmFileSelectionBoxGetChild(filebox, XmDIALOG_LIST); + XtAddCallback(list, XmNbrowseSelectionCallback, (XtCallbackProc)motFileDlgBrowseSelectionCallback, (XtPointer)ih); + list = XmFileSelectionBoxGetChild(filebox, XmDIALOG_DIR_LIST); + XtAddCallback(list, XmNbrowseSelectionCallback, (XtCallbackProc)motFileDlgBrowseSelectionCallback, (XtPointer)ih);  if (iupAttribGetBoolean(ih, "SHOWPREVIEW")) { @@ -575,4 +655,6 @@ static int motFileDlgPopup(Ihandle* ih, int x, int y) void iupdrvFileDlgInitClass(Iclass* ic) { ic->DlgPopup = motFileDlgPopup; + + iupClassRegisterAttribute(ic, "MULTIPLEFILES", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT); } diff --git a/iup/src/mot/iupmot_font.c b/iup/src/mot/iupmot_font.c index 8da06dd..42154b6 100755 --- a/iup/src/mot/iupmot_font.c +++ b/iup/src/mot/iupmot_font.c @@ -135,19 +135,19 @@ static XmFontList motFontCreateRenderTable(XFontStruct* fontstruct, int is_under Arg args[10]; int num_args = 0;  - iupmotSetArg(args, num_args, XmNfontType, XmFONT_IS_FONT); - iupmotSetArg(args, num_args, XmNfont, (XtPointer)fontstruct); - iupmotSetArg(args, num_args, XmNloadModel, XmLOAD_IMMEDIATE); + iupMOT_SETARG(args, num_args, XmNfontType, XmFONT_IS_FONT); + iupMOT_SETARG(args, num_args, XmNfont, (XtPointer)fontstruct); + iupMOT_SETARG(args, num_args, XmNloadModel, XmLOAD_IMMEDIATE);  if (is_underline) - iupmotSetArg(args, num_args, XmNunderlineType, XmSINGLE_LINE); + iupMOT_SETARG(args, num_args, XmNunderlineType, XmSINGLE_LINE); else - iupmotSetArg(args, num_args, XmNunderlineType, XmNO_LINE); + iupMOT_SETARG(args, num_args, XmNunderlineType, XmNO_LINE);  if (is_strikeout) - iupmotSetArg(args, num_args, XmNstrikethruType, XmSINGLE_LINE); + iupMOT_SETARG(args, num_args, XmNstrikethruType, XmSINGLE_LINE); else - iupmotSetArg(args, num_args, XmNstrikethruType, XmNO_LINE); + iupMOT_SETARG(args, num_args, XmNstrikethruType, XmNO_LINE);  rendition = XmRenditionCreate(NULL, "", args, num_args);  diff --git a/iup/src/mot/iupmot_frame.c b/iup/src/mot/iupmot_frame.c index 39de5d8..cfda44f 100755 --- a/iup/src/mot/iupmot_frame.c +++ b/iup/src/mot/iupmot_frame.c @@ -42,22 +42,33 @@ static int motFrameSetBgColorAttrib(Ihandle* ih, const char* value) { Pixel color;  - /* ignore given value, must use only from parent */ - value = iupBaseNativeParentGetBgColor(ih); + if (!iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR")) + { + /* ignore given value, must use only from parent */ + value = iupBaseNativeParentGetBgColor(ih); + }  color = iupmotColorGetPixelStr(value); if (color != (Pixel)-1) { Widget title_label, child_manager;  - iupmotSetBgColor(ih->handle, color); + if (!iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR")) + { + iupmotSetBgColor(ih->handle, color);  - child_manager = XtNameToWidget(ih->handle, "*child_manager"); - iupmotSetBgColor(child_manager, color); + child_manager = XtNameToWidget(ih->handle, "*child_manager"); + iupmotSetBgColor(child_manager, color);  - title_label = XtNameToWidget(ih->handle, "*title_label"); - if (!title_label) return 1; - iupmotSetBgColor(title_label, color); + title_label = XtNameToWidget(ih->handle, "*title_label"); + if (!title_label) return 1; + iupmotSetBgColor(title_label, color); + } + else + { + child_manager = XtNameToWidget(ih->handle, "*child_manager"); + iupmotSetBgColor(child_manager, color); + }  return 1; } @@ -171,22 +182,25 @@ static int motFrameMapMethod(Ihandle* ih) { char* value = iupAttribGetStr(ih, "SUNKEN"); if (iupStrBoolean(value)) - iupmotSetArg(args, num_args, XmNshadowType, XmSHADOW_IN);  + iupMOT_SETARG(args, num_args, XmNshadowType, XmSHADOW_IN);  else - iupmotSetArg(args, num_args, XmNshadowType, XmSHADOW_ETCHED_IN);  + iupMOT_SETARG(args, num_args, XmNshadowType, XmSHADOW_ETCHED_IN);  + + if (iupAttribGet(ih, "BGCOLOR")) + iupAttribSetStr(ih, "_IUPFRAME_HAS_BGCOLOR", "1"); }  /* Core */ - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */ /* Manager */ - iupmotSetArg(args, num_args, XmNshadowThickness, 2); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 2); /* Frame */ - iupmotSetArg(args, num_args, XmNmarginHeight, 0); /* no shadow margins */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); /* no shadow margins */ + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); /* no shadow margins */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); /* no shadow margins */  ih->handle = XtCreateManagedWidget( iupDialogGetChildIdStr(ih), /* child identifier */ @@ -204,11 +218,11 @@ static int motFrameMapMethod(Ihandle* ih) Widget title_label; num_args = 0; /* Label */ - iupmotSetArg(args, num_args, XmNlabelType, XmSTRING);  - iupmotSetArg(args, num_args, XmNmarginHeight, 0); /* default padding */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNlabelType, XmSTRING);  + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); /* default padding */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); /* Frame Constraint */ - iupmotSetArg(args, num_args, XmNchildType, XmFRAME_TITLE_CHILD); + iupMOT_SETARG(args, num_args, XmNchildType, XmFRAME_TITLE_CHILD); title_label = XtCreateManagedWidget("title_label", xmLabelWidgetClass, ih->handle, args, num_args); iupmotSetString(title_label, XmNlabelString, title); } diff --git a/iup/src/mot/iupmot_key.c b/iup/src/mot/iupmot_key.c index 835b5d7..9897741 100755 --- a/iup/src/mot/iupmot_key.c +++ b/iup/src/mot/iupmot_key.c @@ -393,33 +393,33 @@ void iupmotKeyPressEvent(Widget w, Ihandle *ih, XEvent *evt, Boolean *cont) void iupmotButtonKeySetStatus(unsigned int state, unsigned int but, char* status, int doubleclick) { if (state & ShiftMask) - iupKEYSETSHIFT(status); + iupKEY_SETSHIFT(status);  if (state & ControlMask) - iupKEYSETCONTROL(status);  + iupKEY_SETCONTROL(status);   if ((state & Button1Mask) || but==Button1) - iupKEYSETBUTTON1(status); + iupKEY_SETBUTTON1(status);  if ((state & Button2Mask) || but==Button2) - iupKEYSETBUTTON2(status); + iupKEY_SETBUTTON2(status);  if ((state & Button3Mask) || but==Button3) - iupKEYSETBUTTON3(status); + iupKEY_SETBUTTON3(status);  if ((state & Button4Mask) || but==Button4) - iupKEYSETBUTTON4(status); + iupKEY_SETBUTTON4(status);  if ((state & Button5Mask) || but==Button5) - iupKEYSETBUTTON5(status); + iupKEY_SETBUTTON5(status);  if (state & Mod1Mask || state & Mod5Mask) /* Alt */ - iupKEYSETALT(status); + iupKEY_SETALT(status);  if (state & Mod4Mask) /* Apple/Win */ - iupKEYSETSYS(status); + iupKEY_SETSYS(status);  if (doubleclick) - iupKEYSETDOUBLE(status); + iupKEY_SETDOUBLE(status); }  diff --git a/iup/src/mot/iupmot_label.c b/iup/src/mot/iupmot_label.c index 52dfc9a..afff3c3 100755 --- a/iup/src/mot/iupmot_label.c +++ b/iup/src/mot/iupmot_label.c @@ -147,8 +147,10 @@ static int motLabelSetPaddingAttrib(Ihandle* ih, const char* value) { XtVaSetValues(ih->handle, XmNmarginHeight, ih->data->vert_padding, XmNmarginWidth, ih->data->horiz_padding, NULL); + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int motLabelMapMethod(Ihandle* ih) @@ -165,12 +167,12 @@ static int motLabelMapMethod(Ihandle* ih) if (iupStrEqualNoCase(value, "HORIZONTAL")) { ih->data->type = IUP_LABEL_SEP_HORIZ; - iupmotSetArg(args, num_args, XmNorientation, XmHORIZONTAL); + iupMOT_SETARG(args, num_args, XmNorientation, XmHORIZONTAL); } else /* "VERTICAL" */ { ih->data->type = IUP_LABEL_SEP_VERT; - iupmotSetArg(args, num_args, XmNorientation, XmVERTICAL); + iupMOT_SETARG(args, num_args, XmNorientation, XmVERTICAL); } } else @@ -180,32 +182,32 @@ static int motLabelMapMethod(Ihandle* ih) if (value) { ih->data->type = IUP_LABEL_IMAGE; - iupmotSetArg(args, num_args, XmNlabelType, XmPIXMAP);  + iupMOT_SETARG(args, num_args, XmNlabelType, XmPIXMAP);  } else { ih->data->type = IUP_LABEL_TEXT; - iupmotSetArg(args, num_args, XmNlabelType, XmSTRING);  + iupMOT_SETARG(args, num_args, XmNlabelType, XmSTRING);  } }  /* Core */ - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */ /* Primitive */ - iupmotSetArg(args, num_args, XmNtraversalOn, False); - iupmotSetArg(args, num_args, XmNhighlightThickness, 0); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 0); /* Label */ - iupmotSetArg(args, num_args, XmNrecomputeSize, False); /* no automatic resize from text */ - iupmotSetArg(args, num_args, XmNmarginHeight, 0); /* default padding */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); - iupmotSetArg(args, num_args, XmNmarginTop, 0); /* no extra margins */ - iupmotSetArg(args, num_args, XmNmarginLeft, 0); - iupmotSetArg(args, num_args, XmNmarginBottom, 0); - iupmotSetArg(args, num_args, XmNmarginRight, 0); + iupMOT_SETARG(args, num_args, XmNrecomputeSize, False); /* no automatic resize from text */ + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); /* default padding */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNmarginTop, 0); /* no extra margins */ + iupMOT_SETARG(args, num_args, XmNmarginLeft, 0); + iupMOT_SETARG(args, num_args, XmNmarginBottom, 0); + iupMOT_SETARG(args, num_args, XmNmarginRight, 0);  ih->handle = XtCreateManagedWidget( iupDialogGetChildIdStr(ih), /* child identifier */ diff --git a/iup/src/mot/iupmot_list.c b/iup/src/mot/iupmot_list.c index f8e73ed..800e6e9 100755 --- a/iup/src/mot/iupmot_list.c +++ b/iup/src/mot/iupmot_list.c @@ -143,15 +143,36 @@ void iupdrvListInsertItem(Ihandle* ih, int pos, const char* value) motListAddSortedItem(ih, value); else motListAddItem(ih, pos, value); + + iupListUpdateOldValue(ih, pos, 0); }  void iupdrvListRemoveItem(Ihandle* ih, int pos) { /* The utility functions use 0=last 1=first */ if (ih->data->is_dropdown || ih->data->has_editbox) + { + if (ih->data->is_dropdown && !ih->data->has_editbox) + { + /* must check if removing the current item */ + int curpos; + XtVaGetValues(ih->handle, XmNselectedPosition, &curpos, NULL); + if (pos == curpos && iupdrvListGetCount(ih)>1) + { + if (curpos > 0) curpos--; + else curpos++; + + XtRemoveCallback(ih->handle, XmNselectionCallback, (XtCallbackProc)motListComboBoxSelectionCallback, (XtPointer)ih); + XtVaSetValues(ih->handle, XmNselectedPosition, curpos, NULL);  + XtAddCallback(ih->handle, XmNselectionCallback, (XtCallbackProc)motListComboBoxSelectionCallback, (XtPointer)ih); + } + } XmComboBoxDeletePos(ih->handle, pos+1); + } else XmListDeletePos(ih->handle, pos+1); + + iupListUpdateOldValue(ih, pos, 1); }  void iupdrvListRemoveAllItems(Ihandle* ih) @@ -174,7 +195,7 @@ void iupdrvListRemoveAllItems(Ihandle* ih) static char* motListGetIdValueAttrib(Ihandle* ih, const char* name_id) { int pos = iupListGetPos(ih, name_id); - if (pos != -1) + if (pos >= 0) { XmString* items; XtVaGetValues(ih->handle, XmNitems, &items, NULL); @@ -852,8 +873,10 @@ static int motListSetNCAttrib(Ihandle* ih, const char* value) Widget cbedit; XtVaGetValues(ih->handle, XmNtextField, &cbedit, NULL); XtVaSetValues(cbedit, XmNmaxLength, ih->data->nc, NULL); + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int motListSetClipboardAttrib(Ihandle *ih, const char *value) @@ -1181,32 +1204,32 @@ static int motListMapMethod(Ihandle* ih) if (ih->data->is_dropdown || ih->data->has_editbox) { /* could not set XmNmappedWhenManaged to False because the list and the edit box where not displayed */ - /* iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); */ - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ - iupmotSetArg(args, num_args, XmNmarginHeight, 0); - iupmotSetArg(args, num_args, XmNmarginWidth, 0); + /* iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0);  if (iupAttribGetBoolean(ih, "CANFOCUS")) - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); else - iupmotSetArg(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False);  - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); - iupmotSetArg(args, num_args, XmNhighlightThickness, 2); - iupmotSetArg(args, num_args, XmNshadowThickness, 2); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 2); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 2);  if (ih->data->has_editbox) { if (ih->data->is_dropdown) - iupmotSetArg(args, num_args, XmNcomboBoxType, XmDROP_DOWN_COMBO_BOX); /* hidden-list+edit */ + iupMOT_SETARG(args, num_args, XmNcomboBoxType, XmDROP_DOWN_COMBO_BOX); /* hidden-list+edit */ else - iupmotSetArg(args, num_args, XmNcomboBoxType, XmCOMBO_BOX); /* visible-list+edit */ + iupMOT_SETARG(args, num_args, XmNcomboBoxType, XmCOMBO_BOX); /* visible-list+edit */ } else - iupmotSetArg(args, num_args, XmNcomboBoxType, XmDROP_DOWN_LIST); /* hidden-list */ + iupMOT_SETARG(args, num_args, XmNcomboBoxType, XmDROP_DOWN_LIST); /* hidden-list */  ih->handle = XtCreateManagedWidget( child_id, /* child identifier */ @@ -1220,13 +1243,13 @@ static int motListMapMethod(Ihandle* ih)  /* Create the scrolled window */  - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNscrollingPolicy, XmAPPLICATION_DEFINED); - iupmotSetArg(args, num_args, XmNvisualPolicy, XmVARIABLE); - iupmotSetArg(args, num_args, XmNscrollBarDisplayPolicy, XmSTATIC); /* can NOT be XmAS_NEEDED because XmAPPLICATION_DEFINED */ - iupmotSetArg(args, num_args, XmNspacing, 0); /* no space between scrollbars and text */ - iupmotSetArg(args, num_args, XmNborderWidth, 0); - iupmotSetArg(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNscrollingPolicy, XmAPPLICATION_DEFINED); + iupMOT_SETARG(args, num_args, XmNvisualPolicy, XmVARIABLE); + iupMOT_SETARG(args, num_args, XmNscrollBarDisplayPolicy, XmSTATIC); /* can NOT be XmAS_NEEDED because XmAPPLICATION_DEFINED */ + iupMOT_SETARG(args, num_args, XmNspacing, 0); /* no space between scrollbars and text */ + iupMOT_SETARG(args, num_args, XmNborderWidth, 0); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0);  sb_win = XtCreateManagedWidget( child_id, /* child identifier */ @@ -1243,34 +1266,34 @@ static int motListMapMethod(Ihandle* ih) /* Create the list */  num_args = 0; - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */  if (iupAttribGetBoolean(ih, "CANFOCUS")) - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); else - iupmotSetArg(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False);  - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); - iupmotSetArg(args, num_args, XmNhighlightThickness, 2); - iupmotSetArg(args, num_args, XmNshadowThickness, 2); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 2); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 2);  - iupmotSetArg(args, num_args, XmNlistMarginHeight, 0); /* default padding */ - iupmotSetArg(args, num_args, XmNlistMarginWidth, 0); - iupmotSetArg(args, num_args, XmNlistSpacing, 0); - iupmotSetArg(args, num_args, XmNlistSizePolicy, XmCONSTANT); /* don't grow to fit, add scrollbar */ + iupMOT_SETARG(args, num_args, XmNlistMarginHeight, 0); /* default padding */ + iupMOT_SETARG(args, num_args, XmNlistMarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNlistSpacing, 0); + iupMOT_SETARG(args, num_args, XmNlistSizePolicy, XmCONSTANT); /* don't grow to fit, add scrollbar */  if (ih->data->is_multiple) - iupmotSetArg(args, num_args, XmNselectionPolicy, XmEXTENDED_SELECT); + iupMOT_SETARG(args, num_args, XmNselectionPolicy, XmEXTENDED_SELECT); else - iupmotSetArg(args, num_args, XmNselectionPolicy, XmBROWSE_SELECT); + iupMOT_SETARG(args, num_args, XmNselectionPolicy, XmBROWSE_SELECT);  if (iupAttribGetBoolean(ih, "AUTOHIDE")) - iupmotSetArg(args, num_args, XmNscrollBarDisplayPolicy, XmAS_NEEDED); + iupMOT_SETARG(args, num_args, XmNscrollBarDisplayPolicy, XmAS_NEEDED); else - iupmotSetArg(args, num_args, XmNscrollBarDisplayPolicy, XmSTATIC); + iupMOT_SETARG(args, num_args, XmNscrollBarDisplayPolicy, XmSTATIC);  ih->handle = XtCreateManagedWidget( child_id, /* child identifier */ diff --git a/iup/src/mot/iupmot_loop.c b/iup/src/mot/iupmot_loop.c index 828ddcd..c1f92ec 100755 --- a/iup/src/mot/iupmot_loop.c +++ b/iup/src/mot/iupmot_loop.c @@ -56,7 +56,7 @@ void iupdrvSetIdleFunction(Icallback f) mot_idle_id = XtAppAddWorkProc(iupmot_appcontext, motIdlecbWorkProc, NULL); }  -static int motLoopStep(void) +static int motLoopProcessEvent(void) { XtAppProcessEvent(iupmot_appcontext, XtIMAll); return (mot_exitmainloop)? IUP_CLOSE : IUP_DEFAULT; @@ -79,7 +79,7 @@ int IupMainLoop(void)  while (!mot_exitmainloop) { - if (motLoopStep() == IUP_CLOSE) + if (motLoopProcessEvent() == IUP_CLOSE) break; }  @@ -88,19 +88,26 @@ int IupMainLoop(void) return IUP_NOERROR; }  +int IupLoopStepWait(void) +{ + while(!XtAppPending(iupmot_appcontext)); + + return motLoopProcessEvent(); +} + int IupLoopStep(void) { if (!XtAppPending(iupmot_appcontext))  return IUP_DEFAULT;  - return motLoopStep(); + return motLoopProcessEvent(); }  void IupFlush(void) { while (XPending(iupmot_display) != 0) { - if (motLoopStep() == IUP_CLOSE) + if (motLoopProcessEvent() == IUP_CLOSE) break; }  diff --git a/iup/src/mot/iupmot_menu.c b/iup/src/mot/iupmot_menu.c index be9b953..8f51334 100755 --- a/iup/src/mot/iupmot_menu.c +++ b/iup/src/mot/iupmot_menu.c @@ -125,7 +125,10 @@ static void motPopupMenuUnmapCallback(Widget w, Ihandle* ih, XtPointer call_data static void motMenuUnMapMethod(Ihandle* ih) { if (iupMenuIsMenuBar(ih)) + { XtDestroyWidget(ih->handle); + ih->parent = NULL; + } else XtDestroyWidget(XtParent(ih->handle)); /* in this case the RowColumn widget is a child of a MenuShell. */ } @@ -146,7 +149,6 @@ static int motMenuMapMethod(Ihandle* ih) XmNrowColumnType, XmMENU_BAR, XmNmarginHeight, 0, XmNmarginWidth, 0, - XmNresizeWidth, False, NULL); if (!ih->handle) return IUP_ERROR; @@ -161,8 +163,8 @@ static int motMenuMapMethod(Ihandle* ih)  if (iupAttribGetBoolean(ih, "RADIO")) { - iupmotSetArg(args, num_args, XmNpacking, XmPACK_COLUMN); - iupmotSetArg(args, num_args, XmNradioBehavior, TRUE); + iupMOT_SETARG(args, num_args, XmNpacking, XmPACK_COLUMN); + iupMOT_SETARG(args, num_args, XmNradioBehavior, TRUE); }  ih->handle = XmCreatePulldownMenu( @@ -183,7 +185,7 @@ static int motMenuMapMethod(Ihandle* ih) { /* top level menu used for IupPopup */  - iupmotSetArg(args, num_args, XmNpopupEnabled, XmPOPUP_AUTOMATIC); + iupMOT_SETARG(args, num_args, XmNpopupEnabled, XmPOPUP_AUTOMATIC);  ih->handle = XmCreatePopupMenu( iupmot_appshell,  @@ -307,19 +309,19 @@ static int motItemMapMethod(Ihandle* ih)  if (iupAttribGetBoolean(ih->parent, "RADIO")) { - iupmotSetArg(args, num_args, XmNtoggleMode, XmTOGGLE_BOOLEAN); - iupmotSetArg(args, num_args, XmNindicatorType, XmONE_OF_MANY_ROUND); - iupmotSetArg(args, num_args, XmNindicatorOn, XmINDICATOR_CHECK_BOX); - iupmotSetArg(args, num_args, XmNindicatorSize, 13); - iupmotSetArg(args, num_args, XmNselectColor, iupmotColorGetPixel(0, 0, 0)); + iupMOT_SETARG(args, num_args, XmNtoggleMode, XmTOGGLE_BOOLEAN); + iupMOT_SETARG(args, num_args, XmNindicatorType, XmONE_OF_MANY_ROUND); + iupMOT_SETARG(args, num_args, XmNindicatorOn, XmINDICATOR_CHECK_BOX); + iupMOT_SETARG(args, num_args, XmNindicatorSize, 13); + iupMOT_SETARG(args, num_args, XmNselectColor, iupmotColorGetPixel(0, 0, 0)); } else { if (iupAttribGetBoolean(ih, "HIDEMARK")) - iupmotSetArg(args, num_args, XmNindicatorOn, XmINDICATOR_NONE); + iupMOT_SETARG(args, num_args, XmNindicatorOn, XmINDICATOR_NONE); else - iupmotSetArg(args, num_args, XmNindicatorOn, XmINDICATOR_CHECK); - iupmotSetArg(args, num_args, XmNlabelType, iupAttribGet(ih, "TITLEIMAGE")? XmPIXMAP: XmSTRING); + iupMOT_SETARG(args, num_args, XmNindicatorOn, XmINDICATOR_CHECK); + iupMOT_SETARG(args, num_args, XmNlabelType, iupAttribGet(ih, "TITLEIMAGE")? XmPIXMAP: XmSTRING); }  ih->handle = XtCreateManagedWidget( diff --git a/iup/src/mot/iupmot_progressbar.c b/iup/src/mot/iupmot_progressbar.c index 7266d38..82fa178 100755 --- a/iup/src/mot/iupmot_progressbar.c +++ b/iup/src/mot/iupmot_progressbar.c @@ -98,25 +98,25 @@ static int motProgressBarMapMethod(Ihandle* ih) Arg args[30];  /* Core */ - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */ /* Primitive */ - iupmotSetArg(args, num_args, XmNtraversalOn, False); - iupmotSetArg(args, num_args, XmNhighlightThickness, 0); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 0); /* Scale */ - iupmotSetArg(args, num_args, XmNminimum, 0); - iupmotSetArg(args, num_args, XmNmaximum, SHRT_MAX); - iupmotSetArg(args, num_args, XmNslidingMode, XmTHERMOMETER); /* thermometer effect */ - iupmotSetArg(args, num_args, XmNsliderMark, XmNONE); - iupmotSetArg(args, num_args, XmNeditable, False); - iupmotSetArg(args, num_args, XmNshowValue, XmNONE); + iupMOT_SETARG(args, num_args, XmNminimum, 0); + iupMOT_SETARG(args, num_args, XmNmaximum, SHRT_MAX); + iupMOT_SETARG(args, num_args, XmNslidingMode, XmTHERMOMETER); /* thermometer effect */ + iupMOT_SETARG(args, num_args, XmNsliderMark, XmNONE); + iupMOT_SETARG(args, num_args, XmNeditable, False); + iupMOT_SETARG(args, num_args, XmNshowValue, XmNONE);  if (iupStrEqualNoCase(iupAttribGetStr(ih, "ORIENTATION"), "VERTICAL")) { - iupmotSetArg(args, num_args, XmNorientation, XmVERTICAL); + iupMOT_SETARG(args, num_args, XmNorientation, XmVERTICAL);  if (ih->currentheight < ih->currentwidth) { @@ -126,7 +126,7 @@ static int motProgressBarMapMethod(Ihandle* ih) } } else - iupmotSetArg(args, num_args, XmNorientation, XmHORIZONTAL); + iupMOT_SETARG(args, num_args, XmNorientation, XmHORIZONTAL);  ih->handle = XtCreateManagedWidget( iupDialogGetChildIdStr(ih), /* child identifier */ diff --git a/iup/src/mot/iupmot_tabs.c b/iup/src/mot/iupmot_tabs.c index 7c8a6b5..cafc41d 100755 --- a/iup/src/mot/iupmot_tabs.c +++ b/iup/src/mot/iupmot_tabs.c @@ -52,8 +52,10 @@ void iupdrvTabsSetCurrentTab(Ihandle* ih, int pos) { Ihandle* child = IupGetChild(ih, pos); Ihandle* prev_child = IupGetChild(ih, iupdrvTabsGetCurrentTab(ih)); - IupSetAttribute(child, "VISIBLE", "YES"); - IupSetAttribute(prev_child, "VISIBLE", "NO"); + Widget child_manager = (Widget)iupAttribGet(child, "_IUPTAB_CONTAINER"); + Widget prev_child_manager = (Widget)iupAttribGet(prev_child, "_IUPTAB_CONTAINER"); + XtMapWidget(child_manager); + if (prev_child_manager) XtUnmapWidget(prev_child_manager);  XtVaSetValues(ih->handle, XmNcurrentPageNumber, pos, NULL); } @@ -200,7 +202,7 @@ static int motTabsSetTabTypeAttrib(Ihandle* ih, const char* value) ih->data->type = ITABS_TOP;  if (ih->handle) - motTabsUpdateTabType(ih); + motTabsUpdateTabType(ih); /* for this to work must be updated in map */  return 0; } @@ -313,8 +315,10 @@ void motTabsPageChangedCallback(Widget w, Ihandle* ih, XmNotebookCallbackStruct IFnnn cb; Ihandle* child = IupGetChild(ih, nptr->page_number); Ihandle* prev_child = IupGetChild(ih, nptr->prev_page_number); - IupSetAttribute(child, "VISIBLE", "YES"); - IupSetAttribute(prev_child, "VISIBLE", "NO"); + Widget child_manager = (Widget)iupAttribGet(child, "_IUPTAB_CONTAINER"); + Widget prev_child_manager = (Widget)iupAttribGet(prev_child, "_IUPTAB_CONTAINER"); + XtMapWidget(child_manager); + if (prev_child_manager) XtUnmapWidget(prev_child_manager);  cb = (IFnnn)IupGetCallback(ih, "TABCHANGE_CB"); if (cb) @@ -397,12 +401,12 @@ static void motTabsChildAddedMethod(Ihandle* ih, Ihandle* child)  /* Create tabs */ /* Label */ - iupmotSetArg(args, num_args, XmNlabelType, tabtitle? XmSTRING: XmPIXMAP); - iupmotSetArg(args, num_args, XmNmarginHeight, 0); - iupmotSetArg(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNlabelType, tabtitle? XmSTRING: XmPIXMAP); + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); /* Notebook Constraint */ - iupmotSetArg(args, num_args, XmNnotebookChildType, XmMAJOR_TAB); - iupmotSetArg(args, num_args, XmNpageNumber, pos); + iupMOT_SETARG(args, num_args, XmNnotebookChildType, XmMAJOR_TAB); + iupMOT_SETARG(args, num_args, XmNpageNumber, pos); tab_button = XtCreateManagedWidget("tab_button", xmPushButtonWidgetClass, ih->handle, args, num_args);  /* Disable Drag Source */ @@ -450,10 +454,8 @@ static void motTabsChildAddedMethod(Ihandle* ih, Ihandle* child) iupAttribSetStr(child, "_IUPMOT_TABBUTTON", (char*)tab_button); iupAttribSetInt(child, "_IUPMOT_TABNUMBER", pos);  - if (pos == iupdrvTabsGetCurrentTab(ih)) - IupSetAttribute(child, "VISIBLE", "YES"); - else - IupSetAttribute(child, "VISIBLE", "NO"); + if (pos != iupdrvTabsGetCurrentTab(ih)) + XtUnmapWidget(child_manager); } }  @@ -464,20 +466,11 @@ static void motTabsChildRemovedMethod(Ihandle* ih, Ihandle* child) Widget child_manager = (Widget)iupAttribGet(child, "_IUPTAB_CONTAINER"); if (child_manager) { - int cur_pos, pos; + int pos; Widget tab_button = (Widget)iupAttribGet(child, "_IUPMOT_TABBUTTON");  - cur_pos = iupdrvTabsGetCurrentTab(ih); pos = iupAttribGetInt(child, "_IUPMOT_TABNUMBER"); /* did not work when using XtVaGetValues(child_manager, XmNpageNumber) */ - if (cur_pos == pos) - { - if (cur_pos == 0) - cur_pos = 1; - else - cur_pos--; - - iupdrvTabsSetCurrentTab(ih, cur_pos); - } + iupTabsTestRemoveTab(ih, pos);  XtDestroyWidget(tab_button); XtDestroyWidget(child_manager); @@ -501,22 +494,22 @@ static int motTabsMapMethod(Ihandle* ih) return IUP_ERROR;  /* Core */ - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */ /* Manager */ - iupmotSetArg(args, num_args, XmNshadowThickness, 0); - iupmotSetArg(args, num_args, XmNtraversalOn, True); - iupmotSetArg(args, num_args, XmNhighlightThickness, 0); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 0); /* Notebook */ - iupmotSetArg(args, num_args, XmNbindingType, XmNONE); - iupmotSetArg(args, num_args, XmNbindingWidth, 0); - iupmotSetArg(args, num_args, XmNfirstPageNumber, 0); /* IupTabs index always starts with zero */ - iupmotSetArg(args, num_args, XmNbackPageSize, 0); - iupmotSetArg(args, num_args, XmNbackPageNumber, 1); - iupmotSetArg(args, num_args, XmNframeShadowThickness, 2); + iupMOT_SETARG(args, num_args, XmNbindingType, XmNONE); + iupMOT_SETARG(args, num_args, XmNbindingWidth, 0); + iupMOT_SETARG(args, num_args, XmNfirstPageNumber, 0); /* IupTabs index always starts with zero */ + iupMOT_SETARG(args, num_args, XmNbackPageSize, 0); + iupMOT_SETARG(args, num_args, XmNbackPageNumber, 1); + iupMOT_SETARG(args, num_args, XmNframeShadowThickness, 2);  ih->handle = XtCreateManagedWidget( iupDialogGetChildIdStr(ih), /* child identifier */ @@ -589,5 +582,5 @@ void iupdrvTabsInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "TABORIENTATION", iupTabsGetTabOrientationAttrib, NULL, IUPAF_SAMEASSYSTEM, "HORIZONTAL", IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); /* can not be set, always HORIZONTAL in Motif */ iupClassRegisterAttributeId(ic, "TABTITLE", NULL, motTabsSetTabTitleAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TABIMAGE", NULL, motTabsSetTabImageAttrib, IUPAF_NO_INHERIT); - iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, motTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, motTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); } diff --git a/iup/src/mot/iupmot_text.c b/iup/src/mot/iupmot_text.c index 4a8f936..d9d2c74 100755 --- a/iup/src/mot/iupmot_text.c +++ b/iup/src/mot/iupmot_text.c @@ -142,8 +142,10 @@ static int motTextSetPaddingAttrib(Ihandle* ih, const char* value) { XtVaSetValues(ih->handle, XmNmarginHeight, ih->data->vert_padding, XmNmarginWidth, ih->data->horiz_padding, NULL); + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int motTextSetReadOnlyAttrib(Ihandle* ih, const char* value) @@ -164,7 +166,7 @@ static char* motTextGetReadOnlyAttrib(Ihandle* ih)  static int motTextSetInsertAttrib(Ihandle* ih, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (!value) return 0; @@ -207,12 +209,12 @@ static char* motTextGetSelectedTextAttrib(Ihandle* ih) static int motTextSetAppendAttrib(Ihandle* ih, const char* value) { XmTextPosition pos; - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; pos = XmTextGetLastPosition(ih->handle); /* disable callbacks */ iupAttribSetStr(ih, "_IUPMOT_DISABLE_TEXT_CB", "1"); - if (ih->data->is_multiline && ih->data->append_newline) + if (ih->data->is_multiline && ih->data->append_newline && pos!=0) XmTextInsert(ih->handle, pos, "\n"); if (value) XmTextInsert(ih->handle, pos+1, (char*)value); @@ -482,8 +484,12 @@ static int motTextSetNCAttrib(Ihandle* ih, const char* value) if (!iupStrToInt(value, &ih->data->nc)) ih->data->nc = INT_MAX; if (ih->handle) + { XtVaSetValues(ih->handle, XmNmaxLength, ih->data->nc, NULL); - return 0; + return 0; + } + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int motTextSetClipboardAttrib(Ihandle *ih, const char *value) @@ -911,6 +917,10 @@ static void motTextLayoutUpdateMethod(Ihandle* ih) Widget spinbox = (Widget)iupAttribGet(ih, "_IUP_EXTRAPARENT"); if (spinbox && XmIsSpinBox(spinbox)) { + /* avoid abort in X */ + if (ih->currentwidth == 0) ih->currentwidth = 1; + if (ih->currentheight == 0) ih->currentheight = 1; + XtVaSetValues(ih->handle, XmNwidth, (XtArgVal)ih->currentwidth-ih->currentheight/2, XmNheight, (XtArgVal)ih->currentheight, @@ -952,13 +962,13 @@ static int motTextMapMethod(Ihandle* ih) /* Create the scrolled window */ /******************************/  - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNscrollingPolicy, XmAPPLICATION_DEFINED); - iupmotSetArg(args, num_args, XmNvisualPolicy, XmVARIABLE); - iupmotSetArg(args, num_args, XmNscrollBarDisplayPolicy, XmSTATIC); /* can NOT be XmAS_NEEDED because XmAPPLICATION_DEFINED */ - iupmotSetArg(args, num_args, XmNspacing, 0); /* no space between scrollbars and text */ - iupmotSetArg(args, num_args, XmNborderWidth, 0); - iupmotSetArg(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNscrollingPolicy, XmAPPLICATION_DEFINED); + iupMOT_SETARG(args, num_args, XmNvisualPolicy, XmVARIABLE); + iupMOT_SETARG(args, num_args, XmNscrollBarDisplayPolicy, XmSTATIC); /* can NOT be XmAS_NEEDED because XmAPPLICATION_DEFINED */ + iupMOT_SETARG(args, num_args, XmNspacing, 0); /* no space between scrollbars and text */ + iupMOT_SETARG(args, num_args, XmNborderWidth, 0); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0);  sb_win = XtCreateManagedWidget( child_id, /* child identifier */ @@ -973,9 +983,9 @@ static int motTextMapMethod(Ihandle* ih) child_id = "text";  num_args = 0; - iupmotSetArg(args, num_args, XmNeditMode, XmMULTI_LINE_EDIT); + iupMOT_SETARG(args, num_args, XmNeditMode, XmMULTI_LINE_EDIT); if (wordwrap) - iupmotSetArg(args, num_args, XmNwordWrap, True); + iupMOT_SETARG(args, num_args, XmNwordWrap, True); } else { @@ -986,18 +996,18 @@ static int motTextMapMethod(Ihandle* ih) Widget spinbox;  num_args = 0; - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNspacing, 0); /* no space between spin and text */ - iupmotSetArg(args, num_args, XmNborderWidth, 0); - iupmotSetArg(args, num_args, XmNshadowThickness, 0); - iupmotSetArg(args, num_args, XmNmarginHeight, 0); - iupmotSetArg(args, num_args, XmNmarginWidth, 0); - iupmotSetArg(args, num_args, XmNarrowSize, 8); + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNspacing, 0); /* no space between spin and text */ + iupMOT_SETARG(args, num_args, XmNborderWidth, 0); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNarrowSize, 8);  if (iupStrEqualNoCase(iupAttribGetStr(ih, "SPINALIGN"), "LEFT")) - iupmotSetArg(args, num_args, XmNarrowLayout, XmARROWS_BEGINNING); + iupMOT_SETARG(args, num_args, XmNarrowLayout, XmARROWS_BEGINNING); else - iupmotSetArg(args, num_args, XmNarrowLayout, XmARROWS_END); + iupMOT_SETARG(args, num_args, XmNarrowLayout, XmARROWS_END);  spinbox = XtCreateManagedWidget( child_id, /* child identifier */ @@ -1019,61 +1029,61 @@ static int motTextMapMethod(Ihandle* ih) }  num_args = 0; - iupmotSetArg(args, num_args, XmNeditMode, XmSINGLE_LINE_EDIT); + iupMOT_SETARG(args, num_args, XmNeditMode, XmSINGLE_LINE_EDIT);  if (spin) { /* Spin Constraints */ - iupmotSetArg(args, num_args, XmNspinBoxChildType, XmNUMERIC); - iupmotSetArg(args, num_args, XmNminimumValue, 0); - iupmotSetArg(args, num_args, XmNmaximumValue, 100); - iupmotSetArg(args, num_args, XmNposition, 0); + iupMOT_SETARG(args, num_args, XmNspinBoxChildType, XmNUMERIC); + iupMOT_SETARG(args, num_args, XmNminimumValue, 0); + iupMOT_SETARG(args, num_args, XmNmaximumValue, 100); + iupMOT_SETARG(args, num_args, XmNposition, 0);  if (iupAttribGetBoolean(ih, "SPINWRAP")) - iupmotSetArg(args, num_args, XmNwrap, TRUE); + iupMOT_SETARG(args, num_args, XmNwrap, TRUE); else - iupmotSetArg(args, num_args, XmNwrap, FALSE); + iupMOT_SETARG(args, num_args, XmNwrap, FALSE); } else { - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ } }  - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */  - iupmotSetArg(args, num_args, XmNmarginHeight, 0); /* default padding */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); /* default padding */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0);  if (iupAttribGetBoolean(ih, "CANFOCUS")) - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); else - iupmotSetArg(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False);  - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); - iupmotSetArg(args, num_args, XmNhighlightThickness, 2); - iupmotSetArg(args, num_args, XmNverifyBell, False); - iupmotSetArg(args, num_args, XmNspacing, 0); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 2); + iupMOT_SETARG(args, num_args, XmNverifyBell, False); + iupMOT_SETARG(args, num_args, XmNspacing, 0);  if (iupAttribGetBoolean(ih, "BORDER")) - iupmotSetArg(args, num_args, XmNshadowThickness, 2); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 2); else - iupmotSetArg(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0);  if (ih->data->is_multiline) { if (ih->data->sb & IUP_SB_HORIZ) - iupmotSetArg(args, num_args, XmNscrollHorizontal, True); + iupMOT_SETARG(args, num_args, XmNscrollHorizontal, True); else - iupmotSetArg(args, num_args, XmNscrollHorizontal, False); + iupMOT_SETARG(args, num_args, XmNscrollHorizontal, False);  if (ih->data->sb & IUP_SB_VERT) - iupmotSetArg(args, num_args, XmNscrollVertical, True); + iupMOT_SETARG(args, num_args, XmNscrollVertical, True); else - iupmotSetArg(args, num_args, XmNscrollVertical, False); + iupMOT_SETARG(args, num_args, XmNscrollVertical, False); }  ih->handle = XtCreateManagedWidget( diff --git a/iup/src/mot/iupmot_toggle.c b/iup/src/mot/iupmot_toggle.c index b18f24d..1fda258 100755 --- a/iup/src/mot/iupmot_toggle.c +++ b/iup/src/mot/iupmot_toggle.c @@ -236,8 +236,10 @@ static int motToggleSetPaddingAttrib(Ihandle* ih, const char* value) { XtVaSetValues(ih->handle, XmNmarginHeight, ih->data->vert_padding, XmNmarginWidth, ih->data->horiz_padding, NULL); + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static char* motToggleGetSelectColorAttrib(Ihandle* ih) @@ -336,40 +338,40 @@ static int motToggleMapMethod(Ihandle* ih) if (value) { ih->data->type = IUP_TOGGLE_IMAGE; - iupmotSetArg(args, num_args, XmNlabelType, XmPIXMAP);  + iupMOT_SETARG(args, num_args, XmNlabelType, XmPIXMAP);  } else { ih->data->type = IUP_TOGGLE_TEXT; - iupmotSetArg(args, num_args, XmNlabelType, XmSTRING);  + iupMOT_SETARG(args, num_args, XmNlabelType, XmSTRING);  }  /* Core */ - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */ /* Primitive */ if (iupAttribGetBoolean(ih, "CANFOCUS")) - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); else - iupmotSetArg(args, num_args, XmNtraversalOn, False); - iupmotSetArg(args, num_args, XmNhighlightThickness, 2); - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 2); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); /* Label */ - iupmotSetArg(args, num_args, XmNrecomputeSize, False); /* no automatic resize from text */ - iupmotSetArg(args, num_args, XmNmarginHeight, 0); /* default padding */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); - iupmotSetArg(args, num_args, XmNmarginTop, 0); /* no extra margins */ - iupmotSetArg(args, num_args, XmNmarginLeft, 0); - iupmotSetArg(args, num_args, XmNmarginBottom, 0); - iupmotSetArg(args, num_args, XmNmarginRight, 0); + iupMOT_SETARG(args, num_args, XmNrecomputeSize, False); /* no automatic resize from text */ + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); /* default padding */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNmarginTop, 0); /* no extra margins */ + iupMOT_SETARG(args, num_args, XmNmarginLeft, 0); + iupMOT_SETARG(args, num_args, XmNmarginBottom, 0); + iupMOT_SETARG(args, num_args, XmNmarginRight, 0);  if (radio) { - iupmotSetArg(args, num_args, XmNtoggleMode, XmTOGGLE_BOOLEAN); - iupmotSetArg(args, num_args, XmNindicatorType, XmONE_OF_MANY_ROUND); + iupMOT_SETARG(args, num_args, XmNtoggleMode, XmTOGGLE_BOOLEAN); + iupMOT_SETARG(args, num_args, XmNindicatorType, XmONE_OF_MANY_ROUND);  if (!iupAttribGet(radio, "_IUPMOT_LASTTOGGLE")) { @@ -380,33 +382,33 @@ static int motToggleMapMethod(Ihandle* ih) else { if (ih->data->type == IUP_TOGGLE_TEXT && iupAttribGetBoolean(ih, "3STATE")) - iupmotSetArg(args, num_args, XmNtoggleMode, XmTOGGLE_INDETERMINATE); + iupMOT_SETARG(args, num_args, XmNtoggleMode, XmTOGGLE_INDETERMINATE); else - iupmotSetArg(args, num_args, XmNtoggleMode, XmTOGGLE_BOOLEAN); - iupmotSetArg(args, num_args, XmNindicatorType, XmN_OF_MANY); + iupMOT_SETARG(args, num_args, XmNtoggleMode, XmTOGGLE_BOOLEAN); + iupMOT_SETARG(args, num_args, XmNindicatorType, XmN_OF_MANY); }  if (ih->data->type == IUP_TOGGLE_IMAGE) { - iupmotSetArg(args, num_args, XmNindicatorOn, XmINDICATOR_NONE); - iupmotSetArg(args, num_args, XmNalignment, XmALIGNMENT_CENTER); - iupmotSetArg(args, num_args, XmNshadowThickness, 2); + iupMOT_SETARG(args, num_args, XmNindicatorOn, XmINDICATOR_NONE); + iupMOT_SETARG(args, num_args, XmNalignment, XmALIGNMENT_CENTER); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 2); } else { - iupmotSetArg(args, num_args, XmNspacing, 3); - iupmotSetArg(args, num_args, XmNindicatorOn, XmINDICATOR_CHECK_BOX); - iupmotSetArg(args, num_args, XmNalignment, XmALIGNMENT_BEGINNING); + iupMOT_SETARG(args, num_args, XmNspacing, 3); + iupMOT_SETARG(args, num_args, XmNindicatorOn, XmINDICATOR_CHECK_BOX); + iupMOT_SETARG(args, num_args, XmNalignment, XmALIGNMENT_BEGINNING); if (radio) { - iupmotSetArg(args, num_args, XmNindicatorSize, 13); - iupmotSetArg(args, num_args, XmNselectColor, iupmotColorGetPixel(0, 0, 0)); + iupMOT_SETARG(args, num_args, XmNindicatorSize, 13); + iupMOT_SETARG(args, num_args, XmNselectColor, iupmotColorGetPixel(0, 0, 0)); } else - iupmotSetArg(args, num_args, XmNindicatorSize, 15); + iupMOT_SETARG(args, num_args, XmNindicatorSize, 15);  - iupmotSetArg(args, num_args, XmNshadowThickness, 0); - iupmotSetArg(args, num_args, XmNdetailShadowThickness, 2); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNdetailShadowThickness, 2); }  ih->handle = XtCreateManagedWidget( diff --git a/iup/src/mot/iupmot_tree.c b/iup/src/mot/iupmot_tree.c index eb230af..fa5ef09 100755 --- a/iup/src/mot/iupmot_tree.c +++ b/iup/src/mot/iupmot_tree.c @@ -46,48 +46,20 @@ typedef struct _motTreeItemData Pixmap image, image_mask; Pixmap image_expanded, image_expanded_mask; unsigned char kind; - void* userdata; } motTreeItemData;   static void motTreeShowEditField(Ihandle* ih, Widget wItem); -static int motTreeGetNodeId(Ihandle* ih, Widget wItem); +static void motTreeRemoveNode(Ihandle* ih, Widget wItem, int del_data, int call_cb);  -typedef int (*motTreeNodeFunc)(Ihandle* ih, Widget wItem, void* userdata); - -static int motTreeForEach(Ihandle* ih, Widget wItem, motTreeNodeFunc func, void* userdata) -{ - WidgetList wItemChildList = NULL; - int i, numChild; - - if (!wItem) - wItem = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - - if (!func(ih, wItem, userdata)) - return 0; - - numChild = XmContainerGetItemChildren(ih->handle, wItem, &wItemChildList); - for (i=0; idata->spacing); - iupmotSetArg(args, num_args, XmNmarginWidth, 0); - iupmotSetArg(args, num_args, XmNviewType, XmSMALL_ICON); - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); - iupmotSetArg(args, num_args, XmNtraversalOn, True); - iupmotSetArg(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNentryParent, wParent); + iupMOT_SETARG(args, num_args, XmNmarginHeight, ih->data->spacing); + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNviewType, XmSMALL_ICON); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0);  /* Get values to copy */ XtVaGetValues(wItem, XmNlabelString, &title, @@ -113,49 +85,73 @@ static Widget motTreeCopyItem(Ihandle* ih, Widget wItem, Widget wParent, int pos XmNoutlineState, &state, NULL);  - if (full_copy) /* during a full copy the userdata reference is not copied */ + if (is_copy) /* during a copy the itemdata reference is not reused */ { /* create a new one */ motTreeItemData* itemDataNew = malloc(sizeof(motTreeItemData)); memcpy(itemDataNew, itemData, sizeof(motTreeItemData)); - itemDataNew->userdata = NULL; itemData = itemDataNew; }  - iupmotSetArg(args, num_args, XmNlabelString, title); - iupmotSetArg(args, num_args, XmNuserData, itemData); - iupmotSetArg(args, num_args, XmNforeground, fgcolor); - iupmotSetArg(args, num_args, XmNsmallIconPixmap, image); - iupmotSetArg(args, num_args, XmNsmallIconMask, mask); - iupmotSetArg(args, num_args, XmNoutlineState, state); + iupMOT_SETARG(args, num_args, XmNlabelString, title); + iupMOT_SETARG(args, num_args, XmNuserData, itemData); + iupMOT_SETARG(args, num_args, XmNforeground, fgcolor); + iupMOT_SETARG(args, num_args, XmNsmallIconPixmap, image); + iupMOT_SETARG(args, num_args, XmNsmallIconMask, mask); + iupMOT_SETARG(args, num_args, XmNoutlineState, state);  - iupmotSetArg(args, num_args, XmNentryParent, wParent); - iupmotSetArg(args, num_args, XmNpositionIndex, pos); + iupMOT_SETARG(args, num_args, XmNentryParent, wParent); + iupMOT_SETARG(args, num_args, XmNpositionIndex, pos);  XtVaGetValues(ih->handle, XmNbackground, &bgcolor, NULL); - iupmotSetArg(args, num_args, XmNbackground, bgcolor); + iupMOT_SETARG(args, num_args, XmNbackground, bgcolor); + + /* Add the new node */ + wItemNew = XtCreateManagedWidget("icon", xmIconGadgetClass, ih->handle, args, num_args); + ih->data->node_count++; + + XtRealizeWidget(wItemNew); + + return wItemNew; +} + +static void motTreeChildRebuildCacheRec(Ihandle* ih, Widget wItem, int *id) +{ + WidgetList itemChildList = NULL; + int i, numChild;  - wNewItem = XtCreateManagedWidget("icon", xmIconGadgetClass, ih->handle, args, num_args); + /* Check whether we have child items */ + numChild = XmContainerGetItemChildren(ih->handle, wItem, &itemChildList); + + for (i = 0; i < numChild; i++) + { + (*id)++; + ih->data->node_cache[*id].node_handle = itemChildList[i];  - /* Root always expanded */ - XtVaSetValues((Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"), XmNoutlineState, XmEXPANDED, NULL); + /* go recursive to children */ + motTreeChildRebuildCacheRec(ih, itemChildList[i], id); + }  - XtRealizeWidget(wNewItem); + if (itemChildList) XtFree((char*)itemChildList); +}  - return wNewItem; +static void motTreeRebuildNodeCache(Ihandle* ih, int id, Widget wItem) +{ + ih->data->node_cache[id].node_handle = wItem; + motTreeChildRebuildCacheRec(ih, wItem, &id); }  -static void motTreeCopyChildren(Ihandle* ih, Widget wItemSrc, Widget wItemDst, int full_copy) +static void motTreeCopyChildren(Ihandle* ih, Widget wItemSrc, Widget wItemDst, int is_copy) { WidgetList wItemChildList = NULL; int i = 0; int numChild = XmContainerGetItemChildren(ih->handle, wItemSrc, &wItemChildList); while(i != numChild) { - Widget wNewItem = motTreeCopyItem(ih, wItemChildList[i], wItemDst, i, full_copy); /* Use the same order they where enumerated */ + Widget wItemNew = motTreeCopyItem(ih, wItemChildList[i], wItemDst, i, is_copy); /* Use the same order they where enumerated */  /* Recursively transfer all the items */ - motTreeCopyChildren(ih, wItemChildList[i], wNewItem, full_copy);  + motTreeCopyChildren(ih, wItemChildList[i], wItemNew, is_copy);   /* Go to next sibling item */ i++; @@ -165,12 +161,18 @@ static void motTreeCopyChildren(Ihandle* ih, Widget wItemSrc, Widget wItemDst, i }  /* Copies all items in a branch to a new location. Returns the new branch node. */ -static Widget motTreeCopyNode(Ihandle* ih, Widget wItemSrc, Widget wItemDst, int full_copy) +static Widget motTreeCopyMoveNode(Ihandle* ih, Widget wItemSrc, Widget wItemDst, int is_copy) { - Widget wNewItem, wParent; + Widget wItemNew, wParent; motTreeItemData *itemDataDst; unsigned char stateDst; - int pos; + int pos, id_new, count, id_src, id_dst; + + int old_count = ih->data->node_count; + + id_src = iupTreeFindNodeId(ih, wItemSrc); + id_dst = iupTreeFindNodeId(ih, wItemDst); + id_new = id_dst+1; /* contains the position for a copy operation */  XtVaGetValues(wItemDst, XmNoutlineState, &stateDst,  XmNuserData, &itemDataDst,  @@ -184,17 +186,46 @@ static Widget motTreeCopyNode(Ihandle* ih, Widget wItemSrc, Widget wItemDst, int } else { + if (itemDataDst->kind == ITREE_BRANCH) + { + int child_count = iupdrvTreeTotalChildCount(ih, wItemDst); + id_new += child_count; + } + /* copy as next brother of item or collapsed branch */ XtVaGetValues(wItemDst, XmNentryParent, &wParent, NULL); XtVaGetValues(wItemDst, XmNpositionIndex, &pos, NULL); pos++; }  - wNewItem = motTreeCopyItem(ih, wItemSrc, wParent, pos, full_copy); + /* move to the same place does nothing */ + if (!is_copy && id_new == id_src) + return NULL; + + wItemNew = motTreeCopyItem(ih, wItemSrc, wParent, pos, is_copy); + + motTreeCopyChildren(ih, wItemSrc, wItemNew, is_copy); + + count = ih->data->node_count - old_count; + iupTreeCopyMoveCache(ih, id_src, id_new, count, is_copy);  - motTreeCopyChildren(ih, wItemSrc, wNewItem, full_copy); + if (!is_copy) + { + /* Deleting the node (and its children) from the old position */ + /* do not delete the itemdata, we reuse the references in CopyNode */ + motTreeRemoveNode(ih, wItemSrc, 0, 0); + + /* restore count, because we remove src */ + ih->data->node_count = old_count; + + /* compensate position for a move */ + if (id_new > id_src) + id_new -= count; + }  - return wNewItem; + motTreeRebuildNodeCache(ih, id_new, wItemNew); + + return wItemNew; }  static void motTreeContainerDeselectAll(Ihandle *ih) @@ -233,229 +264,181 @@ static void motTreeContainerSelectAll(Ihandle *ih) XtCallActionProc(ih->handle, "ContainerSelectAll", (XEvent*)&ev, 0, 0); }  -static Widget motTreeGetLastVisibleNode(Ihandle* ih, Widget wItem) +static int motTreeIsNodeVisible(Widget wItem, Widget *wLastItemParent) { - unsigned char itemState; - - XtVaGetValues(wItem, XmNoutlineState, &itemState, NULL); - - if (itemState == XmEXPANDED) + unsigned char itemParentState; + Widget wItemParent = NULL; + XtVaGetValues(wItem, XmNentryParent, &wItemParent, NULL); + if (!wItemParent || wItemParent == *wLastItemParent) + return 1; + while(wItemParent) { - WidgetList wChildrenTree = NULL; - int numChildren = XmContainerGetItemChildren(ih->handle, wItem, &wChildrenTree); - if(numChildren) - wItem = motTreeGetLastVisibleNode(ih, wChildrenTree[numChildren - 1]); - if (wChildrenTree) XtFree((char*)wChildrenTree); + XtVaGetValues(wItemParent, XmNoutlineState, &itemParentState, NULL); + if (itemParentState != XmEXPANDED) + return 0; + + XtVaGetValues(wItemParent, XmNentryParent, &wItemParent, NULL); }  - return wItem; + /* save last parent */ + XtVaGetValues(wItem, XmNentryParent, &wItemParent, NULL); + *wLastItemParent = wItemParent; + return 1; }  -static Widget motTreeFindVisibleNodeId(Ihandle* ih, WidgetList itemList, int numItems, Widget itemNode) +static Widget motTreeGetLastVisibleNode(Ihandle* ih) { - Widget itemChild; - WidgetList itemChildList; - int i = 0; - int numChild; - unsigned char itemState; + int i; + Widget wLastItemParent = NULL;  - while(i != numItems) + for (i = ih->data->node_count-1; i >= 0; i--) { - /* ID control to traverse items */ - ih->data->id_control++; /* not the real id since it counts only the visible ones */ - - /* StateID founded! */ - if(itemList[i] == itemNode) - return itemList[i]; - - /* Check whether we have child items */ - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - XtVaGetValues(itemList[i], XmNoutlineState, &itemState, NULL); - - /* The itemWidget has child and it is expanded (visible) */ - if (numChild && itemState == XmEXPANDED) - { - /* pass the list of children of this item */ - itemChild = motTreeFindVisibleNodeId(ih, itemChildList, numChild, itemNode); - - /* StateID founded! */ - if(itemChild) - { - XtFree((char*)itemChildList); - return itemChild; - } - } - - if (itemChildList) XtFree((char*)itemChildList); - /* Go to next sibling item */ - i++; + if (motTreeIsNodeVisible(ih->data->node_cache[i].node_handle, &wLastItemParent)) + return ih->data->node_cache[i].node_handle; }  - return NULL; + return ih->data->node_cache[0].node_handle; /* root is always visible */ }  -static Widget motTreeFindVisibleNodeFromId(Ihandle* ih, WidgetList itemList, int numItems) +static Widget motTreeGetNextVisibleNode(Ihandle* ih, Widget wItem, int count) { - Widget itemChild; - WidgetList itemChildList; - int i = 0; - int numChild; - unsigned char itemState; + int i, id; + Widget wLastItemParent = NULL;  - while(i != numItems) - { - /* ID control to traverse items */ - ih->data->id_control--; /* not the real id since it counts only the visible ones */ + id = iupTreeFindNodeId(ih, wItem); + id += count;  - /* StateID founded! */ - if(ih->data->id_control < 0) - return itemList[i]; + for (i = id; i < ih->data->node_count; i++) + { + if (motTreeIsNodeVisible(ih->data->node_cache[i].node_handle, &wLastItemParent)) + return ih->data->node_cache[i].node_handle; + }  - /* Check whether we have child items */ - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - XtVaGetValues(itemList[i], XmNoutlineState, &itemState, NULL); + return ih->data->node_cache[0].node_handle; /* root is always visible */ +}  - /* The itemWidget has child and it is expanded (visible) */ - if (numChild && itemState == XmEXPANDED) - { - /* pass the list of children of this item */ - itemChild = motTreeFindVisibleNodeFromId(ih, itemChildList, numChild); +static Widget motTreeGetPreviousVisibleNode(Ihandle* ih, Widget wItem, int count) +{ + int i, id; + Widget wLastItemParent = NULL;  - /* StateID founded! */ - if(ih->data->id_control < 0) - { - if (itemChildList) XtFree((char*)itemChildList); - return itemChild; - } - } + id = iupTreeFindNodeId(ih, wItem); + id -= count;  - if (itemChildList) XtFree((char*)itemChildList); - /* Go to next sibling item */ - i++; + for (i = id; i >= 0; i--) + { + if (motTreeIsNodeVisible(ih->data->node_cache[i].node_handle, &wLastItemParent)) + return ih->data->node_cache[i].node_handle; }  - return NULL; + return motTreeGetLastVisibleNode(ih); }  -static Widget motTreeGetNextVisibleNode(Ihandle* ih, Widget wRoot, Widget wItem) +static void motTreeChildCountRec(Ihandle* ih, Widget wItem, int *count) { - Widget wNext; + WidgetList itemChildList = NULL; + int i, numChild;  - ih->data->id_control = -1; - motTreeFindVisibleNodeId(ih, &wRoot, 1, wItem); - ih->data->id_control++; /* more 1 visible node */ + /* Check whether we have child items */ + numChild = XmContainerGetItemChildren(ih->handle, wItem, &itemChildList);  - wNext = motTreeFindVisibleNodeFromId(ih, &wRoot, 1); + for (i = 0; i < numChild; i++) + { + (*count)++;  - if (ih->data->id_control >= 0) - wNext = motTreeGetLastVisibleNode(ih, wRoot); + /* go recursive to children */ + motTreeChildCountRec(ih, itemChildList[i], count); + }  - return wNext; + if (itemChildList) XtFree((char*)itemChildList); }  -static Widget motTreeGetPreviousVisibleNode(Ihandle* ih, Widget wRoot, Widget wItem) +int iupdrvTreeTotalChildCount(Ihandle* ih, Widget wItem) { - ih->data->id_control = -1; - motTreeFindVisibleNodeId(ih, &wRoot, 1, wItem); - ih->data->id_control--; /* less 1 visible node */ - - if (ih->data->id_control < 0) - ih->data->id_control = 0; /* Begin of tree = Root id */ - - return motTreeFindVisibleNodeFromId(ih, &wRoot, 1); + int count = 0; + motTreeChildCountRec(ih, wItem, &count); + return count; }  -static void motTreeUpdateBgColor(Ihandle* ih, WidgetList itemList, int numItems, Pixel bgcolor) +static void motTreeUpdateBgColor(Ihandle* ih, Pixel bgcolor) { - WidgetList itemChildList; - int i = 0; - int numChild; - - while(i != numItems) + int i; + for (i = 0; i < ih->data->node_count; i++) { - XtVaSetValues(itemList[i], XmNbackground, bgcolor, NULL); - - /* Check whether we have child items */ - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - if(numChild) - motTreeUpdateBgColor(ih, itemChildList, numChild, bgcolor); - if (itemChildList) XtFree((char*)itemChildList); - - /* Go to next sibling item */ - i++; + XtVaSetValues(ih->data->node_cache[i].node_handle, XmNbackground, bgcolor, NULL); } }  -static void motTreeUpdateImages(Ihandle* ih, WidgetList itemList, int numItems, int mode) +static void motTreeUpdateImages(Ihandle* ih, int mode) { - motTreeItemData *itemData; - int i = 0; - + int i; /* called when one of the default images is changed */ - - while(i != numItems) + for (i = 0; i < ih->data->node_count; i++) { - /* Get node attributes */ - XtVaGetValues(itemList[i], XmNuserData, &itemData, NULL); -  + motTreeItemData *itemData; + Widget wItem = ih->data->node_cache[i].node_handle; + + XtVaGetValues(wItem, XmNuserData, &itemData, NULL); + if (itemData->kind == ITREE_BRANCH) { unsigned char itemState; - XtVaGetValues(itemList[i], XmNoutlineState, &itemState, NULL); + XtVaGetValues(wItem, XmNoutlineState, &itemState, NULL);  if (itemState == XmEXPANDED) { if (mode == ITREE_UPDATEIMAGE_EXPANDED) { - XtVaSetValues(itemList[i], XmNsmallIconPixmap, (itemData->image_expanded!=XmUNSPECIFIED_PIXMAP)? itemData->image_expanded: (Pixmap)ih->data->def_image_expanded, NULL); - XtVaSetValues(itemList[i], XmNsmallIconMask, (itemData->image_expanded_mask!=XmUNSPECIFIED_PIXMAP)? itemData->image_expanded_mask: (Pixmap)ih->data->def_image_expanded_mask, NULL); + XtVaSetValues(wItem, XmNsmallIconPixmap, (itemData->image_expanded!=XmUNSPECIFIED_PIXMAP)? itemData->image_expanded: (Pixmap)ih->data->def_image_expanded, NULL); + XtVaSetValues(wItem, XmNsmallIconMask, (itemData->image_expanded_mask!=XmUNSPECIFIED_PIXMAP)? itemData->image_expanded_mask: (Pixmap)ih->data->def_image_expanded_mask, NULL); } } else  { if (mode == ITREE_UPDATEIMAGE_COLLAPSED) { - XtVaSetValues(itemList[i], XmNsmallIconPixmap, (itemData->image!=XmUNSPECIFIED_PIXMAP)? itemData->image: (Pixmap)ih->data->def_image_collapsed, NULL); - XtVaSetValues(itemList[i], XmNsmallIconMask, (itemData->image_mask!=XmUNSPECIFIED_PIXMAP)? itemData->image_mask: (Pixmap)ih->data->def_image_collapsed_mask, NULL); + XtVaSetValues(wItem, XmNsmallIconPixmap, (itemData->image!=XmUNSPECIFIED_PIXMAP)? itemData->image: (Pixmap)ih->data->def_image_collapsed, NULL); + XtVaSetValues(wItem, XmNsmallIconMask, (itemData->image_mask!=XmUNSPECIFIED_PIXMAP)? itemData->image_mask: (Pixmap)ih->data->def_image_collapsed_mask, NULL); } } - - /* Recursively traverse child items */ - { - WidgetList itemChildList; - int numChild; - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - motTreeUpdateImages(ih, itemChildList, numChild, mode); - if (itemChildList) XtFree((char*)itemChildList); - } } else  { if (mode == ITREE_UPDATEIMAGE_LEAF) { - XtVaSetValues(itemList[i], XmNsmallIconPixmap, (itemData->image!=XmUNSPECIFIED_PIXMAP)? itemData->image: (Pixmap)ih->data->def_image_leaf, NULL); - XtVaSetValues(itemList[i], XmNsmallIconMask, (itemData->image_mask!=XmUNSPECIFIED_PIXMAP)? itemData->image_mask: (Pixmap)ih->data->def_image_leaf_mask, NULL); + XtVaSetValues(wItem, XmNsmallIconPixmap, (itemData->image!=XmUNSPECIFIED_PIXMAP)? itemData->image: (Pixmap)ih->data->def_image_leaf, NULL); + XtVaSetValues(wItem, XmNsmallIconMask, (itemData->image_mask!=XmUNSPECIFIED_PIXMAP)? itemData->image_mask: (Pixmap)ih->data->def_image_leaf_mask, NULL); } } - - /* Go to next sibling node */ - i++; } }  -static int motTreeSelectFunc(Ihandle* ih, Widget wItem, int *select) +static int motTreeIsNodeSelected(Widget wItem) +{ + unsigned char isSelected; + XtVaGetValues(wItem, XmNvisualEmphasis, &isSelected, NULL); + if(isSelected == XmSELECTED) + return 1; + else + return 0; +} + +static void motTreeSelectNode(Widget wItem, int select) +{ + if (select == -1) + select = !motTreeIsNodeSelected(wItem); /* toggle */ + + if (select) + XtVaSetValues(wItem, XmNvisualEmphasis, XmSELECTED, NULL); + else + XtVaSetValues(wItem, XmNvisualEmphasis, XmNOT_SELECTED, NULL); +} + +static int motTreeSelectFunc(Ihandle* ih, Widget wItem, int id, int *select) { int do_select = *select; if (do_select == -1) - { - unsigned char isSelected; - XtVaGetValues(wItem, XmNvisualEmphasis, &isSelected, NULL); - do_select = (isSelected == XmSELECTED)? 0: 1; /* toggle */ - } + do_select = !motTreeIsNodeSelected(wItem); /* toggle */  if (do_select) XtVaSetValues(wItem, XmNvisualEmphasis, XmSELECTED, NULL); @@ -463,272 +446,111 @@ static int motTreeSelectFunc(Ihandle* ih, Widget wItem, int *select) XtVaSetValues(wItem, XmNvisualEmphasis, XmNOT_SELECTED, NULL);  (void)ih; + (void)id; return 1; }  static void motTreeInvertAllNodeMarking(Ihandle* ih) { int select = -1; - motTreeForEach(ih, NULL, (motTreeNodeFunc)motTreeSelectFunc, &select); + iupTreeForEach(ih, (iupTreeNodeFunc)motTreeSelectFunc, &select); }  -typedef struct _motTreeRange{ - Widget wItem1, wItem2; - char inside, clear; -}motTreeRange; - -static int motTreeSelectRangeFunc(Ihandle* ih, Widget wItem, motTreeRange* range) +static void motTreeSelectRange(Ihandle* ih, Widget wItem1, Widget wItem2, int clear) { - int end_range = 0; - - if (range->inside == 0) /* detect the range start */ - { - if (range->wItem1 == wItem) range->inside=1; - else if (range->wItem2 == wItem) range->inside=1; - } - else if (range->inside == 1) /* detect the range end */ + int i; + int id1 = iupTreeFindNodeId(ih, wItem1); + int id2 = iupTreeFindNodeId(ih, wItem2); + if (id1 > id2) { - if (range->wItem1 == wItem) end_range=1; - else if (range->wItem2 == wItem) end_range=1; + int tmp = id1; + id1 = id2; + id2 = tmp; }  - if (range->inside == 1) /* if inside, select */ - XtVaSetValues(wItem, XmNvisualEmphasis, XmSELECTED, NULL); - else if (range->clear) /* if outside and clear, unselect */ - XtVaSetValues(wItem, XmNvisualEmphasis, XmNOT_SELECTED, NULL); - - if (end_range || (range->inside && range->wItem1==range->wItem2)) - range->inside=-1; /* update after selecting the node */ - - (void)ih; - return 1; -} - -static void motTreeSelectRange(Ihandle* ih, Widget wItem1, Widget wItem2, int clear) -{ - motTreeRange range; - range.wItem1 = wItem1; - range.wItem2 = wItem2; - range.inside = 0; - range.clear = (char)clear; - motTreeForEach(ih, NULL, (motTreeNodeFunc)motTreeSelectRangeFunc, &range); -} - -void motTreeExpandCollapseAllNodes(Ihandle* ih, WidgetList itemList, int numItems, unsigned char itemState) -{ - WidgetList itemChildList; - int numChild; - int i = 0; - - while(i != numItems) + for (i = 0; i < ih->data->node_count; i++) { - /* Check whether we have child items */ - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - - if(numChild) + if (i < id1 || i > id2) { - XtVaSetValues(itemList[i], XmNoutlineState, itemState, NULL); - motTreeExpandCollapseAllNodes(ih, itemChildList, numChild, itemState); + if (clear) + XtVaSetValues(ih->data->node_cache[i].node_handle, XmNvisualEmphasis, XmNOT_SELECTED, NULL); } - - if (itemChildList) XtFree((char*)itemChildList); - /* Go to next sibling item */ - i++; + else + XtVaSetValues(ih->data->node_cache[i].node_handle, XmNvisualEmphasis, XmSELECTED, NULL); } }  -static void motTreeDestroyItemData(Ihandle* ih, Widget wItem) +void motTreeExpandCollapseAllNodes(Ihandle* ih, unsigned char itemState) { - motTreeItemData *itemData = NULL; - XtVaGetValues(wItem, XmNuserData, &itemData, NULL); - if (itemData) + int i; + /* called when one of the default images is changed */ + for (i = 0; i < ih->data->node_count; i++) { - IFnis cb = (IFnis)IupGetCallback(ih, "NODEREMOVED_CB"); - if (cb) cb(ih, motTreeGetNodeId(ih, wItem), (char*)itemData->userdata); - free(itemData); - XtVaSetValues(wItem, XmNuserData, NULL, NULL); - } -} - -static void motTreeRemoveChildren(Ihandle* ih, WidgetList itemList, int numItems, int del_userdata) -{ - WidgetList itemChildList; - int numChild; - int i = 0; + motTreeItemData *itemData; + Widget wItem = ih->data->node_cache[i].node_handle;  - while(i != numItems) - {  + XtVaGetValues(wItem, XmNuserData, &itemData, NULL); +  /* Check whether we have child items */ - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - if (numChild) - motTreeRemoveChildren(ih, itemChildList, numChild, del_userdata); - - if (del_userdata) - motTreeDestroyItemData(ih, itemList[i]); - - XtDestroyWidget(itemList[i]); - - if (itemChildList) XtFree((char*)itemChildList); - /* Go to next sibling item */ - i++; + if (itemData->kind == ITREE_BRANCH) + XtVaSetValues(wItem, XmNoutlineState, itemState, NULL); } }  -static void motTreeRemoveNode(Ihandle* ih, Widget wItem, int del_userdata) +static void motTreeDestroyItemData(Ihandle* ih, Widget wItem, int del_data, IFns cb, int id) { - WidgetList wChildList = NULL; - int numChild = XmContainerGetItemChildren(ih->handle, wItem, &wChildList); - if (numChild) - motTreeRemoveChildren(ih, wChildList, numChild, del_userdata); - if (del_userdata) - motTreeDestroyItemData(ih, wItem); - XtDestroyWidget(wItem); - if (wChildList) XtFree((char*)wChildList); -} - -static Widget motTreeFindNodeID(Ihandle* ih, WidgetList itemList, int numItems, Widget itemNode) -{ - Widget itemChild; - WidgetList itemChildList; - int i = 0; - int numChild; - - while(i != numItems) + motTreeItemData *itemData = NULL; + XtVaGetValues(wItem, XmNuserData, &itemData, NULL); + if (itemData) { - /* ID control to traverse items */ - ih->data->id_control++; + if (cb)  + cb(ih, (char*)ih->data->node_cache[id].userdata);  - /* StateID founded! */ - if(itemList[i] == itemNode) - return itemList[i]; - - /* Check whether we have child items */ - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - if(numChild) + if (del_data) { - /* pass the list of children of this item */ - itemChild = motTreeFindNodeID(ih, itemChildList, numChild, itemNode); - - /* StateID founded! */ - if(itemChild) - { - if (itemChildList) XtFree((char*)itemChildList); - return itemChild; - } + free(itemData); + XtVaSetValues(wItem, XmNuserData, NULL, NULL); } - - if (itemChildList) XtFree((char*)itemChildList); - /* Go to next sibling item */ - i++; } - - return NULL; }  -static Widget motTreeFindNodeFromID(Ihandle* ih, WidgetList itemList, int numItems) +static void motTreeRemoveNodeRec(Ihandle* ih, Widget wItem, int del_data, IFns cb, int *id) { - Widget itemChild; - WidgetList itemChildList; - int i = 0; - int numChild; + WidgetList itemChildList = NULL; + int i, numChild; + int old_id = *id;  - while(i != numItems) + /* Check whether we have child items */ + /* remove from children first */ + numChild = XmContainerGetItemChildren(ih->handle, wItem, &itemChildList); + for (i = 0; i < numChild; i++) { - /* ID control to traverse items */ - ih->data->id_control--; - - /* StateID founded! */ - if(ih->data->id_control < 0) - return itemList[i]; - - /* Check whether we have child items */ - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - if(numChild) - { - /* pass the list of children of this item */ - itemChild = motTreeFindNodeFromID(ih, itemChildList, numChild); - - /* StateID founded! */ - if(ih->data->id_control < 0) - { - if (itemChildList) XtFree((char*)itemChildList); - return itemChild; - } - } - - if (itemChildList) XtFree((char*)itemChildList); - /* Go to next sibling item */ - i++; + /* go recursive to children */ + motTreeRemoveNodeRec(ih, itemChildList[i], del_data, cb, id); } + if (itemChildList) XtFree((char*)itemChildList);  - return NULL; -} + /* actually do it for the node */ + ih->data->node_count--; + (*id)++;  -static int motTreeGetNodeId(Ihandle* ih, Widget wItem) -{ - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - ih->data->id_control = -1; - if (motTreeFindNodeID(ih, &wRoot, 1, wItem)) - return ih->data->id_control; - else - return -1; + if (del_data || cb) + motTreeDestroyItemData(ih, wItem, del_data, cb, old_id); + + XtDestroyWidget(wItem); /* must manually destroy each node, this is NOT recursive */ }  -static Widget motTreeFindUserDataID(Ihandle* ih, WidgetList itemList, int numItems, void* userdata) +static void motTreeRemoveNode(Ihandle* ih, Widget wItem, int del_data, int call_cb) { - Widget itemChild; - WidgetList itemChildList; - motTreeItemData *itemData; - int i = 0; - int numChild; - - while(i != numItems) - { - /* ID control to traverse items */ - ih->data->id_control++; - - XtVaGetValues(itemList[i], XmNuserData, &itemData, NULL); - - /* StateID founded! */ - if(itemData->userdata == userdata) - return itemList[i]; + IFns cb = call_cb? (IFns)IupGetCallback(ih, "NODEREMOVED_CB"): NULL; + int old_count = ih->data->node_count; + int id = iupTreeFindNodeId(ih, wItem); + int old_id = id;  - /* Check whether we have child items */ - itemChildList = NULL; - numChild = XmContainerGetItemChildren(ih->handle, itemList[i], &itemChildList); - if(numChild) - { - /* pass the list of children of this item */ - itemChild = motTreeFindUserDataID(ih, itemChildList, numChild, userdata); - - /* StateID founded! */ - if (itemChild) - { - if (itemChildList) XtFree((char*)itemChildList); - return itemChild; - } - } + motTreeRemoveNodeRec(ih, wItem, del_data, cb, &id);  - if (itemChildList) XtFree((char*)itemChildList); - /* Go to next sibling item */ - i++; - } - - return NULL; -} - -static int motTreeGetUserDataId(Ihandle* ih, void* userdata) -{ - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - ih->data->id_control = -1; - if (motTreeFindUserDataID(ih, &wRoot, 1, userdata)) - return ih->data->id_control; - else - return -1; + if (call_cb) + iupTreeDelFromCache(ih, old_id, old_count-ih->data->node_count); }  static void motTreeSetFocusNode(Ihandle* ih, Widget wItem) @@ -737,7 +559,7 @@ static void motTreeSetFocusNode(Ihandle* ih, Widget wItem) XmProcessTraversal(wItem, XmTRAVERSE_CURRENT); }  -static Widget motTreeGetFocusNode(Ihandle* ih) +Widget iupdrvTreeGetFocusNode(Ihandle* ih) { Widget wItem = XmGetFocusWidget(ih->handle); /* returns the focus in the dialog */ if (wItem && XtParent(wItem) == ih->handle) /* is a node */ @@ -746,18 +568,6 @@ static Widget motTreeGetFocusNode(Ihandle* ih) return (Widget)iupAttribGet(ih, "_IUPTREE_LAST_FOCUS"); }  -static Widget motTreeFindNodeFromString(Ihandle* ih, const char* name_id) -{ - if (name_id[0]) - { - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - iupStrToInt(name_id, &ih->data->id_control); - return motTreeFindNodeFromID(ih, &wRoot, 1); - } - else - return motTreeGetFocusNode(ih); -} - static void motTreeEnterLeaveWindowEvent(Widget w, Ihandle *ih, XEvent *evt, Boolean *cont) { if (iupAttribGet(ih, "_IUPTREE_EDITFIELD")) @@ -812,16 +622,24 @@ static void motTreeFocusChangeEvent(Widget w, Ihandle *ih, XEvent *evt, Boolean  void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* title, int add) { - Widget wItemPrev = motTreeFindNodeFromString(ih, name_id); - Widget wNewItem; + Widget wItemPrev = iupTreeGetNodeFromString(ih, name_id); + Widget wItemNew; XmString itemTitle; - motTreeItemData *itemData, *itemDataPrev; + motTreeItemData *itemData; Pixel bgcolor, fgcolor; - int kindPrev, num_args = 0; + int kindPrev = 0, num_args = 0; Arg args[30];  if (!wItemPrev) - return; + { + /* check if the root was really specified */ + int id = 0; + if (!iupStrToInt(name_id, &id) || id != -1) + return; + } + + if (!title) + title = "";  itemData = calloc(1, sizeof(motTreeItemData)); itemData->image = XmUNSPECIFIED_PIXMAP; @@ -836,138 +654,103 @@ void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* t XtVaGetValues(ih->handle, XmNforeground, &fgcolor, NULL); XtVaGetValues(ih->handle, XmNbackground, &bgcolor, NULL);  - /* Get the kind of previous item */ - XtVaGetValues(wItemPrev, XmNuserData, &itemDataPrev, NULL); - kindPrev = itemDataPrev->kind; - - if (kindPrev == ITREE_BRANCH && add) + if (wItemPrev) { - /* wItemPrev is parent of the new item (firstchild of it) */ - iupmotSetArg(args, num_args, XmNentryParent, wItemPrev); - iupmotSetArg(args, num_args, XmNpositionIndex, 0); - } - else - { - /* wItemPrev is sibling of the new item (set its parent to the new item) */ - Widget wItemParent; - int pos; + motTreeItemData *itemDataPrev;  - XtVaGetValues(wItemPrev, XmNentryParent, &wItemParent, NULL); - XtVaGetValues(wItemPrev, XmNpositionIndex, &pos, NULL); + /* Get the kind of previous item */ + XtVaGetValues(wItemPrev, XmNuserData, &itemDataPrev, NULL); + kindPrev = itemDataPrev->kind; + + if (kindPrev == ITREE_BRANCH && add) + { + /* wItemPrev is parent of the new item (firstchild of it) */ + iupMOT_SETARG(args, num_args, XmNentryParent, wItemPrev); + iupMOT_SETARG(args, num_args, XmNpositionIndex, 0); + } + else + { + /* wItemPrev is sibling of the new item (set its parent to the new item) */ + Widget wItemParent; + int pos;  - iupmotSetArg(args, num_args, XmNentryParent, wItemParent); - iupmotSetArg(args, num_args, XmNpositionIndex, pos+1); + XtVaGetValues(wItemPrev, XmNentryParent, &wItemParent, NULL); + XtVaGetValues(wItemPrev, XmNpositionIndex, &pos, NULL); + + iupMOT_SETARG(args, num_args, XmNentryParent, wItemParent); + iupMOT_SETARG(args, num_args, XmNpositionIndex, pos+1); + } }  - iupmotSetArg(args, num_args, XmNuserData, itemData); - iupmotSetArg(args, num_args, XmNforeground, fgcolor); - iupmotSetArg(args, num_args, XmNbackground, bgcolor); - iupmotSetArg(args, num_args, XmNmarginHeight, ih->data->spacing); - iupmotSetArg(args, num_args, XmNmarginWidth, 0); - iupmotSetArg(args, num_args, XmNviewType, XmSMALL_ICON); - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); - iupmotSetArg(args, num_args, XmNtraversalOn, True); - iupmotSetArg(args, num_args, XmNshadowThickness, 0); - iupmotSetArg(args, num_args, XmNlabelString, itemTitle); + iupMOT_SETARG(args, num_args, XmNuserData, itemData); + iupMOT_SETARG(args, num_args, XmNforeground, fgcolor); + iupMOT_SETARG(args, num_args, XmNbackground, bgcolor); + iupMOT_SETARG(args, num_args, XmNmarginHeight, ih->data->spacing); + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNviewType, XmSMALL_ICON); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNlabelString, itemTitle);  if (kind == ITREE_BRANCH) { if (ih->data->add_expanded) { - iupmotSetArg(args, num_args, XmNsmallIconPixmap, ih->data->def_image_expanded); - iupmotSetArg(args, num_args, XmNsmallIconMask, ih->data->def_image_expanded_mask); + iupMOT_SETARG(args, num_args, XmNsmallIconPixmap, ih->data->def_image_expanded); + iupMOT_SETARG(args, num_args, XmNsmallIconMask, ih->data->def_image_expanded_mask); } else { - iupmotSetArg(args, num_args, XmNsmallIconPixmap, ih->data->def_image_collapsed); - iupmotSetArg(args, num_args, XmNsmallIconMask, ih->data->def_image_collapsed_mask); + iupMOT_SETARG(args, num_args, XmNsmallIconPixmap, ih->data->def_image_collapsed); + iupMOT_SETARG(args, num_args, XmNsmallIconMask, ih->data->def_image_collapsed_mask); } } else { - iupmotSetArg(args, num_args, XmNsmallIconPixmap, ih->data->def_image_leaf); - iupmotSetArg(args, num_args, XmNsmallIconMask, ih->data->def_image_leaf_mask); + iupMOT_SETARG(args, num_args, XmNsmallIconPixmap, ih->data->def_image_leaf); + iupMOT_SETARG(args, num_args, XmNsmallIconMask, ih->data->def_image_leaf_mask); }  + /* Add the new node */ + wItemNew = XtCreateManagedWidget("icon", xmIconGadgetClass, ih->handle, args, num_args); + if (wItemPrev) + iupTreeAddToCache(ih, add, kindPrev, wItemPrev, wItemNew); + else + { + iupTreeAddToCache(ih, 0, 0, NULL, wItemNew); + + if (ih->data->node_count == 1) + { + /* MarkStart node */ + iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)wItemNew);  - wNewItem = XtCreateManagedWidget("icon", xmIconGadgetClass, ih->handle, args, num_args); + /* Set the default VALUE */ + motTreeSetFocusNode(ih, wItemNew); + } + }  if (kind == ITREE_BRANCH) { + iupAttribSetStr(ih, "_IUP_IGNORE_BRANCH_CB", "1"); if (ih->data->add_expanded) - { - iupAttribSetStr(ih, "_IUP_IGNORE_BRANCHOPEN", "1"); - XtVaSetValues(wNewItem, XmNoutlineState, XmEXPANDED, NULL); - } + XtVaSetValues(wItemNew, XmNoutlineState, XmEXPANDED, NULL); else - XtVaSetValues(wNewItem, XmNoutlineState, XmCOLLAPSED, NULL); + XtVaSetValues(wItemNew, XmNoutlineState, XmCOLLAPSED, NULL); + iupAttribSetStr(ih, "_IUP_IGNORE_BRANCH_CB", NULL); }  - /* Root always expanded */ - XtVaSetValues((Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"), XmNoutlineState, XmEXPANDED, NULL); - - XtRealizeWidget(wNewItem); + XtRealizeWidget(wItemNew); XmStringFree(itemTitle); }  -static void motTreeAddRootNode(Ihandle* ih) -{ - Widget wRootItem; - motTreeItemData *itemData; - Pixel bgcolor, fgcolor; - int num_args = 0; - Arg args[30]; - - itemData = calloc(1, sizeof(motTreeItemData)); - itemData->image = XmUNSPECIFIED_PIXMAP; - itemData->image_expanded = XmUNSPECIFIED_PIXMAP; - itemData->image_mask = XmUNSPECIFIED_PIXMAP; - itemData->image_expanded_mask = XmUNSPECIFIED_PIXMAP; - itemData->kind = ITREE_BRANCH; - - /* Get default foreground color */ - XtVaGetValues(ih->handle, XmNforeground, &fgcolor, NULL); - XtVaGetValues(ih->handle, XmNbackground, &bgcolor, NULL); - - iupmotSetArg(args, num_args, XmNentryParent, NULL); - iupmotSetArg(args, num_args, XmNuserData, itemData); - iupmotSetArg(args, num_args, XmNforeground, fgcolor); - iupmotSetArg(args, num_args, XmNbackground, bgcolor); - iupmotSetArg(args, num_args, XmNoutlineState, XmEXPANDED); - iupmotSetArg(args, num_args, XmNmarginHeight, ih->data->spacing); - iupmotSetArg(args, num_args, XmNmarginWidth, 0); - iupmotSetArg(args, num_args, XmNviewType, XmSMALL_ICON); - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); - iupmotSetArg(args, num_args, XmNtraversalOn, True); - iupmotSetArg(args, num_args, XmNshadowThickness, 0); - iupmotSetArg(args, num_args, XmNsmallIconPixmap, ih->data->def_image_expanded); - iupmotSetArg(args, num_args, XmNsmallIconMask, ih->data->def_image_expanded_mask); - - wRootItem = XtCreateManagedWidget("icon", xmIconGadgetClass, ih->handle, args, num_args); - - /* Select the new item */ - XtVaSetValues(wRootItem, XmNvisualEmphasis, XmSELECTED, NULL); - - XtRealizeWidget(wRootItem); - - /* Save the root node for later use */ - iupAttribSetStr(ih, "_IUPTREE_ROOTITEM", (char*)wRootItem); - - /* MarkStart node */ - iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)wRootItem); - - /* Set the default VALUE */ - /* In Motif this will set also the current focus */ - motTreeSetFocusNode(ih, wRootItem); -} - /*****************************************************************************/  static int motTreeSetImageExpandedAttrib(Ihandle* ih, const char* name_id, const char* value) { motTreeItemData *itemData; unsigned char itemState; - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem) return 0;  @@ -1003,7 +786,7 @@ static int motTreeSetImageExpandedAttrib(Ihandle* ih, const char* name_id, const static int motTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* value) { motTreeItemData *itemData; - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return 0;  @@ -1053,7 +836,6 @@ static int motTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v  static int motTreeSetImageBranchExpandedAttrib(Ihandle* ih, const char* value) { - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); ih->data->def_image_expanded = iupImageGetImage(value, ih, 0); if (!ih->data->def_image_expanded)  { @@ -1067,14 +849,13 @@ static int motTreeSetImageBranchExpandedAttrib(Ihandle* ih, const char* value) }  /* Update all images, starting at root node */ - motTreeUpdateImages(ih, &wRoot, 1, ITREE_UPDATEIMAGE_EXPANDED); + motTreeUpdateImages(ih, ITREE_UPDATEIMAGE_EXPANDED);  return 1; }  static int motTreeSetImageBranchCollapsedAttrib(Ihandle* ih, const char* value) { - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); ih->data->def_image_collapsed = iupImageGetImage(value, ih, 0); if (!ih->data->def_image_collapsed)  { @@ -1088,14 +869,13 @@ static int motTreeSetImageBranchCollapsedAttrib(Ihandle* ih, const char* value) }  /* Update all images, starting at root node */ - motTreeUpdateImages(ih, &wRoot, 1, ITREE_UPDATEIMAGE_COLLAPSED); + motTreeUpdateImages(ih, ITREE_UPDATEIMAGE_COLLAPSED);  return 1; }  static int motTreeSetImageLeafAttrib(Ihandle* ih, const char* value) { - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); ih->data->def_image_leaf = iupImageGetImage(value, ih, 0); if (!ih->data->def_image_leaf)  { @@ -1109,7 +889,7 @@ static int motTreeSetImageLeafAttrib(Ihandle* ih, const char* value) }  /* Update all images, starting at root node */ - motTreeUpdateImages(ih, &wRoot, 1, ITREE_UPDATEIMAGE_LEAF); + motTreeUpdateImages(ih, ITREE_UPDATEIMAGE_LEAF);  return 1; } @@ -1118,7 +898,7 @@ static char* motTreeGetStateAttrib(Ihandle* ih, const char* name_id) { int hasChildren; unsigned char itemState; - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return 0;  @@ -1138,14 +918,21 @@ static char* motTreeGetStateAttrib(Ihandle* ih, const char* name_id)  static int motTreeSetStateAttrib(Ihandle* ih, const char* name_id, const char* value) { - Widget wItem = motTreeFindNodeFromString(ih, name_id); - if (!wItem)  + motTreeItemData *itemData; + Widget wItem = iupTreeGetNodeFromString(ih, name_id); + if (!wItem) return 0;  - if (iupStrEqualNoCase(value, "EXPANDED")) - XtVaSetValues(wItem, XmNoutlineState, XmEXPANDED, NULL); - else  - XtVaSetValues(wItem, XmNoutlineState, XmCOLLAPSED, NULL); + XtVaGetValues(wItem, XmNuserData, &itemData, NULL); + if (itemData->kind == ITREE_BRANCH) + { + iupAttribSetStr(ih, "_IUP_IGNORE_BRANCH_CB", "1"); + if (iupStrEqualNoCase(value, "EXPANDED")) + XtVaSetValues(wItem, XmNoutlineState, XmEXPANDED, NULL); + else  + XtVaSetValues(wItem, XmNoutlineState, XmCOLLAPSED, NULL); + iupAttribSetStr(ih, "_IUP_IGNORE_BRANCH_CB", NULL); + }  return 0; } @@ -1155,7 +942,7 @@ static char* motTreeGetColorAttrib(Ihandle* ih, const char* name_id) unsigned char r, g, b; Pixel color; char* str; - Widget wItem = motTreeFindNodeFromString(ih, name_id);  + Widget wItem = iupTreeGetNodeFromString(ih, name_id);  if (!wItem)  return NULL;  @@ -1170,7 +957,7 @@ static char* motTreeGetColorAttrib(Ihandle* ih, const char* name_id) static int motTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* value) { Pixel color; - Widget wItem = motTreeFindNodeFromString(ih, name_id);  + Widget wItem = iupTreeGetNodeFromString(ih, name_id);  if (!wItem)  return 0;  @@ -1182,36 +969,33 @@ static int motTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* v  static char* motTreeGetDepthAttrib(Ihandle* ih, const char* name_id) { - Widget wRoot; - int dep = 0; - char* depth; - Widget wItem = motTreeFindNodeFromString(ih, name_id);  + int depth = -1; + char* str; + Widget wItem = iupTreeGetNodeFromString(ih, name_id);  if (!wItem)  return NULL;  - wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - - while((wRoot != wItem) && (wItem != NULL)) + while(wItem != NULL) { XtVaGetValues(wItem, XmNentryParent, &wItem, NULL); - dep++; + depth++; }  - depth = iupStrGetMemory(10); - sprintf(depth, "%d", dep); - return depth; + str = iupStrGetMemory(10); + sprintf(str, "%d", depth); + return str; }  static int motTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char* value) { Widget wItemDst, wParent, wItemSrc;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; - wItemSrc = motTreeFindNodeFromString(ih, name_id); + wItemSrc = iupTreeGetNodeFromString(ih, name_id); if (!wItemSrc) return 0; - wItemDst = motTreeFindNodeFromString(ih, value); + wItemDst = iupTreeGetNodeFromString(ih, value); if (!wItemDst) return 0;  @@ -1224,11 +1008,8 @@ static int motTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char return 0; }  - /* Copying the node and its children to the new position */ - motTreeCopyNode(ih, wItemSrc, wItemDst, 0); /* not a full copy, preserve user data */ - - /* Deleting the node (and its children) inserted into the old position */ - motTreeRemoveNode(ih, wItemSrc, 0); /* do not delete the user data, we copy the references in CopyNode */ + /* Move the node and its children to the new position */ + motTreeCopyMoveNode(ih, wItemSrc, wItemDst, 0);  return 0; } @@ -1237,12 +1018,12 @@ static int motTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char { Widget wItemDst, wParent, wItemSrc;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; - wItemSrc = motTreeFindNodeFromString(ih, name_id); + wItemSrc = iupTreeGetNodeFromString(ih, name_id); if (!wItemSrc) return 0; - wItemDst = motTreeFindNodeFromString(ih, value); + wItemDst = iupTreeGetNodeFromString(ih, value); if (!wItemDst) return 0;  @@ -1255,8 +1036,8 @@ static int motTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char return 0; }  - /* Copying the node and its children to the new position */ - motTreeCopyNode(ih, wItemSrc, wItemDst, 1); + /* Copy the node and its children to the new position */ + motTreeCopyMoveNode(ih, wItemSrc, wItemDst, 1);  return 0; } @@ -1265,7 +1046,7 @@ static char* motTreeGetParentAttrib(Ihandle* ih, const char* name_id) { Widget wItemParent; char* str; - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return NULL;  @@ -1275,7 +1056,7 @@ static char* motTreeGetParentAttrib(Ihandle* ih, const char* name_id) return NULL;  str = iupStrGetMemory(10); - sprintf(str, "%d", motTreeGetNodeId(ih, wItemParent)); + sprintf(str, "%d", iupTreeFindNodeId(ih, wItemParent)); return str; }  @@ -1283,7 +1064,7 @@ static char* motTreeGetChildCountAttrib(Ihandle* ih, const char* name_id) { char* str; WidgetList wList = NULL; - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return NULL;  @@ -1293,30 +1074,10 @@ static char* motTreeGetChildCountAttrib(Ihandle* ih, const char* name_id) return str; }  -static int motTreeCount(Ihandle* ih, Widget wItem) -{ - WidgetList wList = NULL; - int i, count = 0; - int childCount = XmContainerGetItemChildren(ih->handle, wItem, &wList); - count++; - for (i=0; idata->node_count) + return "0"; /* default VALUE is root */ + else + return "-1"; + }  str = iupStrGetMemory(10); - sprintf(str, "%d", motTreeGetNodeId(ih, wItem)); + sprintf(str, "%d", iupTreeFindNodeId(ih, wItem)); + return str; +} + +static char* motTreeGetMarkedNodesAttrib(Ihandle* ih) +{ + char* str; + int i; + + if (ih->data->mark_mode==ITREE_MARK_SINGLE) + return NULL; + + str = iupStrGetMemory(ih->data->node_count+1); + + for (i=0; idata->node_count; i++) + { + if (motTreeIsNodeSelected(ih->data->node_cache[i].node_handle)) + str[i] = '+'; + else + str[i] = '-'; + } + + str[ih->data->node_count] = 0; return str; }  +static int motTreeSetMarkedNodesAttrib(Ihandle* ih, const char* value) +{ + int count, i; + + if (ih->data->mark_mode==ITREE_MARK_SINGLE || !value) + return 0; + + count = strlen(value); + if (count > ih->data->node_count) + count = ih->data->node_count; + + for (i=0; idata->node_cache[i].node_handle, XmNvisualEmphasis, XmSELECTED, NULL); + else + XtVaSetValues(ih->data->node_cache[i].node_handle, XmNvisualEmphasis, XmNOT_SELECTED, NULL); + } + + return 0; +} + static int motTreeSetMarkAttrib(Ihandle* ih, const char* value) { if (ih->data->mark_mode==ITREE_MARK_SINGLE) @@ -1353,21 +1163,16 @@ static int motTreeSetMarkAttrib(Ihandle* ih, const char* value) motTreeInvertAllNodeMarking(ih); else if(iupStrEqualPartial(value, "INVERT")) { - unsigned char isSelected; - Widget wItem = motTreeFindNodeFromString(ih, &value[strlen("INVERT")]); + Widget wItem = iupTreeGetNodeFromString(ih, &value[strlen("INVERT")]); if (!wItem)  return 0;  - XtVaGetValues(wItem, XmNvisualEmphasis, &isSelected, NULL); - if (isSelected == XmSELECTED) - XtVaSetValues(wItem, XmNvisualEmphasis, XmNOT_SELECTED, NULL); - else - XtVaSetValues(wItem, XmNvisualEmphasis, XmSELECTED, NULL); + motTreeSelectNode(wItem, -1); } else if(iupStrEqualNoCase(value, "BLOCK")) { Widget wItem = (Widget)iupAttribGet(ih, "_IUPTREE_MARKSTART_NODE"); - Widget wFocusItem = motTreeGetFocusNode(ih); + Widget wFocusItem = iupdrvTreeGetFocusNode(ih); if(!wFocusItem || !wItem) return 0; motTreeSelectRange(ih, wFocusItem, wItem, 0); @@ -1379,10 +1184,10 @@ static int motTreeSetMarkAttrib(Ihandle* ih, const char* value) if (iupStrToStrStr(value, str1, str2, '-')!=2) return 0;  - wItem1 = motTreeFindNodeFromString(ih, str1); + wItem1 = iupTreeGetNodeFromString(ih, str1); if (!wItem1)  return 0; - wItem2 = motTreeFindNodeFromString(ih, str2); + wItem2 = iupTreeGetNodeFromString(ih, str2); if (!wItem2)  return 0;  @@ -1394,69 +1199,49 @@ static int motTreeSetMarkAttrib(Ihandle* ih, const char* value)  static int motTreeSetValueAttrib(Ihandle* ih, const char* value) { - Widget wRoot, wItem; + Widget wItem, wItemParent;  if (motTreeSetMarkAttrib(ih, value)) return 0;  - wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - - if (iupStrEqualNoCase(value, "ROOT")) - wItem = wRoot; + if (iupStrEqualNoCase(value, "ROOT") || iupStrEqualNoCase(value, "FIRST")) + wItem = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); else if(iupStrEqualNoCase(value, "LAST")) - wItem = motTreeGetLastVisibleNode(ih, wRoot); + wItem = motTreeGetLastVisibleNode(ih); else if(iupStrEqualNoCase(value, "PGUP")) { - Widget wItemFocus = motTreeGetFocusNode(ih); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); if(!wItemFocus) return 0;  - ih->data->id_control = -1; - motTreeFindVisibleNodeId(ih, &wRoot, 1, wItemFocus); - ih->data->id_control -= 10; /* less 10 visible nodes */ - - if(ih->data->id_control < 0) - ih->data->id_control = 0; /* Begin of tree = Root id */ - - wItem = motTreeFindVisibleNodeFromId(ih, &wRoot, 1); + wItem = motTreeGetPreviousVisibleNode(ih, wItemFocus, 10); } else if(iupStrEqualNoCase(value, "PGDN")) { - Widget wNext, wItemFocus; - - wItemFocus = motTreeGetFocusNode(ih); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); if(!wItemFocus) return 0;  - ih->data->id_control = -1; - motTreeFindVisibleNodeId(ih, &wRoot, 1, wItemFocus); - ih->data->id_control += 10; /* more 10 visible nodes */ - - wNext = motTreeFindVisibleNodeFromId(ih, &wRoot, 1); - - if (ih->data->id_control >= 0) - wNext = motTreeGetLastVisibleNode(ih, wRoot); -  - wItem = wNext; + wItem = motTreeGetNextVisibleNode(ih, wItemFocus, 10); } else if(iupStrEqualNoCase(value, "NEXT")) { - Widget wItemFocus = motTreeGetFocusNode(ih); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); if (!wItemFocus) return 0;  - wItem = motTreeGetNextVisibleNode(ih, wRoot, wItemFocus); + wItem = motTreeGetNextVisibleNode(ih, wItemFocus, 1); } else if(iupStrEqualNoCase(value, "PREVIOUS")) { - Widget wItemFocus = motTreeGetFocusNode(ih); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); if(!wItemFocus) return 0;  - wItem = motTreeGetPreviousVisibleNode(ih, wRoot, wItemFocus); + wItem = motTreeGetPreviousVisibleNode(ih, wItemFocus, 1); } else - wItem = motTreeFindNodeFromString(ih, value); + wItem = iupTreeGetNodeFromString(ih, value);  if (!wItem)  return 0; @@ -1471,17 +1256,26 @@ static int motTreeSetValueAttrib(Ihandle* ih, const char* value) XtVaSetValues(wItem, XmNvisualEmphasis, XmSELECTED, NULL); }  + + /* expand all parents */ + XtVaGetValues(wItem, XmNentryParent, &wItemParent, NULL); + while(wItemParent) + { + XtVaSetValues(wItemParent, XmNoutlineState, XmEXPANDED, NULL); + XtVaGetValues(wItemParent, XmNentryParent, &wItemParent, NULL); + } + /* set focus (will scroll to visible) */ motTreeSetFocusNode(ih, wItem);  - iupAttribSetInt(ih, "_IUPTREE_OLDVALUE", motTreeGetNodeId(ih, wItem)); + iupAttribSetInt(ih, "_IUPTREE_OLDVALUE", iupTreeFindNodeId(ih, wItem));  return 0; }   static int motTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id) { - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return 0;  @@ -1492,14 +1286,11 @@ static int motTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id)  static char* motTreeGetMarkedAttrib(Ihandle* ih, const char* name_id) { - unsigned char isSelected; - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return NULL;  - XtVaGetValues(wItem, XmNvisualEmphasis, &isSelected, NULL); - - if(isSelected == XmSELECTED) + if (motTreeIsNodeSelected(wItem)) return "YES"; else return "NO"; @@ -1507,7 +1298,7 @@ static char* motTreeGetMarkedAttrib(Ihandle* ih, const char* name_id)  static int motTreeSetMarkedAttrib(Ihandle* ih, const char* name_id, const char* value) { - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return 0;  @@ -1531,7 +1322,7 @@ static char* motTreeGetTitle(Widget wItem)  static char* motTreeGetTitleAttrib(Ihandle* ih, const char* name_id) { - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return NULL; return motTreeGetTitle(wItem); @@ -1539,10 +1330,13 @@ static char* motTreeGetTitleAttrib(Ihandle* ih, const char* name_id)  static int motTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* value) { - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return 0;  + if (!value) + value = ""; + iupmotSetString(wItem, XmNlabelString, value);  return 0; @@ -1551,7 +1345,7 @@ static int motTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* v static int motTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const char* value) { XmFontList fontlist = NULL; - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return 0;  @@ -1569,7 +1363,7 @@ static int motTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const cha static char* motTreeGetTitleFontAttrib(Ihandle* ih, const char* name_id) { XmFontList fontlist; - Widget wItem = motTreeFindNodeFromString(ih, name_id); + Widget wItem = iupTreeGetNodeFromString(ih, name_id); if (!wItem)  return NULL;  @@ -1577,118 +1371,81 @@ static char* motTreeGetTitleFontAttrib(Ihandle* ih, const char* name_id) return iupmotFindFontList(fontlist); }  -static char* motTreeGetFindUserDataAttrib(Ihandle* ih, const char* name_id) -{ - int id; - char* str = (char*)(name_id+1); /* skip ':' */ - void* userdata = NULL; - if (sscanf(str, "%p", &userdata)!=1) - return NULL; - id = motTreeGetUserDataId(ih, userdata); - if (id == -1) - return NULL; - str = iupStrGetMemory(16); - sprintf(str, "%d", id); - return str; -} - -static char* motTreeGetUserDataAttrib(Ihandle* ih, const char* name_id) -{ - motTreeItemData *itemData; - Widget wItem = motTreeFindNodeFromString(ih, name_id); - if (!wItem)  - return NULL; - - XtVaGetValues(wItem, XmNuserData, &itemData, NULL); - - return itemData->userdata; -} - -static int motTreeSetUserDataAttrib(Ihandle* ih, const char* name_id, const char* value) -{ - motTreeItemData *itemData; - Widget wItem = motTreeFindNodeFromString(ih, name_id); - if (!wItem)  - return 0; - - XtVaGetValues(wItem, XmNuserData, &itemData, NULL); - itemData->userdata = (void*)value; - - return 0; -} - static int motTreeSetRenameAttrib(Ihandle* ih, const char* value) {  if (ih->data->show_rename) { - IFni cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB"); - Widget wItemFocus = motTreeGetFocusNode(ih); - if (cbShowRename) - cbShowRename(ih, motTreeGetNodeId(ih, wItemFocus)); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); motTreeShowEditField(ih, wItemFocus); } - else - { - IFnis cbRenameNode = (IFnis)IupGetCallback(ih, "RENAMENODE_CB"); - if (cbRenameNode) - { - Widget wItemFocus = motTreeGetFocusNode(ih); - cbRenameNode(ih, motTreeGetNodeId(ih, wItemFocus), motTreeGetTitle(wItemFocus));  - } - }  (void)value; return 0; }  +static void motTreeRemoveAllNodes(Ihandle* ih, int call_cb) +{ + IFns cb = call_cb? (IFns)IupGetCallback(ih, "NODEREMOVED_CB"): NULL; + int i, old_count = ih->data->node_count; + Widget wItem; + + for (i = 0; i < ih->data->node_count; i++) + { + wItem = ih->data->node_cache[i].node_handle; + + motTreeDestroyItemData(ih, wItem, 1, cb, i); + + XtDestroyWidget(wItem); /* must manually destroy each node, this is NOT recursive */ + } + + ih->data->node_count = 0; + + if (call_cb) + iupTreeDelFromCache(ih, 0, old_count); +} + static int motTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; - if(iupStrEqualNoCase(value, "SELECTED")) /* selected here means the specified one */ + if (iupStrEqualNoCase(value, "ALL")) { - Widget wItem = motTreeFindNodeFromString(ih, name_id); - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - - /* the root node can't be deleted */ - if(!wItem || wItem == wRoot) /* root is the unique child */ + motTreeRemoveAllNodes(ih, 1); + return 0; + } + if(iupStrEqualNoCase(value, "SELECTED")) /* selected here means the reference node */ + { + Widget wItem = iupTreeGetNodeFromString(ih, name_id); + if(!wItem) return 0;  - /* deleting the specified node (and it's children) */ - motTreeRemoveNode(ih, wItem, 1); + /* deleting the reference node (and it's children) */ + motTreeRemoveNode(ih, wItem, 1, 1); } - else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the specified one */ + else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the reference node */ { - Widget wItem = motTreeFindNodeFromString(ih, name_id); + int numChild, i; + WidgetList wItemList = NULL; + Widget wItem = iupTreeGetNodeFromString(ih, name_id);  if(!wItem) return 0;  - { - /* deleting the selected node's children only */ - WidgetList wItemList = NULL; - int numChild = XmContainerGetItemChildren(ih->handle, wItem, &wItemList); - if(numChild) - motTreeRemoveChildren(ih, wItemList, numChild, 1); - if (wItemList) XtFree((char*)wItemList); - } + /* deleting the reference node children only */ + numChild = XmContainerGetItemChildren(ih->handle, wItem, &wItemList); + for(i = 0; i < numChild; i++) + motTreeRemoveNode(ih, wItemList[i], 1, 1); + if (wItemList) XtFree((char*)wItemList); } else if(iupStrEqualNoCase(value, "MARKED")) /* Delete the array of marked nodes */ { - WidgetList wSelectedItemList = NULL; - Widget wRoot; - int countItems, i; - - XtVaGetValues(ih->handle, XmNselectedObjects, &wSelectedItemList, - XmNselectedObjectCount, &countItems, NULL); - - wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - - for(i = 0; i < countItems; i++) + int i; + for(i = 1; i < ih->data->node_count; /* increment only if not removed */) { - int ok = XmIsIconGadget(wSelectedItemList[i]); - if ((wSelectedItemList[i] != wRoot) && ok) /* the root node can't be deleted */ - motTreeRemoveNode(ih, wSelectedItemList[i], 1); + if (motTreeIsNodeSelected(ih->data->node_cache[i].node_handle)) + motTreeRemoveNode(ih, ih->data->node_cache[i].node_handle, 1, 1); + else + i++; } }  @@ -1714,7 +1471,7 @@ static int motTreeSetIndentationAttrib(Ihandle* ih, const char* value)  static int motTreeSetTopItemAttrib(Ihandle* ih, const char* value) { - Widget wItem = motTreeFindNodeFromString(ih, value); + Widget wItem = iupTreeGetNodeFromString(ih, value); Widget sb_win; Widget wItemParent;  @@ -1735,10 +1492,11 @@ static int motTreeSetTopItemAttrib(Ihandle* ih, const char* value) return 0; }  -static int motTreeSpacingFunc(Ihandle* ih, Widget wItem, void *data) +static int motTreeSpacingFunc(Ihandle* ih, Widget wItem, int id, void *data) { XtVaSetValues(wItem, XmNmarginHeight, ih->data->spacing, NULL); (void)data; + (void)id; return 1; }  @@ -1752,7 +1510,7 @@ static int motTreeSetSpacingAttrib(Ihandle* ih, const char* value)  if (ih->handle) { - motTreeForEach(ih, NULL, (motTreeNodeFunc)motTreeSpacingFunc, 0); + iupTreeForEach(ih, (iupTreeNodeFunc)motTreeSpacingFunc, 0); return 0; } else @@ -1761,17 +1519,10 @@ static int motTreeSetSpacingAttrib(Ihandle* ih, const char* value)  static int motTreeSetExpandAllAttrib(Ihandle* ih, const char* value) { - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); - if (iupStrBoolean(value)) - motTreeExpandCollapseAllNodes(ih, &wRoot, 1, XmEXPANDED); + motTreeExpandCollapseAllNodes(ih, XmEXPANDED); else - { - motTreeExpandCollapseAllNodes(ih, &wRoot, 1, XmCOLLAPSED); - - /* The root node is always expanded */ - XtVaSetValues((Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"), XmNoutlineState, XmEXPANDED, NULL); - } + motTreeExpandCollapseAllNodes(ih, XmCOLLAPSED);  return 0; } @@ -1801,16 +1552,13 @@ static int motTreeSetBgColorAttrib(Ihandle* ih, const char* value) color = iupmotColorGetPixelStr(value); if (color != (Pixel)-1) { - Widget wRoot; Widget clipwin = NULL;  XtVaGetValues(sb_win, XmNclipWindow, &clipwin, NULL); if (clipwin) iupmotSetBgColor(clipwin, color);  - wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); -  /* Update all children, starting at root node */ - motTreeUpdateBgColor(ih, &wRoot, 1, color); + motTreeUpdateBgColor(ih, color); }  iupdrvBaseSetBgColorAttrib(ih, value); /* use given value for contents */ @@ -1871,10 +1619,14 @@ static void motTreeSetRenameSelectionPos(Widget cbEdit, const char* value)  static int motTreeCallBranchCloseCb(Ihandle* ih, Widget wItem) { - IFni cbBranchClose = (IFni)IupGetCallback(ih, "BRANCHCLOSE_CB"); + IFni cbBranchClose; + + if (iupAttribGet(ih, "_IUP_IGNORE_BRANCH_CB")) + return IUP_DEFAULT;  - if(cbBranchClose) - return cbBranchClose(ih, motTreeGetNodeId(ih, wItem)); + cbBranchClose = (IFni)IupGetCallback(ih, "BRANCHCLOSE_CB"); + if (cbBranchClose) + return cbBranchClose(ih, iupTreeFindNodeId(ih, wItem));  return IUP_DEFAULT; } @@ -1883,59 +1635,136 @@ static int motTreeCallBranchOpenCb(Ihandle* ih, Widget wItem) { IFni cbBranchOpen;  - if (iupAttribGet(ih, "_IUP_IGNORE_BRANCHOPEN")) - { - iupAttribSetStr(ih, "_IUP_IGNORE_BRANCHOPEN", NULL); + if (iupAttribGet(ih, "_IUP_IGNORE_BRANCH_CB")) return IUP_DEFAULT; - }  cbBranchOpen = (IFni)IupGetCallback(ih, "BRANCHOPEN_CB"); if (cbBranchOpen) - return cbBranchOpen(ih, motTreeGetNodeId(ih, wItem)); + return cbBranchOpen(ih, iupTreeFindNodeId(ih, wItem));  return IUP_DEFAULT; }  +static void motTreeFindRange(Ihandle* ih, WidgetList wSelectedItemList, int countItems, int *id1, int *id2) +{ + int i = 0, id; + + *id1 = ih->data->node_count; + *id2 = -1; + + for(i = 0; i < countItems; i++) + { + int is_icon = XmIsIconGadget(wSelectedItemList[i]); /* this line generates a warning in some compilers */ + if (is_icon) + { + id = iupTreeFindNodeId(ih, wSelectedItemList[i]); + if (id < *id1) + *id1 = id; + if (id > *id2) + *id2 = id; + } + } + + /* interactive selection of several nodes will NOT select hidden nodes, + so make sure that they are selected. */ + for(i = *id1; i <= *id2; i++) + { + if (!motTreeIsNodeSelected(ih->data->node_cache[i].node_handle)) + XtVaSetValues(ih->data->node_cache[i].node_handle, XmNvisualEmphasis, XmSELECTED, NULL); + } + + /* if last selected item is a branch, then select its children */ + iupTreeSelectLastCollapsedBranch(ih, id2); +} + +static Iarray* motTreeGetSelectedArrayId(Ihandle* ih, WidgetList wSelectedItemList, int countItems) +{ + Iarray* selarray = iupArrayCreate(1, sizeof(int)); + int i; + + for(i = 0; i < countItems; i++) + { + int is_icon = XmIsIconGadget(wSelectedItemList[i]); /* this line generates a warning in some compilers */ + if (is_icon) + { + int* id_hitem = (int*)iupArrayInc(selarray); + int j = iupArrayCount(selarray); + id_hitem[j-1] = iupTreeFindNodeId(ih, wSelectedItemList[i]); + } + } + + return selarray; +} + +static void motTreeCallMultiUnSelectionCb(Ihandle* ih) +{ + IFnIi cbMulti = (IFnIi)IupGetCallback(ih, "MULTIUNSELECTION_CB"); + IFnii cbSelec = (IFnii)IupGetCallback(ih, "SELECTION_CB"); + if (cbSelec || cbMulti) + { + WidgetList wSelectedItemList = NULL; + int countItems = 0; + + XtVaGetValues(ih->handle, XmNselectedObjects, &wSelectedItemList, + XmNselectedObjectCount, &countItems, NULL); + if (countItems > 1) + { + Iarray* markedArray = motTreeGetSelectedArrayId(ih, wSelectedItemList, countItems); + int* id_hitem = (int*)iupArrayGetData(markedArray); + int i, count = iupArrayCount(markedArray); + + if (cbMulti) + cbMulti(ih, id_hitem, iupArrayCount(markedArray)); + else + { + for (i=0; ihandle, XmNselectedObjects, &wSelectedItemList, XmNselectedObjectCount, &countItems, NULL); if (countItems == 0) return;  - if (cbMulti || cbSelec) + /* Must be a continuous range of selection ids */ + motTreeFindRange(ih, wSelectedItemList, countItems, &id1, &id2); + countItems = id2-id1+1; + + if (cbMulti) { int* id_rowItem = malloc(sizeof(int) * countItems); - int i = 0;  for(i = 0; i < countItems; i++) - id_rowItem[i] = motTreeGetNodeId(ih, wSelectedItemList[i]); + id_rowItem[i] = id1+i;  - if (cbMulti) - cbMulti(ih, id_rowItem, countItems); - else - { - for (i=0; ihandle, (Position)x, (Position)y); if (wItem) - return motTreeGetNodeId(ih, wItem); + return iupTreeFindNodeId(ih, wItem); return -1; }  @@ -1965,7 +1794,7 @@ static void motTreeCallRenameCb(Ihandle* ih) cbRename = (IFnis)IupGetCallback(ih, "RENAME_CB"); if (cbRename) { - if (cbRename(ih, motTreeGetNodeId(ih, wItem), title) == IUP_IGNORE) + if (cbRename(ih, iupTreeFindNodeId(ih, wItem), title) == IUP_IGNORE) ignore = 1; }  @@ -1993,8 +1822,8 @@ static int motTreeCallDragDropCb(Ihandle* ih, Widget wItemDrag, Widget wItemDrop  if (cbDragDrop) { - int drag_id = motTreeGetNodeId(ih, wItemDrag); - int drop_id = motTreeGetNodeId(ih, wItemDrop); + int drag_id = iupTreeFindNodeId(ih, wItemDrag); + int drop_id = iupTreeFindNodeId(ih, wItemDrop); return cbDragDrop(ih, drag_id, drop_id, is_shift, *is_ctrl); }  @@ -2069,6 +1898,10 @@ static void motTreeShowEditField(Ihandle* ih, Widget wItem) XmFontList fontlist; Widget sb_win = (Widget)iupAttribGet(ih, "_IUP_EXTRAPARENT");  + IFni cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB"); + if (cbShowRename && cbShowRename(ih, iupTreeFindNodeId(ih, wItem))==IUP_IGNORE) + return; + XtVaGetValues(wItem, XmNx, &x,  XmNy, &y, XmNwidth, &w,  @@ -2083,16 +1916,16 @@ static void motTreeShowEditField(Ihandle* ih, Widget wItem) iupdrvImageGetInfo((void*)image, &w_img, NULL, NULL); w_img += 3; /* add some room for borders */  - iupmotSetArg(args, num_args, XmNx, x+w_img); /* x-position */ - iupmotSetArg(args, num_args, XmNy, y); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, w-w_img); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, h); /* default height to avoid 0 */ - iupmotSetArg(args, num_args, XmNmarginHeight, ih->data->spacing); /* default padding */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); - iupmotSetArg(args, num_args, XmNforeground, color); - iupmotSetArg(args, num_args, XmNrenderTable, fontlist); - iupmotSetArg(args, num_args, XmNvalue, iupmotConvertString(title)); - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNx, x+w_img); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, y); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, w-w_img); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, h); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmarginHeight, ih->data->spacing); /* default padding */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNforeground, color); + iupMOT_SETARG(args, num_args, XmNrenderTable, fontlist); + iupMOT_SETARG(args, num_args, XmNvalue, iupmotConvertString(title)); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True);  cbEdit = XtCreateManagedWidget( child_id, /* child identifier */ @@ -2134,8 +1967,6 @@ static void motTreeSelectionCallback(Widget w, Ihandle* ih, XmContainerSelectCal (void)w; (void)nptr;  -printf("SelectionCallback(%d)\n", nptr->selected_item_count); - if (ih->data->mark_mode == ITREE_MARK_MULTIPLE) { char key[5]; @@ -2149,11 +1980,13 @@ printf("SelectionCallback(%d)\n", nptr->selected_item_count); { if (IupGetCallback(ih, "MULTISELECTION_CB")) { + /* current selection same as the initial selection */ if (nptr->auto_selection_type==XmAUTO_NO_CHANGE) motTreeCallMultiSelectionCb(ih); } else { + /* current selection is caused by button drag */ if (nptr->auto_selection_type==XmAUTO_MOTION) motTreeCallMultiSelectionCb(ih); } @@ -2164,14 +1997,10 @@ printf("SelectionCallback(%d)\n", nptr->selected_item_count); cbSelec = (IFnii)IupGetCallback(ih, "SELECTION_CB"); if (cbSelec) { - Widget wItemFocus = motTreeGetFocusNode(ih); - int curpos = motTreeGetNodeId(ih, wItemFocus); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); + int curpos = iupTreeFindNodeId(ih, wItemFocus); if (is_ctrl)  - { - unsigned char isSelected; - XtVaGetValues(wItemFocus, XmNvisualEmphasis, &isSelected, NULL); - cbSelec(ih, curpos, isSelected == XmSELECTED? 1: 0); - } + cbSelec(ih, curpos, motTreeIsNodeSelected(wItemFocus)); else { int oldpos = iupAttribGetInt(ih, "_IUPTREE_OLDVALUE"); @@ -2218,7 +2047,7 @@ static void motTreeDefaultActionCallback(Widget w, Ihandle* ih, XmContainerSelec { IFni cbExecuteLeaf = (IFni)IupGetCallback(ih, "EXECUTELEAF_CB"); if (cbExecuteLeaf) - cbExecuteLeaf(ih, motTreeGetNodeId(ih, wItem)); + cbExecuteLeaf(ih, iupTreeFindNodeId(ih, wItem)); } }  @@ -2295,15 +2124,14 @@ static void motTreeKeyPressEvent(Widget w, Ihandle *ih, XKeyEvent *evt, Boolean iupmotHelpCallback(w, ih, NULL); else if ((motcode == XK_Down || motcode == XK_Up) && (evt->state & ControlMask)) { - Widget wRoot = (Widget)iupAttribGet(ih, "_IUPTREE_ROOTITEM"); Widget wItem; - Widget wItemFocus = motTreeGetFocusNode(ih); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih);  /* Ctrl+Arrows move only focus */ if (motcode == XK_Down) - wItem = motTreeGetNextVisibleNode(ih, wRoot, wItemFocus); + wItem = motTreeGetNextVisibleNode(ih, wItemFocus, 1); else - wItem = motTreeGetPreviousVisibleNode(ih, wRoot, wItemFocus); + wItem = motTreeGetPreviousVisibleNode(ih, wItemFocus, 1);  motTreeSetFocusNode(ih, wItem); *cont = False; @@ -2317,8 +2145,8 @@ static void motTreeKeyPressEvent(Widget w, Ihandle *ih, XKeyEvent *evt, Boolean  if (motcode == XK_Home) wItem = wRoot; - else - wItem = motTreeGetLastVisibleNode(ih, wRoot); + else /* motcode == XK_End */ + wItem = motTreeGetLastVisibleNode(ih);  /* Ctrl+Arrows move only focus */ if (!(evt->state & ControlMask)) @@ -2326,7 +2154,7 @@ static void motTreeKeyPressEvent(Widget w, Ihandle *ih, XKeyEvent *evt, Boolean /* Shift+Arrows select block */ if (evt->state & ShiftMask) { - Widget wItemFocus = motTreeGetFocusNode(ih); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); if (!wItemFocus) return; motTreeSelectRange(ih, wItemFocus, wItem, 1); @@ -2346,16 +2174,9 @@ static void motTreeKeyPressEvent(Widget w, Ihandle *ih, XKeyEvent *evt, Boolean } else if(motcode == XK_space && (evt->state & ControlMask)) { - Widget wItemFocus = motTreeGetFocusNode(ih); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); if (wItemFocus) - { - unsigned char isSelected; - XtVaGetValues(wItemFocus, XmNvisualEmphasis, &isSelected, NULL); - if (isSelected == XmSELECTED) - XtVaSetValues(wItemFocus, XmNvisualEmphasis, XmNOT_SELECTED, NULL); - else - XtVaSetValues(wItemFocus, XmNvisualEmphasis, XmSELECTED, NULL); - } + motTreeSelectNode(wItemFocus, -1); } }  @@ -2378,7 +2199,7 @@ static void motTreeButtonEvent(Widget w, Ihandle* ih, XButtonEvent* evt, Boolean  if (evt->button==Button1) { - Widget wItemFocus = motTreeGetFocusNode(ih); + Widget wItemFocus = iupdrvTreeGetFocusNode(ih); static Widget wLastItem = NULL; static Time last = 0; int clicktwice = 0, doubleclicktime = XtGetMultiClickTime(iupmot_display); @@ -2395,6 +2216,11 @@ static void motTreeButtonEvent(Widget w, Ihandle* ih, XButtonEvent* evt, Boolean *cont = False; } wLastItem = wItemFocus; + + if (ih->data->mark_mode==ITREE_MARK_MULTIPLE &&  + !(evt->state & ShiftMask) && + !(evt->state & ControlMask)) + motTreeCallMultiUnSelectionCb(ih); } else if (evt->button==Button3) motTreeCallRightClickCb(ih, evt->x, evt->y); @@ -2436,21 +2262,18 @@ static void motTreeTransferProc(Widget drop_context, XtPointer client_data, Atom  if (motTreeCallDragDropCb(ih, wItemDrag, wItemDrop, &is_ctrl) == IUP_CONTINUE) { - /* Copy the dragged item to the new position. */ - Widget wNewItem = motTreeCopyNode(ih, wItemDrag, wItemDrop, is_ctrl); + /* Copy or move the dragged item to the new position. */ + Widget wItemNew = motTreeCopyMoveNode(ih, wItemDrag, wItemDrop, is_ctrl);  - if (!is_ctrl) + /* Set focus and selection */ + if (wItemNew) { - /* do not delete the user data, we copy the references in CopyNode */ - motTreeRemoveNode(ih, wItemDrag, 0); - } - - /* Select the dragged item */ - XtVaSetValues(ih->handle, XmNselectedObjects, NULL, NULL); - XtVaSetValues(ih->handle, XmNselectedObjectCount, 0, NULL); - XtVaSetValues(wNewItem, XmNvisualEmphasis, XmSELECTED, NULL); + XtVaSetValues(ih->handle, XmNselectedObjects, NULL, NULL); + XtVaSetValues(ih->handle, XmNselectedObjectCount, 0, NULL); + XtVaSetValues(wItemNew, XmNvisualEmphasis, XmSELECTED, NULL);  - motTreeSetFocusNode(ih, wNewItem); + motTreeSetFocusNode(ih, wItemNew); + } } }  @@ -2475,8 +2298,8 @@ static void motTreeDropProc(Widget w, XtPointer client_data, XmDropProcCallbackS drop_context = drop_data->dragContext;  /* retrieve the data targets */ - iupmotSetArg(args, num_args, XmNexportTargets, &exportTargets); - iupmotSetArg(args, num_args, XmNnumExportTargets, &numExportTargets); + iupMOT_SETARG(args, num_args, XmNexportTargets, &exportTargets); + iupMOT_SETARG(args, num_args, XmNnumExportTargets, &numExportTargets); XtGetValues(drop_context, args, num_args);  for (i = 0; i < (int)numExportTargets; i++)  @@ -2495,17 +2318,17 @@ static void motTreeDropProc(Widget w, XtPointer client_data, XmDropProcCallbackS num_args = 0; if ((!found) || (drop_data->dropAction != XmDROP) || (drop_data->operation != XmDROP_COPY && drop_data->operation != XmDROP_MOVE))  { - iupmotSetArg(args, num_args, XmNtransferStatus, XmTRANSFER_FAILURE); - iupmotSetArg(args, num_args, XmNnumDropTransfers, 0); + iupMOT_SETARG(args, num_args, XmNtransferStatus, XmTRANSFER_FAILURE); + iupMOT_SETARG(args, num_args, XmNnumDropTransfers, 0); } else  { /* set up transfer requests for drop site */ transferList[0].target = atomTreeItem; transferList[0].client_data = (XtPointer)wItemDrop; - iupmotSetArg(args, num_args, XmNdropTransfers, transferList); - iupmotSetArg(args, num_args, XmNnumDropTransfers, 1); - iupmotSetArg(args, num_args, XmNtransferProc, motTreeTransferProc); + iupMOT_SETARG(args, num_args, XmNdropTransfers, transferList); + iupMOT_SETARG(args, num_args, XmNnumDropTransfers, 1); + iupMOT_SETARG(args, num_args, XmNtransferProc, motTreeTransferProc); }  XmDropTransferStart(drop_context, args, num_args); @@ -2584,23 +2407,23 @@ static void motTreeStartDrag(Widget w, XButtonEvent* evt, String* params, Cardin XmNforeground, &fg, NULL);  - iupmotSetArg(args, num_args, XmNpixmap, pixmap); - iupmotSetArg(args, num_args, XmNmask, mask); + iupMOT_SETARG(args, num_args, XmNpixmap, pixmap); + iupMOT_SETARG(args, num_args, XmNmask, mask); drag_icon = XmCreateDragIcon(w, "drag_icon", args, num_args);  exportList[0] = atomTreeItem;  /* specify resources for DragContext for the transfer */ num_args = 0; - iupmotSetArg(args, num_args, XmNcursorBackground, bg); - iupmotSetArg(args, num_args, XmNcursorForeground, fg); - /* iupmotSetArg(args, num_args, XmNsourcePixmapIcon, drag_icon); works, but only outside the dialog, inside disapears */ - iupmotSetArg(args, num_args, XmNsourceCursorIcon, drag_icon); /* does not work, shows the default cursor */ - iupmotSetArg(args, num_args, XmNexportTargets, exportList); - iupmotSetArg(args, num_args, XmNnumExportTargets, 1); - iupmotSetArg(args, num_args, XmNdragOperations, XmDROP_MOVE|XmDROP_COPY); - iupmotSetArg(args, num_args, XmNconvertProc, motTreeConvertProc); - iupmotSetArg(args, num_args, XmNclientData, wItemDrag); + iupMOT_SETARG(args, num_args, XmNcursorBackground, bg); + iupMOT_SETARG(args, num_args, XmNcursorForeground, fg); + /* iupMOT_SETARG(args, num_args, XmNsourcePixmapIcon, drag_icon); works, but only outside the dialog, inside disapears */ + iupMOT_SETARG(args, num_args, XmNsourceCursorIcon, drag_icon); /* does not work, shows the default cursor */ + iupMOT_SETARG(args, num_args, XmNexportTargets, exportList); + iupMOT_SETARG(args, num_args, XmNnumExportTargets, 1); + iupMOT_SETARG(args, num_args, XmNdragOperations, XmDROP_MOVE|XmDROP_COPY); + iupMOT_SETARG(args, num_args, XmNconvertProc, motTreeConvertProc); + iupMOT_SETARG(args, num_args, XmNclientData, wItemDrag);  /* start the drag and register a callback to clean up when done */ drop_context = XmDragStart(w, (XEvent*)evt, args, num_args); @@ -2628,10 +2451,10 @@ static void motTreeEnableDragDrop(Widget w) XtOverrideTranslations(w, XtParseTranslationTable(dragTranslations));  importList[0] = atomTreeItem; - iupmotSetArg(args, num_args, XmNimportTargets, importList); - iupmotSetArg(args, num_args, XmNnumImportTargets, 1); - iupmotSetArg(args, num_args, XmNdropSiteOperations, XmDROP_MOVE|XmDROP_COPY); - iupmotSetArg(args, num_args, XmNdropProc, motTreeDropProc); + iupMOT_SETARG(args, num_args, XmNimportTargets, importList); + iupMOT_SETARG(args, num_args, XmNnumImportTargets, 1); + iupMOT_SETARG(args, num_args, XmNdropSiteOperations, XmDROP_MOVE|XmDROP_COPY); + iupMOT_SETARG(args, num_args, XmNdropProc, motTreeDropProc); XmDropSiteUpdate(w, args, num_args);  XtVaSetValues(XmGetXmDisplay(iupmot_display), XmNenableDragIcon, True, NULL); @@ -2648,13 +2471,13 @@ static int motTreeMapMethod(Ihandle* ih) /******************************/ /* Create the scrolled window */ /******************************/ - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNscrollingPolicy, XmAUTOMATIC); - iupmotSetArg(args, num_args, XmNvisualPolicy, XmVARIABLE);  - iupmotSetArg(args, num_args, XmNscrollBarDisplayPolicy, XmAS_NEEDED); - iupmotSetArg(args, num_args, XmNspacing, 0); /* no space between scrollbars and text */ - iupmotSetArg(args, num_args, XmNborderWidth, 0); - iupmotSetArg(args, num_args, XmNshadowThickness, 2); + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNscrollingPolicy, XmAUTOMATIC); + iupMOT_SETARG(args, num_args, XmNvisualPolicy, XmVARIABLE);  + iupMOT_SETARG(args, num_args, XmNscrollBarDisplayPolicy, XmAS_NEEDED); + iupMOT_SETARG(args, num_args, XmNspacing, 0); /* no space between scrollbars and text */ + iupMOT_SETARG(args, num_args, XmNborderWidth, 0); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 2);  sb_win = XtCreateManagedWidget( child_id, /* child identifier */ @@ -2672,37 +2495,37 @@ static int motTreeMapMethod(Ihandle* ih)  num_args = 0;  - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */  - iupmotSetArg(args, num_args, XmNmarginHeight, 0); /* default padding */ - iupmotSetArg(args, num_args, XmNmarginWidth, 0); + iupMOT_SETARG(args, num_args, XmNmarginHeight, 0); /* default padding */ + iupMOT_SETARG(args, num_args, XmNmarginWidth, 0);  if (iupAttribGetBoolean(ih, "CANFOCUS")) - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); else - iupmotSetArg(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False);  - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); - iupmotSetArg(args, num_args, XmNhighlightThickness, 2); - iupmotSetArg(args, num_args, XmNshadowThickness, 0); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 2); + iupMOT_SETARG(args, num_args, XmNshadowThickness, 0);  - iupmotSetArg(args, num_args, XmNlayoutType, XmOUTLINE); - iupmotSetArg(args, num_args, XmNentryViewType, XmSMALL_ICON); - iupmotSetArg(args, num_args, XmNselectionPolicy, XmSINGLE_SELECT); - iupmotSetArg(args, num_args, XmNoutlineIndentation, 20); + iupMOT_SETARG(args, num_args, XmNlayoutType, XmOUTLINE); + iupMOT_SETARG(args, num_args, XmNentryViewType, XmSMALL_ICON); + iupMOT_SETARG(args, num_args, XmNselectionPolicy, XmSINGLE_SELECT); + iupMOT_SETARG(args, num_args, XmNoutlineIndentation, 20);  if (iupAttribGetBoolean(ih, "HIDELINES")) - iupmotSetArg(args, num_args, XmNoutlineLineStyle, XmNO_LINE); + iupMOT_SETARG(args, num_args, XmNoutlineLineStyle, XmNO_LINE); else - iupmotSetArg(args, num_args, XmNoutlineLineStyle, XmSINGLE); + iupMOT_SETARG(args, num_args, XmNoutlineLineStyle, XmSINGLE);  if (iupAttribGetBoolean(ih, "HIDEBUTTONS")) - iupmotSetArg(args, num_args, XmNoutlineButtonPolicy, XmOUTLINE_BUTTON_ABSENT); + iupMOT_SETARG(args, num_args, XmNoutlineButtonPolicy, XmOUTLINE_BUTTON_ABSENT); else - iupmotSetArg(args, num_args, XmNoutlineButtonPolicy, XmOUTLINE_BUTTON_PRESENT); + iupMOT_SETARG(args, num_args, XmNoutlineButtonPolicy, XmOUTLINE_BUTTON_PRESENT);  ih->handle = XtCreateManagedWidget( child_id, /* child identifier */ @@ -2788,17 +2611,30 @@ static int motTreeMapMethod(Ihandle* ih) if (!ih->data->def_image_expanded_mask) ih->data->def_image_expanded_mask = (void*)XmUNSPECIFIED_PIXMAP; }  - motTreeAddRootNode(ih); + if (iupAttribGetInt(ih, "ADDROOT")) + iupdrvTreeAddNode(ih, "-1", ITREE_BRANCH, "", 0);  IupSetCallback(ih, "_IUP_XY2POS_CB", (Icallback)motTreeConvertXYToPos);  + iupdrvTreeUpdateMarkMode(ih); + return IUP_NOERROR; }  +static void motTreeUnMapMethod(Ihandle* ih) +{ + motTreeRemoveAllNodes(ih, 0); + + ih->data->node_count = 0; + + iupdrvBaseUnMapMethod(ih); +} + void iupdrvTreeInitClass(Iclass* ic) { /* Driver Dependent Class functions */ ic->Map = motTreeMapMethod; + ic->UnMap = motTreeUnMapMethod;  /* Visual */ iupClassRegisterAttribute(ic, "BGCOLOR", NULL, motTreeSetBgColorAttrib, "TXTBGCOLOR", NULL, IUPAF_DEFAULT); @@ -2807,7 +2643,6 @@ void iupdrvTreeInitClass(Iclass* ic) /* IupTree Attributes - GENERAL */ iupClassRegisterAttribute(ic, "EXPANDALL", NULL, motTreeSetExpandAllAttrib, NULL, NULL, IUPAF_WRITEONLY||IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "INDENTATION", motTreeGetIndentationAttrib, motTreeSetIndentationAttrib, NULL, NULL, IUPAF_DEFAULT); - iupClassRegisterAttribute(ic, "COUNT", motTreeGetCountAttrib, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_READONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SPACING", iupTreeGetSpacingAttrib, motTreeSetSpacingAttrib, NULL, NULL, IUPAF_NOT_MAPPED); iupClassRegisterAttribute(ic, "TOPITEM", NULL, motTreeSetTopItemAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);  @@ -2827,7 +2662,6 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttributeId(ic, "COLOR", motTreeGetColorAttrib, motTreeSetColorAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "NAME", motTreeGetTitleAttrib, motTreeSetTitleAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TITLE", motTreeGetTitleAttrib, motTreeSetTitleAttrib, IUPAF_NO_INHERIT); - iupClassRegisterAttributeId(ic, "USERDATA", motTreeGetUserDataAttrib, motTreeSetUserDataAttrib, IUPAF_NO_STRING|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "CHILDCOUNT", motTreeGetChildCountAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TITLEFONT", motTreeGetTitleFontAttrib, motTreeSetTitleFontAttrib, IUPAF_NO_INHERIT);  @@ -2836,6 +2670,7 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttribute (ic, "MARK", NULL, motTreeSetMarkAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute (ic, "STARTING", NULL, motTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); iupClassRegisterAttribute (ic, "MARKSTART", NULL, motTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + iupClassRegisterAttribute (ic, "MARKEDNODES", motTreeGetMarkedNodesAttrib, motTreeSetMarkedNodesAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);  iupClassRegisterAttribute (ic, "VALUE", motTreeGetValueAttrib, motTreeSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);  @@ -2844,5 +2679,4 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "RENAME", NULL, motTreeSetRenameAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "MOVENODE", NULL, motTreeSetMoveNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "COPYNODE", NULL, motTreeSetCopyNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); - iupClassRegisterAttributeId(ic, "FINDUSERDATA", motTreeGetFindUserDataAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); } diff --git a/iup/src/mot/iupmot_val.c b/iup/src/mot/iupmot_val.c index 200d2b4..ce9eba7 100755 --- a/iup/src/mot/iupmot_val.c +++ b/iup/src/mot/iupmot_val.c @@ -383,41 +383,41 @@ static int motValMapMethod(Ihandle* ih) int show_ticks;  /* Core */ - iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ - iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ - iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ - iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ - iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupMOT_SETARG(args, num_args, XmNx, 0); /* x-position */ + iupMOT_SETARG(args, num_args, XmNy, 0); /* y-position */ + iupMOT_SETARG(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupMOT_SETARG(args, num_args, XmNheight, 10); /* default height to avoid 0 */ /* Primitive */ if (iupAttribGetBoolean(ih, "CANFOCUS")) - iupmotSetArg(args, num_args, XmNtraversalOn, True); + iupMOT_SETARG(args, num_args, XmNtraversalOn, True); else - iupmotSetArg(args, num_args, XmNtraversalOn, False); - iupmotSetArg(args, num_args, XmNhighlightThickness, 2); - iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); + iupMOT_SETARG(args, num_args, XmNtraversalOn, False); + iupMOT_SETARG(args, num_args, XmNhighlightThickness, 2); + iupMOT_SETARG(args, num_args, XmNnavigationType, XmTAB_GROUP); /* Scale */ - iupmotSetArg(args, num_args, XmNminimum, 0); - iupmotSetArg(args, num_args, XmNmaximum, SHRT_MAX); - iupmotSetArg(args, num_args, XmNslidingMode, XmSLIDER); - iupmotSetArg(args, num_args, XmNsliderMark, XmETCHED_LINE); - iupmotSetArg(args, num_args, XmNsliderSize, 16); - iupmotSetArg(args, num_args, XmNshowValue, XmNONE); + iupMOT_SETARG(args, num_args, XmNminimum, 0); + iupMOT_SETARG(args, num_args, XmNmaximum, SHRT_MAX); + iupMOT_SETARG(args, num_args, XmNslidingMode, XmSLIDER); + iupMOT_SETARG(args, num_args, XmNsliderMark, XmETCHED_LINE); + iupMOT_SETARG(args, num_args, XmNsliderSize, 16); + iupMOT_SETARG(args, num_args, XmNshowValue, XmNONE);  if (ih->data->type == IVAL_HORIZONTAL) { - iupmotSetArg(args, num_args, XmNorientation, XmHORIZONTAL); + iupMOT_SETARG(args, num_args, XmNorientation, XmHORIZONTAL); if (ih->data->inverted) - iupmotSetArg(args, num_args, XmNprocessingDirection, XmMAX_ON_LEFT); + iupMOT_SETARG(args, num_args, XmNprocessingDirection, XmMAX_ON_LEFT); else - iupmotSetArg(args, num_args, XmNprocessingDirection, XmMAX_ON_RIGHT); + iupMOT_SETARG(args, num_args, XmNprocessingDirection, XmMAX_ON_RIGHT); } else { - iupmotSetArg(args, num_args, XmNorientation, XmVERTICAL); + iupMOT_SETARG(args, num_args, XmNorientation, XmVERTICAL); if (ih->data->inverted) - iupmotSetArg(args, num_args, XmNprocessingDirection, XmMAX_ON_TOP); + iupMOT_SETARG(args, num_args, XmNprocessingDirection, XmMAX_ON_TOP); else - iupmotSetArg(args, num_args, XmNprocessingDirection, XmMAX_ON_BOTTOM); + iupMOT_SETARG(args, num_args, XmNprocessingDirection, XmMAX_ON_BOTTOM); }  ih->handle = XtCreateManagedWidget( diff --git a/iup/src/mot/iupunix_info.c b/iup/src/mot/iupunix_info.c index b522638..f09573c 100755 --- a/iup/src/mot/iupunix_info.c +++ b/iup/src/mot/iupunix_info.c @@ -282,7 +282,7 @@ char *iupdrvGetSystemName(void) char *iupdrvGetSystemVersion(void) { struct utsname un; - char *str = iupStrGetMemory(60);  + char *str = iupStrGetMemory(100);   uname(&un); strcpy(str, un.release); diff --git a/iup/src/win/iupwin_button.c b/iup/src/win/iupwin_button.c index 7f780e3..3b05ba7 100755 --- a/iup/src/win/iupwin_button.c +++ b/iup/src/win/iupwin_button.c @@ -27,6 +27,7 @@ #include "iupwin_drv.h" #include "iupwin_handle.h" #include "iupwin_draw.h" +#include "iupwin_info.h"   #ifndef CDIS_SHOWKEYBOARDCUES @@ -308,18 +309,22 @@ static void winButtonDrawText(Ihandle* ih, HDC hDC, int rect_width, int rect_hei  static void winButtonDrawItem(Ihandle* ih, DRAWITEMSTRUCT *drawitem) {  + HDC hDC; iupwinBitmapDC bmpDC; int border, draw_border; int width = drawitem->rcItem.right - drawitem->rcItem.left; int height = drawitem->rcItem.bottom - drawitem->rcItem.top;  - HDC hDC = iupwinDrawCreateBitmapDC(&bmpDC, drawitem->hDC, width, height); + hDC = iupwinDrawCreateBitmapDC(&bmpDC, drawitem->hDC, width, height);  iupwinDrawParentBackground(ih, hDC, &drawitem->rcItem);  if ((drawitem->itemState & ODS_FOCUS) && !(drawitem->itemState & ODS_HOTLIGHT)) drawitem->itemState |= ODS_DEFAULT;  + if (iupAttribGet(ih, "_IUPWINBUT_SELECTED")) + drawitem->itemState |= ODS_SELECTED; + border = winButtonGetBorder();  if (ih->data->type & IUP_BUTTON_IMAGE && iupAttribGet(ih, "IMPRESS") && !iupAttribGetStr(ih, "IMPRESSBORDER")) @@ -365,7 +370,7 @@ static int winButtonSetImageAttrib(Ihandle* ih, const char* value) (void)value; if (ih->data->type != IUP_BUTTON_TEXT) { - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih); return 1; } else @@ -377,7 +382,7 @@ static int winButtonSetImInactiveAttrib(Ihandle* ih, const char* value) (void)value; if (ih->data->type != IUP_BUTTON_TEXT) { - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih); return 1; } else @@ -389,7 +394,7 @@ static int winButtonSetImPressAttrib(Ihandle* ih, const char* value) (void)value; if (ih->data->type != IUP_BUTTON_TEXT) { - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih); return 1; } else @@ -400,7 +405,7 @@ static int winButtonSetActiveAttrib(Ihandle* ih, const char* value) { /* redraw IMINACTIVE image if any */ if (ih->data->type != IUP_BUTTON_TEXT) - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih);  return iupBaseSetActiveAttrib(ih, value); } @@ -425,7 +430,7 @@ static int winButtonSetAlignmentAttrib(Ihandle* ih, const char* value) else /* "ACENTER" */ ih->data->vert_alignment = IUP_ALIGN_ACENTER;  - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih);  return 1; } @@ -443,7 +448,7 @@ static int winButtonSetPaddingAttrib(Ihandle* ih, const char* value) { iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x'); if (ih->handle) - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); return 0; }  @@ -454,7 +459,7 @@ static int winButtonSetBgColorAttrib(Ihandle* ih, const char* value) { iupAttribSetStr(ih, "BGCOLOR", value); iupImageUpdateParent(ih); - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); } return 1; } @@ -486,7 +491,9 @@ static int winButtonSetFgColorAttrib(Ihandle* ih, const char* value) if (iupStrToRGB(value, &r, &g, &b)) { ih->data->fgcolor = RGB(r,g,b); - iupdrvDisplayRedraw(ih); + + if (ih->handle) + iupdrvRedrawNow(ih); } return 1; } @@ -499,7 +506,7 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r { /* redraw IMPRESS image if any */ if ((msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) && iupAttribGet(ih, "IMPRESS")) - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); }  switch (msg) @@ -514,6 +521,13 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r case WM_RBUTTONDOWN: { iupwinButtonDown(ih, msg, wp, lp); + + /* Feedback will NOT be done when not receiving the focus */ + if (msg==WM_LBUTTONDOWN && !iupAttribGetBoolean(ih, "FOCUSONCLICK")) + { + iupAttribSetStr(ih, "_IUPWINBUT_SELECTED", "1"); + iupdrvRedrawNow(ih); + } break; } case WM_XBUTTONUP: @@ -526,11 +540,24 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r /* BN_CLICKED will NOT be notified when not receiving the focus */ if (msg==WM_LBUTTONUP && !iupAttribGetBoolean(ih, "FOCUSONCLICK")) { - Icallback cb = IupGetCallback(ih, "ACTION"); + Icallback cb; + + iupAttribSetStr(ih, "_IUPWINBUT_SELECTED", NULL); + iupdrvRedrawNow(ih); + + cb = IupGetCallback(ih, "ACTION"); if (cb && cb(ih) == IUP_CLOSE) IupExitLoop(); }  + if (!iupwinIsVistaOrNew()) + { + /* TIPs desapear forever after a button click in XP, + so we force an update. */ + char* tip = iupAttribGet(ih, "TIP"); + if (tip) + iupdrvBaseSetTipAttrib(ih, tip); + } break; } case WM_KEYDOWN: @@ -549,7 +576,12 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r if (!iupwin_comctl32ver6) { iupAttribSetStr(ih, "_IUPWINBUT_ENTERWIN", NULL); - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); + } + if (!iupAttribGetBoolean(ih, "FOCUSONCLICK")) + { + iupAttribSetStr(ih, "_IUPWINBUT_SELECTED", NULL); + iupdrvRedrawNow(ih); } break; case WM_MOUSEMOVE: @@ -558,7 +590,7 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r if (!iupAttribGet(ih, "_IUPWINBUT_ENTERWIN")) { iupAttribSetStr(ih, "_IUPWINBUT_ENTERWIN", "1"); - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); } } break; @@ -635,7 +667,7 @@ static int winButtonWmCommand(Ihandle* ih, WPARAM wp, LPARAM lp) static int winButtonMapMethod(Ihandle* ih) { char* value; - DWORD dwStyle = WS_CHILD |  + DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | BS_NOTIFY; /* necessary because of the base messages */  if (!ih->parent) @@ -661,7 +693,7 @@ static int winButtonMapMethod(Ihandle* ih) ih->data->type = IUP_BUTTON_IMAGE;  value = iupAttribGet(ih, "TITLE"); - if (value) + if (value && *value!=0) ih->data->type |= IUP_BUTTON_TEXT; } else diff --git a/iup/src/win/iupwin_canvas.c b/iup/src/win/iupwin_canvas.c index bb88b8a..b865160 100755 --- a/iup/src/win/iupwin_canvas.c +++ b/iup/src/win/iupwin_canvas.c @@ -45,7 +45,7 @@ static void winCanvasSetScrollInfo(HWND hWnd, int imin, int imax, int ipos, int static int winCanvasSetBgColorAttrib(Ihandle *ih, const char *value) { (void)value; - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih); return 1; }  @@ -220,7 +220,7 @@ static void winCanvasUpdateHorScroll(Ihandle* ih, WORD winop) xmax = iupAttribGetFloat(ih,"XMAX"); xmin = iupAttribGetFloat(ih,"XMIN");  - winCanvasGetScrollInfo(ih->handle, &iposx, &ipagex, SB_HORZ, winop==SB_THUMBTRACK? 1: 0); + winCanvasGetScrollInfo(ih->handle, &iposx, &ipagex, SB_HORZ, winop==SB_THUMBTRACK||winop==SB_THUMBPOSITION? 1: 0);  if (!iupAttribGet(ih,"LINEX")) { @@ -296,7 +296,7 @@ static void winCanvasUpdateVerScroll(Ihandle* ih, WORD winop) ymax = iupAttribGetFloat(ih,"YMAX"); ymin = iupAttribGetFloat(ih,"YMIN");  - winCanvasGetScrollInfo(ih->handle, &iposy, &ipagey, SB_VERT, winop==SB_THUMBTRACK? 1: 0); + winCanvasGetScrollInfo(ih->handle, &iposy, &ipagey, SB_VERT, winop==SB_THUMBTRACK||winop==SB_THUMBPOSITION? 1: 0);  if (!iupAttribGet(ih, "LINEY")) { @@ -372,6 +372,10 @@ static int winCanvasProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r GetClientRect(ih->handle, &rect);  FillRect(hdc, &rect, iupwinBrushGet(color));  } + else + InvalidateRect(ih->handle,NULL,FALSE); /* This will invalidate all area.  + Necessary in XP, or overlapping windows will have the effect of partial redrawing. */ + /* always return non zero value */ *result = 1; return 1;  @@ -382,7 +386,7 @@ static int winCanvasProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r { PAINTSTRUCT ps; HDC hdc = BeginPaint(ih->handle, &ps); - iupAttribSetStr(ih, "HDC_WMPAINT", (char*)&hdc); + iupAttribSetStr(ih, "HDC_WMPAINT", (char*)hdc); iupAttribSetStrf(ih, "CLIPRECT", "%d %d %d %d", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top);  cb(ih, ih->data->posx, ih->data->posy); @@ -542,27 +546,13 @@ static int winCanvasProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r return iupwinBaseProc(ih, msg, wp, lp, result); }  -static void winCanvasRegisterClass(void) -{ - WNDCLASS wndclass; - ZeroMemory(&wndclass, sizeof(WNDCLASS)); -  - wndclass.hInstance = iupwin_hinstance; - wndclass.lpszClassName = "IupCanvas"; - wndclass.lpfnWndProc = (WNDPROC)iupwinBaseWinProc; - wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; /* using CS_OWNDC will minimize the work of cdActivate in the CD library */ - wndclass.hbrBackground = NULL; /* remove the background to optimize redraw */ -  - RegisterClass(&wndclass); -} - static int winCanvasMapMethod(Ihandle* ih) { CLIENTCREATESTRUCT clientstruct; void *clientdata = NULL; char *classname; - DWORD dwStyle = WS_CHILD, dwExStyle = 0; + DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS,  + dwExStyle = 0;  if (!ih->parent) return IUP_ERROR; @@ -574,14 +564,7 @@ static int winCanvasMapMethod(Ihandle* ih) }  if (ih->firstchild) /* can be a container */ - { - dwStyle |= WS_CLIPSIBLINGS; - - if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED")) - dwExStyle |= WS_EX_COMPOSITED; - else - dwStyle |= WS_CLIPCHILDREN; - } + iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);  if (iupAttribGetBoolean(ih, "MDICLIENT"))  { @@ -693,6 +676,21 @@ static void winCanvasReleaseMethod(Iclass* ic) UnregisterClass("IupCanvas", iupwin_hinstance); }  +static void winCanvasRegisterClass(void) +{ + WNDCLASS wndclass; + ZeroMemory(&wndclass, sizeof(WNDCLASS)); +  + wndclass.hInstance = iupwin_hinstance; + wndclass.lpszClassName = "IupCanvas"; + wndclass.lpfnWndProc = (WNDPROC)iupwinBaseWinProc; + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; /* using CS_OWNDC will minimize the work of cdActivate in the CD library */ + wndclass.hbrBackground = NULL; /* remove the background to optimize redraw */ +  + RegisterClass(&wndclass); +} + void iupdrvCanvasInitClass(Iclass* ic) { if (!iupwinClassExist("IupCanvas")) diff --git a/iup/src/win/iupwin_common.c b/iup/src/win/iupwin_common.c index a1a7c0f..ba68b78 100755 --- a/iup/src/win/iupwin_common.c +++ b/iup/src/win/iupwin_common.c @@ -94,16 +94,17 @@ void iupdrvBaseLayoutUpdateMethod(Ihandle *ih) SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOOWNERZORDER); }  -void iupdrvDisplayRedraw(Ihandle *ih) +void iupdrvRedrawNow(Ihandle *ih) { /* REDRAW Now */ - RedrawWindow(ih->handle,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_NOCHILDREN|RDW_UPDATENOW); + RedrawWindow(ih->handle,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_UPDATENOW); }  -void iupdrvDisplayUpdate(Ihandle *ih) +void iupdrvPostRedraw(Ihandle *ih) { /* Post a REDRAW */ - RedrawWindow(ih->handle,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_NOCHILDREN); + /* can NOT use RDW_NOCHILDREN because IupList has internal children that needs to be redraw */ + RedrawWindow(ih->handle,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT);  }  void iupdrvScreenToClient(Ihandle* ih, int *x, int *y) @@ -534,6 +535,8 @@ int iupdrvBaseSetZorderAttrib(Ihandle* ih, const char* value)  void iupdrvSetVisible(Ihandle* ih, int visible) { + if (iupStrEqual(ih->iclass->name, "colorbar")) + ih=ih; ShowWindow(ih->handle, visible? SW_SHOWNORMAL: SW_HIDE); }  @@ -618,6 +621,18 @@ char* iupdrvBaseGetClientSizeAttrib(Ihandle* ih) #define IDC_HELP MAKEINTRESOURCE(32651) #endif  +static HCURSOR winLoadComCtlCursor(LPCTSTR lpCursorName) +{ + HCURSOR cur = NULL; + HINSTANCE hinstDll = LoadLibrary("comctl32.dll"); + if (hinstDll) + { + cur = LoadCursor(hinstDll, lpCursorName); + FreeLibrary(hinstDll); + } + return cur; +} + static HCURSOR winGetCursor(Ihandle* ih, const char* name) { static struct { @@ -649,7 +664,7 @@ static HCURSOR winGetCursor(Ihandle* ih, const char* name) {"APPSTARTING", IDC_APPSTARTING} };  - HCURSOR cur; + HCURSOR cur = NULL; char str[50]; int i, count = sizeof(table)/sizeof(table[0]);  @@ -676,14 +691,22 @@ static HCURSOR winGetCursor(Ihandle* ih, const char* name) if (i == count) { /* check other system cursors */ - /* cursor PEN is handled here */ + if (iupStrEqualNoCase(name, "PEN")) - name = "CURSOR_PEN"; + name = "CURSOR_PEN"; /* name in "iup.rc" */  /* check for an name defined cursor */ cur = iupImageGetCursor(name); }  + if (!cur) + { + if (iupStrEqualNoCase(name, "SPLITTER_VERT")) + cur = winLoadComCtlCursor(MAKEINTRESOURCE(107)); + else if (iupStrEqualNoCase(name, "SPLITTER_HORIZ")) + cur = winLoadComCtlCursor(MAKEINTRESOURCE(135)); + } + iupAttribSetStr(ih, str, (char*)cur); return cur; } @@ -758,29 +781,29 @@ int iupwinButtonUp(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp) if (msg==WM_LBUTTONUP) { b = IUP_BUTTON1; - iupKEYSETBUTTON1(status);  + iupKEY_SETBUTTON1(status);  } else if (msg==WM_MBUTTONUP) { b = IUP_BUTTON2; - iupKEYSETBUTTON2(status); + iupKEY_SETBUTTON2(status); } else if (msg==WM_RBUTTONUP) { b = IUP_BUTTON3; - iupKEYSETBUTTON3(status); + iupKEY_SETBUTTON3(status); } else if (msg==WM_XBUTTONUP) { if (HIWORD(wp) == XBUTTON1) { b = IUP_BUTTON4; - iupKEYSETBUTTON4(status); + iupKEY_SETBUTTON4(status); } else { b = IUP_BUTTON5; - iupKEYSETBUTTON5(status); + iupKEY_SETBUTTON5(status); } }  @@ -807,6 +830,14 @@ int iupwinMouseMove(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp) return 0; }  +void iupwinGetNativeParentStyle(Ihandle* ih, DWORD *dwExStyle, DWORD *dwStyle) +{ + *dwStyle |= WS_CLIPCHILDREN; + + if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED")) + *dwExStyle |= WS_EX_COMPOSITED; +} + int iupwinCreateWindowEx(Ihandle* ih, LPCSTR lpClassName, DWORD dwExStyle, DWORD dwStyle) { ih->serial = iupDialogGetChildId(ih); diff --git a/iup/src/win/iupwin_dialog.c b/iup/src/win/iupwin_dialog.c index 39fdc0c..c13b88d 100755 --- a/iup/src/win/iupwin_dialog.c +++ b/iup/src/win/iupwin_dialog.c @@ -102,9 +102,9 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu else { int has_titlebar = iupAttribGetBoolean(ih, "MAXBOX") || - iupAttribGetBoolean(ih, "MINBOX") || - iupAttribGetBoolean(ih, "MENUBOX") ||  - IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */ + iupAttribGetBoolean(ih, "MINBOX") || + iupAttribGetBoolean(ih, "MENUBOX") ||  + IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */  *caption = 0; if (has_titlebar) @@ -118,14 +118,17 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu *border = 0; if (iupAttribGetBoolean(ih, "RESIZE")) { + /* has_border */ *border = GetSystemMetrics(SM_CXFRAME); /* Thickness of the sizing border around the perimeter of a window */ } /* that can be resized, in pixels. */ else if (has_titlebar) { + /* has_border */ *border = GetSystemMetrics(SM_CXFIXEDFRAME); /* Thickness of the frame around the perimeter of a window */ } /* that has a caption but is not sizable, in pixels. */ else if (iupAttribGetBoolean(ih, "BORDER")) { + /* has_border */ *border = GetSystemMetrics(SM_CXBORDER); } } @@ -712,28 +715,27 @@ static int winDialogMapMethod(Ihandle* ih) }  if (iupAttribGetBoolean(ih, "RESIZE")) + { dwStyle |= WS_THICKFRAME; + has_border = 1; + } else iupAttribSetStr(ih, "MAXBOX", "NO"); /* Must also remove this to RESIZE=NO work */ - if (iupAttribGetBoolean(ih, "MAXBOX")) { dwStyle |= WS_MAXIMIZEBOX; has_titlebar = 1; } - if (iupAttribGetBoolean(ih, "MINBOX")) { dwStyle |= WS_MINIMIZEBOX; has_titlebar = 1; } - if (iupAttribGetBoolean(ih, "MENUBOX")) { dwStyle |= WS_SYSMENU; has_titlebar = 1; } - if (iupAttribGetBoolean(ih, "BORDER") || has_titlebar) has_border = 1;  @@ -815,10 +817,7 @@ static int winDialogMapMethod(Ihandle* ih) if (iupAttribGetBoolean(ih, "DIALOGFRAME") && native_parent) dwExStyle |= WS_EX_DLGMODALFRAME; /* this will hide the MENUBOX but not the close button */  - if (iupAttribGetBoolean(ih, "COMPOSITED")) - dwExStyle |= WS_EX_COMPOSITED; - else - dwStyle |= WS_CLIPCHILDREN; + iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);  if (iupAttribGetBoolean(ih, "HELPBUTTON")) dwExStyle |= WS_EX_CONTEXTHELP; @@ -878,7 +877,6 @@ static int winDialogMapMethod(Ihandle* ih) /* Reset attributes handled during creation that */ /* also can be changed later, and can be consulted from the native system. */ iupAttribSetStr(ih, "TITLE", NULL);  - iupAttribSetStr(ih, "BORDER", NULL);  /* Ignore VISIBLE before mapping */ iupAttribSetStr(ih, "VISIBLE", NULL); @@ -956,7 +954,7 @@ static int winDialogSetBgColorAttrib(Ihandle* ih, const char* value) { iupAttribStoreStr(ih, "_IUPWIN_BACKGROUND_COLOR", value); iupAttribSetStr(ih, "_IUPWIN_BACKGROUND_BITMAP", NULL); - RedrawWindow(ih->handle, NULL, NULL, RDW_ERASE|RDW_ERASENOW); /* force a WM_ERASEBKGND now */ + RedrawWindow(ih->handle, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); /* post WM_ERASEBKGND and WM_PAINT */ return 1; } return 0; @@ -973,7 +971,7 @@ static int winDialogSetBackgroundAttrib(Ihandle* ih, const char* value) { iupAttribSetStr(ih, "_IUPWIN_BACKGROUND_COLOR", NULL); iupAttribSetStr(ih, "_IUPWIN_BACKGROUND_BITMAP", (char*)hBitmap); - RedrawWindow(ih->handle, NULL, NULL, RDW_ERASE|RDW_ERASENOW); /* force a WM_ERASEBKGND now */ + RedrawWindow(ih->handle, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); /* post WM_ERASEBKGND and WM_PAINT */ return 1; } } diff --git a/iup/src/win/iupwin_draw.c b/iup/src/win/iupwin_draw.c index 4a810e6..f663d20 100755 --- a/iup/src/win/iupwin_draw.c +++ b/iup/src/win/iupwin_draw.c @@ -14,12 +14,16 @@ #include  #include  #include  +#include   #include "iup.h"  #include "iup_attrib.h" #include "iup_class.h" #include "iup_str.h" +#include "iup_object.h" +#include "iup_image.h" +#include "iup_draw.h"  #include "iupwin_drv.h" #include "iupwin_info.h" @@ -38,6 +42,11 @@ #endif   +/****************************************************************************** + Themes +*******************************************************************************/ + + typedef HTHEME (STDAPICALLTYPE *_winThemeOpenData)(HWND hwnd, LPCWSTR pszClassList); typedef HRESULT (STDAPICALLTYPE *_winThemeCloseData)(HTHEME hTheme); typedef HRESULT (STDAPICALLTYPE *_winThemeDrawBackground)(HTHEME hTheme, HDC hDC, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect); @@ -61,58 +70,6 @@ static int winDrawThemeEnabled(void) return winThemeOpenData? 1: 0; }  -void iupwinDrawText(HDC hDC, const char* text, int x, int y, int width, int height, HFONT hFont, COLORREF fgcolor, int style) -{ - COLORREF oldcolor; - RECT rect; - HFONT hOldFont = SelectObject(hDC, hFont); - - rect.left = x; - rect.top = y; - rect.right = x+width; - rect.bottom = y+height; - - SetTextAlign(hDC, TA_TOP|TA_LEFT); - SetBkMode(hDC, TRANSPARENT); - oldcolor = SetTextColor(hDC, fgcolor); - - DrawText(hDC, text, -1, &rect, style|DT_NOCLIP); - - SelectObject(hDC, hOldFont); - SetTextColor(hDC, oldcolor); - SetBkMode(hDC, OPAQUE); -} - -void iupwinDrawBitmap(HDC hDC, HBITMAP hBitmap, HBITMAP hMask, int x, int y, int width, int height, int bpp) -{ - HDC hMemDC = CreateCompatibleDC(hDC); - SelectObject(hMemDC, hBitmap); - - if (bpp == 32 && winAlphaBlend) - { - BLENDFUNCTION blendfunc; - blendfunc.BlendOp = AC_SRC_OVER; - blendfunc.BlendFlags = 0; - blendfunc.SourceConstantAlpha = 0xFF; - blendfunc.AlphaFormat = AC_SRC_ALPHA; - - winAlphaBlend(hDC, x, y, width, height,  - hMemDC, 0, 0, width, height,  - blendfunc); - } - else if (bpp == 8 && hMask) - MaskBlt(hDC, x, y, width, height,  - hMemDC, 0, 0,  - hMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000)); - else - BitBlt(hDC, x, y, width, height,  - hMemDC, 0, 0,  - SRCCOPY); - - - DeleteDC(hMemDC); -} - void iupwinDrawInit(void) { if (!winAlphaBlend) @@ -201,7 +158,7 @@ int iupwinDrawGetThemeTabsBgColor(HWND hWnd, COLORREF *color) if (!hTheme)  return 0;  - if (iupwinIsVista()) + if (iupwinIsVistaOrNew()) ret = winThemeGetColor(hTheme, TABP_AEROWIZARDBODY, TIS_NORMAL, TMT_FILLCOLORHINT, color); else ret = winThemeGetColor(hTheme, TABP_BODY, TIS_NORMAL, TMT_FILLCOLORHINT, color); @@ -246,6 +203,79 @@ int iupwinDrawGetThemeFrameFgColor(HWND hWnd, COLORREF *color) return (ret == S_OK)? 1: 0; }  +void iupwinDrawRemoveTheme(HWND hwnd) +{ + typedef HRESULT (STDAPICALLTYPE *winSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); + static winSetWindowTheme mySetWindowTheme = NULL; + if (!mySetWindowTheme) + { + HMODULE hinstDll = LoadLibrary("uxtheme.dll"); + if (hinstDll) + mySetWindowTheme = (winSetWindowTheme)GetProcAddress(hinstDll, "SetWindowTheme"); + } + + if (mySetWindowTheme) + mySetWindowTheme(hwnd, L"", L""); +} + + +/****************************************************************************** + Utilities +*******************************************************************************/ + + +void iupwinDrawText(HDC hDC, const char* text, int x, int y, int width, int height, HFONT hFont, COLORREF fgcolor, int style) +{ + COLORREF oldcolor; + RECT rect; + HFONT hOldFont = SelectObject(hDC, hFont); + + rect.left = x; + rect.top = y; + rect.right = x+width; + rect.bottom = y+height; + + SetTextAlign(hDC, TA_TOP|TA_LEFT); + SetBkMode(hDC, TRANSPARENT); + oldcolor = SetTextColor(hDC, fgcolor); + + DrawText(hDC, text, -1, &rect, style|DT_NOCLIP); + + SelectObject(hDC, hOldFont); + SetTextColor(hDC, oldcolor); + SetBkMode(hDC, OPAQUE); +} + +void iupwinDrawBitmap(HDC hDC, HBITMAP hBitmap, HBITMAP hMask, int x, int y, int width, int height, int bpp) +{ + HDC hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hBitmap); + + if (bpp == 32 && winAlphaBlend) + { + BLENDFUNCTION blendfunc; + blendfunc.BlendOp = AC_SRC_OVER; + blendfunc.BlendFlags = 0; + blendfunc.SourceConstantAlpha = 0xFF; + blendfunc.AlphaFormat = AC_SRC_ALPHA; + + winAlphaBlend(hDC, x, y, width, height,  + hMemDC, 0, 0, width, height,  + blendfunc); + } + else if (bpp == 8 && hMask) + MaskBlt(hDC, x, y, width, height,  + hMemDC, 0, 0,  + hMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000)); + else + BitBlt(hDC, x, y, width, height,  + hMemDC, 0, 0,  + SRCCOPY); + + + DeleteDC(hMemDC); +} + static int winDrawGetStateId(int itemState) { if (itemState & ODS_DISABLED) @@ -282,21 +312,6 @@ void iupdrvDrawFocusRect(Ihandle* ih, void* gc, int x, int y, int w, int h) DrawFocusRect(hDC, &rect); }  -void iupwinDrawRemoveTheme(HWND hwnd) -{ - typedef HRESULT (STDAPICALLTYPE *winSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); - static winSetWindowTheme mySetWindowTheme = NULL; - if (!mySetWindowTheme) - { - HMODULE hinstDll = LoadLibrary("uxtheme.dll"); - if (hinstDll) - mySetWindowTheme = (winSetWindowTheme)GetProcAddress(hinstDll, "SetWindowTheme"); - } - - if (mySetWindowTheme) - mySetWindowTheme(hwnd, L"", L""); -} - void iupwinDrawParentBackground(Ihandle* ih, HDC hDC, RECT* rect) { unsigned char r=0, g=0, b=0; @@ -326,3 +341,226 @@ void iupwinDrawDestroyBitmapDC(iupwinBitmapDC *bmpDC) DeleteDC(bmpDC->hBitmapDC); }  + +/****************************************************************************** + Simple Draw +*******************************************************************************/ + +struct _IdrawCanvas{ + Ihandle* ih; + int w, h; + + int release_dc; + HBITMAP hBitmap, hOldBitmap; + HDC hBitmapDC, hDC; +}; + +IdrawCanvas* iupDrawCreateCanvas(Ihandle* ih) +{ + IdrawCanvas* dc = calloc(1, sizeof(IdrawCanvas)); + RECT rect; + + /* valid only inside the ACTION callback of an IupCanvas */ + dc->hDC = (HDC)IupGetAttribute(ih, "HDC_WMPAINT"); + if (!dc->hDC) + { + dc->hDC = GetDC(ih->handle); + dc->release_dc = 1; + } + + GetClientRect(ih->handle, &rect); + dc->w = rect.right - rect.left; + dc->h = rect.bottom - rect.top; + + dc->hBitmap = CreateCompatibleBitmap(dc->hDC, dc->w, dc->h); + dc->hBitmapDC = CreateCompatibleDC(dc->hDC); + dc->hOldBitmap = SelectObject(dc->hBitmapDC, dc->hBitmap); + + SetBkMode(dc->hBitmapDC, TRANSPARENT); + SetTextAlign(dc->hBitmapDC, TA_TOP|TA_LEFT); + + return dc; +} + +void iupDrawKillCanvas(IdrawCanvas* dc) +{ + SelectObject(dc->hBitmapDC, dc->hOldBitmap); + DeleteObject(dc->hBitmap); + DeleteDC(dc->hBitmapDC); + if (dc->release_dc) + DeleteDC(dc->hDC); + + free(dc); +} + +void iupDrawUpdateSize(IdrawCanvas* dc) +{ + int w, h; + RECT rect; + GetClientRect(dc->ih->handle, &rect); + w = rect.right - rect.left; + h = rect.bottom - rect.top; + + if (w != dc->w || h != dc->h) + { + SelectObject(dc->hBitmapDC, dc->hOldBitmap); + DeleteObject(dc->hBitmap); + DeleteDC(dc->hBitmapDC); + + dc->hBitmap = CreateCompatibleBitmap(dc->hDC, dc->w, dc->h); + dc->hBitmapDC = CreateCompatibleDC(dc->hDC); + dc->hOldBitmap = SelectObject(dc->hBitmapDC, dc->hBitmap); + + SetBkMode(dc->hBitmapDC, TRANSPARENT); + SetTextAlign(dc->hBitmapDC, TA_TOP|TA_LEFT); + } +} + +void iupDrawFlush(IdrawCanvas* dc) +{ + BitBlt(dc->hDC, 0, 0, dc->w, dc->h, dc->hBitmapDC, 0, 0, SRCCOPY); +} + +void iupDrawGetSize(IdrawCanvas* dc, int *w, int *h) +{ + if (w) *w = dc->w; + if (h) *h = dc->h; +} + +void iupDrawParentBackground(IdrawCanvas* dc) +{ + unsigned char r=0, g=0, b=0; + char* color = iupBaseNativeParentGetBgColorAttrib(dc->ih); + iupStrToRGB(color, &r, &g, &b); + iupDrawRectangle(dc, 0, 0, dc->w-1, dc->h-1, r, g, b, 1); +} + +void iupDrawRectangle(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b, int filled) +{ + RECT rect; + rect.left = x1; rect.top = y1; rect.right = x2+1; rect.bottom = y2+1; + SetDCBrushColor(dc->hBitmapDC, RGB(r,g,b)); + if (filled) + FillRect(dc->hBitmapDC, &rect, (HBRUSH)GetStockObject(DC_BRUSH)); + else + FrameRect(dc->hBitmapDC, &rect, (HBRUSH)GetStockObject(DC_BRUSH)); +} + +void iupDrawLine(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b) +{ + POINT line_poly[2]; + HPEN hPen = CreatePen(PS_SOLID, 1, RGB(r, g, b)); + HPEN hPenOld = SelectObject(dc->hBitmapDC, hPen); + line_poly[0].x = x1; + line_poly[0].y = y1; + line_poly[1].x = x2; + line_poly[1].y = y2; + Polyline(dc->hBitmapDC, line_poly, 2); + SelectObject(dc->hBitmapDC, hPenOld); + DeleteObject(hPen); +} + +#define IUP_DEG2RAD 0.01745329252 /* degrees to radians (rad = CD_DEG2RAD * deg) */ + +static int winDrawCalcArc(int c1, int c2, double a, int start) +{ + double proj, off; + if (start) + proj = cos(IUP_DEG2RAD * a); + else + proj = sin(IUP_DEG2RAD * a); + off = (c2+c1)/2.0 + (c2-c1+1)*proj/2.0; + return iupROUND(off); +} + +void iupDrawArc(IdrawCanvas* dc, int x1, int y1, int x2, int y2, double a1, double a2, unsigned char r, unsigned char g, unsigned char b, int filled) +{ + int XStartArc = winDrawCalcArc(x1, x2, a1, 1); + int XEndArc = winDrawCalcArc(x1, x2, a2, 0); + int YStartArc = winDrawCalcArc(y1, y2, a1, 1); + int YEndArc = winDrawCalcArc(y1, y2, a2, 0); + + if (filled) + { + HBRUSH hBrush = CreateSolidBrush(RGB(r,g,b)); + HPEN hBrushOld = SelectObject(dc->hBitmapDC, hBrush);  + BeginPath(dc->hBitmapDC);  + Pie(dc->hBitmapDC, x1, y1, x2+1, y2+1, XStartArc, YStartArc, XEndArc, YEndArc); + EndPath(dc->hBitmapDC); + FillPath(dc->hBitmapDC); + SelectObject(dc->hBitmapDC, hBrushOld); + DeleteObject(hBrush); + } + else + { + HPEN hPen = CreatePen(PS_SOLID, 1, RGB(r, g, b)); + HPEN hPenOld = SelectObject(dc->hBitmapDC, hPen); + Arc(dc->hBitmapDC, x1, y1, x2+1, y2+1, XStartArc, YStartArc, XEndArc, YEndArc); + SelectObject(dc->hBitmapDC, hPenOld); + DeleteObject(hPen); + } +} + +void iupDrawPolygon(IdrawCanvas* dc, int* points, int count, unsigned char r, unsigned char g, unsigned char b, int filled) +{ + if (filled) + { + HBRUSH hBrush = CreateSolidBrush(RGB(r,g,b)); + HPEN hBrushOld = SelectObject(dc->hBitmapDC, hBrush);  + BeginPath(dc->hBitmapDC);  + Polygon(dc->hBitmapDC, (POINT*)points, count); + EndPath(dc->hBitmapDC); + FillPath(dc->hBitmapDC); + SelectObject(dc->hBitmapDC, hBrushOld); + DeleteObject(hBrush); + } + else + { + HPEN hPen = CreatePen(PS_SOLID, 1, RGB(r, g, b)); + HPEN hPenOld = SelectObject(dc->hBitmapDC, hPen); + Polyline(dc->hBitmapDC, (POINT*)points, count); + SelectObject(dc->hBitmapDC, hPenOld); + DeleteObject(hPen); + } +} + +void iupDrawSetClipRect(IdrawCanvas* dc, int x1, int y1, int x2, int y2) +{ + HRGN clip_hrgn = CreateRectRgn(x1, y1, x2, y2); + SelectClipRgn(dc->hBitmapDC, clip_hrgn); + DeleteObject(clip_hrgn); +} + +void iupDrawResetClip(IdrawCanvas* dc) +{ + SelectClipRgn(dc->hBitmapDC, NULL); +} + +void iupDrawText(IdrawCanvas* dc, const char* text, int len, int x, int y, unsigned char r, unsigned char g, unsigned char b) +{ + HFONT hOldFont, hFont = (HFONT)IupGetAttribute(dc->ih, "HFONT"); + SetTextColor(dc->hBitmapDC, RGB(r, g, b)); + hOldFont = SelectObject(dc->hBitmapDC, hFont); + TextOut(dc->hBitmapDC, x, y, text, len); + SelectObject(dc->hBitmapDC, hOldFont); +} + +void iupDrawImage(IdrawCanvas* dc, const char* name, int make_inactive, int x, int y) +{ + int img_w, img_h, bpp; + HBITMAP hMask = NULL; + HBITMAP hBitmap = iupImageGetImage(name, dc->ih, make_inactive); + if (!hBitmap) + return; + + /* must use this info, since image can be a driver image loaded from resources */ + iupdrvImageGetInfo(hBitmap, &img_w, &img_h, &bpp); + + if (bpp == 8) + hMask = iupdrvImageCreateMask(IupGetHandle(name)); + + iupwinDrawBitmap(dc->hBitmapDC, hBitmap, hMask, x, y, img_w, img_h, bpp); + + if (hMask) + DeleteObject(hMask); +} diff --git a/iup/src/win/iupwin_drv.h b/iup/src/win/iupwin_drv.h index 3372c1a..7407a7a 100755 --- a/iup/src/win/iupwin_drv.h +++ b/iup/src/win/iupwin_drv.h @@ -77,6 +77,7 @@ int iupwinBaseContainerProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT /* Creates the Window with native parent and child ID, associate HWND with Ihandle*,  and replace the WinProc by iupwinBaseWinProc */ int iupwinCreateWindowEx(Ihandle* ih, LPCSTR lpClassName, DWORD dwExStyle, DWORD dwStyle); +void iupwinGetNativeParentStyle(Ihandle* ih, DWORD *dwExStyle, DWORD *dwStyle);  int iupwinClassExist(const char* name); int iupwinGetColorRef(Ihandle *ih, char *name, COLORREF *color); @@ -97,8 +98,8 @@ char* iupwinGetClipboardText(Ihandle* ih); int iupwinGetScreenRes(void); /* 1 point = 1/72 inch */ /* pixel = (point/72)*(pixel/inch) */ -#define IUPWIN_PT2PIXEL(_pt, _res) MulDiv(_pt, _res, 72) /* (((_pt)*(_res))/72) */ -#define IUPWIN_PIXEL2PT(_pixel, _res) MulDiv(_pixel, 72, _res) /* (((_pixel)*72)/(_res)) */ +#define iupWIN_PT2PIXEL(_pt, _res) MulDiv(_pt, _res, 72) /* (((_pt)*(_res))/72) */ +#define iupWIN_PIXEL2PT(_pixel, _res) MulDiv(_pixel, 72, _res) /* (((_pixel)*72)/(_res)) */   /* child window identifier of the first MDI child window created, diff --git a/iup/src/win/iupwin_filedlg.c b/iup/src/win/iupwin_filedlg.c index da66b4b..26994e5 100755 --- a/iup/src/win/iupwin_filedlg.c +++ b/iup/src/win/iupwin_filedlg.c @@ -63,7 +63,7 @@ static INT CALLBACK winFileDlgBrowseCallback(HWND hWnd, UINT uMsg, LPARAM lParam } else if (uMsg == BFFM_SELCHANGED) { - char* buffer = iupStrGetMemory(MAX_FILENAME_SIZE); + char buffer[MAX_FILENAME_SIZE]; ITEMIDLIST* selecteditem = (ITEMIDLIST*)lParam; buffer[0] = 0; SHGetPathFromIDList(selecteditem, buffer); @@ -90,7 +90,7 @@ static void winFileDlgGetFolder(Ihandle *ih) browseinfo.pszDisplayName = buffer;  browseinfo.lpfn = winFileDlgBrowseCallback; browseinfo.lParam = (LPARAM)ih; - browseinfo.ulFlags = BIF_NEWDIALOGSTYLE; + browseinfo.ulFlags = IupGetGlobal("_IUPWIN_COINIT_MULTITHREADED")? 0: BIF_NEWDIALOGSTYLE; browseinfo.hwndOwner = parent;  selecteditem = SHBrowseForFolder(&browseinfo); @@ -112,6 +112,37 @@ static void winFileDlgGetFolder(Ihandle *ih)  /************************************************************************************************/  +static int winFileDlgGetSelectedFile(Ihandle* ih, HWND hWnd, char* filename) +{ + int ret = CommDlg_OpenSave_GetFilePath(GetParent(hWnd), filename, MAX_FILENAME_SIZE); + if (ret < 0) + return 0; + + if (iupAttribGetBoolean(ih, "MULTIPLEFILES")) + { + /* check if there are more than 1 files and return only the first one */ + int found = 0; + while(*filename != 0) + {  + if (*filename == '"') + { + if (!found) + found = 1; + else + { + *(filename-1) = 0; + return 1; + } + } + if (found) + *filename = *(filename+1); + filename++; + } + } + + return 1; +} + static UINT_PTR CALLBACK winFileDlgSimpleHook(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) { (void)wParam; @@ -152,16 +183,15 @@ static UINT_PTR CALLBACK winFileDlgSimpleHook(HWND hWnd, UINT uiMsg, WPARAM wPar IFnss cb = (IFnss)IupGetCallback(ih, "FILE_CB"); if (cb) { - char* filename = iupStrGetMemory(MAX_FILENAME_SIZE); - if (CommDlg_OpenSave_GetFilePath(GetParent(hWnd), filename, MAX_FILENAME_SIZE) <= MAX_FILENAME_SIZE) + char filename[MAX_FILENAME_SIZE]; + if (winFileDlgGetSelectedFile(ih, hWnd, filename)) { int ret; char* file_msg;  if (!iupdrvIsFile(filename)) - break; - - if (pofn->hdr.code == CDN_FILEOK) + file_msg = "OTHER"; + else if (pofn->hdr.code == CDN_FILEOK) file_msg = "OK"; else  file_msg = "SELECT"; @@ -267,9 +297,9 @@ static UINT_PTR CALLBACK winFileDlgPreviewHook(HWND hWnd, UINT uiMsg, WPARAM wPa LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT)lParam; Ihandle* ih = (Ihandle*)GetWindowLongPtr(hWnd, DWLP_USER); IFnss cb = (IFnss)IupGetCallback(ih, "FILE_CB"); - char* filename = iupStrGetMemory(MAX_FILENAME_SIZE); + char filename[MAX_FILENAME_SIZE]; iupAttribSetStr(ih, "PREVIEWDC", (char*)lpDrawItem->hDC); - if (CommDlg_OpenSave_GetFilePath(GetParent(hWnd), filename, MAX_FILENAME_SIZE) <= MAX_FILENAME_SIZE) + if (winFileDlgGetSelectedFile(ih, hWnd, filename)) { if (iupdrvIsFile(filename)) cb(ih, filename, "PAINT"); @@ -324,16 +354,15 @@ static UINT_PTR CALLBACK winFileDlgPreviewHook(HWND hWnd, UINT uiMsg, WPARAM wPa case CDN_SELCHANGE: { HWND hWndPreview = GetDlgItem(hWnd, IUP_PREVIEWCANVAS); - char* filename = iupStrGetMemory(MAX_FILENAME_SIZE); - if (CommDlg_OpenSave_GetFilePath(GetParent(hWnd), filename, MAX_FILENAME_SIZE) <= MAX_FILENAME_SIZE) + char filename[MAX_FILENAME_SIZE]; + if (winFileDlgGetSelectedFile(ih, hWnd, filename)) { int ret; char* file_msg;  if (!iupdrvIsFile(filename)) - break; - - if (pofn->hdr.code == CDN_FILEOK) + file_msg = "OTHER"; + else if (pofn->hdr.code == CDN_FILEOK) file_msg = "OK"; else file_msg = "SELECT"; @@ -520,9 +549,14 @@ static int winFileDlgPopup(Ihandle *ih, int x, int y) if (iupAttribGetBoolean(ih, "MULTIPLEFILES")) { int i = 0; -  + + char* dir = iupStrFileGetPath(openfilename.lpstrFile); /* the first part is the directory already */ + iupAttribStoreStr(ih, "DIRECTORY", dir); + free(dir); +  /* If there is more than one file, replace terminator by the separator */ - if (openfilename.lpstrFile && openfilename.lpstrFile[openfilename.nFileOffset-1] == 0 && openfilename.nFileOffset>0)  + if (openfilename.lpstrFile[openfilename.nFileOffset-1] == 0 &&  + openfilename.nFileOffset>0)  { while (openfilename.lpstrFile[i] != 0 || openfilename.lpstrFile[i+1] != 0) { @@ -534,12 +568,16 @@ static int winFileDlgPopup(Ihandle *ih, int x, int y) }  iupAttribSetStr(ih, "STATUS", "0"); - iupAttribSetStr(ih, "FILEEXIST", NULL); + iupAttribSetStr(ih, "FILEEXIST", "YES"); } else { if (iupdrvIsFile(openfilename.lpstrFile)) /* check if file exists */ { + char* dir = iupStrFileGetPath(openfilename.lpstrFile); + iupAttribStoreStr(ih, "DIRECTORY", dir); + free(dir); + iupAttribSetStr(ih, "FILEEXIST", "YES"); iupAttribSetStr(ih, "STATUS", "0"); } diff --git a/iup/src/win/iupwin_focus.c b/iup/src/win/iupwin_focus.c index 63da02d..2328dea 100755 --- a/iup/src/win/iupwin_focus.c +++ b/iup/src/win/iupwin_focus.c @@ -32,7 +32,7 @@  /* Since Windows XP, the focus feedback only appears after the user press a key. Except for the IupText where the feedback is the caret. - Before that if you click in a control the focus feedback will be hidden. + Before a key is pressed if you click in a control the focus feedback will be hidden.  We manually send WM_CHANGEUISTATE because we do not use IsDialogMessage anymore, and the focus feedback was not shown even after the used press a key. @@ -43,19 +43,28 @@ void iupdrvSetFocus(Ihandle *ih) { SetFocus(ih->handle); - SendMessage(ih->handle, WM_CHANGEUISTATE, UIS_CLEAR|UISF_HIDEFOCUS, 0); + + /* See comments above */ + SendMessage(ih->handle, WM_CHANGEUISTATE, UIS_CLEAR|UISF_HIDEFOCUS, 0); /* clear+hidefocus=showfocus */ }  void iupwinWmSetFocus(Ihandle *ih) { Ihandle* dialog = IupGetDialog(ih); if (ih != dialog) - iupAttribSetStr(dialog, "_IUPWIN_LASTFOCUS", (char*)ih); /* used by IupMenu */ + iupAttribSetStr(dialog, "_IUPWIN_LASTFOCUS", (char*)ih); /* used by IupMenu and here. */ else { /* if a control inside that dialog had the focus, then reset to it when the dialog gets the focus */ Ihandle* lastfocus = (Ihandle*)iupAttribGet(dialog, "_IUPWIN_LASTFOCUS"); - if (lastfocus) IupSetFocus(lastfocus); + if (lastfocus) + { + /* call the callback and update current focus before changing it again */ + iupCallGetFocusCb(ih); + + IupSetFocus(lastfocus); + return; + } }  iupCallGetFocusCb(ih); diff --git a/iup/src/win/iupwin_font.c b/iup/src/win/iupwin_font.c index 659e2d9..c10befb 100755 --- a/iup/src/win/iupwin_font.c +++ b/iup/src/win/iupwin_font.c @@ -70,7 +70,7 @@ static IwinFont* winFindFont(const char *standardfont) if (height < 0)  height_pixels = height; /* already in pixels */ else - height_pixels = -IUPWIN_PT2PIXEL(height, res); + height_pixels = -iupWIN_PT2PIXEL(height, res);  if (height_pixels == 0) return NULL; @@ -119,7 +119,7 @@ static void winFontFromLogFont(LOGFONT* logfont, char * font) int is_strikeout = logfont->lfStrikeOut; int height_pixels = logfont->lfHeight; /* negative value */ int res = iupwinGetScreenRes(); - int height = IUPWIN_PIXEL2PT(-height_pixels, res); /* return in points */ + int height = iupWIN_PIXEL2PT(-height_pixels, res); /* return in points */  sprintf(font, "%s, %s%s%s%s %d", logfont->lfFaceName,  is_bold?"Bold ":"",  diff --git a/iup/src/win/iupwin_fontdlg.c b/iup/src/win/iupwin_fontdlg.c index 0602441..ce27cf2 100755 --- a/iup/src/win/iupwin_fontdlg.c +++ b/iup/src/win/iupwin_fontdlg.c @@ -68,7 +68,7 @@ static int winFontDlgPopup(Ihandle* ih, int x, int y)  standardfont = iupAttribGet(ih, "VALUE"); if (!standardfont) - return IUP_ERROR; + standardfont = IupGetGlobal("DEFAULTFONT");  /* parse the old format first */ if (!iupFontParseWin(standardfont, typeface, &height, &is_bold, &is_italic, &is_underline, &is_strikeout)) @@ -81,7 +81,7 @@ static int winFontDlgPopup(Ihandle* ih, int x, int y) if (height < 0) height_pixels = height; /* already in pixels */ else - height_pixels = -IUPWIN_PT2PIXEL(height, res); + height_pixels = -iupWIN_PT2PIXEL(height, res);  if (height_pixels == 0) return IUP_ERROR; @@ -134,7 +134,7 @@ static int winFontDlgPopup(Ihandle* ih, int x, int y) if (height < 0) /* not an error, use old value as a reference for the units */ height = height_pixels; /* return in pixels */ else - height = IUPWIN_PIXEL2PT(-height_pixels, res); /* return in points */ + height = iupWIN_PIXEL2PT(-height_pixels, res); /* return in points */  iupAttribSetStrf(ih, "VALUE", "%s, %s%s%s%s %d", logfont.lfFaceName,  is_bold?"Bold ":"",  diff --git a/iup/src/win/iupwin_frame.c b/iup/src/win/iupwin_frame.c index 0949b5d..3f56aed 100755 --- a/iup/src/win/iupwin_frame.c +++ b/iup/src/win/iupwin_frame.c @@ -47,6 +47,27 @@ void iupdrvFrameGetDecorOffset(Ihandle* ih, int *x, int *y) } }  +static char* winFrameGetBgColorAttrib(Ihandle* ih) +{ + if (iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR")) + return NULL; + else + return iupBaseNativeParentGetBgColorAttrib(ih); +} + +static int winFrameSetBgColorAttrib(Ihandle* ih, const char* value) +{ + (void)value; + + if (iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR")) + { + IupUpdate(ih); /* post a redraw */ + return 1; + } + else + return 0; +} + static void winFrameDrawText(HDC hDC, const char* text, int x, int y, COLORREF fgcolor) { COLORREF oldcolor; @@ -126,6 +147,16 @@ static void winFrameDrawItem(Ihandle* ih, DRAWITEMSTRUCT *drawitem) DrawEdge(hDC, &drawitem->rcItem, EDGE_SUNKEN, BF_RECT); else DrawEdge(hDC, &drawitem->rcItem, EDGE_ETCHED, BF_RECT); + + if (iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR")) + { + unsigned char r=0, g=0, b=0; + char* color = iupAttribGetStr(ih, "BGCOLOR"); + iupStrToRGB(color, &r, &g, &b); + SetDCBrushColor(hDC, RGB(r,g,b)); + InflateRect(&drawitem->rcItem, -2, -2); + FillRect(hDC, &drawitem->rcItem, (HBRUSH)GetStockObject(DC_BRUSH)); + } }  iupwinDrawDestroyBitmapDC(&bmpDC); @@ -169,11 +200,13 @@ static int winFrameMapMethod(Ihandle* ih) title = iupAttribGet(ih, "TITLE"); if (title) iupAttribSetStr(ih, "_IUPFRAME_HAS_TITLE", "1"); - - if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED")) - dwExStyle |= WS_EX_COMPOSITED; else - dwStyle |= WS_CLIPCHILDREN; + { + if (iupAttribGet(ih, "BGCOLOR")) + iupAttribSetStr(ih, "_IUPFRAME_HAS_BGCOLOR", "1"); + } + + iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);  if (!iupwinCreateWindowEx(ih, "BUTTON", dwExStyle, dwStyle)) return IUP_ERROR; @@ -195,7 +228,7 @@ void iupdrvFrameInitClass(Iclass* ic) /* Driver Dependent Attribute functions */  /* Visual */ - iupClassRegisterAttribute(ic, "BGCOLOR", iupBaseNativeParentGetBgColorAttrib, NULL, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);  + iupClassRegisterAttribute(ic, "BGCOLOR", winFrameGetBgColorAttrib, winFrameSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);   /* Special */ iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_NOT_MAPPED); diff --git a/iup/src/win/iupwin_globalattrib.c b/iup/src/win/iupwin_globalattrib.c index a176925..bcd6355 100755 --- a/iup/src/win/iupwin_globalattrib.c +++ b/iup/src/win/iupwin_globalattrib.c @@ -148,6 +148,11 @@ int iupdrvSetGlobal(const char *name, const char *value) winGlobalSendKey(key, 0x03); return 0; } + if (iupStrEqual(name, "DLL_HINSTANCE")) + { + iupwin_dll_hinstance = (HINSTANCE)value; + return 0; + } return 1; }  @@ -239,5 +244,7 @@ char *iupdrvGetGlobal(const char *name) return "YES"; return "NO"; } + if (iupStrEqual(name, "DLL_HINSTANCE")) + return (char*)iupwin_dll_hinstance; return NULL; } diff --git a/iup/src/win/iupwin_info.c b/iup/src/win/iupwin_info.c index 8ea7dd4..4d57289 100755 --- a/iup/src/win/iupwin_info.c +++ b/iup/src/win/iupwin_info.c @@ -18,7 +18,7 @@ #include "iupwin_info.h"   -int iupwinIsVista(void) +int iupwinIsVistaOrNew(void) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); diff --git a/iup/src/win/iupwin_info.h b/iup/src/win/iupwin_info.h index d39bae0..8d461fb 100755 --- a/iup/src/win/iupwin_info.h +++ b/iup/src/win/iupwin_info.h @@ -16,7 +16,7 @@ int iupwinGetSystemMajorVersion(void); int iupwinGetComCtl32Version(void); char* iupwinGetSystemLanguage(void); int iupwinIsAppThemed(void); -int iupwinIsVista(void); +int iupwinIsVistaOrNew(void);  /* color */ void iupwinGetSysColor(char* color, int wincolor); diff --git a/iup/src/win/iupwin_key.c b/iup/src/win/iupwin_key.c index 921ed94..899e837 100755 --- a/iup/src/win/iupwin_key.c +++ b/iup/src/win/iupwin_key.c @@ -317,32 +317,32 @@ int iupwinKeyEvent(Ihandle* ih, int wincode, int press) void iupwinButtonKeySetStatus(WORD keys, char* status, int doubleclick) { if (keys & MK_SHIFT) - iupKEYSETSHIFT(status); + iupKEY_SETSHIFT(status);  if (keys & MK_CONTROL) - iupKEYSETCONTROL(status);  + iupKEY_SETCONTROL(status);   if (keys & MK_LBUTTON) - iupKEYSETBUTTON1(status); + iupKEY_SETBUTTON1(status);  if (keys & MK_MBUTTON) - iupKEYSETBUTTON2(status); + iupKEY_SETBUTTON2(status);  if (keys & MK_RBUTTON) - iupKEYSETBUTTON3(status); + iupKEY_SETBUTTON3(status);  if (doubleclick) - iupKEYSETDOUBLE(status); + iupKEY_SETDOUBLE(status);  if (GetKeyState(VK_MENU) & 0x8000) - iupKEYSETALT(status); + iupKEY_SETALT(status);  if ((GetKeyState(VK_LWIN) & 0x8000) || (GetKeyState(VK_RWIN) & 0x8000)) - iupKEYSETSYS(status); + iupKEY_SETSYS(status);  if (keys & MK_XBUTTON1) - iupKEYSETBUTTON4(status); + iupKEY_SETBUTTON4(status);  if (keys & MK_XBUTTON2) - iupKEYSETBUTTON5(status); + iupKEY_SETBUTTON5(status); } diff --git a/iup/src/win/iupwin_label.c b/iup/src/win/iupwin_label.c index d5a1f53..95dd10c 100755 --- a/iup/src/win/iupwin_label.c +++ b/iup/src/win/iupwin_label.c @@ -173,7 +173,7 @@ static int winLabelSetAlignmentAttrib(Ihandle* ih, const char* value) else /* "ATOP" */ ih->data->vert_alignment = IUP_ALIGN_ATOP;  - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); } return 0; } @@ -197,7 +197,7 @@ static int winLabelSetPaddingAttrib(Ihandle* ih, const char* value) iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');  if (ih->handle && ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT) - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih);  return 0; } @@ -211,7 +211,7 @@ static int winLabelSetWordWrapAttrib(Ihandle* ih, const char* value) else ih->data->text_style &= ~DT_WORDBREAK;  - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); }  return 1; @@ -226,7 +226,7 @@ static int winLabelSetEllipsisAttrib(Ihandle* ih, const char* value) else ih->data->text_style &= ~DT_END_ELLIPSIS;  - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); }  return 1; @@ -240,12 +240,24 @@ static int winLabelSetFgColorAttrib(Ihandle* ih, const char* value) if (iupStrToRGB(value, &r, &g, &b)) { ih->data->fgcolor = RGB(r,g,b); - iupdrvDisplayRedraw(ih); + + if (ih->handle) + iupdrvRedrawNow(ih); } } return 1; }  +static int winLabelSetUpdateAttrib(Ihandle* ih, const char* value) +{ + (void)value; + + if (ih->handle) + iupdrvPostRedraw(ih); /* Post a redraw */ + + return 1; +} + static int winLabelProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { switch (msg) @@ -257,6 +269,7 @@ static int winLabelProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *re *result = WVR_HREDRAW|WVR_VREDRAW; return 1; } + break; } }  @@ -266,7 +279,7 @@ static int winLabelProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *re static int winLabelMapMethod(Ihandle* ih) { char* value; - DWORD dwStyle = WS_CHILD | + DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | SS_NOTIFY; /* SS_NOTIFY is necessary because of the base messages */  if (!ih->parent) @@ -330,7 +343,7 @@ void iupdrvLabelInitClass(Iclass* ic)  /* IupLabel only */ iupClassRegisterAttribute(ic, "ALIGNMENT", winLabelGetAlignmentAttrib, winLabelSetAlignmentAttrib, IUPAF_SAMEASSYSTEM, "ALEFT:ACENTER", IUPAF_NO_INHERIT); - iupClassRegisterAttribute(ic, "IMAGE", NULL, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "IMAGE", NULL, winLabelSetUpdateAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "PADDING", iupLabelGetPaddingAttrib, winLabelSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);  /* IupLabel Windows and GTK only */ diff --git a/iup/src/win/iupwin_list.c b/iup/src/win/iupwin_list.c index 8fdadb6..cb510b5 100755 --- a/iup/src/win/iupwin_list.c +++ b/iup/src/win/iupwin_list.c @@ -154,6 +154,8 @@ void iupdrvListInsertItem(Ihandle* ih, int pos, const char* value) SendMessage(ih->handle, WIN_INSERTSTRING(ih), pos, (LPARAM)value); SendMessage(ih->handle, WIN_SETITEMDATA(ih), pos, (LPARAM)iupdrvFontGetStringWidth(ih, value)); winListUpdateScrollWidth(ih); + + iupListUpdateOldValue(ih, pos, 0); }  void iupdrvListRemoveItem(Ihandle* ih, int pos) @@ -164,8 +166,14 @@ void iupdrvListRemoveItem(Ihandle* ih, int pos) int curpos = SendMessage(ih->handle, WIN_GETCURSEL(ih), 0, 0); if (pos == curpos) { - if (curpos > 0) curpos--; - else curpos++; + if (curpos > 0)  + curpos--; + else  + { + curpos=1; + if (iupdrvListGetCount(ih)==1) + curpos = -1; /* remove the selection */ + }  SendMessage(ih->handle, WIN_SETCURSEL(ih), curpos, 0); } @@ -173,6 +181,8 @@ void iupdrvListRemoveItem(Ihandle* ih, int pos)  SendMessage(ih->handle, WIN_DELETESTRING(ih), pos, 0L); winListUpdateScrollWidth(ih); + + iupListUpdateOldValue(ih, pos, 1); }  void iupdrvListRemoveAllItems(Ihandle* ih) @@ -220,18 +230,29 @@ static void winListUpdateItemWidth(Ihandle* ih) } }  +static int winListSetBgColorAttrib(Ihandle *ih, const char *value) +{ + (void)value; + if (ih->handle) + iupdrvPostRedraw(ih); + return 1; +} + static int winListSetStandardFontAttrib(Ihandle* ih, const char* value) { iupdrvSetStandardFontAttrib(ih, value); - winListUpdateItemWidth(ih); - winListUpdateScrollWidth(ih); + if (ih->handle) + { + winListUpdateItemWidth(ih); + winListUpdateScrollWidth(ih); + } return 1; }  static char* winListGetIdValueAttrib(Ihandle* ih, const char* name_id) { int pos = iupListGetPos(ih, name_id); - if (pos != -1) + if (pos >= 0) { int len = SendMessage(ih->handle, WIN_GETTEXTLEN(ih), (WPARAM)pos, 0); char* str = iupStrGetMemory(len+1); @@ -514,8 +535,10 @@ static int winListSetNCAttrib(Ihandle* ih, const char* value) { HWND cbedit = (HWND)iupAttribGet(ih, "_IUPWIN_EDITBOX"); SendMessage(cbedit, EM_LIMITTEXT, ih->data->nc, 0L); + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int winListSetSelectionAttrib(Ihandle* ih, const char* value) @@ -995,13 +1018,27 @@ static int winListEditProc(Ihandle* ih, HWND cbedit, UINT msg, WPARAM wp, LPARAM if (msg==WM_KEYDOWN) /* process K_ANY before text callbacks */ { ret = iupwinBaseProc(ih, msg, wp, lp, result); - if (ret) return 1; + if (ret)  + { + iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", "1"); + *result = 0; + return 1; + } + else + iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", NULL); }  switch (msg) { case WM_CHAR: { + if (iupAttribGet(ih, "_IUPWIN_IGNORE_CHAR")) + { + iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", NULL); + *result = 0; + return 1; + } + if ((char)wp == '\b') {  if (!winListCallEditCb(ih, cbedit, NULL, 0, -1)) @@ -1301,7 +1338,7 @@ static void winListLayoutUpdateMethod(Ihandle *ih) static int winListMapMethod(Ihandle* ih) { char* class_name; - DWORD dwStyle = WS_CHILD, + DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS, dwExStyle = WS_EX_CLIENTEDGE;  if (!ih->parent) @@ -1426,7 +1463,7 @@ void iupdrvListInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, winListSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NOT_MAPPED);  /* Visual */ - iupClassRegisterAttribute(ic, "BGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_NOT_MAPPED);  + iupClassRegisterAttribute(ic, "BGCOLOR", NULL, winListSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_NOT_MAPPED);  /* Special */ iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "TXTFGCOLOR", IUPAF_NOT_MAPPED); diff --git a/iup/src/win/iupwin_loop.c b/iup/src/win/iupwin_loop.c index 7c5dbe7..fd25537 100755 --- a/iup/src/win/iupwin_loop.c +++ b/iup/src/win/iupwin_loop.c @@ -106,6 +106,18 @@ int IupMainLoop(void) return IUP_NOERROR; }  +int IupLoopStepWait(void) +{ + MSG msg; + int ret = GetMessage(&msg, NULL, 0, 0); + if (ret == -1) /* error */ + return IUP_ERROR; + if (ret == 0 || /* WM_QUIT */ + winLoopProcessMessage(&msg) == IUP_CLOSE) /* ret != 0 */ + return IUP_CLOSE; + return IUP_DEFAULT; +} + int IupLoopStep(void) { MSG msg; diff --git a/iup/src/win/iupwin_menu.c b/iup/src/win/iupwin_menu.c index 74a8b52..06ad93e 100755 --- a/iup/src/win/iupwin_menu.c +++ b/iup/src/win/iupwin_menu.c @@ -385,7 +385,10 @@ static int winMenuMapMethod(Ihandle* ih) static void winMenuUnMapMethod(Ihandle* ih) { if (iupMenuIsMenuBar(ih)) + { SetMenu(ih->parent->handle, NULL); + ih->parent = NULL; + }  DestroyMenu((HMENU)ih->handle); /* DestroyMenu is recursive */ } diff --git a/iup/src/win/iupwin_open.c b/iup/src/win/iupwin_open.c index 7357cde..3629ce4 100755 --- a/iup/src/win/iupwin_open.c +++ b/iup/src/win/iupwin_open.c @@ -76,8 +76,9 @@ int iupdrvOpen(int *argc, char ***argv) iupwin_hinstance = GetModuleHandle(NULL); IupSetGlobal("HINSTANCE", (char*)iupwin_hinstance); } - - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); +  + if (CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)==RPC_E_CHANGED_MODE) + IupSetGlobal("_IUPWIN_COINIT_MULTITHREADED", "1");  { INITCOMMONCONTROLSEX InitCtrls; diff --git a/iup/src/win/iupwin_progressbar.c b/iup/src/win/iupwin_progressbar.c index 9038d79..4a52cc4 100755 --- a/iup/src/win/iupwin_progressbar.c +++ b/iup/src/win/iupwin_progressbar.c @@ -106,7 +106,7 @@ static int winProgressBarSetFgColorAttrib(Ihandle* ih, const char* value)  static int winProgressBarMapMethod(Ihandle* ih) { - DWORD dwStyle = WS_CHILD; + DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS;  if (!ih->parent) return IUP_ERROR; diff --git a/iup/src/win/iupwin_tabs.c b/iup/src/win/iupwin_tabs.c index 682f451..b39f7fe 100755 --- a/iup/src/win/iupwin_tabs.c +++ b/iup/src/win/iupwin_tabs.c @@ -232,10 +232,7 @@ static HWND winTabCreatePageWindow(Ihandle* ih) DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS,  dwExStyle = 0;  - if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED")) - dwExStyle |= WS_EX_COMPOSITED; - else - dwStyle |= WS_CLIPCHILDREN; + iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);  hWnd = CreateWindowEx(dwExStyle, "IupTabsPage", NULL, dwStyle,  0, 0, CW_USEDEFAULT, CW_USEDEFAULT,  @@ -255,9 +252,12 @@ static int winTabsSetPaddingAttrib(Ihandle* ih, const char* value) iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');  if (ih->handle) + { SendMessage(ih->handle, TCM_SETPADDING, 0, MAKELPARAM(ih->data->horiz_padding, ih->data->vert_padding)); - - return 0; + return 0; + } + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int winTabsSetMultilineAttrib(Ihandle* ih, const char* value) @@ -368,6 +368,13 @@ static char* winTabsGetBgColorAttrib(Ihandle* ih) return IupGetGlobal("DLGBGCOLOR"); }  +static int winTabsSetBgColorAttrib(Ihandle *ih, const char *value) +{ + (void)value; + iupdrvPostRedraw(ih); + return 1; +} +  /* ------------------------------------------------------------------------- */ /* winTabs - Calls the user callback to change of tab */ @@ -397,6 +404,7 @@ static int winTabsWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) int prev_pos = SendMessage(ih->handle, TCM_GETCURSEL, 0, 0); iupAttribSetInt(ih, "_IUPTABS_PREV_CHILD_POS", prev_pos);  + /* save the previous handle if callback exists */ if (cb) { Ihandle* prev_child = IupGetChild(ih, prev_pos); @@ -420,7 +428,9 @@ static int winTabsWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) Ihandle* prev_child = (Ihandle*)iupAttribGet(ih, "_IUPTABS_PREV_CHILD"); iupAttribSetStr(ih, "_IUPTABS_PREV_CHILD", NULL);  - cb(ih, child, prev_child); + /* avoid duplicate calls when a Tab is inside another Tab. */ + if (prev_child) + cb(ih, child, prev_child); } }  @@ -522,7 +532,7 @@ static void winTabsChildAddedMethod(Ihandle* ih, Ihandle* child) } }  - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); } } } @@ -535,12 +545,11 @@ static void winTabsChildRemovedMethod(Ihandle* ih, Ihandle* child) if (tab_page) { int pos = winTabsGetPageWindowPos(ih, tab_page); + iupTabsTestRemoveTab(ih, pos); + SendMessage(ih->handle, TCM_DELETEITEM, pos, 0); DestroyWindow(tab_page);  - if (pos==0) pos++; - iupdrvTabsSetCurrentTab(ih, pos-1); - iupAttribSetStr(child, "_IUPTAB_CONTAINER", NULL); } } @@ -564,19 +573,14 @@ static int winTabsMapMethod(Ihandle* ih) if (ih->data->is_multiline) dwStyle |= TCS_MULTILINE;  - if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED")) - { - dwExStyle |= WS_EX_COMPOSITED; + iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);  - if (!ih->data->is_multiline && iupwinIsVista()) - { - /* workaround for composite bug in Vista */ - ih->data->is_multiline = 1;  - dwStyle |= TCS_MULTILINE; - } + if (dwExStyle & WS_EX_COMPOSITED && !ih->data->is_multiline && iupwinIsVistaOrNew()) + { + /* workaround for composite bug in Vista */ + ih->data->is_multiline = 1;  + dwStyle |= TCS_MULTILINE; } - else - dwStyle |= WS_CLIPCHILDREN;  if (!iupwinCreateWindowEx(ih, WC_TABCONTROL, dwExStyle, dwStyle)) return IUP_ERROR; @@ -665,7 +669,7 @@ void iupdrvTabsInitClass(Iclass* ic) /* Driver Dependent Attribute functions */  /* Visual */ - iupClassRegisterAttribute(ic, "BGCOLOR", winTabsGetBgColorAttrib, NULL, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);  + iupClassRegisterAttribute(ic, "BGCOLOR", winTabsGetBgColorAttrib, winTabsSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);  /* Special */ iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_NOT_MAPPED); @@ -676,5 +680,9 @@ void iupdrvTabsInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "MULTILINE", winTabsGetMultilineAttrib, winTabsSetMultilineAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TABTITLE", NULL, winTabsSetTabTitleAttrib, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TABIMAGE", NULL, winTabsSetTabImageAttrib, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); - iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, winTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, winTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + + /* necessary because transparent background does not work when not using visual styles */ + if (!iupwin_comctl32ver6) /* Used by iupdrvImageCreateImage */ + iupClassRegisterAttribute(ic, "FLAT_ALPHA", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); } diff --git a/iup/src/win/iupwin_text.c b/iup/src/win/iupwin_text.c index dfe489a..2a61724 100755 --- a/iup/src/win/iupwin_text.c +++ b/iup/src/win/iupwin_text.c @@ -432,8 +432,8 @@ static int winTextSetLinColToPosition(Ihandle *ih, int lin, int col) col--;  linmax = SendMessage(ih->handle, EM_GETLINECOUNT, 0, 0L); - if (lin > linmax) - lin = linmax; + if (lin > linmax-1) + lin = linmax-1;  lineindex = SendMessage(ih->handle, EM_LINEINDEX, (WPARAM)lin, 0L);  @@ -639,8 +639,12 @@ static int winTextSetPaddingAttrib(Ihandle* ih, const char* value) iupStrToIntInt(value, &(ih->data->horiz_padding), &(ih->data->vert_padding), 'x'); ih->data->vert_padding = 0; if (ih->handle) + { SendMessage(ih->handle, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELPARAM(ih->data->horiz_padding, ih->data->horiz_padding)); - return 0; + return 0; + } + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int winTextSetSelectedTextAttrib(Ihandle* ih, const char* value) @@ -713,8 +717,11 @@ static int winTextSetNCAttrib(Ihandle* ih, const char* value) SendMessage(ih->handle, EM_EXLIMITTEXT, 0, ih->data->nc); /* so it can be larger than 64k */ else SendMessage(ih->handle, EM_LIMITTEXT, ih->data->nc, 0L); + + return 0; } - return 0; + else + return 1; /* store until not mapped, when mapped will be set again */ }  static int winTextSetSelectionAttrib(Ihandle* ih, const char* value) @@ -845,7 +852,7 @@ static char* winTextGetSelectionPosAttrib(Ihandle* ih)  static int winTextSetInsertAttrib(Ihandle* ih, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (value) { @@ -867,9 +874,9 @@ static int winTextSetInsertAttrib(Ihandle* ih, const char* value)  static int winTextSetAppendAttrib(Ihandle* ih, const char* value) { - int len; + int pos; char* str; - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (!value) value = ""; str = (char*)value; @@ -881,9 +888,9 @@ static int winTextSetAppendAttrib(Ihandle* ih, const char* value) str = iupStrToDos(str); }  - len = GetWindowTextLength(ih->handle)+1; - SendMessage(ih->handle, EM_SETSEL, (WPARAM)len, (LPARAM)len); - if (ih->data->is_multiline && ih->data->append_newline) + pos = GetWindowTextLength(ih->handle)+1; + SendMessage(ih->handle, EM_SETSEL, (WPARAM)pos, (LPARAM)pos); + if (ih->data->is_multiline && ih->data->append_newline && pos!=1) { if (ih->data->has_formatting) SendMessage(ih->handle, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)"\r"); @@ -920,7 +927,7 @@ static int winTextSetTabSizeAttrib(Ihandle* ih, const char* value) iupStrToInt(value, &tabsize); tabsize *= 4; SendMessage(ih->handle, EM_SETTABSTOPS, (WPARAM)1L, (LPARAM)&tabsize); - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); return 1; }  @@ -1120,6 +1127,7 @@ static int winTextSetBgColorAttrib(Ihandle *ih, const char *value) SendMessage(ih->handle, EM_SETBKGNDCOLOR, 0, (LPARAM)color); } } + iupdrvPostRedraw(ih); return 1; }  @@ -1529,15 +1537,27 @@ static int winTextProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res ret = iupwinBaseProc(ih, msg, wp, lp, result); if (ret)  { + iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", "1"); *result = 0; return 1; } + else + iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", NULL); }  switch (msg) { case WM_CHAR: { + /* even aborting WM_KEYDOWN, a WM_CHAR will be sent, so ignore it also */ + /* if a dialog was shown, the loop will be processed, so ignore out of focus WM_CHAR messages */ + if (GetFocus() != ih->handle || iupAttribGet(ih, "_IUPWIN_IGNORE_CHAR")) + { + iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", NULL); + *result = 0; + return 1; + } + if ((char)wp == '\b') {  if (!winTextCallActionCb(ih, NULL, 0, -1)) @@ -1736,7 +1756,7 @@ static int winTextProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res static void winTextCreateSpin(Ihandle* ih) { HWND hSpin; - DWORD dwStyle = WS_CHILD|UDS_ARROWKEYS|UDS_HOTTRACK|UDS_NOTHOUSANDS; + DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS|UDS_ARROWKEYS|UDS_HOTTRACK|UDS_NOTHOUSANDS; int serial = iupDialogGetChildId(ih);  if (iupStrEqualNoCase(iupAttribGetStr(ih, "SPINALIGN"), "LEFT")) @@ -1826,7 +1846,7 @@ static void winTextLayoutUpdateMethod(Ihandle* ih)  static int winTextMapMethod(Ihandle* ih) { - DWORD dwStyle = WS_CHILD,  + DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS,  dwExStyle = 0; char* winclass = "EDIT", *value;  @@ -1873,7 +1893,7 @@ static int winTextMapMethod(Ihandle* ih) } else { - dwStyle |= ES_AUTOHSCROLL|ES_NOHIDESEL; + dwStyle |= ES_AUTOHSCROLL;  if (iupAttribGetBoolean(ih, "PASSWORD")) dwStyle |= ES_PASSWORD; @@ -1950,8 +1970,8 @@ void iupdrvTextInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, winTextSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NOT_MAPPED);  /* Overwrite Visual */ - iupClassRegisterAttribute(ic, "BGCOLOR", NULL, winTextSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_NOT_MAPPED);  - iupClassRegisterAttribute(ic, "VISIBLE", iupBaseGetVisibleAttrib, winTextSetVisibleAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "BGCOLOR", NULL, winTextSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_DEFAULT);  + iupClassRegisterAttribute(ic, "VISIBLE", iupBaseGetVisibleAttrib, winTextSetVisibleAttrib, "YES", "NO", IUPAF_DEFAULT);  /* Special */ iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "TXTFGCOLOR", IUPAF_NOT_MAPPED); /* usually black */  diff --git a/iup/src/win/iupwin_toggle.c b/iup/src/win/iupwin_toggle.c index fcaa438..c17f594 100755 --- a/iup/src/win/iupwin_toggle.c +++ b/iup/src/win/iupwin_toggle.c @@ -35,7 +35,9 @@  void iupdrvToggleAddCheckBox(int *x, int *y) { - (*x) += 16+6; + (*x) += 16+8; + if (!iupwin_comctl32ver6) + (*x) += 4; if ((*y) < 16) (*y) = 16; /* minimum height */ }  @@ -229,7 +231,7 @@ static int winToggleSetImageAttrib(Ihandle* ih, const char* value) iupAttribSetStr(ih, "IMAGE", (char*)value);  if (iupwin_comctl32ver6) - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); else { int check = SendMessage(ih->handle, BM_GETCHECK, 0L, 0L); @@ -249,7 +251,7 @@ static int winToggleSetImInactiveAttrib(Ihandle* ih, const char* value) iupAttribSetStr(ih, "IMINACTIVE", (char*)value);  if (iupwin_comctl32ver6) - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); else { int check = SendMessage(ih->handle, BM_GETCHECK, 0L, 0L); @@ -269,7 +271,7 @@ static int winToggleSetImPressAttrib(Ihandle* ih, const char* value) iupAttribSetStr(ih, "IMPRESS", (char*)value);  if (iupwin_comctl32ver6) - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); else { int check = SendMessage(ih->handle, BM_GETCHECK, 0L, 0L); @@ -339,7 +341,7 @@ static int winToggleSetActiveAttrib(Ihandle* ih, const char* value) if (iupwin_comctl32ver6) { iupBaseSetActiveAttrib(ih, value); - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); return 0; } else @@ -382,11 +384,21 @@ static int winToggleSetPaddingAttrib(Ihandle* ih, const char* value) iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');  if (ih->handle && iupwin_comctl32ver6 && ih->data->type == IUP_TOGGLE_IMAGE) - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih);  return 0; }  +static int winToggleSetUpdateAttrib(Ihandle* ih, const char* value) +{ + (void)value; + + if (ih->handle) + iupdrvPostRedraw(ih); /* Post a redraw */ + + return 1; +} + static int winToggleSetBgColorAttrib(Ihandle* ih, const char* value) { (void)value; @@ -395,7 +407,7 @@ static int winToggleSetBgColorAttrib(Ihandle* ih, const char* value) /* update internal image cache for controls that have the IMAGE attribute */ iupAttribSetStr(ih, "BGCOLOR", value); iupImageUpdateParent(ih); - iupdrvDisplayRedraw(ih); + iupdrvRedrawNow(ih); } return 1; } @@ -591,7 +603,7 @@ static int winToggleMapMethod(Ihandle* ih) { Ihandle* radio = iupRadioFindToggleParent(ih); char* value; - DWORD dwStyle = WS_CHILD |  + DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | BS_NOTIFY; /* necessary because of the base messages */  if (!ih->parent) @@ -673,11 +685,11 @@ void iupdrvToggleInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "BGCOLOR", winToggleGetBgColorAttrib, winToggleSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);   /* Special */ - iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, "DLGFGCOLOR", NULL, IUPAF_NOT_MAPPED); /* force the new default value */  + iupClassRegisterAttribute(ic, "FGCOLOR", NULL, winToggleSetUpdateAttrib, "DLGFGCOLOR", NULL, IUPAF_NOT_MAPPED); /* force the new default value */  iupClassRegisterAttribute(ic, "TITLE", iupdrvBaseGetTitleAttrib, winToggleSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);  /* IupToggle only */ - iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, NULL, IUPAF_SAMEASSYSTEM, "ACENTER:ACENTER", IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, winToggleSetUpdateAttrib, IUPAF_SAMEASSYSTEM, "ACENTER:ACENTER", IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "IMAGE", NULL, winToggleSetImageAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "IMINACTIVE", NULL, winToggleSetImInactiveAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "IMPRESS", NULL, winToggleSetImPressAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); diff --git a/iup/src/win/iupwin_tree.c b/iup/src/win/iupwin_tree.c index e6877dc..4a5f8be 100755 --- a/iup/src/win/iupwin_tree.c +++ b/iup/src/win/iupwin_tree.c @@ -31,17 +31,19 @@ #include "iupwin_draw.h" #include "iupwin_info.h"  + typedef struct _winTreeItemData { COLORREF color; unsigned char kind; - void* userdata; HFONT hFont; short image; short image_expanded; } winTreeItemData;  -#ifndef TVN_ITEMCHANGING /* Vista Only */ +/* Vista Only */ + +#ifndef TVN_ITEMCHANGING  typedef struct tagNMTVITEMCHANGE { NMHDR hdr; UINT uChanged; @@ -54,257 +56,125 @@ typedef struct tagNMTVITEMCHANGE { #define TVN_ITEMCHANGINGW (TVN_FIRST-17)  #endif  -static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem); -typedef int (*winTreeNodeFunc)(Ihandle* ih, HTREEITEM hItem, void* userdata); - -static int winTreeForEach(Ihandle* ih, HTREEITEM hItem, winTreeNodeFunc func, void* userdata) -{ - HTREEITEM hItemChild; - - if (!hItem) - hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); +#ifndef TVS_EX_DOUBLEBUFFER +#define TVS_EX_DOUBLEBUFFER 0x0004 +#endif  - while(hItem != NULL) - { - if (!func(ih, hItem, userdata)) - return 0; +#ifndef TVM_SETEXTENDEDSTYLE +#define TVM_SETEXTENDEDSTYLE (TV_FIRST + 44) +#endif  - hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); - if (hItemChild) - { - /* Recursively traverse child items */ - if (!winTreeForEach(ih, hItemChild, func, userdata)) - return 0; - }  - /* Go to next sibling item */ - hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); - } +static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem);  - return 1; -}  /*****************************************************************************/ /* FINDING ITEMS */ /*****************************************************************************/ -static HTREEITEM winTreeFindNodeID(Ihandle* ih, HTREEITEM hItem, HTREEITEM hNode) -{ - TVITEM item; - winTreeItemData* itemData; - - while(hItem != NULL) - { - /* ID control to traverse items */ - ih->data->id_control++; - - /* StateID founded! */ - if(hItem == hNode) - return hItem;  - /* Get hItem attributes */ - item.hItem = hItem; - item.mask = TVIF_HANDLE|TVIF_PARAM; - SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); - itemData = (winTreeItemData*)item.lParam; - - /* Check whether we have child items */ - if (itemData->kind == ITREE_BRANCH) - { - /* Recursively traverse child items */ - HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); - hItemChild = winTreeFindNodeID(ih, hItemChild, hNode); - - /* StateID founded! */ - if(hItemChild) - return hItemChild; - } - /* Go to next sibling item */ - hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); - } - - return NULL; +InodeHandle* iupdrvTreeGetFocusNode(Ihandle* ih) +{ + return (InodeHandle*)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0); }  -static int winTreeGetNodeId(Ihandle* ih, HTREEITEM hItem) +static HTREEITEM winTreeFindNodeXY(Ihandle* ih, int x, int y) { - HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); - ih->data->id_control = -1; - if (winTreeFindNodeID(ih, hItemRoot, hItem)) - return ih->data->id_control; - else - return -1; + TVHITTESTINFO info; + info.pt.x = x; + info.pt.y = y; + return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info); }  -static HTREEITEM winTreeFindUserDataID(Ihandle* ih, HTREEITEM hItem, void* userdata) +static HTREEITEM winTreeFindNodePointed(Ihandle* ih) { - TVITEM item; - winTreeItemData* itemData; - - while(hItem != NULL) - { - /* ID control to traverse items */ - ih->data->id_control++; - - /* Get hItem attributes */ - item.hItem = hItem; - item.mask = TVIF_HANDLE|TVIF_PARAM; - SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); - itemData = (winTreeItemData*)item.lParam; - - /* userdata founded! */ - if(itemData->userdata == userdata) - return hItem; - - /* Check whether we have child items */ - if (itemData->kind == ITREE_BRANCH) - { - /* Recursively traverse child items */ - HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); - hItemChild = winTreeFindUserDataID(ih, hItemChild, userdata); - - /* userdata founded! */ - if (hItemChild) - return hItemChild; - } - - /* Go to next sibling item */ - hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); - } - - return NULL; + TVHITTESTINFO info; + DWORD pos = GetMessagePos(); + info.pt.x = LOWORD(pos); + info.pt.y = HIWORD(pos); + ScreenToClient(ih->handle, &info.pt); + return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info); }  -static int winTreeGetUserDataId(Ihandle* ih, void* userdata) +int iupwinGetColor(const char* value, COLORREF *color) { - HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); - ih->data->id_control = -1; - if (winTreeFindUserDataID(ih, hItemRoot, userdata)) - return ih->data->id_control; - else - return -1; + unsigned char r, g, b; + if (iupStrToRGB(value, &r, &g, &b)) + { + *color = RGB(r,g,b); + return 1; + } + return 0; }  -static HTREEITEM winTreeFindNodeFromID(Ihandle* ih, HTREEITEM hItem) +static void winTreeChildCountRec(Ihandle* ih, HTREEITEM hItem, int *count) { - TVITEM item; - winTreeItemData* itemData; - + hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); while(hItem != NULL) { - /* ID control to traverse items */ - ih->data->id_control--; - - /* StateID founded! */ - if(ih->data->id_control < 0) - return hItem; - - /* Get hItem attributes */ - item.hItem = hItem; - item.mask = TVIF_HANDLE|TVIF_PARAM; - SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); - itemData = (winTreeItemData*)item.lParam; - - /* Check whether we have child items */ - if (itemData->kind == ITREE_BRANCH) - { - /* Recursively traverse child items */ - HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); - hItemChild = winTreeFindNodeFromID(ih, hItemChild); + (*count)++;  - /* StateID founded! */ - if(ih->data->id_control < 0) - return hItemChild; - } + /* go recursive to children */ + winTreeChildCountRec(ih, hItem, count);  /* Go to next sibling item */ hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); } - - return hItem; }  -static HTREEITEM winTreeFindNodeFromString(Ihandle* ih, const char* name_id) +int iupdrvTreeTotalChildCount(Ihandle* ih, HTREEITEM hItem) { - if (name_id[0]) - { - HTREEITEM hRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); - iupStrToInt(name_id, &ih->data->id_control); - return winTreeFindNodeFromID(ih, hRoot); - } - else - return (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0); + int count = 0; + winTreeChildCountRec(ih, hItem, &count); + return count; }  -/* Recursively, find a new brother for the item - that will have its depth changed. Returns the new brother. */ -static HTREEITEM winTreeFindNewBrother(Ihandle* ih, HTREEITEM hBrotherItem) +static void winTreeChildRebuildCacheRec(Ihandle* ih, HTREEITEM hItem, int *id) { - TVITEM item; - winTreeItemData* itemData; - - while(hBrotherItem != NULL) + hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); + while(hItem != NULL) { - if(ih->data->id_control < 0) - return hBrotherItem; - - item.hItem = hBrotherItem; - item.mask = TVIF_HANDLE|TVIF_PARAM; - SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); - itemData = (winTreeItemData*)item.lParam; - - if (itemData->kind == ITREE_BRANCH) - { - HTREEITEM hItemChild; - - ih->data->id_control--; - hItemChild = winTreeFindNewBrother(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hBrotherItem)); + (*id)++; + ih->data->node_cache[*id].node_handle = hItem;  - if(ih->data->id_control < 0) - return hItemChild; - } + /* go recursive to children */ + winTreeChildRebuildCacheRec(ih, hItem, id);  - hBrotherItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hBrotherItem); + /* Go to next sibling item */ + hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); } - - return hBrotherItem; }  -static HTREEITEM winTreeFindNodePointed(Ihandle* ih) +static void winTreeRebuildNodeCache(Ihandle* ih, int id, HTREEITEM hItem) { - TVHITTESTINFO info; - DWORD pos = GetMessagePos(); - info.pt.x = LOWORD(pos); - info.pt.y = HIWORD(pos); - - ScreenToClient(ih->handle, &info.pt); -  - return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info); + ih->data->node_cache[id].node_handle = hItem; + winTreeChildRebuildCacheRec(ih, hItem, &id); }  -int iupwinGetColor(const char* value, COLORREF *color) -{ - unsigned char r, g, b; - if (iupStrToRGB(value, &r, &g, &b)) - { - *color = RGB(r,g,b); - return 1; - } - return 0; -}  /*****************************************************************************/ /* ADDING ITEMS */ /*****************************************************************************/ + +static void winTreeExpandItem(Ihandle* ih, HTREEITEM hItem, int expand); + void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* title, int add) { - TVITEM item, tviPrevItem; + TVITEM item; TVINSERTSTRUCT tvins; - HTREEITEM hPrevItem = winTreeFindNodeFromString(ih, name_id); - int kindPrev; + HTREEITEM hPrevItem = iupTreeGetNodeFromString(ih, name_id); + HTREEITEM hItemNew; winTreeItemData* itemData;  if (!hPrevItem) - return; + { + /* check if the root was really specified */ + int id = 0; + if (!iupStrToInt(name_id, &id) || id != -1) + return; + } + + if (!title) + title = "";  itemData = calloc(1, sizeof(winTreeItemData)); itemData->image = -1; @@ -318,83 +188,71 @@ void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* t iupwinGetColor(iupAttribGetStr(ih, "FGCOLOR"), &itemData->color);  if (kind == ITREE_BRANCH) - { item.iSelectedImage = item.iImage = (int)ih->data->def_image_collapsed; - - if (ih->data->add_expanded) - { - item.mask |= TVIF_STATE; - item.state = item.stateMask = TVIS_EXPANDED; - item.iSelectedImage = item.iImage = (int)ih->data->def_image_expanded; - } - } else item.iSelectedImage = item.iImage = (int)ih->data->def_image_leaf;  /* Save the heading level in the node's application-defined data area */ tvins.item = item;  - /* get the KIND attribute of node selected */  - tviPrevItem.hItem = hPrevItem; - tviPrevItem.mask = TVIF_PARAM|TVIF_CHILDREN;  - SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&tviPrevItem); - kindPrev = ((winTreeItemData*)tviPrevItem.lParam)->kind; - - /* Define the parent and the position to the new node inside - the list, using the KIND attribute of node selected */ - if (kindPrev == ITREE_BRANCH && add) - { - tvins.hParent = hPrevItem; - tvins.hInsertAfter = TVI_FIRST; /* insert the new node after item selected, as first child */ - } - else - { - tvins.hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hPrevItem); - tvins.hInsertAfter = hPrevItem; /* insert the new node after item selected */ - } - - /* Add the node to the tree-view control */ - SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); - - if (kindPrev == ITREE_BRANCH && tviPrevItem.cChildren==0) + if (hPrevItem) { - /* this is the first child, redraw to update the '+'/'-' buttons */ - iupdrvDisplayRedraw(ih); - } -} + int kindPrev; + TVITEM tviPrevItem;  -static void winTreeAddRootNode(Ihandle* ih) -{ - TVITEM item;  - TVINSERTSTRUCT tvins; - HTREEITEM hNewItem; - winTreeItemData* itemData; + /* get the KIND attribute of reference node */  + tviPrevItem.hItem = hPrevItem; + tviPrevItem.mask = TVIF_PARAM|TVIF_CHILDREN;  + SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&tviPrevItem); + kindPrev = ((winTreeItemData*)tviPrevItem.lParam)->kind;  - itemData = calloc(1, sizeof(winTreeItemData)); - itemData->image = -1; - itemData->image_expanded = -1; - itemData->kind = ITREE_BRANCH; + /* Define the parent and the position to the new node inside + the list, using the KIND attribute of reference node */ + if (kindPrev == ITREE_BRANCH && add) + { + /* depth+1 */ + tvins.hParent = hPrevItem; + tvins.hInsertAfter = TVI_FIRST; /* insert the new node after the reference node, as first child */ + } + else + { + /* same depth */ + tvins.hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hPrevItem); + tvins.hInsertAfter = hPrevItem; /* insert the new node after reference node */ + }  - item.mask = TVIF_PARAM | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;  - item.state = item.stateMask = TVIS_EXPANDED; - item.iSelectedImage = item.iImage = (int)ih->data->def_image_expanded; - item.lParam = (LPARAM)itemData; + /* Add the new node */ + hItemNew = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); + iupTreeAddToCache(ih, add, kindPrev, hPrevItem, hItemNew);  - iupwinGetColor(iupAttribGetStr(ih, "FGCOLOR"), &itemData->color); + if (kindPrev == ITREE_BRANCH && tviPrevItem.cChildren==0) /* was 0, now is 1 */ + { + /* this is the first child, redraw to update the '+'/'-' buttons */ + if (ih->data->add_expanded) + winTreeExpandItem(ih, hPrevItem, 1); + else + winTreeExpandItem(ih, hPrevItem, 0); + }  - /* Save the heading level in the node's application-defined data area */ - tvins.item = item;  - tvins.hInsertAfter = TVI_FIRST; - tvins.hParent = TVI_ROOT; + } + else + { + tvins.hInsertAfter = TVI_FIRST; + tvins.hParent = TVI_ROOT;  - /* Add the node to the tree-view control */ - hNewItem = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); + /* Add the new node */ + hItemNew = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); + iupTreeAddToCache(ih, 0, 0, NULL, hItemNew);  - /* MarkStart node */ - iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)hNewItem); + if (ih->data->node_count == 1) + { + /* MarkStart node */ + iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)hItemNew);  - /* Set the default VALUE */ - winTreeSetFocusNode(ih, hNewItem); + /* Set the default VALUE */ + winTreeSetFocusNode(ih, hItemNew); + } + } }  static int winTreeIsItemExpanded(Ihandle* ih, HTREEITEM hItem) @@ -408,13 +266,28 @@ static int winTreeIsItemExpanded(Ihandle* ih, HTREEITEM hItem)  static void winTreeExpandItem(Ihandle* ih, HTREEITEM hItem, int expand) { - if (expand == -1) - expand = !winTreeIsItemExpanded(ih, hItem); /* toggle */ + TVITEM item; + winTreeItemData* itemData; + + iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", "1"); + /* it only works if the branch has children */ + SendMessage(ih->handle, TVM_EXPAND, expand? TVE_EXPAND: TVE_COLLAPSE, (LPARAM)hItem); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", NULL); + + /* update image */ + item.hItem = hItem; + item.mask = TVIF_HANDLE|TVIF_PARAM; + SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); + itemData = (winTreeItemData*)item.lParam;  if (expand) - SendMessage(ih->handle, TVM_EXPAND, TVE_EXPAND, (LPARAM)hItem); + item.iSelectedImage = item.iImage = (itemData->image_expanded!=-1)? itemData->image_expanded: (int)ih->data->def_image_expanded; else - SendMessage(ih->handle, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hItem); + item.iSelectedImage = item.iImage = (itemData->image!=-1)? itemData->image: (int)ih->data->def_image_collapsed; + + item.hItem = hItem; + item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item); }  /*****************************************************************************/ @@ -445,12 +318,12 @@ static void winTreeExpandTree(Ihandle* ih, HTREEITEM hItem, int expand) /* SELECTING ITEMS */ /*****************************************************************************/  -static int winTreeIsItemSelected(Ihandle* ih, HTREEITEM hItem) +static int winTreeIsNodeSelected(Ihandle* ih, HTREEITEM hItem) { return ((SendMessage(ih->handle, TVM_GETITEMSTATE, (WPARAM)hItem, TVIS_SELECTED)) & TVIS_SELECTED)!=0; }  -static void winTreeSelectItem(Ihandle* ih, HTREEITEM hItem, int select) +static void winTreeSelectNode(Ihandle* ih, HTREEITEM hItem, int select) { TV_ITEM item; item.mask = TVIF_STATE | TVIF_HANDLE; @@ -458,16 +331,13 @@ static void winTreeSelectItem(Ihandle* ih, HTREEITEM hItem, int select) item.hItem = hItem;  if (select == -1) - select = !winTreeIsItemSelected(ih, hItem); + select = !winTreeIsNodeSelected(ih, hItem); /* toggle */  item.state = select ? TVIS_SELECTED : 0;  + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)&item); -} - -static HTREEITEM winTreeGetFocusNode(Ihandle* ih) -{ - return (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); }  /* ------------Comment from wxWidgets-------------------- @@ -475,17 +345,17 @@ static HTREEITEM winTreeGetFocusNode(Ihandle* ih) item without changing anything else. */ static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem) { - HTREEITEM hItemFocus = winTreeGetFocusNode(ih); + HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih); if (hItem != hItemFocus) { /* remember the selection state of the item */ - int wasSelected = winTreeIsItemSelected(ih, hItem); + int wasSelected = winTreeIsNodeSelected(ih, hItem); int wasFocusSelected = 0;  - if (iupwinIsVista()) + if (iupwinIsVistaOrNew() && iupwin_comctl32ver6) iupAttribSetStr(ih, "_IUPTREE_ALLOW_CHANGE", (char*)hItem); /* Vista Only */ else - wasFocusSelected = hItemFocus && winTreeIsItemSelected(ih, hItemFocus); + wasFocusSelected = hItemFocus && winTreeIsNodeSelected(ih, hItemFocus);  iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");  @@ -493,58 +363,42 @@ static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem) { /* prevent the tree from unselecting the old focus which it would do by default */ SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)NULL); /* remove the focus */ - winTreeSelectItem(ih, hItemFocus, 1); /* select again */ + winTreeSelectNode(ih, hItemFocus, 1); /* select again */ }  SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem); /* set focus, selection, and unselect the previous focus */  if (!wasSelected) - winTreeSelectItem(ih, hItem, 0); /* need to clear the selection if was not selected */ + winTreeSelectNode(ih, hItem, 0); /* need to clear the selection if was not selected */  iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); iupAttribSetStr(ih, "_IUPTREE_ALLOW_CHANGE", NULL); } }  -typedef struct _winTreeRange{ - HTREEITEM hItem1, hItem2; - char inside, clear; -}winTreeRange; - -static int winTreeSelectRangeFunc(Ihandle* ih, HTREEITEM hItem, winTreeRange* range) +static void winTreeSelectRange(Ihandle* ih, HTREEITEM hItem1, HTREEITEM hItem2, int clear) { - int end_range = 0; - - if (range->inside == 0) /* detect the range start */ + int i; + int id1 = iupTreeFindNodeId(ih, hItem1); + int id2 = iupTreeFindNodeId(ih, hItem2); + if (id2 == -1) id2 = ih->data->node_count-1; + if (id1 > id2) { - if (range->hItem1 == hItem) range->inside=1; - else if (range->hItem2 == hItem) range->inside=1; + int tmp = id1; + id1 = id2; + id2 = tmp; } - else if (range->inside == 1) /* detect the range end */ + + for (i = 0; i < ih->data->node_count; i++) { - if (range->hItem1 == hItem) end_range=1; - else if (range->hItem2 == hItem) end_range=1; + if (i < id1 || i > id2) + { + if (clear) + winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 0); + } + else + winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 1); } - - if (range->inside == 1) /* if inside, select */ - winTreeSelectItem(ih, hItem, 1); - else if (range->clear) /* if outside and clear, unselect */ - winTreeSelectItem(ih, hItem, 0); - - if (end_range || (range->inside && range->hItem1==range->hItem2)) - range->inside=-1; /* update after selecting the node */ - - return 1; -} - -static void winTreeSelectRange(Ihandle* ih, HTREEITEM hItemFrom, HTREEITEM hItemTo, int clear) -{ - winTreeRange range; - range.hItem1 = hItemFrom; - range.hItem2 = hItemTo; - range.inside = 0; - range.clear = (char)clear; - winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectRangeFunc, &range); }  static void winTreeSelectAll(Ihandle* ih) @@ -558,9 +412,10 @@ static void winTreeClearSelection(Ihandle* ih, HTREEITEM hItemExcept) winTreeSelectRange(ih, hItemExcept, hItemExcept, 1); }  -static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, void* userdata) +static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, int id, void* userdata) { - winTreeSelectItem(ih, hItem, -1); + (void)id; + winTreeSelectNode(ih, hItem, -1); (void)userdata; return 1; } @@ -568,14 +423,11 @@ static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, void* userdata) typedef struct _winTreeSelArray{ Iarray* markedArray; char is_handle; - int id_control; }winTreeSelArray;  -static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, winTreeSelArray* selarray) +static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, int id, winTreeSelArray* selarray) {  - selarray->id_control++; - - if (winTreeIsItemSelected(ih, hItem)) + if (winTreeIsNodeSelected(ih, hItem)) { if (selarray->is_handle) { @@ -587,7 +439,7 @@ static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, winTreeSelArra { int* intArrayData = (int*)iupArrayInc(selarray->markedArray); int i = iupArrayCount(selarray->markedArray); - intArrayData[i-1] = selarray->id_control; + intArrayData[i-1] = id; } }  @@ -599,10 +451,9 @@ static Iarray* winTreeGetSelectedArray(Ihandle* ih) Iarray* markedArray = iupArrayCreate(1, sizeof(HTREEITEM)); winTreeSelArray selarray; selarray.markedArray = markedArray; - selarray.id_control = -1; selarray.is_handle = 1;  - winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectedArrayFunc, &selarray); + iupTreeForEach(ih, (iupTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);  return markedArray; } @@ -612,10 +463,9 @@ static Iarray* winTreeGetSelectedArrayId(Ihandle* ih) Iarray* markedArray = iupArrayCreate(1, sizeof(int)); winTreeSelArray selarray; selarray.markedArray = markedArray; - selarray.id_control = -1; selarray.is_handle = 0;  - winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectedArrayFunc, &selarray); + iupTreeForEach(ih, (iupTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);  return markedArray; } @@ -625,7 +475,7 @@ static Iarray* winTreeGetSelectedArrayId(Ihandle* ih) /* COPYING ITEMS (Branches and its children) */ /*****************************************************************************/ /* Insert the copied item in a new location. Returns the new item. */ -static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent, HTREEITEM hPosition, int full_copy) +static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent, HTREEITEM hPosition, int is_copy) { TVITEM item;  TVINSERTSTRUCT tvins; @@ -637,34 +487,34 @@ static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent item.cchTextMax = 255; SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);  - if (full_copy) /* during a full copy the userdata reference is not copied */ + if (is_copy) /* during a copy the itemdata reference is not reused */ { /* create a new one */ winTreeItemData* itemDataNew = malloc(sizeof(winTreeItemData)); memcpy(itemDataNew, (void*)item.lParam, sizeof(winTreeItemData)); - itemDataNew->userdata = NULL; item.lParam = (LPARAM)itemDataNew; }  - /* Copy everything including user data reference */ + /* Copy everything including itemdata reference */ tvins.item = item;  tvins.hInsertAfter = hPosition; tvins.hParent = hParent;  - /* Add the node to the tree-view control */ + /* Add the new node */ + ih->data->node_count++; return (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); }  -static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int full_copy) +static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int is_copy) { HTREEITEM hChildSrc = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItemSrc); - HTREEITEM hNewItem = TVI_FIRST; + HTREEITEM hItemNew = TVI_FIRST; while (hChildSrc != NULL) { - hNewItem = winTreeCopyItem(ih, hChildSrc, hItemDst, hNewItem, full_copy); /* Use the same order they where enumerated */ + hItemNew = winTreeCopyItem(ih, hChildSrc, hItemDst, hItemNew, is_copy); /* Use the same order they where enumerated */  /* Recursively transfer all the items */ - winTreeCopyChildren(ih, hChildSrc, hNewItem, full_copy);  + winTreeCopyChildren(ih, hChildSrc, hItemNew, is_copy);   /* Go to next sibling item */ hChildSrc = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hChildSrc); @@ -672,11 +522,18 @@ static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItem }  /* Copies all items in a branch to a new location. Returns the new branch node. */ -static HTREEITEM winTreeCopyNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int full_copy) +static HTREEITEM winTreeCopyMoveNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int is_copy) { - HTREEITEM hNewItem, hParent; + HTREEITEM hItemNew, hParent; TVITEM item; winTreeItemData* itemDataDst; + int id_new, count, id_src, id_dst; + + int old_count = ih->data->node_count; + + id_src = iupTreeFindNodeId(ih, hItemSrc); + id_dst = iupTreeFindNodeId(ih, hItemDst); + id_new = id_dst+1; /* contains the position for a copy operation */  /* Get DST node attributes */ item.hItem = hItemDst; @@ -691,31 +548,64 @@ static HTREEITEM winTreeCopyNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hIte hItemDst = TVI_FIRST; } else - {  + {  + if (itemDataDst->kind == ITREE_BRANCH) + { + int child_count = iupdrvTreeTotalChildCount(ih, hItemDst); + id_new += child_count; + } + /* copy as next brother of item or collapsed branch */ hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItemDst); }  - hNewItem = winTreeCopyItem(ih, hItemSrc, hParent, hItemDst, full_copy); + /* move to the same place does nothing */ + if (!is_copy && id_new == id_src) + return NULL; + + hItemNew = winTreeCopyItem(ih, hItemSrc, hParent, hItemDst, is_copy); + + winTreeCopyChildren(ih, hItemSrc, hItemNew, is_copy); + + count = ih->data->node_count - old_count; + iupTreeCopyMoveCache(ih, id_src, id_new, count, is_copy); + + if (!is_copy) + { + /* Deleting the node (and its children) from the old position */ + /* do not delete the itemdata, we reuse the references in CopyNode */ + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemSrc); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);  - winTreeCopyChildren(ih, hItemSrc, hNewItem, full_copy); + /* restore count, because we remove src */ + ih->data->node_count = old_count;  - return hNewItem; + /* compensate position for a move */ + if (id_new > id_src) + id_new -= count; + } + + winTreeRebuildNodeCache(ih, id_new, hItemNew); + + return hItemNew; }  /*****************************************************************************/ /* MANIPULATING IMAGES */ /*****************************************************************************/ -static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode) +static void winTreeUpdateImages(Ihandle* ih, int mode) { - HTREEITEM hItemChild; + HTREEITEM hItem; TVITEM item; winTreeItemData* itemData; + int i;  /* called when one of the default images is changed */ - - while(hItem != NULL) + for (i = 0; i < ih->data->node_count; i++) { + hItem = ih->data->node_cache[i].node_handle; + /* Get node attributes */ item.hItem = hItem; item.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; @@ -742,10 +632,6 @@ static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode) SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item); } } - - /* Recursively traverse child items */ - hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); - winTreeUpdateImages(ih, hItemChild, mode); } else { @@ -756,9 +642,6 @@ static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode) SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item); } } - - /* Go to next sibling node */ - hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); } }  @@ -828,29 +711,57 @@ static int winTreeCallBranchLeafCb(Ihandle* ih, HTREEITEM hItem)  if (itemData->kind == ITREE_BRANCH) { + if (iupAttribGet(ih, "_IUPTREE_IGNORE_BRANCH_CB")) + return IUP_DEFAULT; + if (item.state & TVIS_EXPANDED) { IFni cbBranchClose = (IFni)IupGetCallback(ih, "BRANCHCLOSE_CB"); if (cbBranchClose) - return cbBranchClose(ih, winTreeGetNodeId(ih, hItem)); + return cbBranchClose(ih, iupTreeFindNodeId(ih, hItem)); } else { IFni cbBranchOpen = (IFni)IupGetCallback(ih, "BRANCHOPEN_CB"); if (cbBranchOpen) - return cbBranchOpen(ih, winTreeGetNodeId(ih, hItem)); + return cbBranchOpen(ih, iupTreeFindNodeId(ih, hItem)); } } else { IFni cbExecuteLeaf = (IFni)IupGetCallback(ih, "EXECUTELEAF_CB"); if (cbExecuteLeaf) - return cbExecuteLeaf(ih, winTreeGetNodeId(ih, hItem)); + return cbExecuteLeaf(ih, iupTreeFindNodeId(ih, hItem)); }  return IUP_DEFAULT; }  +static void winTreeCallMultiUnSelectionCb(Ihandle* ih) +{ + IFnIi cbMulti = (IFnIi)IupGetCallback(ih, "MULTIUNSELECTION_CB"); + IFnii cbSelec = (IFnii)IupGetCallback(ih, "SELECTION_CB"); + if (cbSelec || cbMulti) + { + Iarray* markedArray = winTreeGetSelectedArrayId(ih); + int* id_hitem = (int*)iupArrayGetData(markedArray); + int i, count = iupArrayCount(markedArray); + + if (count > 1) + { + if (cbMulti) + cbMulti(ih, id_hitem, iupArrayCount(markedArray)); + else + { + for (i=0; idata->mark_mode == ITREE_MARK_MULTIPLE && IupGetCallback(ih,"MULTISELECTION_CB")) { if ((GetKeyState(VK_SHIFT) & 0x8000)) @@ -894,7 +807,9 @@ static void winTreeCallSelectionCb(Ihandle* ih, int status, HTREEITEM hItem) if (iupAttribGet(ih, "_IUPTREE_IGNORE_SELECTION_CB")) return;  - cbSelec(ih, winTreeGetNodeId(ih, hItem), status); + id = iupTreeFindNodeId(ih, hItem); + if (id != -1) + cbSelec(ih, id, status); } }  @@ -911,8 +826,8 @@ static int winTreeCallDragDropCb(Ihandle* ih, HTREEITEM hItemDrag, HTREEITEM hIt  if (cbDragDrop) { - int drag_id = winTreeGetNodeId(ih, hItemDrag); - int drop_id = winTreeGetNodeId(ih, hItemDrop); + int drag_id = iupTreeFindNodeId(ih, hItemDrag); + int drop_id = iupTreeFindNodeId(ih, hItemDrop); return cbDragDrop(ih, drag_id, drop_id, is_shift, *is_ctrl); }  @@ -929,8 +844,8 @@ static int winTreeSetImageBranchExpandedAttrib(Ihandle* ih, const char* value) { ih->data->def_image_expanded = (void*)winTreeGetImageIndex(ih, value);  - /* Update all images, starting at root node */ - winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_EXPANDED); + /* Update all images */ + winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_EXPANDED);  return 1; } @@ -939,8 +854,8 @@ static int winTreeSetImageBranchCollapsedAttrib(Ihandle* ih, const char* value) { ih->data->def_image_collapsed = (void*)winTreeGetImageIndex(ih, value);  - /* Update all images, starting at root node */ - winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_COLLAPSED); + /* Update all images */ + winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_COLLAPSED);  return 1; } @@ -949,8 +864,8 @@ static int winTreeSetImageLeafAttrib(Ihandle* ih, const char* value) { ih->data->def_image_leaf = (void*)winTreeGetImageIndex(ih, value);  - /* Update all images, starting at root node */ - winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_LEAF); + /* Update all images */ + winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_LEAF);  return 1; } @@ -959,7 +874,7 @@ static int winTreeSetImageExpandedAttrib(Ihandle* ih, const char* name_id, const { TVITEM item; winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return 0;  @@ -986,7 +901,7 @@ static int winTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v { TVITEM item; winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return 0;  @@ -1025,7 +940,7 @@ static int winTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v  static int winTreeSetTopItemAttrib(Ihandle* ih, const char* value) { - HTREEITEM hItem = winTreeFindNodeFromString(ih, value); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, value); if (hItem) SendMessage(ih->handle, TVM_ENSUREVISIBLE, 0, (LPARAM)hItem); return 0; @@ -1056,9 +971,8 @@ static int winTreeSetSpacingAttrib(Ihandle* ih, const char* value) static int winTreeSetExpandAllAttrib(Ihandle* ih, const char* value) { HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); - HTREEITEM hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItemRoot); /* skip the root node that is always expanded */ int expand = iupStrBoolean(value); - winTreeExpandTree(ih, hItem, expand); + winTreeExpandTree(ih, hItemRoot, expand); return 0; }  @@ -1131,7 +1045,7 @@ static char* winTreeGetTitle(Ihandle* ih, HTREEITEM hItem)  static char* winTreeGetTitleAttrib(Ihandle* ih, const char* name_id) { - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return NULL; return winTreeGetTitle(ih, hItem); @@ -1140,10 +1054,13 @@ static char* winTreeGetTitleAttrib(Ihandle* ih, const char* name_id) static int winTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* value) { TVITEM item;  - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return 0;  + if (!value) + value = ""; + item.hItem = hItem; item.mask = TVIF_HANDLE | TVIF_TEXT;  item.pszText = (char*)value; @@ -1151,60 +1068,11 @@ static int winTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* v return 0; }  -static char* winTreeGetFindUserDataAttrib(Ihandle* ih, const char* name_id) -{ - int id; - char* str = (char*)(name_id+1); /* skip ':' */ - void* userdata = NULL; - if (sscanf(str, "%p", &userdata)!=1) - return NULL; - id = winTreeGetUserDataId(ih, userdata); - if (id == -1) - return NULL; - str = iupStrGetMemory(16); - sprintf(str, "%d", id); - return str; -} - -static char* winTreeGetUserDataAttrib(Ihandle* ih, const char* name_id) -{ - TVITEM item; - winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); - if (!hItem) - return NULL; - - item.hItem = hItem; - item.mask = TVIF_HANDLE | TVIF_PARAM; - SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); - itemData = (winTreeItemData*)item.lParam; - - return itemData->userdata; -} - -static int winTreeSetUserDataAttrib(Ihandle* ih, const char* name_id, const char* value) -{ - TVITEM item;  - winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); - if (!hItem) - return 0; - - item.hItem = hItem; - item.mask = TVIF_HANDLE | TVIF_PARAM; - SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); - itemData = (winTreeItemData*)item.lParam; - - itemData->userdata = (void*)value; - - return 0; -} - static char* winTreeGetTitleFontAttrib(Ihandle* ih, const char* name_id) { TVITEM item; winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return NULL;  @@ -1220,7 +1088,7 @@ static int winTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const cha { TVITEM item;  winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return 0;  @@ -1230,11 +1098,23 @@ static int winTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const cha itemData = (winTreeItemData*)item.lParam;  if (value) + { itemData->hFont = iupwinGetHFont(value); + if (itemData->hFont) + { + TV_ITEM item; + item.mask = TVIF_STATE | TVIF_HANDLE | TVIF_TEXT; + item.stateMask = TVIS_BOLD; + item.hItem = hItem; + item.pszText = winTreeGetTitle(ih, hItem); /* reset text to resize item */ + item.state = (strstr(value, "Bold")||strstr(value, "BOLD"))? TVIS_BOLD: 0; + SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)&item); + } + } else itemData->hFont = NULL;  - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih);  return 0; } @@ -1259,7 +1139,7 @@ static char* winTreeGetStateAttrib(Ihandle* ih, const char* name_id) { TVITEM item; winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return NULL;  @@ -1281,25 +1161,34 @@ static char* winTreeGetStateAttrib(Ihandle* ih, const char* name_id)  static int winTreeSetStateAttrib(Ihandle* ih, const char* name_id, const char* value) { - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + TVITEM item; + winTreeItemData* itemData; + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return 0;  - winTreeExpandItem(ih, hItem, iupStrEqualNoCase(value, "EXPANDED")); + /* Get Children: branch or leaf */ + item.mask = TVIF_HANDLE|TVIF_PARAM;  + item.hItem = hItem; + SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); + itemData = (winTreeItemData*)item.lParam; + + if (itemData->kind == ITREE_BRANCH) + winTreeExpandItem(ih, hItem, iupStrEqualNoCase(value, "EXPANDED")); + return 0; }  static char* winTreeGetDepthAttrib(Ihandle* ih, const char* name_id) { - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); - HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); - int depth = 0; + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); + int depth = -1; char* str;  - if (!hItem) + if (!hItem)  return NULL;  - while((hItemRoot != hItem) && (hItem != NULL)) + while(hItem != NULL) { hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem); depth++; @@ -1314,12 +1203,13 @@ static int winTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char { HTREEITEM hItemDst, hParent, hItemSrc;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; - hItemSrc = winTreeFindNodeFromString(ih, name_id); + + hItemSrc = iupTreeGetNodeFromString(ih, name_id); if (!hItemSrc) return 0; - hItemDst = winTreeFindNodeFromString(ih, value); + hItemDst = iupTreeGetNodeFromString(ih, value); if (!hItemDst) return 0;  @@ -1332,11 +1222,8 @@ static int winTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char return 0; }  - /* Copying the node and its children to the new position */ - winTreeCopyNode(ih, hItemSrc, hItemDst, 0); /* not a full copy, preserve user data */ - - /* do not delete the user data, we copy the references in CopyNode */ - SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemSrc); + /* Move the node and its children to the new position */ + winTreeCopyMoveNode(ih, hItemSrc, hItemDst, 0);  return 0; } @@ -1345,12 +1232,13 @@ static int winTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char { HTREEITEM hItemDst, hParent, hItemSrc;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; - hItemSrc = winTreeFindNodeFromString(ih, name_id); + + hItemSrc = iupTreeGetNodeFromString(ih, name_id); if (!hItemSrc) return 0; - hItemDst = winTreeFindNodeFromString(ih, value); + hItemDst = iupTreeGetNodeFromString(ih, value); if (!hItemDst) return 0;  @@ -1363,8 +1251,8 @@ static int winTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char return 0; }  - /* Copying the node and its children to the new position */ - winTreeCopyNode(ih, hItemSrc, hItemDst, 1); + /* Copy the node and its children to the new position */ + winTreeCopyMoveNode(ih, hItemSrc, hItemDst, 1);  return 0; } @@ -1375,7 +1263,7 @@ static char* winTreeGetColorAttrib(Ihandle* ih, const char* name_id) char* str; TVITEM item; winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return NULL;  @@ -1398,7 +1286,7 @@ static int winTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* v unsigned char r, g, b; TVITEM item; winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return 0;  @@ -1410,7 +1298,7 @@ static int winTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* v if (iupStrToRGB(value, &r, &g, &b)) { itemData->color = RGB(r,g,b); - iupdrvDisplayUpdate(ih); + iupdrvPostRedraw(ih); }  return 0; @@ -1435,7 +1323,7 @@ static char* winTreeGetChildCountAttrib(Ihandle* ih, const char* name_id) { int count; char* str; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return NULL;  @@ -1454,18 +1342,11 @@ static char* winTreeGetChildCountAttrib(Ihandle* ih, const char* name_id) return str; }  -static char* winTreeGetCountAttrib(Ihandle* ih) -{ - char* str = iupStrGetMemory(10); - sprintf(str, "%d", (int)SendMessage(ih->handle, TVM_GETCOUNT, 0, 0)); - return str; -} - static char* winTreeGetKindAttrib(Ihandle* ih, const char* name_id) { TVITEM item;  winTreeItemData* itemData; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return NULL;  @@ -1483,7 +1364,7 @@ static char* winTreeGetKindAttrib(Ihandle* ih, const char* name_id) static char* winTreeGetParentAttrib(Ihandle* ih, const char* name_id) { char* str; - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return NULL;  @@ -1492,15 +1373,13 @@ static char* winTreeGetParentAttrib(Ihandle* ih, const char* name_id) return NULL;  str = iupStrGetMemory(10); - sprintf(str, "%d", winTreeGetNodeId(ih, hItem)); + sprintf(str, "%d", iupTreeFindNodeId(ih, hItem)); return str; }  -static void winTreeDelNodeData(Ihandle* ih, HTREEITEM hItem) +static void winTreeRemoveItemData(Ihandle* ih, HTREEITEM hItem, IFns cb, int id) { TVITEM item;  - HTREEITEM hChildItem; - item.hItem = hItem; item.mask = TVIF_HANDLE|TVIF_PARAM;  if (SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item)) @@ -1508,81 +1387,153 @@ static void winTreeDelNodeData(Ihandle* ih, HTREEITEM hItem) winTreeItemData* itemData = (winTreeItemData*)item.lParam; if (itemData) { - IFnis cb = (IFnis)IupGetCallback(ih, "NODEREMOVED_CB"); - if (cb) cb(ih, winTreeGetNodeId(ih, hItem), (char*)itemData->userdata); + if (cb)  + cb(ih, (char*)ih->data->node_cache[id].userdata); + free(itemData); item.lParam = (LPARAM)NULL; SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item); } } +} + +static void winTreeRemoveNodeDataRec(Ihandle* ih, HTREEITEM hItem, IFns cb, int *id) +{ + int old_id = *id;  - hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); + /* Check whether we have child items */ + /* remove from children first */ + HTREEITEM hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); while (hChildItem) { - winTreeDelNodeData(ih, hChildItem); + /* go recursive to children */ + winTreeRemoveNodeDataRec(ih, hChildItem, cb, id); + + /* Go to next sibling item */ hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hChildItem); } + + /* actually do it for the node */ + ih->data->node_count--; + (*id)++; + + winTreeRemoveItemData(ih, hItem, cb, old_id); +} + +static void winTreeRemoveNodeData(Ihandle* ih, HTREEITEM hItem, int call_cb) +{ + IFns cb = call_cb? (IFns)IupGetCallback(ih, "NODEREMOVED_CB"): NULL; + int old_count = ih->data->node_count; + int id = iupTreeFindNodeId(ih, hItem); + int old_id = id; + + winTreeRemoveNodeDataRec(ih, hItem, cb, &id); + + if (call_cb) + iupTreeDelFromCache(ih, old_id, old_count-ih->data->node_count); +} + +static void winTreeRemoveAllNodeData(Ihandle* ih, int call_cb) +{ + IFns cb = call_cb? (IFns)IupGetCallback(ih, "NODEREMOVED_CB"): NULL; + int i, old_count = ih->data->node_count; + HTREEITEM hItem; + + for (i = 0; i < ih->data->node_count; i++) + { + hItem = ih->data->node_cache[i].node_handle; + winTreeRemoveItemData(ih, hItem, cb, i); + } + + ih->data->node_count = 0; + + if (call_cb) + iupTreeDelFromCache(ih, 0, old_count); }  static int winTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char* value) { - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; - if(iupStrEqualNoCase(value, "SELECTED")) /* selected here means the specified one */ + if (iupStrEqualNoCase(value, "ALL")) { - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); - HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); + winTreeRemoveAllNodeData(ih, 1);  - /* the root node can't be deleted */ - if(!hItem || hItem == hItemRoot) + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); + return 0; + } + if (iupStrEqualNoCase(value, "SELECTED")) /* selected here means the reference one */ + { + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); + if(!hItem) return 0;  - /* deleting the specified node (and it's children) */ - winTreeDelNodeData(ih, hItem); + /* deleting the reference node (and it's children) */ + winTreeRemoveNodeData(ih, hItem, 1); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItem); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);  return 0; } - else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the specified one */ + else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the reference node */ { - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); HTREEITEM hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);  if(!hItem) return 0;  - /* deleting the selected node's children */ + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + + /* deleting the reference node children */ while (hChildItem) { - winTreeDelNodeData(ih, hChildItem); + winTreeRemoveNodeData(ih, hChildItem, 1); SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hChildItem); hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); }  + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); return 0; } else if(iupStrEqualNoCase(value, "MARKED")) { - int i, count; - Iarray* markedArray; - HTREEITEM* hItemArrayData; - HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); + int i, del_focus = 0; + HTREEITEM hItemFocus;  - /* Delete the array of marked nodes */ - markedArray = winTreeGetSelectedArray(ih); - hItemArrayData = (HTREEITEM*)iupArrayGetData(markedArray); - count = iupArrayCount(markedArray); + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + hItemFocus = iupdrvTreeGetFocusNode(ih);  - for(i = 0; i < count; i++) + for(i = 1; i < ih->data->node_count; /* increment only if not removed */) { - if (hItemArrayData[i] != hItemRoot) /* the root node can't be deleted */ + if (winTreeIsNodeSelected(ih, ih->data->node_cache[i].node_handle)) { - winTreeDelNodeData(ih, hItemArrayData[i]); - SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemArrayData[i]); + HTREEITEM hItem = ih->data->node_cache[i].node_handle; + if (hItemFocus == hItem) + { + del_focus = 1; + i++; + } + else + { + winTreeRemoveNodeData(ih, hItem, 1); + SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItem); + } } + else + i++; }  - iupArrayDestroy(markedArray); + if (del_focus) + { + winTreeRemoveNodeData(ih, hItemFocus, 1); + SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemFocus); + } + + iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);  return 0; } @@ -1592,22 +1543,13 @@ static int winTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char*  static int winTreeSetRenameAttrib(Ihandle* ih, const char* value) {  - HTREEITEM hItemFocus = winTreeGetFocusNode(ih); if (ih->data->show_rename) { - IFni cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB"); - if (cbShowRename) - cbShowRename(ih, winTreeGetNodeId(ih, hItemFocus)); - + HTREEITEM hItemFocus; SetFocus(ih->handle); /* the tree must have focus to activate the edit */ + hItemFocus = iupdrvTreeGetFocusNode(ih); SendMessage(ih->handle, TVM_EDITLABEL, 0, (LPARAM)hItemFocus); } - else - { - IFnis cbRenameNode = (IFnis)IupGetCallback(ih, "RENAMENODE_CB"); - if (cbRenameNode) - cbRenameNode(ih, winTreeGetNodeId(ih, hItemFocus), winTreeGetTitle(ih, hItemFocus));  - }  (void)value; return 0; @@ -1615,11 +1557,11 @@ static int winTreeSetRenameAttrib(Ihandle* ih, const char* value)  static char* winTreeGetMarkedAttrib(Ihandle* ih, const char* name_id) { - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return NULL;  - if (winTreeIsItemSelected(ih, hItem)) + if (winTreeIsNodeSelected(ih, hItem)) return "YES"; else  return "NO"; @@ -1627,17 +1569,23 @@ static char* winTreeGetMarkedAttrib(Ihandle* ih, const char* name_id)  static int winTreeSetMarkedAttrib(Ihandle* ih, const char* name_id, const char* value) { - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return 0;  - winTreeSelectItem(ih, hItem, iupStrBoolean(value)); + if (ih->data->mark_mode==ITREE_MARK_SINGLE) + { + HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih); + winTreeSelectNode(ih, hItemFocus, 0); + } + + winTreeSelectNode(ih, hItem, iupStrBoolean(value)); return 0; }  static int winTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id) { - HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id); if (!hItem) return 0;  @@ -1649,15 +1597,59 @@ static int winTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id) static char* winTreeGetValueAttrib(Ihandle* ih) { char* str; - HTREEITEM hItemFocus = winTreeGetFocusNode(ih); + HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih); if (!hItemFocus) - return "0"; /* default VALUE is root */ + { + if (ih->data->node_count) + return "0"; /* default VALUE is root */ + else + return "-1"; + }  str = iupStrGetMemory(16); - sprintf(str, "%d", winTreeGetNodeId(ih, hItemFocus)); + sprintf(str, "%d", iupTreeFindNodeId(ih, hItemFocus)); + return str; +} + +static char* winTreeGetMarkedNodesAttrib(Ihandle* ih) +{ + char* str = iupStrGetMemory(ih->data->node_count+1); + int i; + + for (i=0; idata->node_count; i++) + { + if (winTreeIsNodeSelected(ih, ih->data->node_cache[i].node_handle)) + str[i] = '+'; + else + str[i] = '-'; + } + + str[ih->data->node_count] = 0; return str; }  +static int winTreeSetMarkedNodesAttrib(Ihandle* ih, const char* value) +{ + int count, i; + + if (ih->data->mark_mode==ITREE_MARK_SINGLE || !value) + return 0; + + count = strlen(value); + if (count > ih->data->node_count) + count = ih->data->node_count; + + for (i=0; idata->node_cache[i].node_handle, 1); + else + winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 0); + } + + return 0; +} + static int winTreeSetMarkAttrib(Ihandle* ih, const char* value) { if (ih->data->mark_mode==ITREE_MARK_SINGLE) @@ -1665,7 +1657,7 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)  if(iupStrEqualNoCase(value, "BLOCK")) { - HTREEITEM hItemFocus = winTreeGetFocusNode(ih); + HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih); winTreeSelectRange(ih, (HTREEITEM)iupAttribGet(ih, "_IUPTREE_MARKSTART_NODE"), hItemFocus, 0); } else if(iupStrEqualNoCase(value, "CLEARALL")) @@ -1673,14 +1665,14 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value) else if(iupStrEqualNoCase(value, "MARKALL")) winTreeSelectAll(ih); else if(iupStrEqualNoCase(value, "INVERTALL")) /* INVERTALL *MUST* appear before INVERT, or else INVERTALL will never be called. */ - winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeInvertSelectFunc, NULL); + iupTreeForEach(ih, (iupTreeNodeFunc)winTreeInvertSelectFunc, NULL); else if(iupStrEqualPartial(value, "INVERT")) /* iupStrEqualPartial allows the use of "INVERTid" form */ { - HTREEITEM hItem = winTreeFindNodeFromString(ih, &value[strlen("INVERT")]); + HTREEITEM hItem = iupTreeGetNodeFromString(ih, &value[strlen("INVERT")]); if (!hItem) return 0;  - winTreeSelectItem(ih, hItem, -1); /* toggle */ + winTreeSelectNode(ih, hItem, -1); /* toggle */ } else { @@ -1690,10 +1682,10 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value) if (iupStrToStrStr(value, str1, str2, '-')!=2) return 0;  - hItem1 = winTreeFindNodeFromString(ih, str1); + hItem1 = iupTreeGetNodeFromString(ih, str1); if (!hItem1)  return 0; - hItem2 = winTreeFindNodeFromString(ih, str2); + hItem2 = iupTreeGetNodeFromString(ih, str2); if (!hItem2)  return 0;  @@ -1711,9 +1703,9 @@ static int winTreeSetValueAttrib(Ihandle* ih, const char* value) if (winTreeSetMarkAttrib(ih, value)) return 0;  - hItemFocus = winTreeGetFocusNode(ih); + hItemFocus = iupdrvTreeGetFocusNode(ih);  - if(iupStrEqualNoCase(value, "ROOT")) + if(iupStrEqualNoCase(value, "ROOT") || iupStrEqualNoCase(value, "FIRST")) hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); else if(iupStrEqualNoCase(value, "LAST")) hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0); @@ -1759,15 +1751,14 @@ static int winTreeSetValueAttrib(Ihandle* ih, const char* value) else if(iupStrEqualNoCase(value, "PREVIOUS")) hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItemFocus); else - hItem = winTreeFindNodeFromString(ih, value); + hItem = iupTreeGetNodeFromString(ih, value);  if (hItem) { if (ih->data->mark_mode==ITREE_MARK_SINGLE) { - iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); - winTreeSelectItem(ih, hItem, 1); - iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); + winTreeSelectNode(ih, hItemFocus, 0); + winTreeSelectNode(ih, hItem, 1); } winTreeSetFocusNode(ih, hItem); } @@ -1832,27 +1823,60 @@ static LRESULT CALLBACK winTreeEditWinProc(HWND hwnd, UINT msg, WPARAM wp, LPARA return CallWindowProc(oldProc, hwnd, msg, wp, lp); }  -static void winTreeDrag(Ihandle* ih, int x, int y) +static void winTreeBeginDrag(Ihandle* ih, int x, int y) { - HTREEITEM hItemDrop; + HIMAGELIST dragImageList; + + HTREEITEM hItemDrag = winTreeFindNodeXY(ih, x, y); + if (!hItemDrag) + return; + + SendMessage(ih->handle, TVM_ENDEDITLABELNOW, TRUE, 0); + + /* store the drag-and-drop item */ + iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", (char*)hItemDrag);  + /* get the image list for dragging */ + dragImageList = (HIMAGELIST)SendMessage(ih->handle, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItemDrag); + if (dragImageList) + { + POINT pt; + ImageList_BeginDrag(dragImageList, 0, 0, 0); + + pt.x = x; + pt.y = y; + + ClientToScreen(ih->handle, &pt); + ImageList_DragEnter(NULL, pt.x, pt.y); + + iupAttribSetStr(ih, "_IUPTREE_DRAGIMAGELIST", (char*)dragImageList); + } + + ShowCursor(FALSE); + SetCapture(ih->handle); /* drag only inside the tree */ +} + +static void winTreeDrag(Ihandle* ih, int x, int y) +{ + HTREEITEM hItemDrop = winTreeFindNodeXY(ih, x, y); + HTREEITEM hItemDrag = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_DRAGITEM"); HIMAGELIST dragImageList = (HIMAGELIST)iupAttribGet(ih, "_IUPTREE_DRAGIMAGELIST"); + if (dragImageList) { - POINT pnt; - pnt.x = x; - pnt.y = y; - GetCursorPos(&pnt); - ClientToScreen(GetDesktopWindow(), &pnt) ; - ImageList_DragMove(pnt.x, pnt.y); + POINT pt; + pt.x = x; + pt.y = y; + ClientToScreen(ih->handle, &pt); + ImageList_DragMove(pt.x, pt.y); }  - if ((hItemDrop = winTreeFindNodePointed(ih)) != NULL) + if (hItemDrop && hItemDrop!=hItemDrag) { if(dragImageList) ImageList_DragShowNolock(FALSE);  - SendMessage(ih->handle, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)hItemDrop); + SendMessage(ih->handle, TVM_SETINSERTMARK, TRUE, (LPARAM)hItemDrop);  /* store the drop item to be executed */ iupAttribSetStr(ih, "_IUPTREE_DROPITEM", (char*)hItemDrop); @@ -1860,6 +1884,8 @@ static void winTreeDrag(Ihandle* ih, int x, int y) if(dragImageList) ImageList_DragShowNolock(TRUE); } + else + iupAttribSetStr(ih, "_IUPTREE_DROPITEM", NULL); }  static void winTreeDrop(Ihandle* ih) @@ -1882,7 +1908,7 @@ static void winTreeDrop(Ihandle* ih) ShowCursor(TRUE);  /* Remove drop target highlighting */ - SendMessage(ih->handle, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)NULL); + SendMessage(ih->handle, TVM_SETINSERTMARK, 0, (LPARAM)NULL);  iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", NULL); iupAttribSetStr(ih, "_IUPTREE_DROPITEM", NULL); @@ -1901,16 +1927,12 @@ static void winTreeDrop(Ihandle* ih)  if (winTreeCallDragDropCb(ih, hItemDrag, hItemDrop, &is_ctrl) == IUP_CONTINUE) { - /* Copy the dragged item to the new position. */ - HTREEITEM hItemNew = winTreeCopyNode(ih, hItemDrag, hItemDrop, is_ctrl); - - if (!is_ctrl) - { - /* do not delete the user data, we copy the references in CopyNode */ - SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemDrag); - } + /* Copy or move the dragged item to the new position. */ + HTREEITEM hItemNew = winTreeCopyMoveNode(ih, hItemDrag, hItemDrop, is_ctrl);  - SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItemNew); /* set focus and selection */ + /* Set focus and selection */ + if (hItemNew) + SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItemNew);  } }   @@ -1929,9 +1951,7 @@ static void winTreeExtendSelect(Ihandle* ih, int x, int y) hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM"); if (hItemFirstSel) { - iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); winTreeSelectRange(ih, hItemFirstSel, hItem, 1); - iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);  iupAttribSetStr(ih, "_IUPTREE_LASTSELITEM", (char*)hItem); winTreeSetFocusNode(ih, hItem); @@ -1952,10 +1972,10 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y) if (GetKeyState(VK_CONTROL) & 0x8000) /* Control key is down */ { /* Toggle selection state */ - winTreeSelectItem(ih, hItem, -1); + winTreeSelectNode(ih, hItem, -1); iupAttribSetStr(ih, "_IUPTREE_FIRSTSELITEM", (char*)hItem);  - winTreeCallSelectionCb(ih, winTreeIsItemSelected(ih, hItem), hItem); + winTreeCallSelectionCb(ih, winTreeIsNodeSelected(ih, hItem), hItem); winTreeSetFocusNode(ih, hItem);  return 1; @@ -1965,9 +1985,11 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y) HTREEITEM hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM"); if (hItemFirstSel) { - iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); + int last_id = iupTreeFindNodeId(ih, hItem); winTreeSelectRange(ih, hItemFirstSel, hItem, 1); - iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL); + + /* if last selected item is a branch, then select its children */ + iupTreeSelectLastCollapsedBranch(ih, &last_id);  winTreeCallMultiSelectionCb(ih); winTreeSetFocusNode(ih, hItem); @@ -1975,11 +1997,15 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y) } }  + winTreeCallMultiUnSelectionCb(ih); + /* simple click */ winTreeClearSelection(ih, hItem); iupAttribSetStr(ih, "_IUPTREE_FIRSTSELITEM", (char*)hItem); iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", "1");  + /* Call SELECT_CB for all unselected nodes */ + return 0; }  @@ -2039,7 +2065,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res  if (wp == VK_RETURN) { - HTREEITEM hItemFocus = winTreeGetFocusNode(ih); + HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih); if (winTreeCallBranchLeafCb(ih, hItemFocus) != IUP_IGNORE) winTreeExpandItem(ih, hItemFocus, -1);  @@ -2056,14 +2082,14 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res { if (GetKeyState(VK_CONTROL) & 0x8000) { - HTREEITEM hItemFocus = winTreeGetFocusNode(ih); + HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih); /* Toggle selection state */ - winTreeSelectItem(ih, hItemFocus, -1); + winTreeSelectNode(ih, hItemFocus, -1); } } else if (wp == VK_UP || wp == VK_DOWN) { - HTREEITEM hItemFocus = winTreeGetFocusNode(ih); + HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih); if (wp == VK_UP) hItemFocus = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItemFocus); else @@ -2084,9 +2110,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res HTREEITEM hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM"); if (hItemFirstSel) { - iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1"); winTreeSelectRange(ih, hItemFirstSel, hItemFocus, 1); - iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);  winTreeCallMultiSelectionCb(ih); winTreeSetFocusNode(ih, hItemFocus); @@ -2138,10 +2162,20 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res } break; case WM_MOUSEMOVE: - if (ih->data->show_dragdrop && (HTREEITEM)iupAttribGet(ih, "_IUPTREE_DRAGITEM") != NULL) - winTreeDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp)); + if (ih->data->show_dragdrop && (wp & MK_LBUTTON)) + { + if (!iupAttribGet(ih, "_IUPTREE_DRAGITEM")) + winTreeBeginDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp)); + else  + winTreeDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp)); + } else if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT")) - winTreeExtendSelect(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp)); + { + if (wp & MK_LBUTTON) + winTreeExtendSelect(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp)); + else + iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", NULL); + }  iupwinMouseMove(ih, msg, wp, lp); break; @@ -2157,6 +2191,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT")) { iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", NULL); + if (iupAttribGet(ih, "_IUPTREE_LASTSELITEM")) { winTreeCallMultiSelectionCb(ih); @@ -2205,14 +2240,19 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) else if (msg_info->code == TVN_SELCHANGED) { NMTREEVIEW* info = (NMTREEVIEW*)msg_info; - winTreeCallSelectionCb(ih, 0, info->itemOld.hItem); /* node unselected */ - winTreeCallSelectionCb(ih, 1, info->itemNew.hItem); /* node selected */ + if (ih->data->mark_mode!=ITREE_MARK_MULTIPLE || /* (NOT) Multiple selection with Control or Shift key is down */ + !(GetKeyState(VK_CONTROL) & 0x8000 || GetKeyState(VK_SHIFT) & 0x8000))  + { + winTreeCallSelectionCb(ih, 0, info->itemOld.hItem); /* node unselected */ + winTreeCallSelectionCb(ih, 1, info->itemNew.hItem); /* node selected */ + } } else if(msg_info->code == TVN_BEGINLABELEDIT) { char* value; HWND hEdit; NMTVDISPINFO* info = (NMTVDISPINFO*)msg_info; + IFni cbShowRename;  if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT")) { @@ -2220,6 +2260,13 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) return 1; }  + cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB"); + if (cbShowRename && cbShowRename(ih, iupTreeFindNodeId(ih, info->item.hItem))==IUP_IGNORE) + { + *result = TRUE; /* prevent the change */ + return 1; + } + hEdit = (HWND)SendMessage(ih->handle, TVM_GETEDITCONTROL, 0, 0);  /* save the edit box. */ @@ -2253,57 +2300,30 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) } else if(msg_info->code == TVN_ENDLABELEDIT) { + IFnis cbRename; NMTVDISPINFO* info = (NMTVDISPINFO*)msg_info;  iupAttribSetStr(ih, "_IUPWIN_EDITBOX", NULL);  - if (info->item.pszText) - { - IFnis cbRename = (IFnis)IupGetCallback(ih, "RENAME_CB"); - if (cbRename) - { - if (cbRename(ih, winTreeGetNodeId(ih, info->item.hItem), info->item.pszText) == IUP_IGNORE) - { - *result = FALSE; - return 1; - } - } + if (!info->item.pszText) /* cancel, so abort */ + return 0;  - *result = TRUE; - return 1; - } - } - else if(msg_info->code == TVN_BEGINDRAG) - { - if (ih->data->show_dragdrop) + cbRename = (IFnis)IupGetCallback(ih, "RENAME_CB"); + if (cbRename) { - NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)msg_info; - HTREEITEM hItemDrag = pNMTreeView->itemNew.hItem; - HIMAGELIST dragImageList; - - /* store the drag-and-drop item */ - iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", (char*)hItemDrag); - - /* get the image list for dragging */ - dragImageList = (HIMAGELIST)SendMessage(ih->handle, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItemDrag); - if (dragImageList) + if (cbRename(ih, iupTreeFindNodeId(ih, info->item.hItem), info->item.pszText) == IUP_IGNORE) { - POINT pt = pNMTreeView->ptDrag; - ImageList_BeginDrag(dragImageList, 0, 0, 0); - - ClientToScreen(ih->handle, &pt); - ImageList_DragEnter(NULL, pt.x, pt.y); - - iupAttribSetStr(ih, "_IUPTREE_DRAGIMAGELIST", (char*)dragImageList); + *result = FALSE; + return 1; } - - ShowCursor(FALSE); - SetCapture(ih->handle); /* drag only inside the tree */ } + + *result = TRUE; + return 1; } else if(msg_info->code == NM_DBLCLK) { - HTREEITEM hItemFocus = winTreeGetFocusNode(ih); + HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih); TVITEM item; winTreeItemData* itemData;  @@ -2317,7 +2337,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) { IFni cbExecuteLeaf = (IFni)IupGetCallback(ih, "EXECUTELEAF_CB"); if(cbExecuteLeaf) - cbExecuteLeaf(ih, winTreeGetNodeId(ih, hItemFocus)); + cbExecuteLeaf(ih, iupTreeFindNodeId(ih, hItemFocus)); } } else if(msg_info->code == TVN_ITEMEXPANDING) @@ -2351,7 +2371,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) HTREEITEM hItem = winTreeFindNodePointed(ih); IFni cbRightClick = (IFni)IupGetCallback(ih, "RIGHTCLICK_CB"); if (cbRightClick) - cbRightClick(ih, winTreeGetNodeId(ih, hItem)); + cbRightClick(ih, iupTreeFindNodeId(ih, hItem)); } else if (msg_info->code == NM_CUSTOMDRAW) { @@ -2374,7 +2394,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result) SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item); itemData = (winTreeItemData*)item.lParam;  - if (winTreeIsItemSelected(ih, hItem)) + if (GetFocus()==ih->handle && (customdraw->nmcd.uItemState & CDIS_SELECTED)) customdraw->clrText = winTreeInvertColor(itemData->color); else customdraw->clrText = itemData->color; @@ -2402,47 +2422,34 @@ static int winTreeConvertXYToPos(Ihandle* ih, int x, int y) info.pt.y = y; hItem = (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)&info); if (hItem) - return winTreeGetNodeId(ih, hItem); + return iupTreeFindNodeId(ih, hItem); return -1; }   /*******************************************************************************************/  -static void winTreeUnMapMethod(Ihandle* ih) -{ - Iarray* bmp_array; - HIMAGELIST image_list; - - HTREEITEM itemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0); - winTreeDelNodeData(ih, itemRoot); - - image_list = (HIMAGELIST)SendMessage(ih->handle, TVM_GETIMAGELIST, TVSIL_NORMAL, 0); - if (image_list) - ImageList_Destroy(image_list); - - bmp_array = (Iarray*)iupAttribGet(ih, "_IUPWIN_BMPARRAY"); - if (bmp_array) - iupArrayDestroy(bmp_array); - - iupdrvBaseUnMapMethod(ih); -}  static int winTreeMapMethod(Ihandle* ih) { - DWORD dwStyle = WS_CHILD | WS_BORDER | TVS_SHOWSELALWAYS; + DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER | TVS_SHOWSELALWAYS;  - /* can be set only on the Tree View creation */ + /* styles can be set only on the Tree View creation */  - if (!ih->data->show_dragdrop) - dwStyle |= TVS_DISABLEDRAGDROP; + /* always disable the internal drag&drop, because it affects our selection and drawing */ + dwStyle |= TVS_DISABLEDRAGDROP;  if (ih->data->show_rename) dwStyle |= TVS_EDITLABELS;  if (!iupAttribGetBoolean(ih, "HIDELINES")) + { dwStyle |= TVS_HASLINES;  + if (!iupAttribGetInt(ih, "ADDROOT")) + dwStyle |= TVS_LINESATROOT; + } + if (!iupAttribGetBoolean(ih, "HIDEBUTTONS")) dwStyle |= TVS_HASBUTTONS;  @@ -2455,6 +2462,11 @@ static int winTreeMapMethod(Ihandle* ih) if (!iupwinCreateWindowEx(ih, WC_TREEVIEW, 0, dwStyle)) return IUP_ERROR;  + if (!iupwin_comctl32ver6) /* To improve drawing of items when TITLEFONT is set */ + SendMessage(ih->handle, CCM_SETVERSION, 5, 0);  + else + SendMessage(ih->handle, TVM_SETEXTENDEDSTYLE, TVS_EX_DOUBLEBUFFER, TVS_EX_DOUBLEBUFFER);  + IupSetCallback(ih, "_IUPWIN_CTRLPROC_CB", (Icallback)winTreeProc); IupSetCallback(ih, "_IUPWIN_NOTIFY_CB", (Icallback)winTreeWmNotify);  @@ -2466,7 +2478,7 @@ static int winTreeMapMethod(Ihandle* ih) winTreeSetBgColorAttrib(ih, value); iupAttribSetStr(ih, "BGCOLOR", NULL); } - else if (iupwinGetSystemMajorVersion()<6) /* force background in XP because of the editbox background */ + else if (!iupwin_comctl32ver6 || iupwinGetSystemMajorVersion()<6) /* force background in XP because of the editbox background */ winTreeSetBgColorAttrib(ih, IupGetGlobal("TXTBGCOLOR")); }  @@ -2475,8 +2487,8 @@ static int winTreeMapMethod(Ihandle* ih) ih->data->def_image_collapsed = (void*)winTreeGetImageIndex(ih, "IMGCOLLAPSED"); ih->data->def_image_expanded = (void*)winTreeGetImageIndex(ih, "IMGEXPANDED");  - /* Add the Root Node */ - winTreeAddRootNode(ih); + if (iupAttribGetInt(ih, "ADDROOT")) + iupdrvTreeAddNode(ih, "-1", ITREE_BRANCH, "", 0);  /* configure for DRAG&DROP of files */ if (IupGetCallback(ih, "DROPFILES_CB")) @@ -2484,9 +2496,31 @@ static int winTreeMapMethod(Ihandle* ih)  IupSetCallback(ih, "_IUP_XY2POS_CB", (Icallback)winTreeConvertXYToPos);  + iupdrvTreeUpdateMarkMode(ih); + return IUP_NOERROR; }  +static void winTreeUnMapMethod(Ihandle* ih) +{ + Iarray* bmp_array; + HIMAGELIST image_list; + + winTreeRemoveAllNodeData(ih, 0); + + ih->data->node_count = 0; + + image_list = (HIMAGELIST)SendMessage(ih->handle, TVM_GETIMAGELIST, TVSIL_NORMAL, 0); + if (image_list) + ImageList_Destroy(image_list); + + bmp_array = (Iarray*)iupAttribGet(ih, "_IUPWIN_BMPARRAY"); + if (bmp_array) + iupArrayDestroy(bmp_array); + + iupdrvBaseUnMapMethod(ih); +} + void iupdrvTreeInitClass(Iclass* ic) { /* Driver Dependent Class functions */ @@ -2500,7 +2534,6 @@ void iupdrvTreeInitClass(Iclass* ic) /* IupTree Attributes - GENERAL */ iupClassRegisterAttribute(ic, "EXPANDALL", NULL, winTreeSetExpandAllAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "INDENTATION", winTreeGetIndentationAttrib, winTreeSetIndentationAttrib, NULL, NULL, IUPAF_DEFAULT); - iupClassRegisterAttribute(ic, "COUNT", winTreeGetCountAttrib, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_READONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAGDROP", NULL, iupwinSetDragDropAttrib, NULL, NULL, IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SPACING", iupTreeGetSpacingAttrib, winTreeSetSpacingAttrib, NULL, NULL, IUPAF_NOT_MAPPED); iupClassRegisterAttribute(ic, "TOPITEM", NULL, winTreeSetTopItemAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); @@ -2521,7 +2554,6 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttributeId(ic, "NAME", winTreeGetTitleAttrib, winTreeSetTitleAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TITLE", winTreeGetTitleAttrib, winTreeSetTitleAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "CHILDCOUNT", winTreeGetChildCountAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); - iupClassRegisterAttributeId(ic, "USERDATA", winTreeGetUserDataAttrib, winTreeSetUserDataAttrib, IUPAF_NO_STRING|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "COLOR", winTreeGetColorAttrib, winTreeSetColorAttrib, IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "TITLEFONT", winTreeGetTitleFontAttrib, winTreeSetTitleFontAttrib, IUPAF_NO_INHERIT);  @@ -2530,6 +2562,7 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttribute (ic, "MARK", NULL, winTreeSetMarkAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute (ic, "STARTING", NULL, winTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); iupClassRegisterAttribute (ic, "MARKSTART", NULL, winTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + iupClassRegisterAttribute (ic, "MARKEDNODES", winTreeGetMarkedNodesAttrib, winTreeSetMarkedNodesAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);  iupClassRegisterAttribute (ic, "VALUE", winTreeGetValueAttrib, winTreeSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);  @@ -2538,5 +2571,8 @@ void iupdrvTreeInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "RENAME", NULL, winTreeSetRenameAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "MOVENODE", NULL, winTreeSetMoveNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttributeId(ic, "COPYNODE", NULL, winTreeSetCopyNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT); - iupClassRegisterAttributeId(ic, "FINDUSERDATA", winTreeGetFindUserDataAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); + + /* necessary because transparent background does not work when not using visual styles */ + if (!iupwin_comctl32ver6) /* Used by iupdrvImageCreateImage */ + iupClassRegisterAttribute(ic, "FLAT_ALPHA", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); } diff --git a/iup/src/win/iupwin_val.c b/iup/src/win/iupwin_val.c index 706c612..5c956d9 100755 --- a/iup/src/win/iupwin_val.c +++ b/iup/src/win/iupwin_val.c @@ -56,6 +56,13 @@ void iupdrvValGetMinSize(Ihandle* ih, int *w, int *h) } }  +static int winValSetBgColorAttrib(Ihandle *ih, const char *value) +{ + (void)value; + iupdrvPostRedraw(ih); + return 1; +} + static int winValSetStepAttrib(Ihandle* ih, const char* value) { int linesize; @@ -110,18 +117,6 @@ static int winValSetValueAttrib(Ihandle* ih, const char* value) /*********************************************************************************************/   -static int winValCtlColor(Ihandle* ih, HDC hdc, LRESULT *result) -{ - COLORREF cr; - if (iupwinGetParentBgColor(ih, &cr)) - { - SetDCBrushColor(hdc, cr); - *result = (LRESULT)GetStockObject(DC_BRUSH); - return 1; - } - return 0; -} - static int winValCustomScroll(Ihandle* ih, int msg) { double old_val = ih->data->val; @@ -190,6 +185,19 @@ static void winValIncPageValue(Ihandle *ih, int dir) winValCustomScroll(ih, 0); }  +static int winValCtlColor(Ihandle* ih, HDC hdc, LRESULT *result) +{ + COLORREF cr; + if (iupwinGetParentBgColor(ih, &cr)) + { + SetBkColor(hdc, cr); + SetDCBrushColor(hdc, cr); + *result = (LRESULT)GetStockObject(DC_BRUSH); + return 1; + } + return 0; +} + static int winValProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { (void)lp; @@ -240,7 +248,7 @@ static int winValProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *resu  static int winValMapMethod(Ihandle* ih) { - DWORD dwStyle = WS_CHILD | TBS_AUTOTICKS; + DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | TBS_AUTOTICKS; int show_ticks;  if (!ih->parent) @@ -312,4 +320,7 @@ void iupdrvValInitClass(Iclass* ic) iupClassRegisterAttribute(ic, "STEP", iupValGetStepAttrib, winValSetStepAttrib, "0.01", NULL, IUPAF_NO_INHERIT); /* force new default value */  iupClassRegisterAttribute(ic, "TICKSPOS", NULL, NULL, "NORMAL", NULL, IUPAF_NOT_MAPPED); + + /* Visual */ + iupClassRegisterAttribute(ic, "BGCOLOR", NULL, winValSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT); } diff --git a/iup/srccd/Makefile b/iup/srccd/Makefile index 43a3f09..8b1d154 100755 --- a/iup/srccd/Makefile +++ b/iup/srccd/Makefile @@ -3,4 +3,4 @@ do_all: iupcd  iupcd: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak  diff --git a/iup/srccd/iup_cd.c b/iup/srccd/iup_cd.c index 5998775..619ded7 100755 --- a/iup/srccd/iup_cd.c +++ b/iup/srccd/iup_cd.c @@ -14,7 +14,6 @@ #include  #include   - static void (*cdcreatecanvasNATIVE)(cdCanvas* canvas, void* data) = NULL;  static void cdcreatecanvasIUP(cdCanvas* canvas, Ihandle *ih_canvas) @@ -24,8 +23,12 @@ static void cdcreatecanvasIUP(cdCanvas* canvas, Ihandle *ih_canvas) #endif char* data;  - if (IupGetInt(ih_canvas, "CD_GDK")) + if (cdBaseDriver()==CD_BASE_GDK) + { data = IupGetAttribute(ih_canvas, "DRAWABLE"); /* new IUP 3 attribute, works for GTK only */ + if (!data) + return; + } else { #ifdef WIN32 diff --git a/iup/srcconsole/Makefile b/iup/srcconsole/Makefile index 876ca8d..505b103 100755 --- a/iup/srcconsole/Makefile +++ b/iup/srcconsole/Makefile @@ -3,10 +3,10 @@ do_all: iuplua5  iuplua5: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak   iuplua5gtk: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak USE_GTK=Yes + @$(MAKE) --no-print-directory -f ../tecmake.mak USE_GTK=Yes  iuplua3: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iuplua3 + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iuplua3 diff --git a/iup/srcconsole/config.mak b/iup/srcconsole/config.mak index 612a3ab..568bed6 100755 --- a/iup/srcconsole/config.mak +++ b/iup/srcconsole/config.mak @@ -1,12 +1,23 @@ PROJNAME = iup APPNAME = iuplua51 -APPTYPE = console +APPTYPE = CONSOLE + +ifdef GTK_DEFAULT + ifdef USE_MOTIF + # Build Motif version in Linux,Darwin,FreeBSD + APPNAME = iuplua51mot + endif +else  + ifdef USE_GTK + # Build GTK version in IRIX,SunOS,AIX,Win32 + APPNAME = iuplua51gtk + endif +endif  LOHDIR = loh SRCLUA = console5.lua SRC = iup_lua51.c  - # Disable strip STRIP =  # Optimize @@ -35,6 +46,16 @@ ifdef DBG USE_STATIC = Yes USE_LUA51 = Yes  + ifdef DBG_DIR + IUPLIB = $(IUP)/lib/$(TEC_UNAME)d + CDLIB = $(CD)/lib/$(TEC_UNAME)d + IMLIB = $(IM)/lib/$(TEC_UNAME)d + else + IUPLIB = $(IUP)/lib/$(TEC_UNAME) + CDLIB = $(CD)/lib/$(TEC_UNAME) + IMLIB = $(IM)/lib/$(TEC_UNAME) + endif  +  DEFINES = USE_STATIC  USE_CDLUA = Yes @@ -42,7 +63,6 @@ ifdef DBG ifneq ($(findstring Win, $(TEC_SYSNAME)), ) LIBS += iuplua_pplot$(LIBLUASUFX) iup_pplot else - IUPLIB = $(IUP)/lib/$(TEC_UNAME) SLIB += $(IUPLIB)/libiuplua_pplot$(LIBLUASUFX).a $(IUPLIB)/libiup_pplot.a endif  @@ -50,7 +70,6 @@ ifdef DBG ifneq ($(findstring Win, $(TEC_SYSNAME)), ) LIBS += cdluaim$(LIBLUASUFX) else - CDLIB = $(CD)/lib/$(TEC_UNAME) SLIB += $(CDLIB)/libcdluaim$(LIBLUASUFX).a endif endif @@ -65,8 +84,6 @@ ifdef DBG ifneq ($(findstring Win, $(TEC_SYSNAME)), ) LIBS += imlua_process$(LIBLUASUFX) iupluaim$(LIBLUASUFX) im_process iupim else - IUPLIB = $(IUP)/lib/$(TEC_UNAME) - IMLIB = $(IM)/lib/$(TEC_UNAME) SLIB += $(IMLIB)/libimlua_process$(LIBLUASUFX).a $(IUPLIB)/libiupluaim$(LIBLUASUFX).a $(IMLIB)/libim_process.a $(IUPLIB)/libiupim.a endif  @@ -77,20 +94,24 @@ ifdef DBG ifneq ($(findstring Win, $(TEC_SYSNAME)), ) LIBS += iupluaimglib$(LIBLUASUFX) iupimglib else - IUPLIB = $(IUP)/lib/$(TEC_UNAME) SLIB += $(IUPLIB)/libiupluaimglib$(LIBLUASUFX).a $(IUPLIB)/libiupimglib.a endif endif else ifneq ($(findstring Win, $(TEC_SYSNAME)), ) # Dinamically link in Windows, when not debugging - # Must call "tecmake dll8" + # Must call "tecmake dll8" so USE_* will use the correct TEC_UNAME USE_LUA51 = Yes USE_DLL = Yes GEN_MANIFEST = No else # In UNIX Lua is always statically linked, late binding is used. - USE_STATIC = Yes + # Except in Cygwin and MacOSX + ifeq ($(findstring cygw, $(TEC_UNAME)), ) + ifeq ($(findstring Darwin, $(TEC_UNAME)), ) + USE_STATIC = Yes + endif + endif USE_LUA51 = Yes endif endif @@ -102,10 +123,13 @@ ifneq ($(findstring Win, $(TEC_SYSNAME)), ) endif  ifneq ($(findstring cygw, $(TEC_UNAME)), ) - LDFLAGS = -s LIBS += readline history endif  +ifneq ($(findstring Darwin, $(TEC_UNAME)), ) + LIBS += readline +endif + ifneq ($(findstring Linux, $(TEC_UNAME)), ) LIBS += dl  #To allow late binding @@ -129,10 +153,3 @@ ifneq ($(findstring AIX, $(TEC_UNAME)), ) LFLAGS = -Xlinker "-bbigtoc" endif  -ifeq ($(TEC_UNAME), vc8) - ifdef DBG - #debug info not working for vc8 linker - define DBG - endef - endif -endif  diff --git a/iup/srcconsole/console5.lua b/iup/srcconsole/console5.lua index 20f74b2..0b93641 100755 --- a/iup/srcconsole/console5.lua +++ b/iup/srcconsole/console5.lua @@ -1,67 +1,69 @@ require"iuplua"  -iup.console = {} - -- Utilities +iup_console = {}  -function iup.console.printtable(t) - local n,v = next(t, nil) - print("--printtable Start--") - while n do - print(tostring(n).."="..tostring(v)) - n,v = next(t, n) - end - print("--printtable End--") +function iup_console.concat(str, info) + return str .. info .. "\n" end  -function iup.console.print_version_info() - if (im) then print("IM " .. im._VERSION .. " " .. im._COPYRIGHT) end +function iup_console.print_version_info() + iup_console.clear() + local str = "" + if (im) then str = iup_console.concat(str, "IM " .. im._VERSION .. " " .. im._COPYRIGHT) end  - if (cd) then print("CD " .. cd._VERSION .. " " .. cd._COPYRIGHT) end + if (cd) then str = iup_console.concat(str, "CD " .. cd._VERSION .. " " .. cd._COPYRIGHT) end  - print("IUP " .. iup._VERSION .. " " .. iup._COPYRIGHT) - print("") - print("IUP Info") - print(" System: " .. iup.GetGlobal("SYSTEM")) - print(" System Version: " .. iup.GetGlobal("SYSTEMVERSION")) + str = iup_console.concat(str, "IUP " .. iup._VERSION .. " " .. iup._COPYRIGHT) + str = iup_console.concat(str, "") + str = iup_console.concat(str, "IUP Info") + str = iup_console.concat(str, " System: " .. iup.GetGlobal("SYSTEM")) + str = iup_console.concat(str, " System Version: " .. iup.GetGlobal("SYSTEMVERSION"))  local mot = iup.GetGlobal("MOTIFVERSION") - if (mot) then print(" Motif Version: ", mot) end + if (mot) then str = iup_console.concat(str, " Motif Version: ", mot) end  - print(" Screen Size: " .. iup.GetGlobal("SCREENSIZE")) - print(" Screen Depth: " .. iup.GetGlobal("SCREENDEPTH")) + str = iup_console.concat(str, " Screen Size: " .. iup.GetGlobal("SCREENSIZE")) + str = iup_console.concat(str, " Screen Depth: " .. iup.GetGlobal("SCREENDEPTH"))  - if (iup.GL_VENDOR) then print(" OpenGL Vendor: " .. iup.GL_VENDOR) end - if (iup.GL_RENDERER) then print(" OpenGL Renderer: " .. iup.GL_RENDERER) end - if (iup.GL_VERSION) then print(" OpenGL Version: " .. iup.GL_VERSION) end + if (iup.GL_VENDOR) then str = iup_console.concat(str, " OpenGL Vendor: " .. iup.GL_VENDOR) end + if (iup.GL_RENDERER) then str = iup_console.concat(str, " OpenGL Renderer: " .. iup.GL_RENDERER) end + if (iup.GL_VERSION) then str = iup_console.concat(str, " OpenGL Version: " .. iup.GL_VERSION) end +  + iup_console.mlCode.value=str end  -- Console Dialog  -iup.console.lastfilename = nil -- Last file open -iup.console.mlCode = iup.multiline{expand="YES", size="200x120", font="COURIER_NORMAL_10"} -iup.console.lblPosition = iup.label{title="0:0", size="50x"} -iup.console.lblFileName = iup.label{title="", size="50x", expand="HORIZONTAL"} +iup_console.lastfilename = nil -- Last file open +iup_console.mlCode = iup.multiline{expand="YES", size="200x120", font="COURIER_NORMAL_10"} +iup_console.lblPosition = iup.label{title="0:0", size="50x"} +iup_console.lblFileName = iup.label{title="", size="50x", expand="HORIZONTAL"} + +function iup_console.mlCode:caret_cb(lin, col) + iup_console.lblPosition.title = lin..":"..col +end  -function iup.console.mlCode:caret_cb(lin, col) - iup.console.lblPosition.title = lin..":"..col +function iup_console.clear() + iup_console.mlCode.value=''  + iup_console.lblFileName.title = ''  + iup_console.lastfilename = nil end  -iup.console.butExecute = iup.button{size="50x15", title="Execute", - action="iup.dostring(iup.console.mlCode.value)"} -iup.console.butClearCommands = iup.button{size="50x15", title="Clear", - action="iup.console.mlCode.value='' iup.console.lblFileName.title = '' iup.console.lastfilename = nil"} -iup.console.butLoadFile = iup.button{size="50x15", title="Load..."} -iup.console.butSaveasFile = iup.button{size="50x15", title="Save As..."} -iup.console.butSaveFile = iup.button{size="50x15", title="Save"} - -function iup.console.butSaveFile:action() - if (iup.console.lastfilename == nil) then - iup.console.butSaveasFile:action() +iup_console.butExecute = iup.button{size="50x15", title="Execute", + action="iup.dostring(iup_console.mlCode.value)"} +iup_console.butClearCommands = iup.button{size="50x15", title="Clear", action=iup_console.clear} +iup_console.butLoadFile = iup.button{size="50x15", title="Load..."} +iup_console.butSaveasFile = iup.button{size="50x15", title="Save As..."} +iup_console.butSaveFile = iup.button{size="50x15", title="Save"} + +function iup_console.butSaveFile:action() + if (iup_console.lastfilename == nil) then + iup_console.butSaveasFile:action() else - newfile = io.open(iup.console.lastfilename, "w+") + newfile = io.open(iup_console.lastfilename, "w+") if (newfile) then - newfile:write(iup.console.mlCode.value) + newfile:write(iup_console.mlCode.value) newfile:close() else error ("Cannot Save file "..filename) @@ -69,21 +71,26 @@ function iup.console.butSaveFile:action() end end  -function iup.console.butSaveasFile:action() - local fd = iup.filedlg{dialogtype="SAVE", title="Save File", +function iup_console.butSaveasFile:action() + local fd = iup.filedlg{dialogtype="SAVE", title="Save File",  + nochangedir="NO", directory=iup_console.last_directory, filter="*.*", filterinfo="All files",allownew=yes} +  fd:popup(iup.LEFT, iup.LEFT) +  local status = fd.status - iup.console.lastfilename = fd.value - iup.console.lblFileName.title = iup.console.lastfilename + iup_console.lastfilename = fd.value + iup_console.lblFileName.title = fd.value + iup_console.last_directory = fd.directory fd:destroy() +  if status ~= "-1" then - if (iup.console.lastfilename == nil) then + if (iup_console.lastfilename == nil) then error ("Cannot Save file "..filename) end - local newfile=io.open(iup.console.lastfilename, "w+") + local newfile=io.open(iup_console.lastfilename, "w+") if (newfile) then - newfile:write(iup.console.mlCode.value) + newfile:write(iup_console.mlCode.value) newfile:close(newfile) else error ("Cannot Save file") @@ -91,24 +98,26 @@ function iup.console.butSaveasFile:action() end end  -function iup.console.LoadFile(filename) +function iup_console.LoadFile(filename) local newfile = io.open (filename, "r") if (newfile == nil) then error ("Cannot load file "..filename) else - iup.console.mlCode.value=newfile:read("*a") + iup_console.mlCode.value=newfile:read("*a") newfile:close (newfile) - iup.console.lastfilename = filename - iup.console.lblFileName.title = iup.console.lastfilename + iup_console.lastfilename = filename + iup_console.lblFileName.title = iup_console.lastfilename end end  -function iup.console.butLoadFile:action() - local fd=iup.filedlg{dialogtype="OPEN", title="Load File", +function iup_console.butLoadFile:action() + local fd=iup.filedlg{dialogtype="OPEN", title="Load File",  + nochangedir="NO", directory=iup_console.last_directory, filter="*.*", filterinfo="All Files", allownew="NO"} fd:popup(iup.CENTER, iup.CENTER) local status = fd.status local filename = fd.value + iup_console.last_directory = fd.directory fd:destroy()  if (status == "-1") or (status == "1") then @@ -116,21 +125,21 @@ function iup.console.butLoadFile:action() error ("Cannot load file "..filename) end else - iup.console.LoadFile(filename) + iup_console.LoadFile(filename) end end  -iup.console.vbxConsole = iup.vbox +iup_console.vbxConsole = iup.vbox { - iup.frame{iup.hbox{iup.vbox{iup.console.butLoadFile, - iup.console.butSaveFile, - iup.console.butSaveasFile, - iup.console.butClearCommands, - iup.console.butExecute; + iup.frame{iup.hbox{iup.vbox{iup_console.butLoadFile, + iup_console.butSaveFile, + iup_console.butSaveasFile, + iup_console.butClearCommands, + iup_console.butExecute; margin="0x0", gap="10"}, - iup.vbox{iup.console.lblFileName, - iup.console.mlCode, - iup.console.lblPosition; + iup.vbox{iup_console.lblFileName, + iup_console.mlCode, + iup_console.lblPosition; alignment = "ARIGHT"}; alignment="ATOP"}; title="Commands"} ;alignment="ACENTER", margin="5x5", gap="5" @@ -138,7 +147,7 @@ iup.console.vbxConsole = iup.vbox  -- Main Menu Definition.  -iup.console.mnuMain = iup.menu +iup_console.mnuMain = iup.menu { iup.submenu { @@ -149,29 +158,29 @@ iup.console.mnuMain = iup.menu }, iup.submenu{iup.menu { - iup.item{title="Print Version Info...", action=iup.console.print_version_info}, - iup.item{title="About...", action="iup.console.dlgAbout:popup(iup.CENTER, iup.CENTER)"} + iup.item{title="Print Version Info...", action=iup_console.print_version_info}, + iup.item{title="About...", action="iup_console.dlgAbout:popup(iup.CENTER, iup.CENTER)"} };title="Help"} }  -- Main Dialog Definition.  -iup.console.dlgMain = iup.dialog{iup.console.vbxConsole; +iup_console.dlgMain = iup.dialog{iup_console.vbxConsole; title="IupLua Console", - menu=iup.console.mnuMain, + menu=iup_console.mnuMain, dragdrop = "YES", - defaultenter=iup.console.butExecute, + defaultenter=iup_console.butExecute, close_cb = "return iup.CLOSE"}  -function iup.console.dlgMain:dropfiles_cb(filename, num, x, y) +function iup_console.dlgMain:dropfiles_cb(filename, num, x, y) if (num == 0) then - iup.console.LoadFile(filename) + iup_console.LoadFile(filename) end end  -- About Dialog Definition.  -iup.console.dlgAbout = iup.dialog +iup_console.dlgAbout = iup.dialog { iup.vbox { @@ -195,10 +204,12 @@ iup.console.dlgAbout = iup.dialog  -- Displays the Main Dialog  -iup.console.dlgMain:show() -iup.SetFocus(iup.console.mlCode) +iup_console.dlgMain:show() +iup.SetFocus(iup_console.mlCode)  -iup.MainLoop() +if (not iup.MainLoopLevel or iup.MainLoopLevel()==0) then + iup.MainLoop() +end  -iup.console.dlgMain:destroy() -iup.console.dlgAbout:destroy() +iup_console.dlgMain:destroy() +iup_console.dlgAbout:destroy() diff --git a/iup/srcconsole/copy_all_so b/iup/srcconsole/copy_all_so index 52f1fea..ce3c248 100755 --- a/iup/srcconsole/copy_all_so +++ b/iup/srcconsole/copy_all_so @@ -2,10 +2,10 @@  foreach plat ( Linux24 Linux24g3 Linux24g3_64 Linux26 Linux26_64 Linux26g4 Linux26g4_64 Linux26_ia64 SunOS57 SunOS510 SunOS510x86 AIX43 IRIX65 IRIX6465 ) echo $plat - cp -f ../lib/$plat/*.so ../bin/$plat - cp -f ../../cd/lib/$plat/*.so ../bin/$plat - cp -f ../../im/lib/$plat/*.so ../bin/$plat +# cp -f ../lib/$plat/*.so ../bin/$plat +# cp -f ../../cd/lib/$plat/*.so ../bin/$plat +# cp -f ../../im/lib/$plat/*.so ../bin/$plat cp -f ../../luagl/lib/$plat/*.so ../bin/$plat cp -f ../../lfs/lib/$plat/*.so ../bin/$plat - rm -f ../bin/$plat/*3.so +# rm -f ../bin/$plat/*3.so end diff --git a/iup/srcconsole/copy_so b/iup/srcconsole/copy_so index 2535766..e345d31 100755 --- a/iup/srcconsole/copy_so +++ b/iup/srcconsole/copy_so @@ -1,4 +1,6 @@ cp -f ../lib/${TEC_UNAME}/*.so ../bin/$TEC_UNAME cp -f ../../cd/lib/${TEC_UNAME}/*.so ../bin/$TEC_UNAME cp -f ../../im/lib/${TEC_UNAME}/*.so ../bin/$TEC_UNAME +cp -f ../../luagl/lib/${TEC_UNAME}/*.so ../bin/${TEC_UNAME} +cp -f ../../lfs/lib/${TEC_UNAME}/*.so ../bin/${TEC_UNAME} rm -f ../bin/${TEC_UNAME}/*3.so diff --git a/iup/srcconsole/iuplua3.rc b/iup/srcconsole/iuplua3.rc index e741199..9fcc280 100755 --- a/iup/srcconsole/iuplua3.rc +++ b/iup/srcconsole/iuplua3.rc @@ -13,7 +13,7 @@ BEGIN VALUE "CompanyName", "Tecgraf/PUC-Rio\0" VALUE "FileDescription", "Lua Windows Standalone Interpreter with IUP\0" VALUE "FileVersion", "3.0.0\0" - VALUE "LegalCopyright", "Copyright © 1994-2009 Tecgraf, PUC-Rio.\0" + VALUE "LegalCopyright", "Copyright © 1994-2010 Tecgraf, PUC-Rio.\0" VALUE "OriginalFilename", "iuplua51.exe\0" VALUE "ProductName", "IUP for Windows\0" VALUE "ProductVersion", "3.0.0\0" diff --git a/iup/srcconsole/iuplua5.rc b/iup/srcconsole/iuplua5.rc index bc02e07..70e40a4 100755 --- a/iup/srcconsole/iuplua5.rc +++ b/iup/srcconsole/iuplua5.rc @@ -13,7 +13,7 @@ BEGIN VALUE "CompanyName", "Tecgraf/PUC-Rio\0" VALUE "FileDescription", "Lua Windows Standalone Interpreter with IUP\0" VALUE "FileVersion", "3.0.0\0" - VALUE "LegalCopyright", "Copyright © 1994-2009 Tecgraf, PUC-Rio.\0" + VALUE "LegalCopyright", "Copyright © 1994-2010 Tecgraf, PUC-Rio.\0" VALUE "OriginalFilename", "iuplua51.exe\0" VALUE "ProductName", "IUP for Windows\0" VALUE "ProductVersion", "3.0.0\0" diff --git a/iup/srcconsole/make_uname.bat b/iup/srcconsole/make_uname.bat index a5b1d9a..a0db110 100755 --- a/iup/srcconsole/make_uname.bat +++ b/iup/srcconsole/make_uname.bat @@ -6,24 +6,26 @@ if "%1"=="vc8_64" goto iupexe64 if "%1"=="all" goto iupexe goto end  +REM Must use dll8 so USE_* will use the correct TEC_UNAME + :iupexe32 call tecmake dll8 relink %2 %3 %4 %5 %6 %7 -REM call tecmake dll8 USE_GTK=Yes relink %2 %3 %4 %5 %6 %7 +REM call tecmake vc8 USE_GTK=Yes relink %2 %3 %4 %5 %6 %7 REM call tecmake vc8 "MF=iuplua3" relink %2 %3 %4 %5 %6 %7 goto end  :iupexe64 call tecmake dll8_64 relink %2 %3 %4 %5 %6 %7 -REM call tecmake dll8_64 USE_GTK=Yes relink %2 %3 %4 %5 %6 %7 +REM call tecmake vc8_64 USE_GTK=Yes relink %2 %3 %4 %5 %6 %7 REM call tecmake vc8_64 "MF=iuplua3" relink %2 %3 %4 %5 %6 %7 goto end  :iupexe call tecmake dll8 relink %2 %3 %4 %5 %6 %7 -REM call tecmake dll8 USE_GTK=Yes relink %2 %3 %4 %5 %6 %7 +REM call tecmake vc8 USE_GTK=Yes relink %2 %3 %4 %5 %6 %7 REM call tecmake vc8 "MF=iuplua3" relink %2 %3 %4 %5 %6 %7 call tecmake dll8_64 relink %2 %3 %4 %5 %6 %7 -REM call tecmake dll8_64 USE_GTK=Yes relink %2 %3 %4 %5 %6 %7 +REM call tecmake vc8_64 USE_GTK=Yes relink %2 %3 %4 %5 %6 %7 REM call tecmake vc8_64 "MF=iuplua3" relink %2 %3 %4 %5 %6 %7 goto end  diff --git a/iup/srccontrols/Makefile b/iup/srccontrols/Makefile index d02bbc3..c928251 100755 --- a/iup/srccontrols/Makefile +++ b/iup/srccontrols/Makefile @@ -3,4 +3,4 @@ do_all: iupcontrols  iupcontrols: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak  diff --git a/iup/srccontrols/color/iup_colorbrowser.c b/iup/srccontrols/color/iup_colorbrowser.c index 82b4a88..51f8a30 100755 --- a/iup/srccontrols/color/iup_colorbrowser.c +++ b/iup/srccontrols/color/iup_colorbrowser.c @@ -681,7 +681,7 @@ static int iColorBrowserKeypress_CB(Ihandle* ih, int c, int press) static char* iColorBrowserGetHSIAttrib(Ihandle* ih) { char* buffer = iupStrGetMemory(100); - sprintf(buffer, "%f %f %f", (double)ih->data->hue, (double)ih->data->saturation, (double)ih->data->intensity); + sprintf(buffer, "%g %g %g", (double)ih->data->hue, (double)ih->data->saturation, (double)ih->data->intensity); return buffer; }  @@ -781,10 +781,16 @@ static int iColorBrowserMapMethod(Ihandle* ih) static void iColorBrowserUnMapMethod(Ihandle* ih) { if (ih->data->cddbuffer) + { cdKillCanvas(ih->data->cddbuffer); + ih->data->cddbuffer = NULL; + }  if (ih->data->cdcanvas) + { cdKillCanvas(ih->data->cdcanvas); + ih->data->cdcanvas = NULL; + } }  static int iColorBrowserCreateMethod(Ihandle* ih, void **params) diff --git a/iup/srccontrols/color/iup_colorbrowserdlg.c b/iup/srccontrols/color/iup_colorbrowserdlg.c index 65e4d37..dc52725 100755 --- a/iup/srccontrols/color/iup_colorbrowserdlg.c +++ b/iup/srccontrols/color/iup_colorbrowserdlg.c @@ -158,7 +158,7 @@ static void iColorBrowserDlgBrowserRGB_Update(IcolorDlgData* colordlg_data)  static void iColorBrowserDlgBrowserHSI_Update(IcolorDlgData* colordlg_data) { - IupSetfAttribute(colordlg_data->color_browser, "HSI", "%f %f %f", (double)colordlg_data->hue, (double)colordlg_data->saturation, (double)colordlg_data->intensity); + IupSetfAttribute(colordlg_data->color_browser, "HSI", "%g %g %g", (double)colordlg_data->hue, (double)colordlg_data->saturation, (double)colordlg_data->intensity); }  /*****************************************\ @@ -575,10 +575,16 @@ static int iColorBrowserDlgColorCnvUnMap_CB(Ihandle* ih) IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");  if (colordlg_data->color_cddbuffer) + { cdKillCanvas(colordlg_data->color_cddbuffer); + colordlg_data->color_cddbuffer = NULL; + }  if (colordlg_data->color_cdcanvas) + { cdKillCanvas(colordlg_data->color_cdcanvas); + colordlg_data->color_cdcanvas = NULL; + }  return IUP_DEFAULT; } diff --git a/iup/srccontrols/config.mak b/iup/srccontrols/config.mak index 394d607..10f11e1 100755 --- a/iup/srccontrols/config.mak +++ b/iup/srccontrols/config.mak @@ -13,7 +13,7 @@ SRCMATRIX = iupmat_key.c iupmat_mark.c iupmat_aux.c iupmat_mem.c iupmat_mouse.c SRCMATRIX := $(addprefix matrix/, $(SRCMATRIX))  SRC = iup_cdutil.c iup_gauge.c iup_cells.c iup_colorbar.c iup_controls.c \ - iup_dial.c iup_oldtabs.c iup_oldval.c iup_oldmask.c \ + iup_dial.c iup_oldmask.c \ $(SRCCOLOR) $(SRCMATRIX)  LIBS = iup iupcd diff --git a/iup/srccontrols/iup_cells.c b/iup/srccontrols/iup_cells.c index d9a7fe4..c771d6e 100755 --- a/iup/srccontrols/iup_cells.c +++ b/iup/srccontrols/iup_cells.c @@ -882,10 +882,16 @@ static int iCellsMapMethod(Ihandle* ih) static void iCellsUnMapMethod(Ihandle* ih) { if (ih->data->cddbuffer) + { cdKillCanvas(ih->data->cddbuffer); + ih->data->cddbuffer = NULL; + }  if (ih->data->cdcanvas) + { cdKillCanvas(ih->data->cdcanvas); + ih->data->cdcanvas = NULL; + } }  static int iCellsCreateMethod(Ihandle* ih, void **params) diff --git a/iup/srccontrols/iup_colorbar.c b/iup/srccontrols/iup_colorbar.c index 72e717c..1cbcd59 100755 --- a/iup/srccontrols/iup_colorbar.c +++ b/iup/srccontrols/iup_colorbar.c @@ -978,10 +978,16 @@ static int iColorbarMapMethod(Ihandle* ih) static void iColorbarUnMapMethod(Ihandle* ih) { if (ih->data->cddbuffer) + { cdKillCanvas(ih->data->cddbuffer); + ih->data->cddbuffer = NULL; + }  if (ih->data->cdcanvas) + { cdKillCanvas(ih->data->cdcanvas); + ih->data->cdcanvas = NULL; + } }  static int iColorbarCreateMethod(Ihandle* ih, void **params) diff --git a/iup/srccontrols/iup_dial.c b/iup/srccontrols/iup_dial.c index 1dd2d0f..c8c5656 100755 --- a/iup/srccontrols/iup_dial.c +++ b/iup/srccontrols/iup_dial.c @@ -640,7 +640,7 @@ static int iDialWheel_CB(Ihandle* ih, float delta) static char* iDialGetValueAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->angle); + sprintf(str, "%g", ih->data->angle); return str; }  @@ -665,7 +665,7 @@ static int iDialSetDensityAttrib(Ihandle* ih, const char* value) static char* iDialGetDensityAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->density); + sprintf(str, "%g", ih->data->density); return str; }  @@ -780,10 +780,16 @@ static int iDialMapMethod(Ihandle* ih) static void iDialUnMapMethod(Ihandle* ih) { if (ih->data->cddbuffer) + { cdKillCanvas(ih->data->cddbuffer); + ih->data->cddbuffer = NULL; + }  if (ih->data->cdcanvas) + { cdKillCanvas(ih->data->cdcanvas); + ih->data->cdcanvas = NULL; + } }  static int iDialCreateMethod(Ihandle* ih, void **params) diff --git a/iup/srccontrols/iup_gauge.c b/iup/srccontrols/iup_gauge.c index 8732eee..300b28e 100755 --- a/iup/srccontrols/iup_gauge.c +++ b/iup/srccontrols/iup_gauge.c @@ -347,10 +347,16 @@ static char* iGaugeGetTextAttrib(Ihandle* ih) static void iGaugeUnMapMethod(Ihandle* ih) { if (ih->data->cddbuffer) + { cdKillCanvas(ih->data->cddbuffer); + ih->data->cddbuffer = NULL; + }  if (ih->data->cdcanvas) + { cdKillCanvas(ih->data->cdcanvas); + ih->data->cdcanvas = NULL; + } }  static int iGaugeMapMethod(Ihandle* ih) diff --git a/iup/srccontrols/iup_oldmask.c b/iup/srccontrols/iup_oldmask.c index fec10f3..2ec4012 100755 --- a/iup/srccontrols/iup_oldmask.c +++ b/iup/srccontrols/iup_oldmask.c @@ -42,14 +42,14 @@ int iupmaskMatSetInt(Ihandle *ih, int autofill, int min, int max, int lin, int c int iupmaskSetFloat(Ihandle* ih, int autofill, float min, float max) { (void)autofill; - IupSetfAttribute(ih,"MASKFLOAT", "%f:%f", min, max); + IupSetfAttribute(ih,"MASKFLOAT", "%g:%g", min, max); return 1; }  int iupmaskMatSetFloat(Ihandle* ih, int autofill, float min, float max, int lin, int col) { (void)autofill; - IupMatSetfAttribute(ih,"MASKFLOAT", lin, col, "%f:%f", min, max); + IupMatSetfAttribute(ih,"MASKFLOAT", lin, col, "%g:%g", min, max); return 0; }  diff --git a/iup/srccontrols/iup_oldtabs.c b/iup/srccontrols/iup_oldtabs.c index 43b0c57..5ea7f0a 100755 --- a/iup/srccontrols/iup_oldtabs.c +++ b/iup/srccontrols/iup_oldtabs.c @@ -2487,10 +2487,16 @@ static int iTabsMapMethod(Ihandle* ih) static void iTabsUnMapMethod(Ihandle* ih) { if (ih->data->cddbuffer) + { cdKillCanvas(ih->data->cddbuffer); + ih->data->cddbuffer = NULL; + }  if (ih->data->cdcanvas) + { cdKillCanvas(ih->data->cdcanvas); + ih->data->cdcanvas = NULL; + } }  static void iTabsDestroyMethod(Ihandle* ih) diff --git a/iup/srccontrols/iup_oldval.c b/iup/srccontrols/iup_oldval.c index 50dae8a..9c14c90 100755 --- a/iup/srccontrols/iup_oldval.c +++ b/iup/srccontrols/iup_oldval.c @@ -533,7 +533,7 @@ static char* iValGetTypeAttrib(Ihandle* ih) static char* iValGetValueAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->val); + sprintf(str, "%g", ih->data->val); return str; }  @@ -576,7 +576,7 @@ static int iValSetStepAttrib(Ihandle* ih, const char* step) static char* iValGetStepAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->step); + sprintf(str, "%g", ih->data->step); return str; }  @@ -590,7 +590,7 @@ static int iValSetPageStepAttrib(Ihandle* ih, const char* pagestep) static char* iValGetPageStepAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->pagestep); + sprintf(str, "%g", ih->data->pagestep); return str; }  @@ -605,7 +605,7 @@ static int iValSetMaxAttrib(Ihandle* ih, const char* max) static char* iValGetMaxAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->vmax); + sprintf(str, "%g", ih->data->vmax); return str; }  @@ -620,7 +620,7 @@ static int iValSetMinAttrib(Ihandle* ih, const char* min) static char* iValGetMinAttrib(Ihandle* ih) { char* str = iupStrGetMemory(20); - sprintf(str, "%f", ih->data->vmin); + sprintf(str, "%g", ih->data->vmin); return str; }  @@ -719,10 +719,16 @@ static int iValMapMethod(Ihandle* ih) static void iValUnMapMethod(Ihandle* ih) { if (ih->data->cddbuffer) + { cdKillCanvas(ih->data->cddbuffer); + ih->data->cddbuffer = NULL; + }  if (ih->data->cdcanvas) + { cdKillCanvas(ih->data->cdcanvas); + ih->data->cdcanvas = NULL; + } }  static void iValDestroyMethod(Ihandle* ih) diff --git a/iup/srccontrols/matrix/iupmat_aux.c b/iup/srccontrols/matrix/iupmat_aux.c index f8b85bb..1a8df57 100755 --- a/iup/srccontrols/matrix/iupmat_aux.c +++ b/iup/srccontrols/matrix/iupmat_aux.c @@ -24,16 +24,11 @@ #include "iupmat_getset.h"   -static int iMatrixAuxIsFullVisibleLast(Ihandle* ih, int m) +int iupMatrixAuxIsFullVisibleLast(ImatLinColData *p) { int i, sum = 0; - ImatLinColData *p; - - if (m == IMAT_PROCESS_LIN) - p = &(ih->data->lines); - else - p = &(ih->data->columns);  + sum -= p->first_offset; for(i = p->first; i <= p->last; i++) sum += p->sizes[i];  @@ -43,16 +38,20 @@ static int iMatrixAuxIsFullVisibleLast(Ihandle* ih, int m) return 1; }  -int iupMatrixAuxIsCellFullVisible(Ihandle* ih, int lin, int col) +int iupMatrixAuxIsCellStartVisible(Ihandle* ih, int lin, int col) { if(((lin >= ih->data->lines.first) && (lin <= ih->data->lines.last) && (col >= ih->data->columns.first) && (col <= ih->data->columns.last))) { - if (col == ih->data->columns.last && !iMatrixAuxIsFullVisibleLast(ih, IMAT_PROCESS_COL)) + if (col == ih->data->columns.first && ih->data->columns.first_offset!=0) + return 0; + if (lin == ih->data->lines.first && ih->data->lines.first_offset!=0) return 0; - if (lin == ih->data->lines.last && !iMatrixAuxIsFullVisibleLast(ih, IMAT_PROCESS_LIN)) + if (col == ih->data->columns.last && !iupMatrixAuxIsFullVisibleLast(&ih->data->columns)) + return 0; + if (lin == ih->data->lines.last && !iupMatrixAuxIsFullVisibleLast(&ih->data->lines)) return 0;  return 1; @@ -81,18 +80,98 @@ void iupMatrixAuxGetVisibleCellDim(Ihandle* ih, int lin, int col, int* x, int* y /* find the position where the column starts */ *x = ih->data->columns.sizes[0]; for(i = ih->data->columns.first; i < col; i++) + { *x += ih->data->columns.sizes[i];  - /* find the column size */ + if (i == ih->data->columns.first) + *x -= ih->data->columns.first_offset; + } + + /* get the column size */ *w = ih->data->columns.sizes[col] - 1; + if (col == ih->data->columns.first) + *w -= ih->data->columns.first_offset;  /* find the position where the line starts */ *y = ih->data->lines.sizes[0]; for(i = ih->data->lines.first; i < lin; i++) + { *y += ih->data->lines.sizes[i];  - /* find the line size */ + if (i == ih->data->lines.first) + *y -= ih->data->lines.first_offset; + } + + /* get the line size */ *h = ih->data->lines.sizes[lin] - 1; + if (lin == ih->data->lines.first) + *h -= ih->data->lines.first_offset; +} + +void iupMatrixAuxAdjustFirstFromLast(ImatLinColData* p) +{ + int i, sum = 0; + + /* adjust "first" according to "last" */ + + i = p->last; + sum = p->sizes[i]; + while (i>1 && sum < p->visible_size) + { + i--; + sum += p->sizes[i]; + } + + if (i==1 && sum < p->visible_size) + { + /* if there are room for everyone then position at start */ + p->first = 1; + p->first_offset = 0; + } + else + { + /* the "while" found an index for first */ + p->first = i; + + /* position at the remaing space */ + p->first_offset = sum - p->visible_size; + } +} + +void iupMatrixAuxAdjustFirstFromScrollPos(ImatLinColData* p, int scroll_pos) +{ + int index, sp, offset = 0; + + sp = 0; + for(index = 1; index < p->num; index++) + { + sp += p->sizes[index]; + if (sp > scroll_pos) + { + sp -= p->sizes[index]; /* get the previous value */ + offset = scroll_pos - sp; + break; + } + } + + if (index == p->num) + { + if (p->num == 1) + { + /* did NOT go trough the "for" above */ + offset = scroll_pos; + index = 1; + } + else + { + /* go all the way trough the "for" above, but still sp < scroll_pos */ + offset = scroll_pos - sp; + index = p->num-1; + } + } + + p->first = index; + p->first_offset = offset; }  /* Calculate the size, in pixels, of the invisible columns/lines, @@ -101,10 +180,11 @@ void iupMatrixAuxGetVisibleCellDim(Ihandle* ih, int lin, int col, int* x, int* y Depends on the first visible column/line. -> m : choose will operate on lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixAuxUpdateVisiblePos(Ihandle* ih, int m) +void iupMatrixAuxUpdateScrollPos(Ihandle* ih, int m) { + float pos; + int i, sb, scroll_pos; char* POS; - int i, sb, visible_pos; ImatLinColData *p;  if (m == IMAT_PROCESS_LIN) @@ -120,33 +200,44 @@ void iupMatrixAuxUpdateVisiblePos(Ihandle* ih, int m) POS = "POSX"; }  - visible_pos = 0; - for(i = 1; i < p->first; i++) - visible_pos += p->sizes[i]; + /* "first" was changed, so update "last" and the scroll pos */  - if (ih->data->canvas.sb & sb) + if (p->total_size <= p->visible_size) { - float pos; + /* the matrix is fully visible */ + p->first = 1; + p->first_offset = 0; + p->last = p->num==1? 1: p->num-1;  - if (p->total_size) - { - while ((visible_pos + p->visible_size > p->total_size) && p->first>1) - { - /* invalid position, must recalculate first */ - p->first--; - visible_pos -= p->sizes[p->first]; - } + if (ih->data->canvas.sb & sb) + IupSetAttribute(ih, POS, "0");  - pos = (float)visible_pos/(float)p->total_size; - } - else - pos = 0; + return; + } + + /* must check if it is a valid position */ + scroll_pos = 0; + for(i = 1; i < p->first; i++) + scroll_pos += p->sizes[i]; + scroll_pos += p->first_offset; + + if (scroll_pos + p->visible_size > p->total_size) + { + /* invalid condition, must recalculate so it is valid */ + scroll_pos = p->total_size - p->visible_size;  - iupMatrixAuxUpdateLast(p); - IupSetfAttribute(ih, POS, "%.5f", (double)pos); + /* position first and first_offset, according to scroll pos */ + iupMatrixAuxAdjustFirstFromScrollPos(p, scroll_pos); } - else - iupMatrixAuxUpdateLast(p); + + pos = (float)scroll_pos/(float)p->total_size; + + /* update last */ + iupMatrixAuxUpdateLast(p); + + /* update scroll pos */ + if (ih->data->canvas.sb & sb) + IupSetfAttribute(ih, POS, "%g", (double)pos); }  /* Calculate which is the last visible column/line of the matrix.  @@ -157,18 +248,24 @@ void iupMatrixAuxUpdateLast(ImatLinColData *p)  if (p->visible_size > 0) { - /* Find which is the last column/line + /* Find which is the last column/line. Start in the first visible and continue adding the widths - up to the visible size */ + up to the visible size */ + sum -= p->first_offset; for(i = p->first; i < p->num; i++) { - sum += p->sizes[i]; + sum += p->sizes[i]; if(sum >= p->visible_size) break; }  if (i == p->num) - p->last = i-1; + { + if (p->num == 1) + p->last = 1; + else + p->last = p->num-1; + } else p->last = i; } @@ -185,7 +282,7 @@ int iupMatrixAuxGetColumnWidth(Ihandle* ih, int col) char* str = iupStrGetMemory(100); char* value;  - /* can only be called for valid columns */ + /* can be called for invalid columns (col>numcol) */  sprintf(str, "WIDTH%d", col); value = iupAttribGet(ih, str); @@ -219,7 +316,7 @@ int iupMatrixAuxGetColumnWidth(Ihandle* ih, int col) width = max_width; } } - else if (ih->data->use_title_size) + else if (ih->data->use_title_size && (col>=0 && coldata->columns.num)) { char* title_value = iupMatrixCellGetValue(ih, 0, col); if (title_value) @@ -257,7 +354,7 @@ int iupMatrixAuxGetLineHeight(Ihandle* ih, int lin) char* str = iupStrGetMemory(100); char* value;  - /* can only be called for valid lines */ + /* can be called for invalid lines (lin>numlin) */  sprintf(str, "HEIGHT%d", lin); value = iupAttribGet(ih, str); @@ -291,7 +388,7 @@ int iupMatrixAuxGetLineHeight(Ihandle* ih, int lin) height = max_height; } } - else if (ih->data->use_title_size) + else if (ih->data->use_title_size && (lin>=0 && lindata->lines.num)) { char* title_value = iupMatrixCellGetValue(ih, lin, 0); if (title_value && title_value[0]) @@ -374,7 +471,7 @@ static void iMatrixAuxUpdateVisibleSize(Ihandle* ih, int m) p->visible_size = p->total_size;  if (p->total_size) - IupSetfAttribute(ih, D, "%f", (double)p->visible_size/(double)p->total_size); + IupSetfAttribute(ih, D, "%g", (double)p->visible_size/(double)p->total_size); else IupSetAttribute(ih, D, "1.0"); } @@ -390,6 +487,7 @@ void iupMatrixAuxCalcSizes(Ihandle* ih) /* when removing lines the first can be positioned after the last line */ if (ih->data->lines.first > ih->data->lines.num-1)  { + ih->data->lines.first_offset = 0; if (ih->data->lines.num==1) ih->data->lines.first = 1; else @@ -397,46 +495,50 @@ void iupMatrixAuxCalcSizes(Ihandle* ih) } if (ih->data->columns.first > ih->data->columns.num-1)  { + ih->data->columns.first_offset = 0; if (ih->data->columns.num == 1) ih->data->columns.first = 1; else ih->data->columns.first = ih->data->columns.num-1; }  - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL); - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN); + /* make sure scroll pos is consistent */ + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_COL); + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_LIN);  ih->data->need_calcsize = 0; }  int iupMatrixAuxGetLinColFromXY(Ihandle* ih, int x, int y, int* l, int* c) { - int size, lin, col; + int x_col, y_col, lin, col;  - size = ih->data->columns.sizes[0]; /* always visible when non zero */ - if (x < size) + x_col = ih->data->columns.sizes[0]; /* always visible when non zero */ + if (x < x_col) col = 0; /* It is in the column of titles */ else { + x_col -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col <= ih->data->columns.last; col++) /* for all visible columns */ { - size += ih->data->columns.sizes[col]; - if (x < size) + x_col += ih->data->columns.sizes[col]; + if (x < x_col) break; } if (col > ih->data->columns.last) col = -1; }  - size = ih->data->lines.sizes[0]; /* always visible when non zero */ - if (y < size) + y_col = ih->data->lines.sizes[0]; /* always visible when non zero */ + if (y < y_col) lin = 0; /* It is in the line of titles */ else { + y_col -= ih->data->lines.first_offset; for(lin = ih->data->lines.first; lin <= ih->data->lines.last; lin++) /* for all visible lines */ { - size += ih->data->lines.sizes[lin]; - if (y < size) + y_col += ih->data->lines.sizes[lin]; + if (y < y_col) break; } if(lin > ih->data->lines.last) diff --git a/iup/srccontrols/matrix/iupmat_aux.h b/iup/srccontrols/matrix/iupmat_aux.h index 296c1f5..01c77f1 100755 --- a/iup/srccontrols/matrix/iupmat_aux.h +++ b/iup/srccontrols/matrix/iupmat_aux.h @@ -12,19 +12,22 @@ extern "C" { #endif  -int iupMatrixAuxIsCellFullVisible(Ihandle* ih, int lin, int col); +int iupMatrixAuxIsFullVisibleLast(ImatLinColData *p); +int iupMatrixAuxIsCellStartVisible(Ihandle* ih, int lin, int col); int iupMatrixAuxIsCellVisible(Ihandle* ih, int lin, int col); void iupMatrixAuxGetVisibleCellDim (Ihandle* ih, int lin, int col, int* x, int* y, int* w, int* h);  void iupMatrixAuxCalcSizes(Ihandle* ih);  -void iupMatrixAuxUpdateVisiblePos(Ihandle* ih, int m); +void iupMatrixAuxAdjustFirstFromLast(ImatLinColData* p); +void iupMatrixAuxAdjustFirstFromScrollPos(ImatLinColData* p, int scroll_pos); +void iupMatrixAuxUpdateScrollPos(Ihandle* ih, int m); void iupMatrixAuxUpdateLast(ImatLinColData *p);  int iupMatrixAuxGetColumnWidth(Ihandle* ih, int col); int iupMatrixAuxGetLineHeight (Ihandle* ih, int lin);  -int iupMatrixAuxGetLinColFromXY (Ihandle* ih, int x, int y, int* l, int* c); +int iupMatrixAuxGetLinColFromXY (Ihandle* ih, int x, int y, int* l, int* c);  int iupMatrixAuxCallLeaveCellCb (Ihandle* ih); void iupMatrixAuxCallEnterCellCb (Ihandle* ih); diff --git a/iup/srccontrols/matrix/iupmat_cd.h b/iup/srccontrols/matrix/iupmat_cd.h index 1a10f2b..beb616a 100755 --- a/iup/srccontrols/matrix/iupmat_cd.h +++ b/iup/srccontrols/matrix/iupmat_cd.h @@ -11,12 +11,12 @@ extern "C" { #endif  -#define IUPMAT_LINE(_ih,_x1,_y1,_x2,_y2) cdCanvasLine((_ih)->data->cddbuffer, (_x1), iupMatrixInvertYAxis(_ih, _y1), (_x2), iupMatrixInvertYAxis(_ih, _y2)) -#define IUPMAT_VERTEX(_ih,_x,_y) cdCanvasVertex((_ih)->data->cddbuffer, (_x), iupMatrixInvertYAxis(_ih, _y)) -#define IUPMAT_BOX(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasBox((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMatrixInvertYAxis(_ih, _ymin), iupMatrixInvertYAxis(_ih, _ymax)) -#define IUPMAT_RECT(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasRect((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMatrixInvertYAxis(_ih, _ymin), iupMatrixInvertYAxis(_ih, _ymax)) -#define IUPMAT_CLIPAREA(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasClipArea((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMatrixInvertYAxis(_ih, _ymin), iupMatrixInvertYAxis(_ih, _ymax)) -#define IUPMAT_TEXT(_ih,_x,_y,_text) cdCanvasText((_ih)->data->cddbuffer, (_x), iupMatrixInvertYAxis(_ih, _y), (_text)) +#define iupMATRIX_LINE(_ih,_x1,_y1,_x2,_y2) cdCanvasLine((_ih)->data->cddbuffer, (_x1), iupMATRIX_INVERTYAXIS(_ih, _y1), (_x2), iupMATRIX_INVERTYAXIS(_ih, _y2)) +#define iupMATRIX_VERTEX(_ih,_x,_y) cdCanvasVertex((_ih)->data->cddbuffer, (_x), iupMATRIX_INVERTYAXIS(_ih, _y)) +#define iupMATRIX_BOX(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasBox((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMATRIX_INVERTYAXIS(_ih, _ymin), iupMATRIX_INVERTYAXIS(_ih, _ymax)) +#define iupMATRIX_RECT(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasRect((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMATRIX_INVERTYAXIS(_ih, _ymin), iupMATRIX_INVERTYAXIS(_ih, _ymax)) +#define iupMATRIX_CLIPAREA(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasClipArea((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMATRIX_INVERTYAXIS(_ih, _ymin), iupMATRIX_INVERTYAXIS(_ih, _ymax)) +#define iupMATRIX_TEXT(_ih,_x,_y,_text) cdCanvasText((_ih)->data->cddbuffer, (_x), iupMATRIX_INVERTYAXIS(_ih, _y), (_text))  #ifdef __cplusplus } diff --git a/iup/srccontrols/matrix/iupmat_colres.c b/iup/srccontrols/matrix/iupmat_colres.c index d44b7df..79f389e 100755 --- a/iup/srccontrols/matrix/iupmat_colres.c +++ b/iup/srccontrols/matrix/iupmat_colres.c @@ -34,15 +34,17 @@ if so the resize is started */ int iupMatrixColResStart(Ihandle* ih, int x, int y) { - if (ih->data->lines.sizes[0] && y < ih->data->lines.sizes[0] && iupAttribGetBoolean(ih, "RESIZEMATRIX")) + if (ih->data->lines.sizes[0] &&  + y < ih->data->lines.sizes[0] &&  + iupAttribGetBoolean(ih, "RESIZEMATRIX")) { - int size, col; + int x_col, col;  /* Check if is the column of titles */ - size = ih->data->columns.sizes[0]; - if (abs(size-x) < IMAT_COLRES_TOL) + x_col = ih->data->columns.sizes[0]; + if (abs(x_col-x) < IMAT_COLRES_TOL) { - ih->data->colres_drag_col_start_x = 0; + ih->data->colres_drag_col_start_x = x; ih->data->colres_dragging = 1; ih->data->colres_drag_col_last_x = -1; ih->data->colres_drag_col = 0; @@ -51,12 +53,13 @@ int iupMatrixColResStart(Ihandle* ih, int x, int y) else { /* find the column */ + x_col -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col <= ih->data->columns.last; col++) { - ih->data->colres_drag_col_start_x = size; - size += ih->data->columns.sizes[col]; - if (abs(size-x) < IMAT_COLRES_TOL) + x_col += ih->data->columns.sizes[col]; + if (abs(x_col-x) < IMAT_COLRES_TOL) { + ih->data->colres_drag_col_start_x = x; ih->data->colres_dragging = 1; ih->data->colres_drag_col_last_x = -1; ih->data->colres_drag_col = col; @@ -71,7 +74,8 @@ int iupMatrixColResStart(Ihandle* ih, int x, int y) void iupMatrixColResFinish(Ihandle* ih, int x) { char str[100]; - int width = x - ih->data->colres_drag_col_start_x; + int delta = x - ih->data->colres_drag_col_start_x; + int width = ih->data->columns.sizes[ih->data->colres_drag_col] + delta; if (width < 0) width = 0;  @@ -83,8 +87,8 @@ void iupMatrixColResFinish(Ihandle* ih, int x)  cdCanvasWriteMode(ih->data->cdcanvas, CD_XOR); cdCanvasForeground(ih->data->cdcanvas, IMAT_RESIZE_COLOR);  - cdCanvasLine(ih->data->cdcanvas, ih->data->colres_drag_col_last_x, iupMatrixInvertYAxis(ih, y1),  - ih->data->colres_drag_col_last_x, iupMatrixInvertYAxis(ih, y2)); + cdCanvasLine(ih->data->cdcanvas, ih->data->colres_drag_col_last_x, iupMATRIX_INVERTYAXIS(ih, y1),  + ih->data->colres_drag_col_last_x, iupMATRIX_INVERTYAXIS(ih, y2)); cdCanvasWriteMode(ih->data->cdcanvas, CD_REPLACE); }  @@ -106,7 +110,8 @@ void iupMatrixColResMove(Ihandle* ih, int x) { int y1, y2;  - int width = x - ih->data->colres_drag_col_start_x; + int delta = x - ih->data->colres_drag_col_start_x; + int width = ih->data->columns.sizes[ih->data->colres_drag_col] + delta; if (width < 0) return;  @@ -119,12 +124,12 @@ void iupMatrixColResMove(Ihandle* ih, int x) /* If it is not the first time, move old line */ if (ih->data->colres_drag_col_last_x != -1) { - cdCanvasLine(ih->data->cdcanvas, ih->data->colres_drag_col_last_x, iupMatrixInvertYAxis(ih, y1),  - ih->data->colres_drag_col_last_x, iupMatrixInvertYAxis(ih, y2)); + cdCanvasLine(ih->data->cdcanvas, ih->data->colres_drag_col_last_x, iupMATRIX_INVERTYAXIS(ih, y1),  + ih->data->colres_drag_col_last_x, iupMATRIX_INVERTYAXIS(ih, y2)); }  - cdCanvasLine(ih->data->cdcanvas, x, iupMatrixInvertYAxis(ih, y1),  - x, iupMatrixInvertYAxis(ih, y2)); + cdCanvasLine(ih->data->cdcanvas, x, iupMATRIX_INVERTYAXIS(ih, y1),  + x, iupMATRIX_INVERTYAXIS(ih, y2));  ih->data->colres_drag_col_last_x = x; cdCanvasWriteMode(ih->data->cdcanvas, CD_REPLACE); @@ -144,20 +149,23 @@ static void iMatrixColResResetMatrixCursor(Ihandle* ih) /* Change the cursor when it passes over a group of the column titles. */ void iupMatrixColResCheckChangeCursor(Ihandle* ih, int x, int y) { - if(ih->data->lines.sizes[0] && y < ih->data->lines.sizes[0] && iupAttribGetBoolean(ih, "RESIZEMATRIX")) + if(ih->data->lines.sizes[0] &&  + y < ih->data->lines.sizes[0] &&  + iupAttribGetBoolean(ih, "RESIZEMATRIX")) { /* It is in the column titles area and the resize mode is on */ - int found = 0, size, col; + int found = 0, x_col, col;  - size = ih->data->columns.sizes[0]; - if (abs(size - x) < IMAT_COLRES_TOL) + x_col = ih->data->columns.sizes[0]; + if (abs(x_col - x) < IMAT_COLRES_TOL) found = 1; /* line titles */ else { + x_col -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col <= ih->data->columns.last && !found; col++) { - size += ih->data->columns.sizes[col]; - if(abs(size - x) < IMAT_COLRES_TOL) + x_col += ih->data->columns.sizes[col]; + if(abs(x_col - x) < IMAT_COLRES_TOL) found = 1; } } @@ -168,7 +176,7 @@ void iupMatrixColResCheckChangeCursor(Ihandle* ih, int x, int y) iupAttribStoreStr(ih, "_IUPMAT_CURSOR", IupGetAttribute(ih, "CURSOR")); IupSetAttribute(ih, "CURSOR", "RESIZE_W"); } - else /* It is in the empty area after the last column */ + else /* It is in the empty area after the last column, or inside a cell */ iMatrixColResResetMatrixCursor(ih);  } else diff --git a/iup/srccontrols/matrix/iupmat_def.h b/iup/srccontrols/matrix/iupmat_def.h index d45acde..225cc16 100755 --- a/iup/srccontrols/matrix/iupmat_def.h +++ b/iup/srccontrols/matrix/iupmat_def.h @@ -49,6 +49,7 @@ typedef struct _ImatLinColData int num; /* Number of columns/lines in the matrix, default/minimum=1, always includes the title */ int num_alloc; /* Number of columns/lines allocated, default=5 */  + int first_offset; /* scroll offset of the first visible column/line from right to left (or the invisible part of the first cell) */ int first; /* First visible column/line */ int last; /* Last visible column/line */  @@ -84,7 +85,7 @@ struct _IcontrolData  /* attributes */ int mark_continuous, mark_mode, mark_multiple; - int checkframecolor; + int checkframecolor, hidden_text_marks;  /* Mouse and Keyboard AUX */ int leftpressed; /* left mouse button is pressed */ @@ -92,8 +93,8 @@ struct _IcontrolData  /* ColRes AUX */ int colres_dragging, /* indicates if it is being made a column resize */ - colres_drag_col, /* column being resized */ - colres_drag_col_start_x, /* position of the start of the column being resized */ + colres_drag_col, /* column being resized, handler is at right of the column */ + colres_drag_col_start_x, /* handler start position */ colres_drag_col_last_x; /* previous position */  /* Mark AUX */ @@ -107,12 +108,14 @@ struct _IcontrolData IFniiIII fgcolor_cb; IFniiIII bgcolor_cb; char *bgcolor, *bgcolor_parent, *fgcolor, *font; /* not need to free */ + + int clip_x1, clip_x2, clip_y1, clip_y2; /* aux for cell clipping */ };   int iupMatrixIsValid(Ihandle* ih, int check_cells);  -#define iupMatrixInvertYAxis(_ih, _y) ((_ih)->data->h-1 - (_y)) +#define iupMATRIX_INVERTYAXIS(_ih, _y) ((_ih)->data->h-1 - (_y))   #ifdef __cplusplus diff --git a/iup/srccontrols/matrix/iupmat_draw.c b/iup/srccontrols/matrix/iupmat_draw.c index 7c53fb5..ec3df59 100755 --- a/iup/srccontrols/matrix/iupmat_draw.c +++ b/iup/srccontrols/matrix/iupmat_draw.c @@ -47,13 +47,38 @@ #define IMAT_COMBOBOX_W 16   -typedef int (*IFniiiiiiC)(Ihandle *h, int lin, int col,int x1, int x2, int y1, int y2, cdCanvas* cnv); +typedef int (*IFniiiiiiC)(Ihandle *h, int lin, int col, int x1, int x2, int y1, int y2, cdCanvas* cnv);   /**************************************************************************/ /* Private functions */ /**************************************************************************/  +static void iMatrixDrawSetCellClipping(Ihandle* ih, int x1, int x2, int y1, int y2) +{ + int old_clip = cdCanvasClip(ih->data->cddbuffer, CD_QUERY); + if (old_clip == CD_CLIPAREA) + { + cdCanvasGetClipArea(ih->data->cddbuffer, &(ih->data->clip_x1), &(ih->data->clip_x2), &(ih->data->clip_y1), &(ih->data->clip_y2)); + y1 = iupMATRIX_INVERTYAXIS(ih, y1); + y2 = iupMATRIX_INVERTYAXIS(ih, y2); + if (x1 > x2) {int tmp = x1; x1 = x2; x2 = tmp;} + if (y1 > y2) {int tmp = y1; y1 = y2; y2 = tmp;} + if (x1 < ih->data->clip_x1) x1 = ih->data->clip_x1; + if (x2 > ih->data->clip_x2) x2 = ih->data->clip_x2; + if (y1 < ih->data->clip_y1) y1 = ih->data->clip_y1; + if (y2 > ih->data->clip_y2) y2 = ih->data->clip_y2; + cdCanvasClipArea(ih->data->cddbuffer, x1, x2, y1, y2); + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + } +} + +static void iMatrixDrawResetCellClipping(Ihandle* ih) +{ + int old_clip = cdCanvasClip(ih->data->cddbuffer, CD_QUERY); + if (old_clip == CD_CLIPAREA) + cdCanvasClipArea(ih->data->cddbuffer, ih->data->clip_x1, ih->data->clip_x2, ih->data->clip_y1, ih->data->clip_y2); +}  static int iMatrixDrawGetColAlignment(Ihandle* ih, int col, char* str) { @@ -61,6 +86,8 @@ static int iMatrixDrawGetColAlignment(Ihandle* ih, int col, char* str) sprintf(str, "ALIGNMENT%d", col); align = iupAttribGet(ih, str); if (!align) + align = iupAttribGet(ih, "ALIGNMENT"); + if (!align) { if (col == 0) return IMAT_T_LEFT; @@ -80,16 +107,15 @@ static int iMatrixDrawCallDrawCB(Ihandle* ih, int lin, int col, int x1, int x2, int ret; cdCanvas* old_cnv;  - IUPMAT_CLIPAREA(ih, x1, x2, y1, y2); - cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + iMatrixDrawSetCellClipping(ih, x1, x2, y1, y2);  old_cnv = cdActiveCanvas(); if (old_cnv != ih->data->cddbuffer) /* backward compatibility code */ cdActivate(ih->data->cddbuffer);  - ret = draw_cb(ih, lin, col, x1, x2, iupMatrixInvertYAxis(ih, y1), iupMatrixInvertYAxis(ih, y2), ih->data->cddbuffer); + ret = draw_cb(ih, lin, col, x1, x2, iupMATRIX_INVERTYAXIS(ih, y1), iupMATRIX_INVERTYAXIS(ih, y2), ih->data->cddbuffer);  - cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); + iMatrixDrawResetCellClipping(ih);  if (old_cnv && old_cnv != ih->data->cddbuffer) /* backward compatibility code */ { @@ -165,28 +191,36 @@ static void iMatrixDrawFrameHorizLineCell(Ihandle* ih, int lin, int col, int x1, { if (ih->data->checkframecolor && (ih->data->callback_mode || ih->data->cells[lin][col].flags & IUPMAT_FRAMEHCOLOR)) { + char* color; unsigned char r,g,b; sprintf(str, "FRAMEHORIZCOLOR%d:%d", lin, col); - if (iupStrToRGB(iupAttribGet(ih, str), &r, &g, &b)) + color = iupAttribGet(ih, str); + if (iupStrEqual(color, "BGCOLOR")) + return; + if (iupStrToRGB(color, &r, &g, &b)) framecolor = cdEncodeColor(r, g, b); }  cdCanvasForeground(ih->data->cddbuffer, framecolor); - IUPMAT_LINE(ih, x1, y, x2, y); /* bottom horizontal line */ + iupMATRIX_LINE(ih, x1, y, x2, y); /* bottom horizontal line */ }  static void iMatrixDrawFrameVertLineCell(Ihandle* ih, int lin, int col, int x, int y1, int y2, long framecolor, char* str) { if (ih->data->checkframecolor && (ih->data->callback_mode || ih->data->cells[lin][col].flags & IUPMAT_FRAMEVCOLOR)) { + char* color; unsigned char r,g,b; sprintf(str, "FRAMEVERTCOLOR%d:%d", lin, col); - if (iupStrToRGB(iupAttribGet(ih, str), &r, &g, &b)) + color = iupAttribGet(ih, str); + if (iupStrEqual(color, "BGCOLOR")) + return; + if (iupStrToRGB(color, &r, &g, &b)) framecolor = cdEncodeColor(r, g, b); }  cdCanvasForeground(ih->data->cddbuffer, framecolor); - IUPMAT_LINE(ih, x, y1, x, y2); /* right vertical line */ + iupMATRIX_LINE(ih, x, y1, x, y2); /* right vertical line */ }  static void iMatrixDrawFrameRectTitle(Ihandle* ih, int lin, int col, int x1, int x2, int y1, int y2, long framecolor, char* str) @@ -195,37 +229,43 @@ static void iMatrixDrawFrameRectTitle(Ihandle* ih, int lin, int col, int x1, int x2 -= IMAT_FRAME_W/2; y2 -= IMAT_FRAME_H/2;  - iMatrixDrawFrameVertLineCell(ih, lin, col, x2, y1, y2, framecolor, str); /* right vertical line */ + /* right vertical line */ + iMatrixDrawFrameVertLineCell(ih, lin, col, x2, y1, y2, framecolor, str);  if (col==0) { - IUPMAT_LINE(ih, x1, y1, x1, y2); /* left vertical line, reuse Foreground */ + /* left vertical line, reuse Foreground */ + iupMATRIX_LINE(ih, x1, y1, x1, y2);  x1++; } else if (col==1 && ih->data->columns.sizes[0] == 0) { /* If does not have line titles then draw the left line of the cell frame */ - IUPMAT_LINE(ih, x1, y1, x1, y2-1); + iupMATRIX_LINE(ih, x1, y1, x1, y2-1); x1++; }  - cdCanvasForeground(ih->data->cddbuffer, CD_WHITE); /* Titles have a white line near the frame */ - IUPMAT_LINE(ih, x1, y1+1, x1, y2-1); + /* Titles have a white line near the frame, at left */ + cdCanvasForeground(ih->data->cddbuffer, CD_WHITE);  + iupMATRIX_LINE(ih, x1, y1+1, x1, y2-1);  - iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2, y2, framecolor, str); /* bottom horizontal line */ + /* bottom horizontal line */ + iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2, y2, framecolor, str);  if (lin==0) { - IUPMAT_LINE(ih, x1, y1, x2, y1); /* top horizontal line, reuse Foreground */ + /* top horizontal line, reuse Foreground */ + iupMATRIX_LINE(ih, x1, y1, x2, y1);  y1++; } else if (lin==1 && ih->data->lines.sizes[0] == 0) { /* If does not have column titles then draw the top line of the cell frame */ - IUPMAT_LINE(ih, x1, y1, x2-1, y1); + iupMATRIX_LINE(ih, x1, y1, x2-1, y1); y1++; }  - cdCanvasForeground(ih->data->cddbuffer, CD_WHITE); /* Titles have a white line near the frame */ - IUPMAT_LINE(ih, x1, y1, x2-1, y1); + /* Titles have a white line near the frame, at top */ + cdCanvasForeground(ih->data->cddbuffer, CD_WHITE);  + iupMATRIX_LINE(ih, x1, y1, x2-1, y1); }  static void iMatrixDrawFrameRectCell(Ihandle* ih, int lin, int col, int x1, int x2, int y1, int y2, long framecolor, char* str) @@ -233,20 +273,20 @@ static void iMatrixDrawFrameRectCell(Ihandle* ih, int lin, int col, int x1, int if (col==1 && ih->data->columns.sizes[0] == 0) { /* If does not have line titles then draw the left line of the cell frame */ - iMatrixDrawFrameVertLineCell(ih, lin, col, x1, y1, y2-1-1, framecolor, str); + iMatrixDrawFrameVertLineCell(ih, lin, col, x1, y1, y2-1, framecolor, str); }  if (lin==1 && ih->data->lines.sizes[0] == 0) { /* If does not have column titles then draw the top line of the cell frame */ - iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2-1-1, y1, framecolor, str); + iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2-1, y1, framecolor, str); }  /* bottom line */ iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2-1, y2-1, framecolor, str);  /* rigth line */ - iMatrixDrawFrameVertLineCell(ih, lin, col, x2-1, y1, y2-1, framecolor, str); + iMatrixDrawFrameVertLineCell(ih, lin, col, x2-1, y1, y2-2, framecolor, str); }  static int iMatrixDrawSortSign(Ihandle* ih, int x2, int y1, int y2, int col, int active, char* str) @@ -274,15 +314,15 @@ static int iMatrixDrawSortSign(Ihandle* ih, int x2, int y1, int y2, int col, int  if (iupStrEqualNoCase(sort, "DOWN")) { - IUPMAT_VERTEX(ih, x2 - 5, yc + 2); - IUPMAT_VERTEX(ih, x2 - 1, yc - 2); - IUPMAT_VERTEX(ih, x2 - 9, yc - 2); + iupMATRIX_VERTEX(ih, x2 - 5, yc + 2); + iupMATRIX_VERTEX(ih, x2 - 1, yc - 2); + iupMATRIX_VERTEX(ih, x2 - 9, yc - 2); } else { - IUPMAT_VERTEX(ih, x2 - 1, yc + 2); - IUPMAT_VERTEX(ih, x2 - 9, yc + 2); - IUPMAT_VERTEX(ih, x2 - 5, yc - 2); + iupMATRIX_VERTEX(ih, x2 - 1, yc + 2); + iupMATRIX_VERTEX(ih, x2 - 9, yc + 2); + iupMATRIX_VERTEX(ih, x2 - 5, yc - 2); }  cdCanvasEnd(ih->data->cddbuffer); @@ -301,20 +341,20 @@ static void iMatrixDrawComboFeedback(Ihandle* ih, int x2, int y1, int y2, int ac  /* feedback background */ iMatrixDrawSetBgColor(ih, 0, 0, 0, active); - IUPMAT_BOX(ih, x1, x2, y1, y2); + iupMATRIX_BOX(ih, x1, x2, y1, y2);  /* feedback frame */ cdCanvasForeground(ih->data->cddbuffer, framecolor); - IUPMAT_RECT(ih, x1, x2, y1, y2); + iupMATRIX_RECT(ih, x1, x2, y1, y2);  /* feedback arrow */ xh2 = x2 - IMAT_COMBOBOX_W / 2; yh2 = y2 - (y2 - y1) / 2;  cdCanvasBegin(ih->data->cddbuffer, CD_FILL); - IUPMAT_VERTEX(ih, xh2, yh2 + 3); - IUPMAT_VERTEX(ih, xh2 + 4, yh2 - 1); - IUPMAT_VERTEX(ih, xh2 - 4, yh2 - 1); + iupMATRIX_VERTEX(ih, xh2, yh2 + 3); + iupMATRIX_VERTEX(ih, xh2 + 4, yh2 - 1); + iupMATRIX_VERTEX(ih, xh2 - 4, yh2 - 1); cdCanvasEnd(ih->data->cddbuffer); }  @@ -325,7 +365,7 @@ static void iMatrixDrawBackground(Ihandle* ih, int x1, int x2, int y1, int y2, i y2 -= IMAT_FRAME_H/2;  iMatrixDrawSetBgColor(ih, lin, col, marked, active); - IUPMAT_BOX(ih, x1, x2, y1, y2); + iupMATRIX_BOX(ih, x1, x2, y1, y2); }  /* Put the cell contents in the screen, using the specified color and alignment. @@ -372,7 +412,7 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in if (text && *text) { int num_line, line_height, total_height; - int charheight, ypos; + int charheight, ypos, hidden_text_marks = 0;  num_line = iupStrLineCount(text); iupdrvFontGetCharSize(ih, NULL, &charheight); @@ -380,12 +420,18 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in line_height = charheight; total_height = (line_height + IMAT_PADDING_H/2) * num_line - IMAT_PADDING_H/2 - IMAT_FRAME_H/2;  - if (lin==0) + if (lin==0 || ih->data->hidden_text_marks) { int text_w; iupdrvFontGetMultiLineStringSize(ih, text, &text_w, NULL); if (text_w > x2 - x1 + 1 - IMAT_PADDING_W - IMAT_FRAME_W) - alignment = IMAT_T_LEFT; + { + if (lin == 0) + alignment = IMAT_T_LEFT; + + if (ih->data->hidden_text_marks) + hidden_text_marks = 1; + } }  /* Set the color used to draw the text */ @@ -395,8 +441,13 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in iMatrixDrawSetFgColor(ih, lin, col, marked);  /* Set the clip area to the cell region informed, the text maybe greatter than the cell */ - IUPMAT_CLIPAREA(ih, x1, x2, y1, y2); - cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + if (hidden_text_marks) + { + int crop = iupdrvFontGetStringWidth(ih, "...") + 2; + iMatrixDrawSetCellClipping(ih, x1, x2-crop, y1, y2); + } + else + iMatrixDrawSetCellClipping(ih, x1, x2, y1, y2);  cdCanvasNativeFont(ih->data->cddbuffer, iupMatrixGetFont(ih, lin, col));  @@ -417,11 +468,11 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in  /* Put the text */ if (alignment == IMAT_T_CENTER) - IUPMAT_TEXT(ih, (x1 + x2) / 2, ypos, text); + iupMATRIX_TEXT(ih, (x1 + x2) / 2, ypos, text); else if(alignment == IMAT_T_LEFT) - IUPMAT_TEXT(ih, x1, ypos, text); + iupMATRIX_TEXT(ih, x1, ypos, text); else - IUPMAT_TEXT(ih, x2, ypos, text); + iupMATRIX_TEXT(ih, x2, ypos, text); } else { @@ -441,11 +492,11 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in  /* Draw the text */ if(alignment == IMAT_T_CENTER) - IUPMAT_TEXT(ih, (x1 + x2) / 2, ypos, p); + iupMATRIX_TEXT(ih, (x1 + x2) / 2, ypos, p); else if(alignment == IMAT_T_LEFT) - IUPMAT_TEXT(ih, x1, ypos, p); + iupMATRIX_TEXT(ih, x1, ypos, p); else - IUPMAT_TEXT(ih, x2, ypos, p); + iupMATRIX_TEXT(ih, x2, ypos, p);  /* Advance the string */ if (q) p = q + 1; @@ -457,7 +508,15 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in free(newtext); }  - cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); + iMatrixDrawResetCellClipping(ih); + + if (hidden_text_marks) + { + cdCanvasTextAlignment(ih->data->cddbuffer, CD_EAST); + ypos = (int)((y1 + y2) / 2.0 - 0.5); + iupMATRIX_TEXT(ih, x2+IMAT_PADDING_W/2, ypos, "..."); + } + } }  @@ -522,7 +581,7 @@ static void iMatrixDrawFocus(Ihandle* ih) if (ih->data->lines.focus_cell == 1 && ih->data->lines.sizes[0] == 0) y1++;  - cdIupDrawFocusRect(ih, ih->data->cdcanvas, x1, iupMatrixInvertYAxis(ih, y1), x2, iupMatrixInvertYAxis(ih, y2)); + cdIupDrawFocusRect(ih, ih->data->cdcanvas, x1, iupMATRIX_INVERTYAXIS(ih, y1), x2, iupMATRIX_INVERTYAXIS(ih, y2)); }   @@ -560,6 +619,11 @@ void iupMatrixDrawLineTitle(Ihandle* ih, int lin1, int lin2) x2 = ih->data->columns.sizes[0];  y1 = ih->data->lines.sizes[0]; + + iupMATRIX_CLIPAREA(ih, x1, x2, y1, ih->data->h-1); + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + + y1 -= ih->data->lines.first_offset; for(lin = ih->data->lines.first; lin < lin1; lin++) y1 += ih->data->lines.sizes[lin];  @@ -592,6 +656,8 @@ void iupMatrixDrawLineTitle(Ihandle* ih, int lin1, int lin2)  y1 = y2; } + + cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); }  /* Draw the column titles, visible, between col and lastcol, include it.  @@ -623,6 +689,11 @@ void iupMatrixDrawColumnTitle(Ihandle* ih, int col1, int col2) y2 = ih->data->lines.sizes[0];  x1 = ih->data->columns.sizes[0]; + + iupMATRIX_CLIPAREA(ih, x1, ih->data->w-1, y1, y2); + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + + x1 -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col < col1; col++) x1 += ih->data->columns.sizes[col];  @@ -657,6 +728,8 @@ void iupMatrixDrawColumnTitle(Ihandle* ih, int col1, int col2)  x1 = x2; } + + cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); }  /* Redraw a block of cells of the matrix. Handle marked cells, change @@ -673,13 +746,11 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) IFnii dropcheck_cb; IFniiiiiiC draw_cb;  - x1 = 0; x2 = ih->data->w-1; - y1 = 0; y2 = ih->data->h-1;  old_x2 = x2; - old_y1 = y1; + old_y1 = 0; old_y2 = y2;  if (col1 > ih->data->columns.last || @@ -697,8 +768,14 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) if (lin2 > ih->data->lines.last) lin2 = ih->data->lines.last;  + x1 = ih->data->columns.sizes[0]; + y1 = ih->data->lines.sizes[0]; + + iupMATRIX_CLIPAREA(ih, x1, x2, y1, y2); + cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); /* wait for background */ + /* Find the initial position of the first column */ - x1 += ih->data->columns.sizes[0]; + x1 -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col < col1; col++) x1 += ih->data->columns.sizes[col];  @@ -708,7 +785,7 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) x2 += ih->data->columns.sizes[col];  /* Find the initial position of the first line */ - y1 += ih->data->lines.sizes[0]; + y1 -= ih->data->lines.first_offset; for(lin = ih->data->lines.first; lin < lin1; lin++) y1 += ih->data->lines.sizes[lin];  @@ -724,7 +801,7 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2)  /* If it was drawn until the last column and remains space in the right of it, then delete this area with the the background color. */ - IUPMAT_BOX(ih, x2, old_x2, old_y1, old_y2); + iupMATRIX_BOX(ih, x2, old_x2, old_y1, old_y2); }  if ((lin2 == ih->data->lines.num-1) && (old_y2 > y2)) @@ -735,9 +812,12 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2)  /* If it was drawn until the last line visible and remains space below it, then delete this area with the the background color. */ - IUPMAT_BOX(ih, 0, old_x2, y2, old_y2); + iupMATRIX_BOX(ih, 0, old_x2, y2, old_y2); }  + /* after the background */ + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + /***** Draw the cell values and frame */ old_y1 = y1; framecolor = cdIupConvertColor(iupAttribGetStr(ih, "FRAMECOLOR")); @@ -775,7 +855,7 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2)  if (dropcheck_cb && dropcheck_cb(ih, lin, col) == IUP_DEFAULT) { - drop = IMAT_COMBOBOX_W; + drop = IMAT_COMBOBOX_W+IMAT_PADDING_W/2; iMatrixDrawComboFeedback(ih, x2, y1, y2, active, framecolor); }  @@ -788,6 +868,8 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) x1 = x2; y1 = old_y1; /* must reset also y */ } + + cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); }  void iupMatrixDraw(Ihandle* ih, int update) diff --git a/iup/srccontrols/matrix/iupmat_edit.c b/iup/srccontrols/matrix/iupmat_edit.c index a7e0a74..551baed 100755 --- a/iup/srccontrols/matrix/iupmat_edit.c +++ b/iup/srccontrols/matrix/iupmat_edit.c @@ -67,7 +67,7 @@ static int iMatrixEditDropDownAction_CB(Ihandle* ih, char* t, int i, int v) if (ret == IUP_CONTINUE) { iupMatrixEditHide(ih_matrix); - iupMatrixDrawUpdate(ih); + iupMatrixDrawUpdate(ih_matrix); } }  @@ -137,13 +137,31 @@ static int iMatrixEditCancel(Ihandle* ih, int focus, int update, int ignore) return IUP_DEFAULT; }  +static int iMatrixEditDropDown_CB(Ihandle* ih, int state) +{ + /* In Motif if DROPDOWN=YES then when the dropdown button is clicked  + the list looses its focus and when the dropped list is closed  + the list regain the focus, also when that happen if the list looses its focus  + to another control the kill focus callback is not called. */ + Ihandle* ih_matrix = ih->parent; + if (state == 1) + iupAttribSetStr(ih_matrix, "_IUPMAT_DROPDOWN", "1"); + + return IUP_DEFAULT; +} + static int iMatrixEditKillFocus_CB(Ihandle* ih) { Ihandle* ih_matrix = ih->parent; - if (iupStrEqualNoCase(IupGetGlobal("DRIVER"), "Motif")) + if (IupGetGlobal("MOTIFVERSION")) { - if (iupAttribGet(ih_matrix, "_IUPMAT_DOUBLE_CLICK")) + if (iupAttribGet(ih_matrix, "_IUPMAT_DROPDOWN") || /* from iMatrixEditDropDown_CB, in Motif */ + iupAttribGet(ih_matrix, "_IUPMAT_DOUBLECLICK")) /* from iMatrixMouseLeftPress, in Motif */ + { + iupAttribSetStr(ih_matrix, "_IUPMAT_DOUBLECLICK", NULL); + iupAttribSetStr(ih_matrix, "_IUPMAT_DROPDOWN", NULL); return IUP_DEFAULT; + } }  iupMatrixEditForceHidden(ih_matrix); @@ -200,7 +218,7 @@ int iupMatrixEditShow(Ihandle* ih)  /* position the cell to make it visible */ /* If the focus is not visible, a scroll is done for that the focus to be visible */ - if (!iupMatrixAuxIsCellFullVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell)) + if (!iupMatrixAuxIsCellStartVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell)) iupMatrixScrollToVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell);  /* set attributes */ @@ -235,7 +253,7 @@ int iupMatrixEditShow(Ihandle* ih) ih->data->datah->y = y; if (IupGetGlobal("GTKVERSION")) { - /* In GTK, IupCanvas is not the actual container of the IupText/IupList */ + /* In GTK, IupCanvas is NOT the actual container of the IupText/IupList */ ih->data->datah->x += ih->x; ih->data->datah->y += ih->y; } @@ -366,7 +384,7 @@ static int iMatrixEditTextKeyAny_CB(Ihandle* ih, int c)  if (iupMatrixAuxCallLeaveCellCb(ih_matrix) != IUP_IGNORE) { - iupMatrixScrollKeyCr(ih_matrix); + iupMATRIX_ScrollKeyCr(ih_matrix); iupMatrixAuxCallEnterCellCb(ih_matrix); } iupMatrixDrawUpdate(ih_matrix); @@ -399,7 +417,7 @@ static int iMatrixEditDropDownKeyAny_CB(Ihandle* ih, int c) { if (iupMatrixAuxCallLeaveCellCb(ih_matrix) != IUP_IGNORE) { - iupMatrixScrollKeyCr(ih_matrix); + iupMATRIX_ScrollKeyCr(ih_matrix); iupMatrixAuxCallEnterCellCb(ih_matrix); } iupMatrixDrawUpdate(ih_matrix); @@ -440,6 +458,9 @@ void iupMatrixEditCreate(Ihandle* ih) ih->data->droph = IupList(NULL); iupChildTreeAppend(ih, ih->data->droph);  + if (IupGetGlobal("MOTIFVERSION")) + IupSetCallback(ih->data->droph, "DROPDOWN_CB", (Icallback)iMatrixEditDropDown_CB); + IupSetCallback(ih->data->droph, "ACTION", (Icallback)iMatrixEditDropDownAction_CB); IupSetCallback(ih->data->droph, "KILLFOCUS_CB", (Icallback)iMatrixEditKillFocus_CB); IupSetCallback(ih->data->droph, "K_ANY", (Icallback)iMatrixEditDropDownKeyAny_CB); diff --git a/iup/srccontrols/matrix/iupmat_focus.c b/iup/srccontrols/matrix/iupmat_focus.c index 3c000f8..0cf680d 100755 --- a/iup/srccontrols/matrix/iupmat_focus.c +++ b/iup/srccontrols/matrix/iupmat_focus.c @@ -35,13 +35,11 @@ int iupMatrixFocus_CB(Ihandle* ih, int focus) if (!iupMatrixIsValid(ih, 1)) return IUP_DEFAULT;  - if (iupStrEqualNoCase(IupGetGlobal("DRIVER"), "Motif")) + if (IupGetGlobal("MOTIFVERSION")) { - if (focus && iupAttribGet(ih, "_IUPMAT_DOUBLE_CLICK")) - { - iupAttribSetStr(ih, "_IUPMAT_DOUBLE_CLICK", NULL); + if (iupAttribGet(ih, "_IUPMAT_DROPDOWN") || /* from iMatrixEditDropDown_CB, in Motif */ + iupAttribGet(ih, "_IUPMAT_DOUBLECLICK")) /* from iMatrixMouseLeftPress, in Motif */ return IUP_DEFAULT; - } }  ih->data->has_focus = focus; diff --git a/iup/srccontrols/matrix/iupmat_getset.c b/iup/srccontrols/matrix/iupmat_getset.c index 34947b6..4424948 100755 --- a/iup/srccontrols/matrix/iupmat_getset.c +++ b/iup/srccontrols/matrix/iupmat_getset.c @@ -313,7 +313,7 @@ char* iupMatrixGetFont(Ihandle* ih, int lin, int col) return font; }  -char *iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels) +char *iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels_unit) { char* str; int size; @@ -342,7 +342,7 @@ char *iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels) else size -= IMAT_PADDING_H + IMAT_FRAME_H;  - if (!pixels) + if (!pixels_unit) { int charwidth, charheight; iupdrvFontGetCharSize(ih, &charwidth, &charheight); diff --git a/iup/srccontrols/matrix/iupmat_getset.h b/iup/srccontrols/matrix/iupmat_getset.h index 9ae3d07..f26e01e 100755 --- a/iup/srccontrols/matrix/iupmat_getset.h +++ b/iup/srccontrols/matrix/iupmat_getset.h @@ -26,7 +26,7 @@ void iupMatrixGetFgRGB(Ihandle* ih, int lin, int col, unsigned char *r, unsigned  void iupMatrixCellUpdateValue(Ihandle* ih);  -char* iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels); +char* iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels_unit);  int iupMatrixCheckCellPos(Ihandle* ih, int lin, int col);  diff --git a/iup/srccontrols/matrix/iupmat_key.c b/iup/srccontrols/matrix/iupmat_key.c index ae9ed55..4824438 100755 --- a/iup/srccontrols/matrix/iupmat_key.c +++ b/iup/srccontrols/matrix/iupmat_key.c @@ -37,7 +37,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) int ret = IUP_IGNORE; /* default for processed keys */  /* If the focus is not visible, a scroll is done for that the focus to be visible */ - if (!iupMatrixAuxIsCellFullVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell)) + if (!iupMatrixAuxIsCellStartVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell)) iupMatrixScrollToVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell);  switch (c) @@ -47,7 +47,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_HOME: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyHome(ih); + iupMATRIX_ScrollKeyHome(ih); ih->data->homekeycount++; iupMatrixAuxCallEnterCellCb(ih); break; @@ -57,7 +57,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_END: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyEnd(ih); + iupMATRIX_ScrollKeyEnd(ih); ih->data->endkeycount++; iupMatrixAuxCallEnterCellCb(ih); break; @@ -71,7 +71,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_LEFT: if (iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyLeft(ih); + iupMATRIX_ScrollKeyLeft(ih); iupMatrixAuxCallEnterCellCb(ih); break;  @@ -80,7 +80,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_RIGHT: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyRight(ih); + iupMATRIX_ScrollKeyRight(ih); iupMatrixAuxCallEnterCellCb(ih); break;  @@ -89,7 +89,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_UP: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyUp(ih); + iupMATRIX_ScrollKeyUp(ih); iupMatrixAuxCallEnterCellCb(ih); break ;  @@ -98,7 +98,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_DOWN: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyDown(ih); + iupMATRIX_ScrollKeyDown(ih); iupMatrixAuxCallEnterCellCb(ih); break;  @@ -106,7 +106,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_PGUP: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyPgUp(ih); + iupMATRIX_ScrollKeyPgUp(ih); iupMatrixAuxCallEnterCellCb(ih); break;  @@ -114,7 +114,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_PGDN: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyPgDown(ih); + iupMATRIX_ScrollKeyPgDown(ih); iupMatrixAuxCallEnterCellCb(ih); break;  diff --git a/iup/srccontrols/matrix/iupmat_mouse.c b/iup/srccontrols/matrix/iupmat_mouse.c index 33b5fe7..a3ffa82 100755 --- a/iup/srccontrols/matrix/iupmat_mouse.c +++ b/iup/srccontrols/matrix/iupmat_mouse.c @@ -80,12 +80,18 @@ static void iMatrixMouseLeftPress(Ihandle* ih, int lin, int col, int shift, int  if (iupMatrixEditShow(ih)) { - if(ih->data->datah == ih->data->droph)  + if (ih->data->datah == ih->data->droph) IupSetAttribute(ih->data->datah, "SHOWDROPDOWN", "YES");  - if (iupStrEqualNoCase(IupGetGlobal("DRIVER"), "Motif")) - if(atoi(IupGetGlobal("MOTIFNUMBER")) < 2203) /* since OpenMotif version 2.2.3 this is not necessary */ - iupAttribSetStr(ih, "_IUPMAT_DOUBLE_CLICK", "1"); + if (IupGetGlobal("MOTIFVERSION")) + { + /* Sequece of focus_cb in Motif from here: + Matrix-Focus(0) - ok + Edit-KillFocus - weird, must avoid using _IUPMAT_DOUBLECLICK + Since OpenMotif version 2.2.3 this is not necessary anymore. */ + if (atoi(IupGetGlobal("MOTIFNUMBER")) < 2203)  + iupAttribSetStr(ih, "_IUPMAT_DOUBLECLICK", "1"); + } } } else /* single click */ @@ -182,14 +188,14 @@ int iupMatrixMouseMove_CB(Ihandle* ih, int x, int y) if (ih->data->leftpressed && ih->data->mark_multiple && ih->data->mark_mode != IMAT_MARK_NO) { if ((x < ih->data->columns.sizes[0] || x < IMAT_DRAG_SCROLL_DELTA) && (ih->data->columns.first > 1)) - iupMatrixScrollLeft(ih); + iupMATRIX_ScrollLeft(ih); else if ((x > ih->data->w - IMAT_DRAG_SCROLL_DELTA) && (ih->data->columns.last < ih->data->columns.num-1)) - iupMatrixScrollRight(ih); + iupMATRIX_ScrollRight(ih);  if ((y < ih->data->lines.sizes[0] || y < IMAT_DRAG_SCROLL_DELTA) && (ih->data->lines.first > 1)) - iupMatrixScrollUp(ih); + iupMATRIX_ScrollUp(ih); else if ((y > ih->data->h - IMAT_DRAG_SCROLL_DELTA) && (ih->data->lines.last < ih->data->lines.num-1)) - iupMatrixScrollDown(ih); + iupMATRIX_ScrollDown(ih);  if (iupMatrixAuxGetLinColFromXY(ih, x, y, &lin, &col)) { diff --git a/iup/srccontrols/matrix/iupmat_numlc.c b/iup/srccontrols/matrix/iupmat_numlc.c index e48720a..6e628b7 100755 --- a/iup/srccontrols/matrix/iupmat_numlc.c +++ b/iup/srccontrols/matrix/iupmat_numlc.c @@ -294,7 +294,7 @@ int iupMatrixSetAddLinAttrib(Ihandle* ih, const char* value) { int base, count, lines_num = ih->data->lines.num;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0;  if (!iMatrixGetStartEnd(value, &base, &count, lines_num, 0)) @@ -326,7 +326,7 @@ int iupMatrixSetDelLinAttrib(Ihandle* ih, const char* value) { int base, count, lines_num = ih->data->lines.num;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0;  if (!iMatrixGetStartEnd(value, &base, &count, lines_num, 1)) @@ -366,7 +366,7 @@ int iupMatrixSetAddColAttrib(Ihandle* ih, const char* value) { int base, count, columns_num = ih->data->columns.num;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0;  if (!iMatrixGetStartEnd(value, &base, &count, columns_num, 0)) @@ -398,7 +398,7 @@ int iupMatrixSetDelColAttrib(Ihandle* ih, const char* value) { int base, count, columns_num = ih->data->columns.num;  - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0;  if (!iMatrixGetStartEnd(value, &base, &count, columns_num, 1)) diff --git a/iup/srccontrols/matrix/iupmat_scroll.c b/iup/srccontrols/matrix/iupmat_scroll.c index 24bbef2..845d248 100755 --- a/iup/srccontrols/matrix/iupmat_scroll.c +++ b/iup/srccontrols/matrix/iupmat_scroll.c @@ -32,54 +32,32 @@ /* Private functions */ /**************************************************************************/  - -static int iMatrixScrollIsFullVisibleLast(ImatLinColData *p) -{ - int i, sum = 0; - - for(i = p->first; i <= p->last; i++) - sum += p->sizes[i]; - - if (sum > p->visible_size) - return 0; - else - return 1; -} - -/* Scroll columns/lines in the left/top side of the matriz until the last column/line is FULLY visible. - -> m : Define the mode of operation: lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -static void iMatrixScrollToVisible(Ihandle* ih, int m, int index) +static void iMatrixScrollToVisible(ImatLinColData* p, int index) { - ImatLinColData* p; + /* The work here is just to position first and first_offset,  + so "index" is between "first" and "last". */ +  + /* It is called only for discrete scrolling,  + so first_offset usually will be set to 0. */ + + /* already visible, change nothing */ + if (index > p->first && index < p->last) + return;  - if (m == IMAT_PROCESS_LIN) - p = &(ih->data->lines); - else - p = &(ih->data->columns); + /* scroll to visible, means position the cell so the start at left is visible */  - if (index < p->first) + if (index <= p->first) { p->first = index; + p->first_offset = 0; return; } - else if (index > p->last) + else /* (index >= p->last) */ { - /* Increment the first column/line until the index is visible */ - while(index > p->last && p->last != (p->num - 1)) - { - p->first++; - iupMatrixAuxUpdateLast(p); - }  - } + p->last = index;  - if (index == p->last) - { - /* must increment util the last is fully visible */ - while(index == p->last && p->last != (p->num - 1) && !iMatrixScrollIsFullVisibleLast(p)) - { - p->first++; - iupMatrixAuxUpdateLast(p); - }  + /* adjust "first" according to "last" */ + iupMatrixAuxAdjustFirstFromLast(p); } }  @@ -133,119 +111,114 @@ static int iMatrixScrollGetPrevNonEmpty(Ihandle* ih, int m, int index) return index; }  -static void iMatrixScrollSetFocusScrollToVisible(Ihandle* ih, int m, int index) +static void iMatrixScrollSetFocusScrollToVisible(Ihandle* ih, int lin, int col) +{ + /* moving focus and eventually scrolling */ + iupMatrixFocusSet(ih, lin, col); + + /* set for both because focus maybe hidden */ + iMatrixScrollToVisible(&ih->data->columns, ih->data->columns.focus_cell); + iMatrixScrollToVisible(&ih->data->lines, ih->data->lines.focus_cell); +} + +static void iMatrixScrollSetFocusScrollToVisibleLinCol(Ihandle* ih, int m, int index) { if (m == IMAT_PROCESS_COL) - iupMatrixFocusSet(ih, ih->data->lines.focus_cell, index); + iMatrixScrollSetFocusScrollToVisible(ih, ih->data->lines.focus_cell, index); else - iupMatrixFocusSet(ih, index, ih->data->columns.focus_cell); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + iMatrixScrollSetFocusScrollToVisible(ih, index, ih->data->columns.focus_cell); }  + /**************************************************************************/ /* Exported functions */ /**************************************************************************/   -/* Move using the cells of matrix. - Receive as a parameter a pointer to a function that will make the work, - in fact. This is done to avoid a test to each of the manipulation cursor - functions, verifying if it is necessary to call or not the scroll - callback. This is only done here. - -> func - pointer to the function that will make the movement - -> mode - parameter passed to func, specify if the movement request is of - the scrollbar or the keyboard - -> pos - parameter passed to func, that will be the handle position function - of the scrollbar, returning the scrollbar thumb position... - if func is other function, this parameter will be ignored - -> m - parameter passed to func, specify which is the mode of operation: - lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] -*/ -void iupMatrixScrollMoveCursor(iupMatrixScrollMoveF func, Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollToVisible(Ihandle* ih, int lin, int col) { int old_lines_first = ih->data->lines.first; int old_columns_first = ih->data->columns.first; + int old_lines_first_offset = ih->data->lines.first_offset; + int old_columns_first_offset = ih->data->columns.first_offset;  - iupMatrixEditForceHidden(ih); + iMatrixScrollToVisible(&ih->data->columns, col); + iMatrixScrollToVisible(&ih->data->lines, lin);  - func(ih, mode, pos, m); - - if (ih->data->lines.first != old_lines_first || ih->data->columns.first != old_columns_first) + if ((ih->data->lines.first != old_lines_first || ih->data->lines.first_offset != old_lines_first_offset) || + (ih->data->columns.first != old_columns_first || ih->data->columns.first_offset != old_columns_first_offset)) { - if (ih->data->columns.first != old_columns_first) - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL); + /* when "first" is changed must update scroll pos */ + if (ih->data->columns.first != old_columns_first || ih->data->columns.first_offset != old_columns_first_offset) + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_COL);  - if (ih->data->lines.first != old_lines_first) - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN); + if (ih->data->lines.first != old_lines_first || ih->data->lines.first_offset != old_lines_first_offset) + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_LIN);  iMatrixScrollCallScrollTopCb(ih);  - iupMatrixDraw(ih, 0); + iupMatrixDraw(ih, 1); } }  -void iupMatrixScrollToVisible(Ihandle* ih, int lin, int col) +void iupMatrixScrollMove(iupMatrixScrollMoveFunc func, Ihandle* ih, int mode, float pos, int m) { int old_lines_first = ih->data->lines.first; int old_columns_first = ih->data->columns.first; + int old_lines_first_offset = ih->data->lines.first_offset; + int old_columns_first_offset = ih->data->columns.first_offset;  - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, col); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, lin); + iupMatrixEditForceHidden(ih);  - if (ih->data->lines.first != old_lines_first || ih->data->columns.first != old_columns_first) + func(ih, mode, pos, m); + + if ((ih->data->lines.first != old_lines_first || ih->data->lines.first_offset != old_lines_first_offset) || + (ih->data->columns.first != old_columns_first || ih->data->columns.first_offset != old_columns_first_offset)) { - if (ih->data->columns.first != old_columns_first) - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL); + /* when "first" is changed must update scroll pos */ + if (ih->data->columns.first != old_columns_first || ih->data->columns.first_offset != old_columns_first_offset) + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_COL);  - if (ih->data->lines.first != old_lines_first) - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN); + if (ih->data->lines.first != old_lines_first || ih->data->lines.first_offset != old_lines_first_offset) + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_LIN);  iMatrixScrollCallScrollTopCb(ih);  - iupMatrixDraw(ih, 1); + iupMatrixDraw(ih, 0); } }  +/************************************************************************************/ + /* This function is called when the "home" key is pressed. In the first time, go to the beginning of the line. In the second time, go to the beginning of the page. In the third time, go to the beginning of the matrix. -> mode and pos : DO NOT USED. */ -void iupMatrixScrollHome(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) +void iupMatrixScrollHomeFunc(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) { (void)unused_m; (void)unused_mode; (void)unused_pos;  /* called only for mode==IMAT_SCROLLKEY */ + /* moving focus and eventually scrolling */  if(ih->data->homekeycount == 0) /* go to the beginning of the line */ { - ih->data->columns.first = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, 1); - iMatrixScrollSetFocusScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.first); + int col = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, 1); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, IMAT_PROCESS_COL, col); } else if(ih->data->homekeycount == 1) /* go to the beginning of the visible page */ { - iupMatrixFocusSet(ih, ih->data->lines.first, ih->data->columns.first); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + iMatrixScrollSetFocusScrollToVisible(ih, ih->data->lines.first, ih->data->columns.first); } else if(ih->data->homekeycount == 2) /* go to the beginning of the matrix 1:1 */ { - ih->data->columns.first = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, 1); - ih->data->lines.first = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_LIN, 1); - - iupMatrixFocusSet(ih, ih->data->lines.first, ih->data->columns.first); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + int lin = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_LIN, 1); + int col = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, 1); + iMatrixScrollSetFocusScrollToVisible(ih, lin, col); } }  @@ -255,37 +228,29 @@ void iupMatrixScrollHome(Ihandle* ih, int unused_mode, float unused_pos, int unu In the third time, go to the end of the matrix. -> mode and pos : DO NOT USED. */ -void iupMatrixScrollEnd(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) +void iupMatrixScrollEndFunc(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) { (void)unused_m; (void)unused_mode; (void)unused_pos;  /* called only for mode==IMAT_SCROLLKEY */ + /* moving focus and eventually scrolling */  if(ih->data->endkeycount == 0) /* go to the end of the line */ { - int last_col = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_COL, ih->data->columns.num-1); - iMatrixScrollSetFocusScrollToVisible(ih, IMAT_PROCESS_COL, last_col); + int col = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_COL, ih->data->columns.num-1); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, IMAT_PROCESS_COL, col); } else if(ih->data->endkeycount == 1) /* go to the end of the visible page */ { - iupMatrixFocusSet(ih, ih->data->lines.last, ih->data->columns.last); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + iMatrixScrollSetFocusScrollToVisible(ih, ih->data->lines.last, ih->data->columns.last); } else if(ih->data->endkeycount == 2) /* go to the end of the matrix */ { - int last_col = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_COL, ih->data->columns.num-1); - int last_lin = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_LIN, ih->data->lines.num-1); - - iupMatrixFocusSet(ih, last_lin, last_col); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + int lin = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_LIN, ih->data->lines.num-1); + int col = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_COL, ih->data->columns.num-1); + iMatrixScrollSetFocusScrollToVisible(ih, lin, col); } }  @@ -295,7 +260,7 @@ void iupMatrixScrollEnd(Ihandle* ih, int unused_mode, float unused_pos, int unus -> pos : DO NOT USED -> m : define the mode of operation: lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollLeftUp(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollLeftUpFunc(Ihandle* ih, int mode, float pos, int m) { ImatLinColData* p; (void)pos; @@ -307,12 +272,15 @@ void iupMatrixScrollLeftUp(Ihandle* ih, int mode, float pos, int m)  if (mode == IMAT_SCROLLKEY) { + /* moving focus and eventually scrolling */ int next = iMatrixScrollGetPrevNonEmpty(ih, m, p->focus_cell-1); - iMatrixScrollSetFocusScrollToVisible(ih, m, next); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, m, next); } else /* IMAT_SCROLLBAR */ { + /* always scrolling without changing focus */ p->first = iMatrixScrollGetPrevNonEmpty(ih, m, p->first-1); + p->first_offset = 0; } }  @@ -322,7 +290,7 @@ void iupMatrixScrollLeftUp(Ihandle* ih, int mode, float pos, int m) -> pos : DO NOT USED -> m : define the mode of operation: lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollRightDown(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollRightDownFunc(Ihandle* ih, int mode, float pos, int m) { ImatLinColData* p; (void)pos; @@ -334,12 +302,15 @@ void iupMatrixScrollRightDown(Ihandle* ih, int mode, float pos, int m)  if (mode == IMAT_SCROLLKEY) { + /* moving focus and eventually scrolling */ int next = iMatrixScrollGetNextNonEmpty(ih, m, p->focus_cell+1); - iMatrixScrollSetFocusScrollToVisible(ih, m, next); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, m, next); } else /* IMAT_SCROLLBAR */ { + /* always scrolling without changing focus */ p->first = iMatrixScrollGetNextNonEmpty(ih, m, p->first+1); + p->first_offset = 0; } }  @@ -349,7 +320,7 @@ void iupMatrixScrollRightDown(Ihandle* ih, int mode, float pos, int m) -> pos : DO NOT USED -> m : define the mode of operation: lines (PgLeft) or columns (PgUp) [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollPgLeftUp(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollPgLeftUpFunc(Ihandle* ih, int mode, float pos, int m) { ImatLinColData* p; (void)pos; @@ -361,12 +332,15 @@ void iupMatrixScrollPgLeftUp(Ihandle* ih, int mode, float pos, int m)  if (mode == IMAT_SCROLLKEY) { + /* moving focus and eventually scrolling */ int next = iMatrixScrollGetPrevNonEmpty(ih, m, p->focus_cell - (p->last - p->first)); - iMatrixScrollSetFocusScrollToVisible(ih, m, next); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, m, next); } else /* IMAT_SCROLLBAR */ { + /* always scrolling without changing focus */ p->first = iMatrixScrollGetPrevNonEmpty(ih, m, p->first - (p->last - p->first)); + p->first_offset = 0; } }  @@ -376,7 +350,7 @@ void iupMatrixScrollPgLeftUp(Ihandle* ih, int mode, float pos, int m) -> pos : DO NOT USED -> m : define the mode of operation: lines (PgDown) or columns (PgRight) [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollPgRightDown(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollPgRightDownFunc(Ihandle* ih, int mode, float pos, int m) { ImatLinColData* p; (void)pos; @@ -388,16 +362,19 @@ void iupMatrixScrollPgRightDown(Ihandle* ih, int mode, float pos, int m)  if (mode == IMAT_SCROLLKEY) { - int next = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, p->focus_cell + (p->last - p->first)); - iMatrixScrollSetFocusScrollToVisible(ih, m, next); + /* moving focus and eventually scrolling */ + int next = iMatrixScrollGetNextNonEmpty(ih, m, p->focus_cell + (p->last - p->first)); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, m, next); } else /* IMAT_SCROLLBAR */ { + /* always scrolling without changing focus */ p->first = iMatrixScrollGetPrevNonEmpty(ih, m, p->first + (p->last - p->first)); + p->first_offset = 0; } }  -void iupMatrixScrollCr(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) +void iupMatrixScrollCrFunc(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) { int oldlin = ih->data->lines.focus_cell; int oldcol = ih->data->columns.focus_cell; @@ -408,13 +385,13 @@ void iupMatrixScrollCr(Ihandle* ih, int unused_mode, float unused_pos, int unuse /* called only for mode==IMAT_SCROLLKEY */  /* try the normal processing of next cell down */ - iupMatrixScrollRightDown(ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN); + iupMatrixScrollRightDownFunc(ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN);  if(ih->data->lines.focus_cell == oldlin && ih->data->columns.focus_cell == oldcol) { /* If focus was not changed, it was because it is in the last line of the column. Go to the next column of the same line. */ - iupMatrixScrollRightDown(ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL); + iupMatrixScrollRightDownFunc(ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL); } }  @@ -423,70 +400,51 @@ void iupMatrixScrollCr(Ihandle* ih, int unused_mode, float unused_pos, int unuse -> mode : DO NOT USED -> m : define the mode of operation: lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollPos(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollPosFunc(Ihandle* ih, int mode, float pos, int m) { - int scroll_pos, index, vp; - float d; + int scroll_pos; ImatLinColData* p; (void)mode;  if (m == IMAT_PROCESS_LIN) - { p = &(ih->data->lines); - d = IupGetFloat(ih, "DY"); - } else - { p = &(ih->data->columns); - d = IupGetFloat(ih, "DX"); - }  if (p->num == 1) { p->first = 1; + p->first_offset = 0; return; }  scroll_pos = (int)(pos * p->total_size + 0.5);  - vp = 0; - for(index = 1; index < p->num; index++) - { - vp += p->sizes[index]; - if (vp > scroll_pos) - break; - } - - if (index == p->num) - { - if (p->num == 1) - index = 1; - else - index = p->num-1; - } - - p->first = index; + /* position first and first_offset, according to scroll pos */ + iupMatrixAuxAdjustFirstFromScrollPos(p, scroll_pos); }  -int iupMatrixScroll_CB(Ihandle* ih, int action, float x, float y) +/************************************************************************************/ + +int iupMatrixScroll_CB(Ihandle* ih, int action, float posx, float posy) { if (!iupMatrixIsValid(ih, 0)) return IUP_DEFAULT;  switch(action) { - case IUP_SBUP : iupMatrixScrollUp(ih); break; - case IUP_SBDN : iupMatrixScrollDown(ih); break; - case IUP_SBPGUP : iupMatrixScrollPgUp(ih); break; - case IUP_SBPGDN : iupMatrixScrollPgDown(ih); break; - case IUP_SBRIGHT : iupMatrixScrollRight(ih); break; - case IUP_SBLEFT : iupMatrixScrollLeft(ih); break; - case IUP_SBPGRIGHT : iupMatrixScrollPgRight(ih); break; - case IUP_SBPGLEFT : iupMatrixScrollPgLeft(ih); break; - case IUP_SBPOSV : iupMatrixScrollPosVer(ih,y); break; - case IUP_SBPOSH : iupMatrixScrollPosHor(ih,x); break; - case IUP_SBDRAGV : iupMatrixScrollPosVer(ih,y); break; - case IUP_SBDRAGH : iupMatrixScrollPosHor(ih,x); break; + case IUP_SBUP : iupMATRIX_ScrollUp(ih); break; + case IUP_SBDN : iupMATRIX_ScrollDown(ih); break; + case IUP_SBPGUP : iupMATRIX_ScrollPgUp(ih); break; + case IUP_SBPGDN : iupMATRIX_ScrollPgDown(ih); break; + case IUP_SBRIGHT : iupMATRIX_ScrollRight(ih); break; + case IUP_SBLEFT : iupMATRIX_ScrollLeft(ih); break; + case IUP_SBPGRIGHT : iupMATRIX_ScrollPgRight(ih); break; + case IUP_SBPGLEFT : iupMATRIX_ScrollPgLeft(ih); break; + case IUP_SBPOSV : iupMATRIX_ScrollPosVer(ih,posy); break; + case IUP_SBPOSH : iupMATRIX_ScrollPosHor(ih,posx); break; + case IUP_SBDRAGV : iupMATRIX_ScrollPosVer(ih,posy); break; + case IUP_SBDRAGH : iupMATRIX_ScrollPosHor(ih,posx); break; }  iupMatrixDrawUpdate(ih); diff --git a/iup/srccontrols/matrix/iupmat_scroll.h b/iup/srccontrols/matrix/iupmat_scroll.h index 582442b..45d7417 100755 --- a/iup/srccontrols/matrix/iupmat_scroll.h +++ b/iup/srccontrols/matrix/iupmat_scroll.h @@ -12,54 +12,54 @@ extern "C" { #endif  -int iupMatrixScroll_CB(Ihandle* ih, int action, float x, float y); +int iupMatrixScroll_CB(Ihandle* ih, int action, float posx, float posy);  void iupMatrixScrollToVisible(Ihandle* ih, int lin, int col);  -typedef void (*iupMatrixScrollMoveF)(Ihandle* ih, int mode, float pos, int m); -void iupMatrixScrollMoveCursor(iupMatrixScrollMoveF func, Ihandle* ih, int mode, float pos, int m); +typedef void (*iupMatrixScrollMoveFunc)(Ihandle* ih, int mode, float pos, int m); +void iupMatrixScrollMove(iupMatrixScrollMoveFunc func, Ihandle* ih, int mode, float pos, int m);  /* Used only by the macros bellow */ -void iupMatrixScrollHome (Ihandle* ih, int, float, int); -void iupMatrixScrollEnd (Ihandle* ih, int, float, int); -void iupMatrixScrollLeftUp (Ihandle* ih, int, float, int); -void iupMatrixScrollRightDown (Ihandle* ih, int, float, int); -void iupMatrixScrollPgLeftUp (Ihandle* ih, int, float, int); -void iupMatrixScrollPgRightDown(Ihandle* ih, int, float, int); -void iupMatrixScrollPos (Ihandle* ih, int, float, int); -void iupMatrixScrollCr (Ihandle* ih, int, float, int); +void iupMatrixScrollHomeFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollEndFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollLeftUpFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollRightDownFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollPgLeftUpFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollPgRightDownFunc(Ihandle* ih, int, float, int); +void iupMatrixScrollPosFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollCrFunc (Ihandle* ih, int, float, int);  /* Mode used to "walk" inside the matrix. It shows if the movement request was from the scrollbar or from a key. - Possible values for the "mode" parameter of the iupMatrixScrollMoveCursor function. + Possible values for the "mode" parameter of the iupMatrixScrollMove function. */ #define IMAT_SCROLLBAR 0 #define IMAT_SCROLLKEY 1  -/* Macros to help during the call of iupMatrixScrollMoveCursor function */ +/* Macros to help during the call of iupMatrixScrollMove function */  /* used in the keyboard processing module */ -#define iupMatrixScrollKeyHome(ih) iupMatrixScrollMoveCursor(iupMatrixScrollHome , ih, IMAT_SCROLLKEY, 0, 0) -#define iupMatrixScrollKeyEnd(ih) iupMatrixScrollMoveCursor(iupMatrixScrollEnd , ih, IMAT_SCROLLKEY, 0, 0) -#define iupMatrixScrollKeyPgUp(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgLeftUp , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollKeyPgDown(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgRightDown, ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollKeyDown(ih) iupMatrixScrollMoveCursor(iupMatrixScrollRightDown , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollKeyRight(ih) iupMatrixScrollMoveCursor(iupMatrixScrollRightDown , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollKeyUp(ih) iupMatrixScrollMoveCursor(iupMatrixScrollLeftUp , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollKeyLeft(ih) iupMatrixScrollMoveCursor(iupMatrixScrollLeftUp , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollKeyCr(ih) iupMatrixScrollMoveCursor(iupMatrixScrollCr , ih, IMAT_SCROLLKEY, 0, 0) +#define iupMATRIX_ScrollKeyHome(ih) iupMatrixScrollMove(iupMatrixScrollHomeFunc , ih, IMAT_SCROLLKEY, 0, 0) +#define iupMATRIX_ScrollKeyEnd(ih) iupMatrixScrollMove(iupMatrixScrollEndFunc , ih, IMAT_SCROLLKEY, 0, 0) +#define iupMATRIX_ScrollKeyPgUp(ih) iupMatrixScrollMove(iupMatrixScrollPgLeftUpFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollKeyPgDown(ih) iupMatrixScrollMove(iupMatrixScrollPgRightDownFunc, ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollKeyDown(ih) iupMatrixScrollMove(iupMatrixScrollRightDownFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollKeyRight(ih) iupMatrixScrollMove(iupMatrixScrollRightDownFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollKeyUp(ih) iupMatrixScrollMove(iupMatrixScrollLeftUpFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollKeyLeft(ih) iupMatrixScrollMove(iupMatrixScrollLeftUpFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollKeyCr(ih) iupMatrixScrollMove(iupMatrixScrollCrFunc , ih, IMAT_SCROLLKEY, 0, 0)  /* Used by the scrollbar callback only */ -#define iupMatrixScrollUp(ih) iupMatrixScrollMoveCursor(iupMatrixScrollLeftUp , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollLeft(ih) iupMatrixScrollMoveCursor(iupMatrixScrollLeftUp , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollDown(ih) iupMatrixScrollMoveCursor(iupMatrixScrollRightDown , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollRight(ih) iupMatrixScrollMoveCursor(iupMatrixScrollRightDown , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollPgUp(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgLeftUp , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollPgLeft(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgLeftUp , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollPgDown(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgRightDown, ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollPgRight(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgRightDown, ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollPosVer(ih, y) iupMatrixScrollMoveCursor(iupMatrixScrollPos , ih, IMAT_SCROLLBAR, y, IMAT_PROCESS_LIN) -#define iupMatrixScrollPosHor(ih, x) iupMatrixScrollMoveCursor(iupMatrixScrollPos , ih, IMAT_SCROLLBAR, x, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollUp(ih) iupMatrixScrollMove(iupMatrixScrollLeftUpFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollLeft(ih) iupMatrixScrollMove(iupMatrixScrollLeftUpFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollDown(ih) iupMatrixScrollMove(iupMatrixScrollRightDownFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollRight(ih) iupMatrixScrollMove(iupMatrixScrollRightDownFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollPgUp(ih) iupMatrixScrollMove(iupMatrixScrollPgLeftUpFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollPgLeft(ih) iupMatrixScrollMove(iupMatrixScrollPgLeftUpFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollPgDown(ih) iupMatrixScrollMove(iupMatrixScrollPgRightDownFunc, ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollPgRight(ih) iupMatrixScrollMove(iupMatrixScrollPgRightDownFunc, ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollPosVer(ih, y) iupMatrixScrollMove(iupMatrixScrollPosFunc , ih, IMAT_SCROLLBAR, posy, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollPosHor(ih, x) iupMatrixScrollMove(iupMatrixScrollPosFunc , ih, IMAT_SCROLLBAR, posx, IMAT_PROCESS_COL)   #ifdef __cplusplus diff --git a/iup/srccontrols/matrix/iupmatrix.c b/iup/srccontrols/matrix/iupmatrix.c index 20d618d..9e379e2 100755 --- a/iup/srccontrols/matrix/iupmatrix.c +++ b/iup/srccontrols/matrix/iupmatrix.c @@ -76,10 +76,13 @@ static int iMatrixSetOriginAttrib(Ihandle* ih, const char* value) return 0;  ih->data->columns.first = col; + ih->data->columns.first_offset = 0; ih->data->lines.first = lin; + ih->data->lines.first_offset = 0;  - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL); - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN); + /* when "first" is changed must update scroll pos */ + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_COL); + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_LIN);  iupMatrixDraw(ih, 1); return 0; @@ -109,7 +112,7 @@ static int iMatrixSetShowAttrib(Ihandle* ih, const char* value) if((lin < 1) || (col < 1)) return 0;  - if (!iupMatrixAuxIsCellFullVisible(ih, lin, col)) + if (!iupMatrixAuxIsCellStartVisible(ih, lin, col)) iupMatrixScrollToVisible(ih, lin, col);  return 0; @@ -173,6 +176,23 @@ static char* iMatrixGetUseTitleSizeAttrib(Ihandle* ih) return "NO"; }  +static int iMatrixSetHiddenTextMarksAttrib(Ihandle* ih, const char* value) +{ + if (iupStrBoolean(value)) + ih->data->hidden_text_marks = 1; + else  + ih->data->hidden_text_marks = 0; + return 0; +} + +static char* iMatrixGetHiddenTextMarksAttrib(Ihandle* ih) +{ + if (ih->data->hidden_text_marks) + return "YES"; + else + return "NO"; +} + static int iMatrixSetValueAttrib(Ihandle* ih, const char* value) { if (IupGetInt(ih->data->datah, "VISIBLE")) @@ -228,14 +248,14 @@ static char* iMatrixGetMultilineAttrib(Ihandle* ih) static char* iMatrixGetNumLinAttrib(Ihandle* ih) { char* num = iupStrGetMemory(100); - sprintf(num, "%d", ih->data->lines.num-1); + sprintf(num, "%d", ih->data->lines.num-1); /* the attribute does not include the title */ return num; }  static char* iMatrixGetNumColAttrib(Ihandle* ih) { char* num = iupStrGetMemory(100); - sprintf(num, "%d", ih->data->columns.num-1); + sprintf(num, "%d", ih->data->columns.num-1); /* the attribute does not include the title */ return num; }  @@ -427,13 +447,19 @@ static char* iMatrixGetAlignmentAttrib(Ihandle* ih, const char* name_id) align = iupAttribGet(ih, str); if (!align) { - int col; - if (iupStrToInt(name_id, &col)) + align = iupAttribGet(ih, "ALIGNMENT"); + if (align) + return align; + else { - if (col == 0) - return "ALEFT"; - else - return "ACENTER"; + int col; + if (iupStrToInt(name_id, &col)) + { + if (col == 0) + return "ALEFT"; + else + return "ACENTER"; + } } }  @@ -642,7 +668,7 @@ static int iMatrixCreateMethod(Ihandle* ih, void **params) /* Create the edit fields */ iupMatrixEditCreate(ih);  - /* defaults */ + /* defaults that are non zero */ ih->data->datah = ih->data->texth; ih->data->mark_continuous = 1; ih->data->columns.num = 1; @@ -656,7 +682,6 @@ static int iMatrixCreateMethod(Ihandle* ih, void **params) ih->data->mark_col1 = -1; ih->data->mark_lin2 = -1; ih->data->mark_col2 = -1; - ih->data->use_title_size = 0;  return IUP_NOERROR; } @@ -700,11 +725,34 @@ static void iMatrixUnMapMethod(Ihandle* ih) iupMatrixMemRelease(ih); }  +static char* iMatrixGetDefault(Ihandle* ih, const char* name) +{ + int inherit; + char *def_value; + iupClassObjectGetAttributeInfo(ih, name, &def_value, &inherit); + return def_value; +} + +static int iMatrixGetInt(Ihandle* ih, const char* name) +{ + char *value = iupAttribGet(ih, name); + if (!value) value = iMatrixGetDefault(ih, name); + if (value) + { + int i = 0; + if (iupStrToInt(value, &i)) + return i; + } + return 0; +} + static int iMatrixGetNaturalWidth(Ihandle* ih) { int width = 0, num, col;  - num = iupAttribGetInt(ih, "NUMCOL_VISIBLE")+1; /* include the title column */ + /* must use this custom function because  + the get method for this attribute returns a value with a different meaning */ + num = iMatrixGetInt(ih, "NUMCOL_VISIBLE")+1; /* include the title column */  if (iupAttribGetInt(ih, "NUMCOL_VISIBLE_LAST")) { @@ -716,9 +764,7 @@ static int iMatrixGetNaturalWidth(Ihandle* ih) } else { - if (num > ih->data->columns.num) - num = ih->data->columns.num; - for(col = 0; col < num; col++) + for(col = 0; col < num; col++) /* num can be > numcol */ width += iupMatrixAuxGetColumnWidth(ih, col); }  @@ -729,7 +775,9 @@ static int iMatrixGetNaturalHeight(Ihandle* ih) { int height = 0, num, lin;  - num = iupAttribGetInt(ih, "NUMLIN_VISIBLE")+1; /* include the title line */ + /* must use this custom function because  + the get method for this attribute returns a value with a different meaning */ + num = iMatrixGetInt(ih, "NUMLIN_VISIBLE")+1; /* include the title line */  if (iupAttribGetInt(ih, "NUMLIN_VISIBLE_LAST")) { @@ -741,9 +789,7 @@ static int iMatrixGetNaturalHeight(Ihandle* ih) } else { - if (num > ih->data->lines.num) - num = ih->data->lines.num; - for(lin = 0; lin < num; lin++) + for(lin = 0; lin < num; lin++) /* num can be > numlin */ height += iupMatrixAuxGetLineHeight(ih, lin); }  @@ -902,6 +948,8 @@ Iclass* iupMatrixGetClass(void)  /* IupMatrix Attributes - GENERAL */ iupClassRegisterAttribute(ic, "USETITLESIZE", iMatrixGetUseTitleSizeAttrib, iMatrixSetUseTitleSizeAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "HIDDENTEXTMARKS", iMatrixGetHiddenTextMarksAttrib, iMatrixSetHiddenTextMarksAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); +  iupClassRegisterAttribute(ic, "FRAMECOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "100 100 100", IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "READONLY", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "RESIZEMATRIX", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); diff --git a/iup/srcgl/Makefile b/iup/srcgl/Makefile index 882d0d2..48037f0 100755 --- a/iup/srcgl/Makefile +++ b/iup/srcgl/Makefile @@ -3,4 +3,4 @@ do_all: iupgl  iupgl: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak  diff --git a/iup/srcim/Makefile b/iup/srcim/Makefile index 933ded1..d47e014 100755 --- a/iup/srcim/Makefile +++ b/iup/srcim/Makefile @@ -3,4 +3,4 @@ do_all: iupim  iupim: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak  diff --git a/iup/srcim/iup_im.c b/iup/srcim/iup_im.c index c26a3ff..ce58d80 100755 --- a/iup/srcim/iup_im.c +++ b/iup/srcim/iup_im.c @@ -23,7 +23,7 @@ #include "iup_image.h"   -static void PrintError(int error) +static void iSaveErrorMsg(int error) { char* lang = IupGetLanguage(); char* msg; @@ -31,20 +31,22 @@ static void PrintError(int error) { switch (error) { + case IM_ERR_NONE: + msg = NULL; case IM_ERR_OPEN: - msg = "Error Opening File.\n"; + msg = "Error Opening Image File.\n"; break; case IM_ERR_MEM: msg = "Insuficient memory.\n"; break; case IM_ERR_ACCESS: - msg = "Error Accessing File.\n"; + msg = "Error Accessing Image File.\n"; break; case IM_ERR_DATA: msg = "Image type not Suported.\n"; break; case IM_ERR_FORMAT: - msg = "Invalid Format.\n"; + msg = "Invalid Image File Format.\n"; break; case IM_ERR_COMPRESS: msg = "Invalid or unsupported compression.\n"; @@ -57,20 +59,22 @@ static void PrintError(int error) { switch (error) { + case IM_ERR_NONE: + msg = NULL; case IM_ERR_OPEN: - msg = "Erro Abrindo Arquivo.\n"; + msg = "Erro Abrindo Arquivo de Imagem.\n"; break; case IM_ERR_MEM: msg = "Memória Insuficiente.\n"; break; case IM_ERR_ACCESS: - msg = "Erro Acessando Arquivo.\n"; + msg = "Erro Acessando Arquivo de Imagem.\n"; break; case IM_ERR_DATA: msg = "Tipo de Imagem não Suportado.\n"; break; case IM_ERR_FORMAT: - msg = "Formato Inválido.\n"; + msg = "Formato de Arquivo de Imagem Inválido.\n"; break; case IM_ERR_COMPRESS: msg = "Compressão Inválida ou não Suportada.\n"; @@ -80,7 +84,7 @@ static void PrintError(int error) } }  - IupMessage("Error", msg); + IupSetGlobal("IUPIM_LASTERROR", msg); }  Ihandle* IupLoadImage(const char* file_name) @@ -165,7 +169,7 @@ load_finish: imCounterSetCallback(NULL, old_callback); if (ifile) imFileClose(ifile); if (image_data) free(image_data); - if (error) PrintError(error); + iSaveErrorMsg(error); return iup_image; }  @@ -188,7 +192,7 @@ int IupSaveImage(Ihandle* ih, const char* file_name, const char* format) ifile = imFileNew(file_name, format, &error); if (!ifile) { - PrintError(error); + iSaveErrorMsg(error); return 0; }  @@ -238,8 +242,7 @@ int IupSaveImage(Ihandle* ih, const char* file_name, const char* format)  imFileClose(ifile);   - if (error) - PrintError(error); + iSaveErrorMsg(error);  return error == IM_ERR_NONE? 1: 0; } diff --git a/iup/srcimglib/Makefile b/iup/srcimglib/Makefile index 261537a..873715f 100755 --- a/iup/srcimglib/Makefile +++ b/iup/srcimglib/Makefile @@ -3,4 +3,4 @@ do_all: iupimglib  iupimglib: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak + @$(MAKE) --no-print-directory -f ../tecmake.mak diff --git a/iup/srcledc/Makefile b/iup/srcledc/Makefile index 8854269..71b9235 100755 --- a/iup/srcledc/Makefile +++ b/iup/srcledc/Makefile @@ -3,4 +3,4 @@ do_all: ledc  ledc: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak  diff --git a/iup/srclua3/Makefile b/iup/srclua3/Makefile index b63716a..0551725 100755 --- a/iup/srclua3/Makefile +++ b/iup/srclua3/Makefile @@ -3,19 +3,19 @@ do_all: iuplua iupluacd iupluacontrols iuplua_pplot iupluagl iupluaim  iuplua: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak   iupluacd: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupcd + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupcd  iupluacontrols: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupcontrols + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupcontrols  iuplua_pplot: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iup_pplot + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iup_pplot  iupluagl: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupgl + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupgl  iupluaim: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupim + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupim diff --git a/iup/srclua3/config.mak b/iup/srclua3/config.mak index fae6145..a3ffb1d 100755 --- a/iup/srclua3/config.mak +++ b/iup/srclua3/config.mak @@ -6,9 +6,9 @@ OPT = YES  LOHDIR = loh SRCLUA = iuplua.lua iuplua_widgets.lua constants.lua spin.lua \ - sbox.lua val.lua tree.lua tabs.lua + sbox.lua split.lua val.lua tree.lua tabs.lua SRC = iuplua.c iuplua_api.c iuplua_widgets.c il_scanf.c il_cbox.c \ - il_sbox.c il_spin.c il_val.c il_tree.c il_tabs.c il_getcolor.c il_getparam.c + il_sbox.c il_split.c il_spin.c il_val.c il_tree.c il_tabs.c il_getcolor.c il_getparam.c  USE_LUA = Yes  diff --git a/iup/srclua3/il.h b/iup/srclua3/il.h index 406ccc4..63f9866 100755 --- a/iup/srclua3/il.h +++ b/iup/srclua3/il.h @@ -15,6 +15,7 @@ int iupluaapi_open(void); int iupluawidgets_open(int tag);  int sboxlua_open(void); +int splitlua_open(void); int spinlua_open(void); int cboxlua_open(void); int gclua_open (void); diff --git a/iup/srclua3/il_getparam.c b/iup/srclua3/il_getparam.c index 28a41be..6005ce8 100755 --- a/iup/srclua3/il_getparam.c +++ b/iup/srclua3/il_getparam.c @@ -93,6 +93,8 @@ static void GetParam(void) param_data[i] = malloc(sizeof(float)); *(float*)(param_data[i]) = (float)luaL_check_number(lua_param_start); lua_param_start++; break; + case 'f': + case 'c': case 's': case 'm': s = luaL_check_string(lua_param_start); lua_param_start++; @@ -136,6 +138,8 @@ static void GetParam(void) case 'r': lua_pushnumber(*(float*)(param_data[i])); break; + case 'f': + case 'c': case 's': case 'm': lua_pushstring((char*)(param_data[i])); diff --git a/iup/srclua3/il_tree.c b/iup/srclua3/il_tree.c index 8d5fcf8..5d145bf 100755 --- a/iup/srclua3/il_tree.c +++ b/iup/srclua3/il_tree.c @@ -91,6 +91,29 @@ static int TREE_multiselection (Ihandle *handle, int *ids, int n) return iuplua_call(); }  +static int TREE_multiunselection (Ihandle *handle, int *ids, int n) +{ + int i; + lua_Object tb; + + iuplua_call_start(handle, "multiunselection"); + + tb = lua_createtable(); + for (i = 0; i < n; i++)  + { + lua_beginblock(); + lua_pushobject(tb); + lua_pushnumber(i+1); + lua_pushnumber(ids[i]); + lua_settable(); + lua_endblock();  + } + lua_pushobject(tb); + + lua_pushnumber (n); + return iuplua_call(); +} + static int TREE_dragdrop(Ihandle* handle, int drag_id, int drop_id, int isshift, int iscontrol) { iuplua_call_start(handle, "dragdrop"); @@ -232,6 +255,7 @@ int treelua_open(void) lua_CFunction func; } TreeAssocList [] = { {"iup_tree_multiselection_cb", (lua_CFunction)TREE_multiselection}, + {"iup_tree_multiunselection_cb", (lua_CFunction)TREE_multiunselection}, {"iup_tree_selection_cb", (lua_CFunction)TREE_selection}, {"iup_tree_branchopen_cb", (lua_CFunction)TREE_branchopen}, {"iup_tree_branchclose_cb", (lua_CFunction)TREE_branchclose}, diff --git a/iup/srclua3/iuplua.c b/iup/srclua3/iuplua.c index 7789ce8..5563699 100755 --- a/iup/srclua3/iuplua.c +++ b/iup/srclua3/iuplua.c @@ -481,6 +481,7 @@ int iuplua_open(void) iupluawidgets_open(iuplua_tag);  sboxlua_open(); + splitlua_open(); spinlua_open(); cboxlua_open(); vallua_open(); diff --git a/iup/srclua3/iuplua_api.c b/iup/srclua3/iuplua_api.c index 3221658..a9acf1d 100755 --- a/iup/srclua3/iuplua_api.c +++ b/iup/srclua3/iuplua_api.c @@ -182,7 +182,7 @@ static void GetAttribute(void) char *name = luaL_check_string(2); Ihandle* ih = iuplua_checkihandle(1); char *value = IupGetAttribute(ih, name); - if (!value || iupAttribIsInternal(name)) + if (!value || iupATTRIB_ISINTERNAL(name)) lua_pushnil(); else { diff --git a/iup/srclua3/iuplua_widgets.c b/iup/srclua3/iuplua_widgets.c index f6b801b..7591580 100755 --- a/iup/srclua3/iuplua_widgets.c +++ b/iup/srclua3/iuplua_widgets.c @@ -170,6 +170,12 @@ static int iupluaUnMapCb(Ihandle* handle) return iuplua_call(); }  +static int iupluaDestroyCb(Ihandle* handle) +{ + iuplua_call_start(handle, "destroycb"); + return iuplua_call(); +} + static int iupluaMapCb(Ihandle* handle) { iuplua_call_start(handle, "mapcb"); @@ -610,6 +616,7 @@ int iupluawidgets_open(int tag) { "iup_show_cb", (lua_CFunction)dialog_show}, { "iup_map_cb", (lua_CFunction)iupluaMapCb}, { "iup_unmap_cb", (lua_CFunction)iupluaUnMapCb}, + { "iup_destroy_cb", (lua_CFunction)iupluaDestroyCb}, { "iup_dropfiles_cb", (lua_CFunction)iupluaDropfilesCb}, { "iup_trayclick_cb", (lua_CFunction)dialog_trayclick}, { "iup_getfocus_cb", (lua_CFunction)iupluaGetfocusCb}, diff --git a/iup/srclua3/iuplua_widgets.lua b/iup/srclua3/iuplua_widgets.lua index 33be9e3..a59bde6 100755 --- a/iup/srclua3/iuplua_widgets.lua +++ b/iup/srclua3/iuplua_widgets.lua @@ -875,6 +875,7 @@ iup_callbacks = showcb = {"SHOW_CB", iup_show_cb}, mapcb = {"MAP_CB", iup_map_cb}, unmapcb = {"UNMAP_CB", iup_unmap_cb}, + destroycb = {"DESTROY_CB", iup_destroy_cb}, dropfiles = {"DROPFILES_CB", iup_dropfiles_cb}, menuclose = {"MENUCLOSE_CB", iup_menuclose_cb}, highlight = {"HIGHLIGHT_CB", iup_highlight_cb}, @@ -921,6 +922,7 @@ iup_callbacks.open_cb = iup_callbacks.open iup_callbacks.show_cb = iup_callbacks.showcb  iup_callbacks.map_cb = iup_callbacks.mapcb  iup_callbacks.unmap_cb = iup_callbacks.unmapcb  +iup_callbacks.destroy_cb = iup_callbacks.destroycb  iup_callbacks.dropfiles_cb = iup_callbacks.dropfiles  iup_callbacks.menuclose_cb = iup_callbacks.menuclose  iup_callbacks.highlight_cb = iup_callbacks.highlight  diff --git a/iup/srclua3/tree.lua b/iup/srclua3/tree.lua index 659afdb..bf53bca 100755 --- a/iup/srclua3/tree.lua +++ b/iup/srclua3/tree.lua @@ -47,6 +47,7 @@ iup.TreeSetValue = TreeSetValue  iup_callbacks.selection = {"SELECTION_CB", iup_tree_selection_cb} iup_callbacks.multiselection = {"MULTISELECTION_CB", iup_tree_multiselection_cb} +iup_callbacks.multiunselection = {"MULTIUNSELECTION_CB", iup_tree_multiunselection_cb} iup_callbacks.branchopen = {"BRANCHOPEN_CB", iup_tree_branchopen_cb} iup_callbacks.branchclose = {"BRANCHCLOSE_CB", iup_tree_branchclose_cb} iup_callbacks.executeleaf = {"EXECUTELEAF_CB", iup_tree_executeleaf_cb} @@ -58,6 +59,7 @@ iup_callbacks.dragdrop = {"DRAGDROP_CB", iup_tree_dragdrop_cb}  iup_callbacks.selection_cb = iup_callbacks.selection  iup_callbacks.multiselection_cb = iup_callbacks.multiselection  +iup_callbacks.multiunselection_cb = iup_callbacks.multiunselection  iup_callbacks.branchopen_cb = iup_callbacks.branchopen  iup_callbacks.branchclose_cb = iup_callbacks.branchclose  iup_callbacks.executeleaf_cb = iup_callbacks.executeleaf  diff --git a/iup/srclua5/Makefile b/iup/srclua5/Makefile index 3942e79..1189d32 100755 --- a/iup/srclua5/Makefile +++ b/iup/srclua5/Makefile @@ -3,22 +3,22 @@ do_all: iuplua iupluacd iupluacontrols iuplua_pplot iupluagl iupluaim iupluaimglib  iuplua: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak  + @$(MAKE) --no-print-directory -f ../tecmake.mak   iupluacd: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupcd + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupcd  iupluacontrols: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupcontrols + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupcontrols  iuplua_pplot: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iup_pplot + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iup_pplot  iupluagl: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupgl + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupgl  iupluaim: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupim + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupim  iupluaimglib: - @$(MAKE) --no-print-directory -f ../tecmake_compact.mak MF=iupimglib + @$(MAKE) --no-print-directory -f ../tecmake.mak MF=iupimglib diff --git a/iup/srclua5/button.lua b/iup/srclua5/button.lua index 946a05e..fc57b1a 100755 --- a/iup/srclua5/button.lua +++ b/iup/srclua5/button.lua @@ -3,16 +3,16 @@ ------------------------------------------------------------------------------ local ctrl = { nick = "button", - parent = WIDGET, + parent = iup.WIDGET, creation = "S-", callback = { action = "",  } }   -function ctrl.createElement(class, arg) - return Button(arg.title) +function ctrl.createElement(class, param) + return iup.Button(param.title) end  -iupRegisterWidget(ctrl) -iupSetClass(ctrl, "iup widget") +iup.RegisterWidget(ctrl) +iup.SetClass(ctrl, "iup widget") diff --git a/iup/srclua5/canvas.lua b/iup/srclua5/canvas.lua index 562d671..101c4f4 100755 --- a/iup/srclua5/canvas.lua +++ b/iup/srclua5/canvas.lua @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------ local ctrl = { nick = "canvas", - parent = WIDGET, + parent = iup.WIDGET, creation = "-", callback = { action = "ff", @@ -21,9 +21,9 @@ local ctrl = { } }  -function ctrl.createElement(class, arg) - return Canvas() +function ctrl.createElement(class, param) + return iup.Canvas() end  -iupRegisterWidget(ctrl) -iupSetClass(ctrl, "iup widget") +iup.RegisterWidget(ctrl) +iup.SetClass(ctrl, "iup widget") diff --git a/iup/srclua5/cbox.lua b/iup/srclua5/cbox.lua index 3533970..81ba9be 100755 --- a/iup/srclua5/cbox.lua +++ b/iup/srclua5/cbox.lua @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------ local ctrl = { nick = "cbox", - parent = WIDGET, + parent = iup.WIDGET, creation = "v", callback = {}, funcname = "Cboxv", @@ -20,9 +20,9 @@ static int Cboxv(lua_State *L) ]], }  -function ctrl.createElement(class, arg) - return Cboxv(arg) +function ctrl.createElement(class, param) + return iup.Cboxv(param) end  -iupRegisterWidget(ctrl) -iupSetClass(ctrl, "iup widget") +iup.RegisterWidget(ctrl) +iup.SetClass(ctrl, "iup widget") diff --git a/iup/srclua5/cells.lua b/iup/srclua5/cells.lua index 9c914f2..0355b17 100755 --- a/iup/srclua5/cells.lua +++ b/iup/srclua5/cells.lua @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------ local ctrl = { nick = "cells", - parent = WIDGET, + parent = iup.WIDGET, creation = "", callback = { mouseclick_cb = "nnnnnns", @@ -24,9 +24,9 @@ function ctrl.redraw(handle) handle.repaint = "YES" end  -function ctrl.createElement(class, arg) - return Cells() +function ctrl.createElement(class, param) + return iup.Cells() end  -iupRegisterWidget(ctrl) -iupSetClass(ctrl, "iup widget") +iup.RegisterWidget(ctrl) +iup.SetClass(ctrl, "iup widget") diff --git a/iup/srclua5/clipboard.lua b/iup/srclua5/clipboard.lua index e60b8bd..663215b 100755 --- a/iup/srclua5/clipboard.lua +++ b/iup/srclua5/clipboard.lua @@ -3,15 +3,15 @@ ------------------------------------------------------------------------------ local ctrl = { nick = "clipboard", - parent = WIDGET, + parent = iup.WIDGET, creation = "", callback = { }, }   -function ctrl.createElement(class, arg) - return Clipboard() +function ctrl.createElement(class, param) + return iup.Clipboard() end  -iupRegisterWidget(ctrl) -iupSetClass(ctrl, "iup widget") +iup.RegisterWidget(ctrl) +iup.SetClass(ctrl, "iup widget") diff --git a/iup/srclua5/colorbar.lua b/iup/srclua5/colorbar.lua index 524d5f3..7cc07db 100755 --- a/iup/srclua5/colorbar.lua +++ b/iup/srclua5/colorbar.lua @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------ local ctrl = { nick = "colorbar", - parent = WIDGET, + parent = iup.WIDGET, creation = "", callback = { select_cb = "nn", @@ -15,12 +15,12 @@ local ctrl = { include = "iupcontrols.h", }  -PRIMARY = -1 -SECONDARY = -2 +iup.PRIMARY = -1 +iup.SECONDARY = -2  -function ctrl.createElement(class, arg) - return Colorbar(arg.action) +function ctrl.createElement(class, param) + return iup.Colorbar(param.action) end  -iupRegisterWidget(ctrl) -iupSetClass(ctrl, "iup widget") +iup.RegisterWidget(ctrl) +iup.SetClass(ctrl, "iup widget") diff --git a/iup/srclua5/colorbrowser.lua b/iup/srclua5/colorbrowser.lua index 16ac58f..496ce21 100755 --- a/iup/srclua5/colorbrowser.lua +++ b/iup/srclua5/colorbrowser.lua @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------ local ctrl = { nick = "colorbrowser", - parent = WIDGET, + parent = iup.WIDGET, creation = "", callback = { drag_cb = "ccc", @@ -13,9 +13,9 @@ local ctrl = { include = "iupcontrols.h", }  -function ctrl.createElement(class, arg) - return ColorBrowser(arg.action) +function ctrl.createElement(class, param) + return iup.ColorBrowser(param.action) end  -iupRegisterWidget(ctrl) -iupSetClass(ctrl, "iup widget") +iup.RegisterWidget(ctrl) +iup.SetClass(ctrl, "iup widget") diff --git a/iup/srclua5/colordlg.lua b/iup/srclua5/colordlg.lua index 6eea53b..d6a71a4 100755 --- a/iup/srclua5/colordlg.lua +++ b/iup/srclua5/colordlg.lua @@ -3,24 +3,24 @@ ------------------------------------------------------------------------------ local ctrl = { nick = "colordlg", - parent = WIDGET, + parent = iup.WIDGET, creation = "", funcname = "ColorDlg", callback = {} }   function ctrl.popup(handle, x, y) - Popup(handle,x,y) + iup.Popup(handle,x,y) end  function ctrl.destroy(handle) - return Destroy(handle) + return iup.Destroy(handle) end  -function ctrl.createElement(class, arg) - return ColorDlg() +function ctrl.createElement(class, param) + return iup.ColorDlg() end  -iupRegisterWidget(ctrl) -iupSetClass(ctrl, "iup widget") +iup.RegisterWidget(ctrl) +iup.SetClass(ctrl, "iup widget")  diff --git a/iup/srclua5/config.mak b/iup/srclua5/config.mak index 7979f0e..921aa29 100755 --- a/iup/srclua5/config.mak +++ b/iup/srclua5/config.mak @@ -17,7 +17,7 @@ CTRLUA = button.lua canvas.lua dialog.lua colordlg.lua clipboard.lua \ item.lua image.lua imagergb.lua imagergba.lua label.lua \ menu.lua multiline.lua list.lua separator.lua user.lua \ submenu.lua text.lua toggle.lua vbox.lua zbox.lua timer.lua \ - sbox.lua spin.lua spinbox.lua cbox.lua messagedlg.lua \ + sbox.lua split.lua spin.lua spinbox.lua cbox.lua messagedlg.lua \ radio.lua val.lua tabs.lua fontdlg.lua tree.lua progressbar.lua  GC := $(addsuffix .c, $(basename $(CTRLUA))) diff --git a/iup/srclua5/constants.lua b/iup/srclua5/constants.lua index 9a72f6a..2a1e76f 100755 --- a/iup/srclua5/constants.lua +++ b/iup/srclua5/constants.lua @@ -3,70 +3,70 @@ ---------------------------------------------------------------------------- -- Common return values  ---------------------------------------------------------------------------- -ERROR = 1 -NOERROR = 0 -OPENED = -1 -INVALID = -1 +iup.ERROR = 1 +iup.NOERROR = 0 +iup.OPENED = -1 +iup.INVALID = -1  ---------------------------------------------------------------------------- -- Callback return values  ---------------------------------------------------------------------------- -IGNORE = -1 -DEFAULT = -2 -CLOSE = -3 -CONTINUE = -4 +iup.IGNORE = -1 +iup.DEFAULT = -2 +iup.CLOSE = -3 +iup.CONTINUE = -4  ---------------------------------------------------------------------------- -- IupPopup e IupShowXY  -------------------------------