#!/bin/sh
-# create temporary directory
-TEMP_DIR=".tmp-`uname -n`"
-rm -Rf "$TEMP_DIR"
-if mkdir -p "$TEMP_DIR"; then
- :
-else
- echo "Cannot create tmp dir $TEMP_DIR"
- echo "Abort"
- exit 1
-fi
-touch "$TEMP_DIR/options"
-touch "$TEMP_DIR/features"
-# define standard variables
-# also define standard prefix (this is where we will search for config.site)
-prefix=/usr
-exec_prefix=
-bindir=
-sbindir=
-libdir=
-libexecdir=
-datarootdir=
-datadir=
-sysconfdir=
-sharedstatedir=
-localstatedir=
-runstatedir=
-includedir=
-infodir=
-localedir=
-mandir=
-
-# custom variables
-
-# features
+# some utility functions
+isplatform()
+{
+ for p in $PLATFORM
+ do
+ if [ "$p" = "$1" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+notisplatform()
+{
+ for p in $PLATFORM
+ do
+ if [ "$p" = "$1" ]; then
+ return 1
+ fi
+ done
+ return 0
+}
+istoolchain()
+{
+ for t in $TOOLCHAIN
+ do
+ if [ "$t" = "$1" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+notistoolchain()
+{
+ for t in $TOOLCHAIN
+ do
+ if [ "$t" = "$1" ]; then
+ return 1
+ fi
+ done
+ return 0
+}
# clean abort
abort_configure()
exit 1
}
+# Test for availability of pkg-config
+PKG_CONFIG=`command -v pkg-config`
+: ${PKG_CONFIG:="false"}
+
+# Simple uname based platform detection
+# $PLATFORM is used for platform dependent dependency selection
+OS=`uname -s`
+OS_VERSION=`uname -r`
+ARCH=`uname -m`
+printf "detect platform... "
+if [ "$OS" = "SunOS" ]; then
+ PLATFORM="solaris sunos unix svr4"
+elif [ "$OS" = "Linux" ]; then
+ PLATFORM="linux unix"
+elif [ "$OS" = "FreeBSD" ]; then
+ PLATFORM="freebsd bsd unix"
+elif [ "$OS" = "OpenBSD" ]; then
+ PLATFORM="openbsd bsd unix"
+elif [ "$OS" = "NetBSD" ]; then
+ PLATFORM="netbsd bsd unix"
+elif [ "$OS" = "Darwin" ]; then
+ PLATFORM="macos osx bsd unix"
+elif echo "$OS" | grep -i "MINGW" > /dev/null; then
+ PLATFORM="windows mingw"
+fi
+: ${PLATFORM:="unix"}
+
+PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -`
+echo "$PLATFORM_NAME"
+
+
# help text
printhelp()
{
cat << __EOF__
Installation directories:
--prefix=PREFIX path prefix for architecture-independent files
- [/usr]
+ [$prefix]
--exec-prefix=EPREFIX path prefix for architecture-dependent files
[PREFIX]
--mandir=DIR man documentation [DATAROOTDIR/man]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
-Options:
+Build Types:
--debug add extra compile flags for debug builds
--release add extra compile flags for release builds
+
+Options:
--toolkit=(libadwaita|gtk4|gtk3|gtk2|cocoa)
__EOF__
}
+# create temporary directory
+TEMP_DIR=".tmp-`uname -n`"
+rm -Rf "$TEMP_DIR"
+if mkdir -p "$TEMP_DIR"; then
+ :
+else
+ echo "Cannot create tmp dir $TEMP_DIR"
+ echo "Abort"
+ exit 1
+fi
+touch "$TEMP_DIR/options"
+touch "$TEMP_DIR/features"
+
+# define standard variables
+# also define standard prefix (this is where we will search for config.site)
+prefix=/usr
+exec_prefix=
+bindir=
+sbindir=
+libdir=
+libexecdir=
+datarootdir=
+datadir=
+sysconfdir=
+sharedstatedir=
+localstatedir=
+runstatedir=
+includedir=
+infodir=
+localedir=
+mandir=
+
+# custom variables
+
+# features
+
#
# parse arguments
#
"--infodir="*) infodir=${ARG#--infodir=} ;;
"--mandir"*) mandir=${ARG#--mandir} ;;
"--localedir"*) localedir=${ARG#--localedir} ;;
- "--help"*) printhelp; abort_configure ;;
- "--debug") BUILD_TYPE="debug" ;;
- "--release") BUILD_TYPE="release" ;;
+ "--help"*) printhelp; abort_configure ;;
+ "--debug") BUILD_TYPE="debug" ;;
+ "--release") BUILD_TYPE="release" ;;
"--toolkit="*) OPT_TOOLKIT=${ARG#--toolkit=} ;;
+ "--toolkit") echo "option '$ARG' needs a value:"; echo " $ARG=(libadwaita|gtk4|gtk3|gtk2|cocoa)"; abort_configure ;;
"-"*) echo "unknown option: $ARG"; abort_configure ;;
esac
done
: ${mandir:='${datarootdir}/man'}
: ${localedir:='${datarootdir}/locale'}
+# remember the above values and compare them later
+orig_bindir="$bindir"
+orig_sbindir="$sbindir"
+orig_libdir="$libdir"
+orig_libexecdir="$libexecdir"
+orig_datarootdir="$datarootdir"
+orig_datadir="$datadir"
+orig_sysconfdir="$sysconfdir"
+orig_sharedstatedir="$sharedstatedir"
+orig_localstatedir="$localstatedir"
+orig_runstatedir="$runstatedir"
+orig_includedir="$includedir"
+orig_infodir="$infodir"
+orig_mandir="$mandir"
+orig_localedir="$localedir"
+
# check if a config.site exists and load it
if [ -n "$CONFIG_SITE" ]; then
# CONFIG_SITE may contain space separated file names
printf "loading site defaults... "
. "$prefix/etc/config.site"
echo ok
-fi
-
-# Test for availability of pkg-config
-PKG_CONFIG=`command -v pkg-config`
-: ${PKG_CONFIG:="false"}
-
-# Simple uname based platform detection
-# $PLATFORM is used for platform dependent dependency selection
-OS=`uname -s`
-OS_VERSION=`uname -r`
-printf "detect platform... "
-if [ "$OS" = "SunOS" ]; then
- PLATFORM="solaris sunos unix svr4"
-elif [ "$OS" = "Linux" ]; then
- PLATFORM="linux unix"
-elif [ "$OS" = "FreeBSD" ]; then
- PLATFORM="freebsd bsd unix"
-elif [ "$OS" = "OpenBSD" ]; then
- PLATFORM="openbsd bsd unix"
-elif [ "$OS" = "NetBSD" ]; then
- PLATFORM="netbsd bsd unix"
-elif [ "$OS" = "Darwin" ]; then
- PLATFORM="macos osx bsd unix"
-elif echo "$OS" | grep -i "MINGW" > /dev/null; then
- PLATFORM="windows mingw"
-fi
-: ${PLATFORM:="unix"}
-
-PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -`
-echo "$PLATFORM_NAME"
-
-isplatform()
-{
- for p in $PLATFORM
- do
- if [ "$p" = "$1" ]; then
- return 0
- fi
- done
- return 1
-}
-notisplatform()
-{
- for p in $PLATFORM
- do
- if [ "$p" = "$1" ]; then
- return 1
- fi
- done
- return 0
-}
-istoolchain()
-{
- for t in $TOOLCHAIN
- do
- if [ "$t" = "$1" ]; then
- return 0
- fi
- done
- return 1
-}
-notistoolchain()
-{
- for t in $TOOLCHAIN
- do
- if [ "$t" = "$1" ]; then
- return 1
+else
+ # try to detect the correct libdir on our own, except it was changed by the user
+ if test "$libdir" = '${exec_prefix}/lib'; then
+ if [ "$OS" = "SunOS" ]; then
+ test -d "${exec_prefix}/lib/amd64" && libdir='${exec_prefix}/lib/amd64'
+ else
+ # check if the standard libdir even exists
+ if test -d "${exec_prefix}/lib" ; then
+ :
+ else
+ # if it does not, maybe a lib32 exists
+ test -d "${exec_prefix}/lib32" && libdir='${exec_prefix}/lib32'
+ fi
+ # now check if there is a special 64bit libdir that we should use
+ for i in x86_64 ppc64 s390x aarch64 aarch64_be arm64 ; do
+ if [ $ARCH = $i ]; then
+ test -d "${exec_prefix}/lib64" && libdir='${exec_prefix}/lib64'
+ break
+ fi
+ done
fi
- done
- return 0
-}
+ fi
+fi
# generate vars.mk
DEPENDENCIES_FAILED=
ERROR=0
# unnamed dependencies
-TEMP_CFLAGS=
-TEMP_CXXFLAGS=
-TEMP_LDFLAGS=
+TEMP_CFLAGS="$CFLAGS"
+TEMP_CXXFLAGS="$CXXFLAGS"
+TEMP_LDFLAGS="$LDFLAGS"
while true
do
while true
cat >> "$TEMP_DIR/make.mk" << __EOF__
OBJ_EXT = .o
LIB_EXT = .a
+SHLIB_EXT = .dylib
LIB_PREFIX = lib
PACKAGE_SCRIPT = package_osx.sh
__EOF__
cat >> "$TEMP_DIR/make.mk" << __EOF__
OBJ_EXT = .o
LIB_EXT = .a
+SHLIB_EXT = .so
LIB_PREFIX = lib
PACKAGE_SCRIPT = package_unix.sh
__EOF__
break
done
while true
+do
+ while true
+ do
+
+ cat >> "$TEMP_DIR/make.mk" << __EOF__
+BUILD_BIN_DIR = bin
+BUILD_LIB_DIR = lib
+__EOF__
+ break
+ done
+ break
+done
+while true
do
if notisplatform "bsd"; then
break
break
done
+# build type
+if [ "$BUILD_TYPE" = "debug" ]; then
+ TEMP_CFLAGS="\${DEBUG_CFLAGS} $TEMP_CFLAGS"
+ TEMP_CXXFLAGS="\${DEBUG_CXXFLAGS} $TEMP_CXXFLAGS"
+fi
+if [ "$BUILD_TYPE" = "release" ]; then
+ TEMP_CFLAGS="\${RELEASE_CFLAGS} $TEMP_CFLAGS"
+ TEMP_CXXFLAGS="\${RELEASE_CXXFLAGS} $TEMP_CXXFLAGS"
+fi
+
# add general dependency flags to flags.mk
echo "# general flags" >> "$TEMP_DIR/flags.mk"
if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then
if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then
echo "DAV_CXXFLAGS += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk"
fi
-if [ "$BUILD_TYPE" = "debug" ]; then
- if [ -n "$lang_c" ]; then
- echo 'DAV_CFLAGS += ${DEBUG_CC_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
- if [ -n "$lang_cpp" ]; then
- echo 'DAV_CXXFLAGS += ${DEBUG_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
-fi
-if [ "$BUILD_TYPE" = "release" ]; then
- if [ -n "$lang_c" ]; then
- echo 'DAV_CFLAGS += ${RELEASE_CC_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
- if [ -n "$lang_cpp" ]; then
- echo 'DAV_CXXFLAGS += ${RELEASE_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
-fi
if [ -n "${TEMP_LDFLAGS}" ]; then
echo "DAV_LDFLAGS += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk"
fi
ERROR=1
DEPENDENCIES_FAILED="option 'toolkit' $DEPENDENCIES_FAILED"
fi
+ else
+ echo
+ echo "Invalid option value - usage:"
+ echo " --toolkit=(libadwaita|gtk4|gtk3|gtk2|cocoa)"
+ abort_configure
fi
fi
if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then
echo "TK_CXXFLAGS += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk"
fi
-if [ "$BUILD_TYPE" = "debug" ]; then
- if [ -n "$lang_c" ]; then
- echo 'TK_CFLAGS += ${DEBUG_CC_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
- if [ -n "$lang_cpp" ]; then
- echo 'TK_CXXFLAGS += ${DEBUG_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
-fi
-if [ "$BUILD_TYPE" = "release" ]; then
- if [ -n "$lang_c" ]; then
- echo 'TK_CFLAGS += ${RELEASE_CC_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
- if [ -n "$lang_cpp" ]; then
- echo 'TK_CXXFLAGS += ${RELEASE_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
-fi
if [ -n "${TEMP_LDFLAGS}" ]; then
echo "TK_LDFLAGS += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk"
fi
echo "configure finished"
echo
+echo "Toolchain"
+echo " name: $TOOLCHAIN_NAME"
+if [ -n "$TOOLCHAIN_CC" ]; then
+ echo " cc: $TOOLCHAIN_CC"
+fi
+if [ -n "$TOOLCHAIN_CXX" ]; then
+ echo " cxx: $TOOLCHAIN_CXX"
+fi
+if [ -n "$TOOLCHAIN_WSIZE" ]; then
+ echo " word size: $TOOLCHAIN_WSIZE bit"
+fi
+if [ -n "$TOOLCHAIN_CSTD" ]; then
+ echo " default C std: $TOOLCHAIN_CSTD"
+fi
+echo
echo "Build Config:"
-echo " PREFIX: $prefix"
-echo " TOOLCHAIN: $TOOLCHAIN_NAME"
+echo " prefix: $prefix"
+echo " exec_prefix: $exec_prefix"
+if [ "$orig_bindir" != "$bindir" ]; then
+ echo " bindir: $bindir"
+fi
+if [ "$orig_sbindir" != "$sbindir" ]; then
+ echo " sbindir: $sbindir"
+fi
+if [ "$orig_libdir" != "$libdir" ]; then
+ echo " libdir: $libdir"
+fi
+if [ "$orig_libexecdir" != "$libexecdir" ]; then
+ echo " libexecdir: $libexecdir"
+fi
+if [ "$orig_datarootdir" != "$datarootdir" ]; then
+ echo " datarootdir: $datarootdir"
+fi
+if [ "$orig_datadir" != "$datadir" ]; then
+ echo " datadir: $datadir"
+fi
+if [ "$orig_sysconfdir" != "$sysconfdir" ]; then
+ echo " sysconfdir: $sysconfdir"
+fi
+if [ "$orig_sharedstatedir" != "$sharedstatedir" ]; then
+ echo " sharedstatedir: $sharedstatedir"
+fi
+if [ "$orig_localstatedir" != "$localstatedir" ]; then
+ echo " localstatedir: $localstatedir"
+fi
+if [ "$orig_runstatedir" != "$runstatedir" ]; then
+ echo " runstatedir: $runstatedir"
+fi
+if [ "$orig_includedir" != "$includedir" ]; then
+ echo " includedir: $includedir"
+fi
+if [ "$orig_infodir" != "$infodir" ]; then
+ echo " infodir: $infodir"
+fi
+if [ "$orig_mandir" != "$mandir" ]; then
+ echo " mandir: $mandir"
+fi
+if [ "$orig_localedir" != "$localedir" ]; then
+ echo " localedir: $localedir"
+fi
+echo
echo "Options:"
cat "$TEMP_DIR/options"
echo
# generate the config.mk file
+pwd=`pwd`
cat > "$TEMP_DIR/config.mk" << __EOF__
#
-# config.mk generated by configure
+# config.mk generated by:
+# pwd: $pwd
+# $0 $@
#
__EOF__
write_toolchain_defaults "$TEMP_DIR/toolchain.mk"
-cat "$TEMP_DIR/vars.mk" "$TEMP_DIR/toolchain.mk" "$TEMP_DIR/flags.mk" "$TEMP_DIR/make.mk" > config.mk
+cat "$TEMP_DIR/config.mk" "$TEMP_DIR/vars.mk" "$TEMP_DIR/toolchain.mk" "$TEMP_DIR/flags.mk" "$TEMP_DIR/make.mk" > config.mk
rm -Rf "$TEMP_DIR"
include config.mk
BUILD_DIRS = build/bin build/lib
+BUILD_DIRS += build/ucx
BUILD_DIRS += build/libidav
BUILD_DIRS += build/mizunara
BUILD_DIRS += build/mizucp
CFLAGS =
CXXFLAGS =
-DEBUG_CC_FLAGS = -g
-DEBUG_CXX_FLAGS = -g
-RELEASE_CC_FLAGS = -O3 -DNDEBUG
-RELEASE_CXX_FLAGS = -O3 -DNDEBUG
+DEBUG_CFLAGS = -g
+DEBUG_CXXFLAGS = -g
+RELEASE_CFLAGS = -O3 -DNDEBUG
+RELEASE_CXXFLAGS = -O3 -DNDEBUG
LDFLAGS =
SHLIB_CFLAGS = -fPIC
-SHLIB_LDFLAGS = -shared
\ No newline at end of file
+SHLIB_LDFLAGS = -shared
CFLAGS =
CXXFLAGS =
-DEBUG_CC_FLAGS = -g
-DEBUG_CXX_FLAGS = -g
-RELEASE_CC_FLAGS = -O3 -DNDEBUG
-RELEASE_CXX_FLAGS = -O3 -DNDEBUG
+DEBUG_CFLAGS = -g
+DEBUG_CXXFLAGS = -g
+RELEASE_CFLAGS = -O3 -DNDEBUG
+RELEASE_CXXFLAGS = -O3 -DNDEBUG
LDFLAGS =
SHLIB_CFLAGS = -fPIC
#!/bin/sh
-# create temporary directory
-TEMP_DIR=".tmp-`uname -n`"
-rm -Rf "$TEMP_DIR"
-if mkdir -p "$TEMP_DIR"; then
- :
-else
- echo "Cannot create tmp dir $TEMP_DIR"
- echo "Abort"
- exit 1
-fi
-touch "$TEMP_DIR/options"
-touch "$TEMP_DIR/features"
-
-# define standard variables
-# also define standard prefix (this is where we will search for config.site)
-prefix=/usr
-exec_prefix=
-bindir=
-sbindir=
-libdir=
-libexecdir=
-datarootdir=
-datadir=
-sysconfdir=
-sharedstatedir=
-localstatedir=
-runstatedir=
-includedir=
-infodir=
-localedir=
-mandir=
-
-# custom variables
-#foreach( $var in $vars )
-#if( $var.exec )
-${var.varName}=`${var.value}`
-#else
-${var.varName}="${var.value}"
-#end
-#end
-
-# features
-#foreach( $feature in $features )
-#if( ${feature.auto} )
-${feature.varName}=auto
-#end
-#end
+#set( $D = '$' )
+#[[
+# some utility functions
+isplatform()
+{
+ for p in $PLATFORM
+ do
+ if [ "$p" = "$1" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+notisplatform()
+{
+ for p in $PLATFORM
+ do
+ if [ "$p" = "$1" ]; then
+ return 1
+ fi
+ done
+ return 0
+}
+istoolchain()
+{
+ for t in $TOOLCHAIN
+ do
+ if [ "$t" = "$1" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+notistoolchain()
+{
+ for t in $TOOLCHAIN
+ do
+ if [ "$t" = "$1" ]; then
+ return 1
+ fi
+ done
+ return 0
+}
# clean abort
abort_configure()
exit 1
}
+# Test for availability of pkg-config
+PKG_CONFIG=`command -v pkg-config`
+: ${PKG_CONFIG:="false"}
+
+# Simple uname based platform detection
+# $PLATFORM is used for platform dependent dependency selection
+OS=`uname -s`
+OS_VERSION=`uname -r`
+ARCH=`uname -m`
+printf "detect platform... "
+if [ "$OS" = "SunOS" ]; then
+ PLATFORM="solaris sunos unix svr4"
+elif [ "$OS" = "Linux" ]; then
+ PLATFORM="linux unix"
+elif [ "$OS" = "FreeBSD" ]; then
+ PLATFORM="freebsd bsd unix"
+elif [ "$OS" = "OpenBSD" ]; then
+ PLATFORM="openbsd bsd unix"
+elif [ "$OS" = "NetBSD" ]; then
+ PLATFORM="netbsd bsd unix"
+elif [ "$OS" = "Darwin" ]; then
+ PLATFORM="macos osx bsd unix"
+elif echo "$OS" | grep -i "MINGW" > /dev/null; then
+ PLATFORM="windows mingw"
+fi
+: ${PLATFORM:="unix"}
+
+PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -`
+echo "$PLATFORM_NAME"
+]]#
+
# help text
printhelp()
{
cat << __EOF__
Installation directories:
--prefix=PREFIX path prefix for architecture-independent files
- [/usr]
+ [${D}prefix]
--exec-prefix=EPREFIX path prefix for architecture-dependent files
[PREFIX]
--mandir=DIR man documentation [DATAROOTDIR/man]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
-#if( $options.size() > 0 )
-Options:
+Build Types:
--debug add extra compile flags for debug builds
--release add extra compile flags for release builds
+#if( $options.size() > 0 )
+
+Options:
#foreach( $opt in $options )
--${opt.argument}=${opt.valuesString}
#end
-
#end
#if( $features.size() > 0 )
+
Optional Features:
#foreach( $feature in $features )
${feature.helpText}
#end
-
#end
+
__EOF__
}
+# create temporary directory
+TEMP_DIR=".tmp-`uname -n`"
+rm -Rf "$TEMP_DIR"
+if mkdir -p "$TEMP_DIR"; then
+ :
+else
+ echo "Cannot create tmp dir $TEMP_DIR"
+ echo "Abort"
+ exit 1
+fi
+touch "$TEMP_DIR/options"
+touch "$TEMP_DIR/features"
+
+# define standard variables
+# also define standard prefix (this is where we will search for config.site)
+prefix=/usr
+exec_prefix=
+bindir=
+sbindir=
+libdir=
+libexecdir=
+datarootdir=
+datadir=
+sysconfdir=
+sharedstatedir=
+localstatedir=
+runstatedir=
+includedir=
+infodir=
+localedir=
+mandir=
+
+# custom variables
+#foreach( $cfg in $config )
+if true \
+#if( $cfg.platform )
+ && isplatform "${cfg.platform}" \
+#end
+#foreach( $np in $cfg.notList )
+ && notisplatform "${np}" \
+#end
+ ; then
+ #foreach( $var in $cfg.vars )
+ #if( $var.exec )
+ ${var.varName}=`${var.value}`
+ #else
+ ${var.varName}="${var.value}"
+ #end
+ #end
+fi
+#end
+
+# features
+#foreach( $feature in $features )
+#if( ${feature.auto} )
+${feature.varName}=auto
+#end
+#end
+
#
# parse arguments
#
BUILD_TYPE="default"
-#set( $D = '$' )
for ARG in "$@"
do
case "$ARG" in
"--infodir="*) infodir=${D}{ARG#--infodir=} ;;
"--mandir"*) mandir=${D}{ARG#--mandir} ;;
"--localedir"*) localedir=${D}{ARG#--localedir} ;;
- "--help"*) printhelp; abort_configure ;;
- "--debug") BUILD_TYPE="debug" ;;
- "--release") BUILD_TYPE="release" ;;
+ "--help"*) printhelp; abort_configure ;;
+ "--debug") BUILD_TYPE="debug" ;;
+ "--release") BUILD_TYPE="release" ;;
#foreach( $opt in $options )
"--${opt.argument}="*) ${opt.varName}=${D}{ARG#--${opt.argument}=} ;;
+ "--${opt.argument}") echo "option '$ARG' needs a value:"; echo " $ARG=${opt.valuesString}"; abort_configure ;;
#end
#foreach( $feature in $features )
"--enable-${feature.arg}") ${feature.varName}=on ;;
: ${mandir:='${datarootdir}/man'}
: ${localedir:='${datarootdir}/locale'}
+# remember the above values and compare them later
+orig_bindir="$bindir"
+orig_sbindir="$sbindir"
+orig_libdir="$libdir"
+orig_libexecdir="$libexecdir"
+orig_datarootdir="$datarootdir"
+orig_datadir="$datadir"
+orig_sysconfdir="$sysconfdir"
+orig_sharedstatedir="$sharedstatedir"
+orig_localstatedir="$localstatedir"
+orig_runstatedir="$runstatedir"
+orig_includedir="$includedir"
+orig_infodir="$infodir"
+orig_mandir="$mandir"
+orig_localedir="$localedir"
+
# check if a config.site exists and load it
if [ -n "$CONFIG_SITE" ]; then
# CONFIG_SITE may contain space separated file names
printf "loading site defaults... "
. "$prefix/etc/config.site"
echo ok
-fi
-
-# Test for availability of pkg-config
-PKG_CONFIG=`command -v pkg-config`
-: ${PKG_CONFIG:="false"}
-
-# Simple uname based platform detection
-# $PLATFORM is used for platform dependent dependency selection
-OS=`uname -s`
-OS_VERSION=`uname -r`
-printf "detect platform... "
-if [ "$OS" = "SunOS" ]; then
- PLATFORM="solaris sunos unix svr4"
-elif [ "$OS" = "Linux" ]; then
- PLATFORM="linux unix"
-elif [ "$OS" = "FreeBSD" ]; then
- PLATFORM="freebsd bsd unix"
-elif [ "$OS" = "OpenBSD" ]; then
- PLATFORM="openbsd bsd unix"
-elif [ "$OS" = "NetBSD" ]; then
- PLATFORM="netbsd bsd unix"
-elif [ "$OS" = "Darwin" ]; then
- PLATFORM="macos osx bsd unix"
-elif echo "$OS" | grep -i "MINGW" > /dev/null; then
- PLATFORM="windows mingw"
-fi
-: ${PLATFORM:="unix"}
-
-PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -`
-echo "$PLATFORM_NAME"
-
-isplatform()
-{
- for p in $PLATFORM
- do
- if [ "$p" = "$1" ]; then
- return 0
- fi
- done
- return 1
-}
-notisplatform()
-{
- for p in $PLATFORM
- do
- if [ "$p" = "$1" ]; then
- return 1
- fi
- done
- return 0
-}
-istoolchain()
-{
- for t in $TOOLCHAIN
- do
- if [ "$t" = "$1" ]; then
- return 0
- fi
- done
- return 1
-}
-notistoolchain()
-{
- for t in $TOOLCHAIN
- do
- if [ "$t" = "$1" ]; then
- return 1
+else
+ # try to detect the correct libdir on our own, except it was changed by the user
+ if test "$libdir" = '${exec_prefix}/lib'; then
+ if [ "$OS" = "SunOS" ]; then
+ test -d "${exec_prefix}/lib/amd64" && libdir='${exec_prefix}/lib/amd64'
+ else
+ # check if the standard libdir even exists
+ if test -d "${exec_prefix}/lib" ; then
+ :
+ else
+ # if it does not, maybe a lib32 exists
+ test -d "${exec_prefix}/lib32" && libdir='${exec_prefix}/lib32'
+ fi
+ # now check if there is a special 64bit libdir that we should use
+ for i in x86_64 ppc64 s390x aarch64 aarch64_be arm64 ; do
+ if [ $ARCH = $i ]; then
+ test -d "${exec_prefix}/lib64" && libdir='${exec_prefix}/lib64'
+ break
+ fi
+ done
fi
- done
- return 0
-}
+ fi
+fi
]]#
## End of unparsed content **
ERROR=0
#if( $dependencies.size() > 0 )
# unnamed dependencies
-TEMP_CFLAGS=
-TEMP_CXXFLAGS=
-TEMP_LDFLAGS=
+TEMP_CFLAGS="$CFLAGS"
+TEMP_CXXFLAGS="$CXXFLAGS"
+TEMP_LDFLAGS="$LDFLAGS"
#foreach( $dependency in $dependencies )
while true
do
done
#end
+# build type
+if [ "$BUILD_TYPE" = "debug" ]; then
+ TEMP_CFLAGS="\${DEBUG_CFLAGS} $TEMP_CFLAGS"
+ TEMP_CXXFLAGS="\${DEBUG_CXXFLAGS} $TEMP_CXXFLAGS"
+fi
+if [ "$BUILD_TYPE" = "release" ]; then
+ TEMP_CFLAGS="\${RELEASE_CFLAGS} $TEMP_CFLAGS"
+ TEMP_CXXFLAGS="\${RELEASE_CXXFLAGS} $TEMP_CXXFLAGS"
+fi
+
# add general dependency flags to flags.mk
echo "# general flags" >> "$TEMP_DIR/flags.mk"
if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then
unset ${feature.varName}
fi
fi
+if [ -n "${D}${feature.varName}" ]; then
+ :
+#foreach( $def in $feature.defines )
+ TEMP_CFLAGS="$TEMP_CFLAGS ${def.toFlags()}"
+ TEMP_CXXFLAGS="$TEMP_CXXFLAGS ${def.toFlags()}"
+#end
+#if( $feature.hasMake() )
+ cat >> "$TEMP_DIR/make.mk" << __EOF__
+$feature.make
+__EOF__
+#end
+else
+ :
+#foreach( $def in $feature.disabled.defines )
+ TEMP_CFLAGS="$TEMP_CFLAGS ${def.toFlags()}"
+ TEMP_CXXFLAGS="$TEMP_CXXFLAGS ${def.toFlags()}"
+#end
+#if( $feature.disabled.hasMake() )
+ cat >> "$TEMP_DIR/make.mk" << __EOF__
+$feature.disabled.make
+__EOF__
+#end
+#foreach( $dependency in $feature.disabled.dependencies )
+ if dependency_error_$dependency ; then
+ DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED ${dependency} "
+ ERROR=1
+ fi
+#end
+fi
#end
#foreach( $opt in $target.options )
DEPENDENCIES_FAILED="option '${opt.argument}' $DEPENDENCIES_FAILED"
fi
#end
+ else
+ echo
+ echo "Invalid option value - usage:"
+ echo " --${opt.argument}=${opt.valuesString}"
+ abort_configure
fi
fi
#end
if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then
echo "${target.cxxFlags} += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk"
fi
-if [ "$BUILD_TYPE" = "debug" ]; then
- if [ -n "$lang_c" ]; then
- echo '${target.cFlags} += ${DEBUG_CC_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
- if [ -n "$lang_cpp" ]; then
- echo '${target.cxxFlags} += ${DEBUG_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
-fi
-if [ "$BUILD_TYPE" = "release" ]; then
- if [ -n "$lang_c" ]; then
- echo '${target.cFlags} += ${RELEASE_CC_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
- if [ -n "$lang_cpp" ]; then
- echo '${target.cxxFlags} += ${RELEASE_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk"
- fi
-fi
if [ -n "${TEMP_LDFLAGS}" ]; then
echo "${target.ldFlags} += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk"
fi
echo "configure finished"
echo
+echo "Toolchain"
+echo " name: $TOOLCHAIN_NAME"
+if [ -n "$TOOLCHAIN_CC" ]; then
+ echo " cc: $TOOLCHAIN_CC"
+fi
+if [ -n "$TOOLCHAIN_CXX" ]; then
+ echo " cxx: $TOOLCHAIN_CXX"
+fi
+if [ -n "$TOOLCHAIN_WSIZE" ]; then
+ echo " word size: $TOOLCHAIN_WSIZE bit"
+fi
+if [ -n "$TOOLCHAIN_CSTD" ]; then
+ echo " default C std: $TOOLCHAIN_CSTD"
+fi
+echo
echo "Build Config:"
-echo " PREFIX: $prefix"
-echo " TOOLCHAIN: $TOOLCHAIN_NAME"
+echo " prefix: $prefix"
+echo " exec_prefix: $exec_prefix"
+if [ "$orig_bindir" != "$bindir" ]; then
+ echo " bindir: $bindir"
+fi
+if [ "$orig_sbindir" != "$sbindir" ]; then
+ echo " sbindir: $sbindir"
+fi
+if [ "$orig_libdir" != "$libdir" ]; then
+ echo " libdir: $libdir"
+fi
+if [ "$orig_libexecdir" != "$libexecdir" ]; then
+ echo " libexecdir: $libexecdir"
+fi
+if [ "$orig_datarootdir" != "$datarootdir" ]; then
+ echo " datarootdir: $datarootdir"
+fi
+if [ "$orig_datadir" != "$datadir" ]; then
+ echo " datadir: $datadir"
+fi
+if [ "$orig_sysconfdir" != "$sysconfdir" ]; then
+ echo " sysconfdir: $sysconfdir"
+fi
+if [ "$orig_sharedstatedir" != "$sharedstatedir" ]; then
+ echo " sharedstatedir: $sharedstatedir"
+fi
+if [ "$orig_localstatedir" != "$localstatedir" ]; then
+ echo " localstatedir: $localstatedir"
+fi
+if [ "$orig_runstatedir" != "$runstatedir" ]; then
+ echo " runstatedir: $runstatedir"
+fi
+if [ "$orig_includedir" != "$includedir" ]; then
+ echo " includedir: $includedir"
+fi
+if [ "$orig_infodir" != "$infodir" ]; then
+ echo " infodir: $infodir"
+fi
+if [ "$orig_mandir" != "$mandir" ]; then
+ echo " mandir: $mandir"
+fi
+if [ "$orig_localedir" != "$localedir" ]; then
+ echo " localedir: $localedir"
+fi
#if ( $options.size() > 0 )
+echo
echo "Options:"
cat "$TEMP_DIR/options"
#end
#if ( $features.size() > 0 )
+echo
echo "Features:"
#foreach( $feature in $features )
if [ -n "${D}${feature.varName}" ]; then
echo
# generate the config.mk file
+pwd=`pwd`
cat > "$TEMP_DIR/config.mk" << __EOF__
#
-# config.mk generated by configure
+# config.mk generated by:
+# pwd: $pwd
+# $0 $@
#
__EOF__
write_toolchain_defaults "$TEMP_DIR/toolchain.mk"
-cat "$TEMP_DIR/vars.mk" "$TEMP_DIR/toolchain.mk" "$TEMP_DIR/flags.mk" "$TEMP_DIR/make.mk" > config.mk
+cat "$TEMP_DIR/config.mk" "$TEMP_DIR/vars.mk" "$TEMP_DIR/toolchain.mk" "$TEMP_DIR/flags.mk" "$TEMP_DIR/make.mk" > config.mk
rm -Rf "$TEMP_DIR"
CFLAGS =
CXXFLAGS =
-DEBUG_CC_FLAGS = -g
-DEBUG_CXX_FLAGS = -g
-RELEASE_CC_FLAGS = -O3 -DNDEBUG
-RELEASE_CXX_FLAGS = -O3 -DNDEBUG
+DEBUG_CFLAGS = -g
+DEBUG_CXXFLAGS = -g
+RELEASE_CFLAGS = -O3 -DNDEBUG
+RELEASE_CXXFLAGS = -O3 -DNDEBUG
LDFLAGS =
SHLIB_CFLAGS = -fPIC
<dependency platform="macos">
<make>OBJ_EXT = .o</make>
<make>LIB_EXT = .a</make>
+ <make>SHLIB_EXT = .dylib</make>
<make>LIB_PREFIX = lib</make>
<make>PACKAGE_SCRIPT = package_osx.sh</make>
</dependency>
<dependency platform="unix" not="macos">
<make>OBJ_EXT = .o</make>
<make>LIB_EXT = .a</make>
+ <make>SHLIB_EXT = .so</make>
<make>LIB_PREFIX = lib</make>
<make>PACKAGE_SCRIPT = package_unix.sh</make>
</dependency>
+ <dependency>
+ <make>BUILD_BIN_DIR = bin</make>
+ <make>BUILD_LIB_DIR = lib</make>
+ </dependency>
<dependency platform="bsd">
<cflags>-I/usr/local/include</cflags>
CFLAGS =
CXXFLAGS =
-DEBUG_CC_FLAGS = -g
-DEBUG_CXX_FLAGS = -g
-RELEASE_CC_FLAGS = -O3 -DNDEBUG
-RELEASE_CXX_FLAGS = -O3 -DNDEBUG
+DEBUG_CFLAGS = -g
+DEBUG_CXXFLAGS = -g
+RELEASE_CFLAGS = -O3 -DNDEBUG
+RELEASE_CXXFLAGS = -O3 -DNDEBUG
LDFLAGS =
SHLIB_CFLAGS = -Kpic
check_c_compiler()
{
+ command -v $1 2>&1 >/dev/null
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
cat > "$TEMP_DIR/test.c" << __EOF__
/* test file */
#include <stdio.h>
int main(int argc, char **argv) {
#if defined(_MSC_VER)
- printf("msc\n");
+ printf("toolchain:msc\n");
#elif defined(__clang__)
- printf("clang gnuc\n");
+ printf("toolchain:clang gnuc\n");
#elif defined(__GNUC__)
- printf("gcc gnuc\n");
+ printf("toolchain:gcc gnuc\n");
#elif defined(__sun)
- printf("suncc\n");
+ printf("toolchain:suncc\n");
#else
- printf("unknown\n");
+ printf("toolchain:unknown\n");
+#endif
+ printf("wsize:%d\n", (int)sizeof(void*)*8);
+#ifdef __STDC_VERSION__
+ printf("stdcversion:%d\n", __STDC_VERSION__);
#endif
return 0;
}
check_cpp_compiler()
{
+ command -v $1 2>&1 >/dev/null
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
cat > "$TEMP_DIR/test.cpp" << __EOF__
/* test file */
#include <iostream>
int main(int argc, char **argv) {
#if defined(_MSC_VER)
- std::cout << "msc" << std::endl;
+ std::cout << "toolchain:msc" << std::endl;
#elif defined(__clang__)
- std::cout << "clang gnuc" << std::endl;
+ std::cout << "toolchain:clang gnuc" << std::endl;
#elif defined(__GNUC__)
- std::cout << "gcc gnuc" << std::endl;
+ std::cout << "toolchain:gcc gnuc" << std::endl;
#elif defined(__sun)
- std::cout << "suncc" << std::endl;
+ std::cout << "toolchain:suncc" << std::endl;
#else
- std::cout << "cc" << std::endl;
+ std::cout << "toolchain:unknown" << std::endl;
#endif
+ std::cout << "wsize:" << sizeof(void*)*8 << std::endl;
return 0;
}
__EOF__
fi
}
+parse_toolchain_properties()
+{
+ info_file="$1"
+ TOOLCHAIN=`grep '^toolchain:' "$info_file" | tail -c +11`
+ TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
+ TOOLCHAIN_WSIZE=`grep '^wsize:' "$info_file" | tail -c +7`
+}
+
detect_c_compiler()
{
if [ -n "$TOOLCHAIN_CC" ]; then
if [ -n "$CC" ]; then
if check_c_compiler "$CC"; then
TOOLCHAIN_CC=$CC
- TOOLCHAIN=`"$TEMP_DIR/checkcc"`
- TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
+ "$TEMP_DIR/checkcc" > "$TEMP_DIR/checkcc_out"
+ parse_toolchain_properties "$TEMP_DIR/checkcc_out"
+ TOOLCHAIN_CSTD=`grep '^stdcversion:' "$TEMP_DIR/checkcc_out" | tail -c +13`
echo "$CC"
return 0
else
do
if check_c_compiler "$COMP"; then
TOOLCHAIN_CC=$COMP
- TOOLCHAIN=`"$TEMP_DIR/checkcc"`
- TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
+ "$TEMP_DIR/checkcc" > "$TEMP_DIR/checkcc_out"
+ parse_toolchain_properties "$TEMP_DIR/checkcc_out"
+ TOOLCHAIN_CSTD=`grep '^stdcversion:' "$TEMP_DIR/checkcc_out" | tail -c +13`
echo "$COMP"
return 0
fi
if [ -n "$CXX" ]; then
if check_cpp_compiler "$CXX"; then
TOOLCHAIN_CXX=$CXX
- TOOLCHAIN=`"$TEMP_DIR/checkcc"`
- TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
+ "$TEMP_DIR/checkcc" > "$TEMP_DIR/checkcc_out"
+ parse_toolchain_properties "$TEMP_DIR/checkcc_out"
echo "$CXX"
return 0
else
do
if check_cpp_compiler "$COMP"; then
TOOLCHAIN_CXX=$COMP
- TOOLCHAIN=`"$TEMP_DIR/checkcc"`
- TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -`
+ "$TEMP_DIR/checkcc" > "$TEMP_DIR/checkcc_out"
+ parse_toolchain_properties "$TEMP_DIR/checkcc_out"
echo "$COMP"
return 0
fi
xmlns="http://unixwork.de/uwproj"
targetNamespace="http://unixwork.de/uwproj"
elementFormDefault="qualified"
- version="0.2"
+ version="0.3"
>
<xs:element name="project" type="ProjectType"/>
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="config" type="ConfigType" minOccurs="0"/>
+ <xs:element name="config" type="ConfigType" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="dependency" type="DependencyType" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="target" type="TargetType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
+ <xs:attribute name="version" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="ConfigType">
<xs:annotation>
<xs:documentation>
- The configuration section.
- Consists of an arbitrary number of <code>var</code> elements.
+ <p>
+ The configuration section.
+ Consists of an arbitrary number of <code>var</code> elements.
+ </p>
+ <p>
+ The optional <code>platform</code> attribute may specify a <em>single</em> platform identifier and
+ the optional <code>not</code> attribute may specify a comma-separated list of platform identifiers.
+ The configure script shall skip this config declaration if the detected platform is not matching
+ the filter specification of these attributes.
+ </p>
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="var" type="ConfigVarType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
+ <xs:attribute name="platform" type="xs:string"/>
+ <xs:attribute name="not" type="xs:string"/>
</xs:complexType>
<xs:complexType name="ConfigVarType">
<code>dependencies</code> are satisfied.
If a feature is enabled, all <code>define</code> and <code>make</code> definitions are
supposed to be applied to the config file.
+ If a feature is disabled, an optional <code>disabled</code> element may specify which
+ <code>define</code> and <code>make</code> definitions are supposed to be applied.
+ There might also be <code>dependencies</code> when the feature is disabled (e.g. specifying a fallback).
In case the optional <code>default</code> attribute is set to true, the feature is enabled by default
and is supposed to be automatically disabled (without error) when the dependencies are not satisfied.
The name that is supposed to be used for the --enable and --disable arguments can be optionally
</xs:annotation>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:group ref="TargetDataGroup"/>
+ <xs:element name="desc" type="xs:string"/>
+ <xs:element name="disabled">
+ <xs:complexType>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:group ref="TargetDataGroup"/>
+ </xs:choice>
+ </xs:complexType>
+ </xs:element>
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="arg" type="xs:string"/>
<xs:attribute name="default" type="xs:boolean" default="false"/>
- <xs:element name="desc" type="xs:string"/>
</xs:complexType>
<xs:complexType name="OptionType">
all: $(BUILD_ROOT)/build/bin/mizunara
-$(BUILD_ROOT)/build/bin/mizunara: $(OBJ) $(BUILD_ROOT)/build/lib/libuitk.a
- $(CC) -o $(BUILD_ROOT)/build/bin/mizunara$(APP_EXT) $(OBJ) -L$(BUILD_ROOT)/build/lib -luitk -lidav -lucx $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS)
+$(BUILD_ROOT)/build/bin/mizunara: $(OBJ) $(BUILD_ROOT)/build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)uitk$(LIB_EXT)
+ $(CC) -o $(BUILD_ROOT)/build/bin/mizunara$(APP_EXT) $(OBJ) -L$(BUILD_ROOT)/build/lib -lidav $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS) $(BUILD_ROOT)/build/$(BUILD_LIB_DIR)/libucx.a $(BUILD_ROOT)/build/$(BUILD_LIB_DIR)/libuitk.a
$(BUILD_ROOT)/build/mizunara/%.$(OBJ_EXT): %.c
$(CC) $(CFLAGS) $(TK_CFLAGS) -o $@ -c $<
{ .value = wdata->default_dirs, .userdata = window_sidebar_user_dirs_item },
{ .value = wdata->user_dirs, .userdata = window_sidebar_user_dirs_item, .separator = TRUE }
};
- ui_sourcelist(obj, .sublists = sublists, .numsublists = 2, .getvalue = window_sidebar_getvalue, .onactivate = action_sourcelist_activate);
+ ui_sourcelist(obj,
+ .sublists = sublists,
+ .numsublists = 2,
+ .getvalue = window_sidebar_getvalue,
+ .onactivate = action_sourcelist_activate,
+ .fill = TRUE);
}
- ui_hbox(obj, .spacing = 4, .fill = UI_OFF) {
+ ui_hbox(obj, .spacing = 4) {
ui_button(obj, .style_class = "flat", .icon = UI_ICON_GO_BACK);
ui_button(obj, .style_class = "flat", .icon = UI_ICON_GO_FORWARD);
- ui_path_textfield(obj, .varname = "path", .fill = UI_ON, .onactivate = action_pathbar_activate);
+ ui_path_textfield(obj, .varname = "path", .fill = TRUE, .onactivate = action_pathbar_activate);
}
window_create_browser_view(obj, wdata);
}
#ifdef GTK_MAJOR_VERSION
-static UIWIDGET create_filesview(UiObject *obj, UiWidgetArgs args, void *userdata) {
+static UIWIDGET create_filesview(UiObject *obj, UiWidgetArgs *args, void *userdata) {
MainWindow *win = userdata;
MzFilesView *view = mz_files_view_new();
view->open = open_files;
#endif
void window_create_browser_view(UiObject *obj, MainWindow *win) {
- ui_tabview(obj, .tabview = UI_TABVIEW_INVISIBLE, .varname = "view") {
+ ui_tabview(obj, .tabview = UI_TABVIEW_INVISIBLE, .varname = "view", .fill = TRUE) {
ui_tab(obj, "iconview") {
- ui_customwidget(obj, create_filesview, win, .fill = UI_ON);
+ ui_customwidget(obj, create_filesview, win, .fill = TRUE);
}
ui_tab(obj, "listview") {
*
* sublist_userdata: sublist identifier (sidebar_list_default_dirs, sidebar_list_user_dirs)
*/
-void window_sidebar_getvalue(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item) {
+void window_sidebar_getvalue(UiList *list, void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata) {
ui_sublist_getvalue_func getvalue = sublist_userdata;
- getvalue(NULL, rowdata, index, item);
+ getvalue(list ,NULL, rowdata, index, item, userdata);
}
-void window_sidebar_user_dirs_item(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item) {
+void window_sidebar_user_dirs_item(UiList *list, void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata) {
MZBookmark *bookmark = rowdata;
item->icon = strdup(bookmark->icon);
item->label = strdup(bookmark->name);
void windowdata_init(UiContext *ctx, MainWindow *win);
-void window_sidebar_getvalue(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item);
+void window_sidebar_getvalue(UiList *list, void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata);
-void window_sidebar_user_dirs_item(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item);
+void window_sidebar_user_dirs_item(UiList *list, void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata);
void action_pathbar_activate(UiEvent *event, void *userdata);
OBJ = $(SRC:%.c=../build/ucx/%$(OBJ_EXT))
-UCX_LIB = ../build/lib/libucx$(LIB_EXT)
+UCX_LIB = ../build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)ucx$(LIB_EXT)
+UCX_SHLIB = ../build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)ucx$(SHLIB_EXT)
-all: ../build/ucx $(UCX_LIB)
+all: $(UCX_LIB) $(UCX_SHLIB)
$(UCX_LIB): $(OBJ)
- $(AR) $(ARFLAGS) $(UCX_LIB) $(OBJ)
+ $(AR) $(ARFLAGS) $@ $(OBJ)
+
+$(UCX_SHLIB): $(OBJ)
+ $(CC) -o $@ $(LDFLAGS) $(SHLIB_LDFLAGS) $(OBJ)
../build/ucx:
mkdir -p ../build/ucx
../build/ucx/%$(OBJ_EXT): %.c
- $(CC) $(CFLAGS) -o $@ -c $<
+ $(CC) $(CFLAGS) $(SHLIB_CFLAGS) -o $@ -c $<
#include "cx/allocator.h"
#include <errno.h>
+#include <string.h>
static void *cx_malloc_stdlib(
cx_attr_unused void *d,
free(mem);
}
-static cx_allocator_class cx_default_allocator_class = {
+static cx_allocator_class cx_stdlib_allocator_class = {
cx_malloc_stdlib,
cx_realloc_stdlib,
cx_calloc_stdlib,
cx_free_stdlib
};
-struct cx_allocator_s cx_default_allocator = {
- &cx_default_allocator_class,
+struct cx_allocator_s cx_stdlib_allocator = {
+ &cx_stdlib_allocator_class,
NULL
};
-const CxAllocator * const cxDefaultAllocator = &cx_default_allocator;
+const CxAllocator * const cxStdlibAllocator = &cx_stdlib_allocator;
+const CxAllocator * cxDefaultAllocator = cxStdlibAllocator;
int cx_reallocate_(
void **mem,
return allocator->cl->malloc(allocator->data, n);
}
+void *cxZalloc(
+ const CxAllocator *allocator,
+ size_t n
+) {
+ void *mem = allocator->cl->malloc(allocator->data, n);
+ if (mem != NULL) {
+ memset(mem, 0, n);
+ }
+ return mem;
+}
+
void *cxRealloc(
const CxAllocator *allocator,
void *mem,
static void *cx_array_default_realloc(
void *array,
- size_t capacity,
+ cx_attr_unused size_t old_capacity,
+ size_t new_capacity,
size_t elem_size,
cx_attr_unused CxArrayReallocator *alloc
) {
size_t n;
- if (cx_szmul(capacity, elem_size, &n)) {
+ if (cx_szmul(new_capacity, elem_size, &n)) {
errno = EOVERFLOW;
return NULL;
}
- return realloc(array, n);
+ return cxReallocDefault(array, n);
}
CxArrayReallocator cx_array_default_reallocator_impl = {
static void *cx_array_advanced_realloc(
void *array,
- size_t capacity,
+ size_t old_capacity,
+ size_t new_capacity,
size_t elem_size,
cx_attr_unused CxArrayReallocator *alloc
) {
// check for overflow
size_t n;
- if (cx_szmul(capacity, elem_size, &n)) {
+ if (cx_szmul(new_capacity, elem_size, &n)) {
errno = EOVERFLOW;
return NULL;
}
if (array == alloc->ptr2) {
newmem = cxMalloc(al, n);
if (newmem != NULL && array != NULL) {
- memcpy(newmem, array, n);
+ memcpy(newmem, array, old_capacity*elem_size);
}
} else {
newmem = cxRealloc(al, array, n);
// perform reallocation
void *newmem = reallocator->realloc(
- *array, newcap, elem_size, reallocator
+ *array, oldcap, newcap, elem_size, reallocator
);
if (newmem == NULL) {
return 1; // LCOV_EXCL_LINE
// perform reallocation
void *newmem = reallocator->realloc(
- *target, newcap, elem_size, reallocator
+ *target, oldcap, newcap, elem_size, reallocator
);
if (newmem == NULL) {
return 1;
// store some counts
size_t old_size = *size;
+ size_t old_capacity = *capacity;
size_t needed_capacity = old_size + elem_count;
// if we need more than we have, try a reallocation
- if (needed_capacity > *capacity) {
+ if (needed_capacity > old_capacity) {
size_t new_capacity = cx_array_align_capacity(needed_capacity, 16, SIZE_MAX);
void *new_mem = reallocator->realloc(
- *target, new_capacity, elem_size, reallocator
+ *target, old_capacity, new_capacity, elem_size, reallocator
);
if (new_mem == NULL) {
// give it up right away, there is no contract
// decide if we can use the local buffer
if (elem_size > CX_ARRAY_SWAP_SBO_SIZE) {
- tmp = malloc(elem_size);
+ tmp = cxMallocDefault(elem_size);
// we don't want to enforce error handling
if (tmp == NULL) abort();
} else {
// free dynamic memory, if it was needed
if (tmp != sbo_mem) {
- free(tmp);
+ cxFreeDefault(tmp);
}
}
// get a correctly typed pointer to the list
cx_array_list *arl = (cx_array_list *) list;
- // do we need to move some elements?
- if (index < list->collection.size) {
- const char *first_to_move = (const char *) arl->data;
- first_to_move += index * list->collection.elem_size;
- size_t elems_to_move = list->collection.size - index;
- size_t start_of_moved = index + n;
-
- if (cx_array_copy(
- &arl->data,
- &list->collection.size,
- &arl->capacity,
- 0,
- start_of_moved,
- first_to_move,
- list->collection.elem_size,
- elems_to_move,
- &arl->reallocator
- )) {
- // if moving existing elems is unsuccessful, abort
+ // guarantee enough capacity
+ if (arl->capacity < list->collection.size + n) {
+ size_t new_capacity = list->collection.size + n;
+ new_capacity = new_capacity - (new_capacity % 16) + 16;
+ if (cxReallocateArray(
+ list->collection.allocator,
+ &arl->data, new_capacity,
+ list->collection.elem_size)
+ ) {
return 0;
}
+ arl->capacity = new_capacity;
}
- // note that if we had to move the elements, the following operation
- // is guaranteed to succeed, because we have the memory already allocated
- // therefore, it is impossible to leave this function with an invalid array
+ // determine insert position
+ char *arl_data = arl->data;
+ char *insert_pos = arl_data + index * list->collection.elem_size;
- // place the new elements
- if (cx_array_copy(
- &arl->data,
- &list->collection.size,
- &arl->capacity,
- 0,
- index,
- array,
- list->collection.elem_size,
- n,
- &arl->reallocator
- )) {
- // array list implementation is "all or nothing"
- return 0;
- } else {
- return n;
+ // do we need to move some elements?
+ if (index < list->collection.size) {
+ size_t elems_to_move = list->collection.size - index;
+ char *target = insert_pos + n * list->collection.elem_size;
+ memmove(target, insert_pos, elems_to_move * list->collection.elem_size);
}
+
+ // place the new elements, if any
+ if (array != NULL) {
+ memcpy(insert_pos, array, n * list->collection.elem_size);
+ }
+ list->collection.size += n;
+
+ return n;
}
static size_t cx_arl_insert_sorted(
}
}
-static int cx_arl_insert_element(
+static void *cx_arl_insert_element(
struct cx_list_s *list,
size_t index,
const void *element
) {
- return 1 != cx_arl_insert_array(list, index, element, 1);
+ if (cx_arl_insert_array(list, index, element, 1) == 1) {
+ return ((char*)((cx_array_list *) list)->data) + index * list->collection.elem_size;
+ } else {
+ return NULL;
+ }
}
static int cx_arl_insert_iter(
) {
struct cx_list_s *list = iter->src_handle.m;
if (iter->index < list->collection.size) {
- int result = cx_arl_insert_element(
- list,
- iter->index + 1 - prepend,
- elem
- );
- if (result == 0) {
- iter->elem_count++;
- if (prepend != 0) {
- iter->index++;
- iter->elem_handle = ((char *) iter->elem_handle) + list->collection.elem_size;
- }
+ if (cx_arl_insert_element(list,
+ iter->index + 1 - prepend, elem) == NULL) {
+ return 1;
+ }
+ iter->elem_count++;
+ if (prepend != 0) {
+ iter->index++;
+ iter->elem_handle = ((char *) iter->elem_handle) + list->collection.elem_size;
}
- return result;
+ return 0;
} else {
- int result = cx_arl_insert_element(list, list->collection.size, elem);
- if (result == 0) {
- iter->elem_count++;
- iter->index = list->collection.size;
+ if (cx_arl_insert_element(list, list->collection.size, elem) == NULL) {
+ return 1;
}
- return result;
+ iter->elem_count++;
+ iter->index = list->collection.size;
+ return 0;
}
}
#include <string.h>
#include <errno.h>
+#ifdef _WIN32
+#include <Windows.h>
+#include <sysinfoapi.h>
+static unsigned long system_page_size() {
+ static unsigned long ps = 0;
+ if (ps == 0) {
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ ps = sysinfo.dwPageSize;
+ }
+ return ps;
+}
+#define SYSTEM_PAGE_SIZE system_page_size()
+#else
+#include <unistd.h>
+#define SYSTEM_PAGE_SIZE sysconf(_SC_PAGESIZE)
+#endif
+
static int buffer_copy_on_write(CxBuffer* buffer) {
if (0 == (buffer->flags & CX_BUFFER_COPY_ON_WRITE)) return 0;
void *newspace = cxMalloc(buffer->allocator, buffer->capacity);
CxBuffer *buffer,
CxBufferFlushConfig config
) {
- buffer->flush = malloc(sizeof(CxBufferFlushConfig));
+ buffer->flush = cxMallocDefault(sizeof(CxBufferFlushConfig));
if (buffer->flush == NULL) return -1; // LCOV_EXCL_LINE
memcpy(buffer->flush, &config, sizeof(CxBufferFlushConfig));
return 0;
if (buffer->flags & CX_BUFFER_FREE_CONTENTS) {
cxFree(buffer->allocator, buffer->bytes);
}
- free(buffer->flush);
+ cxFreeDefault(buffer->flush);
memset(buffer, 0, sizeof(CxBuffer));
}
npos = 0;
break;
default:
+ errno = EINVAL;
return -1;
}
npos += offset;
if ((offset > 0 && npos < opos) || (offset < 0 && npos > opos)) {
- errno = EOVERFLOW;
+ // to be compliant with fseek() specification
+ // we return EINVAL on underflow
+ errno = EINVAL;
return -1;
}
if (npos > buffer->size) {
+ // not compliant with fseek() specification
+ // but this is the better behavior for CxBuffer
+ errno = EINVAL;
return -1;
} else {
buffer->pos = npos;
return 0;
}
+ unsigned long pagesize = SYSTEM_PAGE_SIZE;
+ // if page size is larger than 64 KB - for some reason - truncate to 64 KB
+ if (pagesize > 65536) pagesize = 65536;
+ if (newcap < pagesize) {
+ // when smaller as one page, map to the next power of two
+ newcap--;
+ newcap |= newcap >> 1;
+ newcap |= newcap >> 2;
+ newcap |= newcap >> 4;
+ // last operation only needed for pages larger 4096 bytes
+ // but if/else would be more expensive than just doing this
+ newcap |= newcap >> 8;
+ newcap++;
+ } else {
+ // otherwise, map to a multiple of the page size
+ newcap -= newcap % pagesize;
+ newcap += pagesize;
+ // note: if newcap is already page aligned,
+ // this gives a full additional page (which is good)
+ }
+
+
const int force_copy_flags = CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_COPY_ON_EXTEND;
if (buffer->flags & force_copy_flags) {
void *newspace = cxMalloc(buffer->allocator, newcap);
}
}
+void cxBufferShrink(
+ CxBuffer *buffer,
+ size_t reserve
+) {
+ // Ensure buffer is in a reallocatable state
+ const int force_copy_flags = CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_COPY_ON_EXTEND;
+ if (buffer->flags & force_copy_flags) {
+ // do nothing when we are not allowed to reallocate
+ return;
+ }
+
+ // calculate new capacity
+ size_t newCapacity = buffer->size + reserve;
+
+ // If new capacity is smaller than current capacity, resize the buffer
+ if (newCapacity < buffer->capacity) {
+ if (0 == cxReallocate(buffer->allocator, &buffer->bytes, newCapacity)) {
+ buffer->capacity = newCapacity;
+ }
+ }
+}
+
static size_t cx_buffer_flush_helper(
const CxBuffer *buffer,
const unsigned char *src,
}
int cxBufferTerminate(CxBuffer *buffer) {
- bool success = 0 == cxBufferPut(buffer, 0);
- if (success) {
- buffer->pos--;
- buffer->size--;
+ if (0 == cxBufferPut(buffer, 0)) {
+ buffer->size = buffer->pos - 1;
return 0;
} else {
return -1;
typedef struct cx_allocator_s CxAllocator;
/**
- * A default allocator using standard library malloc() etc.
+ * A pre-defined allocator using standard library malloc() etc.
*/
cx_attr_export
-extern const CxAllocator * const cxDefaultAllocator;
+extern const CxAllocator * const cxStdlibAllocator;
+
+/**
+ * The default allocator that is used by UCX.
+ * Initialized with cxStdlibAllocator, but you may change it.
+ */
+cx_attr_export
+extern const CxAllocator * cxDefaultAllocator;
/**
* Function pointer type for destructor functions.
* Reallocate a previously allocated block and changes the pointer in-place,
* if necessary.
*
+ * @note This will use stdlib reallocate and @em not the cxDefaultAllocator.
+ *
* @par Error handling
* @c errno will be set by realloc() on failure.
*
*
* The size is calculated by multiplying @p nemb and @p size.
*
+ * @note This will use stdlib reallocate and @em not the cxDefaultAllocator.
+ *
* @par Error handling
* @c errno will be set by realloc() on failure or when the multiplication of
* @p nmemb and @p size overflows.
* Reallocate a previously allocated block and changes the pointer in-place,
* if necessary.
*
+ * @note This will use stdlib reallocate and @em not the cxDefaultAllocator.
+ *
* @par Error handling
* @c errno will be set by realloc() on failure.
*
*
* The size is calculated by multiplying @p nemb and @p size.
*
+ * @note This will use stdlib reallocate and @em not the cxDefaultAllocator.
+ *
* @par Error handling
* @c errno will be set by realloc() on failure or when the multiplication of
* @p nmemb and @p size overflows.
#define cx_reallocatearray(mem, nmemb, size) \
cx_reallocatearray_((void**)(mem), nmemb, size)
+/**
+ * Allocates memory and sets every byte to zero.
+ *
+ * @param n (@c size_t) the number of bytes
+ * @return (@c void*) a pointer to the allocated memory
+ */
+#define cx_zalloc(n) calloc(1, n)
+
/**
* Free a block allocated by this allocator.
*
size_t size
);
+/**
+ * Allocate @p n bytes of memory and sets every byte to zero.
+ *
+ * @param allocator the allocator
+ * @param n the number of bytes
+ * @return a pointer to the allocated memory
+ */
+cx_attr_nodiscard
+cx_attr_nonnull
+cx_attr_malloc
+cx_attr_dealloc_ucx
+cx_attr_allocsize(2)
+cx_attr_export
+void *cxZalloc(
+ const CxAllocator *allocator,
+ size_t n
+);
+
+/**
+ * Convenience macro that invokes cxMalloc() with the cxDefaultAllocator.
+ */
+#define cxMallocDefault(...) cxMalloc(cxDefaultAllocator, __VA_ARGS__)
+/**
+ * Convenience macro that invokes cxZalloc() with the cxDefaultAllocator.
+ */
+#define cxZallocDefault(...) cxZalloc(cxDefaultAllocator, __VA_ARGS__)
+/**
+ * Convenience macro that invokes cxCalloc() with the cxDefaultAllocator.
+ */
+#define cxCallocDefault(...) cxCalloc(cxDefaultAllocator, __VA_ARGS__)
+/**
+ * Convenience macro that invokes cxRealloc() with the cxDefaultAllocator.
+ */
+#define cxReallocDefault(...) cxRealloc(cxDefaultAllocator, __VA_ARGS__)
+/**
+ * Convenience macro that invokes cxReallocate() with the cxDefaultAllocator.
+ */
+#define cxReallocateDefault(...) cxReallocate(cxDefaultAllocator, __VA_ARGS__)
+/**
+ * Convenience macro that invokes cxReallocateArray() with the cxDefaultAllocator.
+ */
+#define cxReallocateArrayDefault(...) cxReallocateArray(cxDefaultAllocator, __VA_ARGS__)
+/**
+ * Convenience macro that invokes cxReallocArray() with the cxDefaultAllocator.
+ */
+#define cxReallocArrayDefault(...) cxReallocArray(cxDefaultAllocator, __VA_ARGS__)
+/**
+ * Convenience macro that invokes cxFree() with the cxDefaultAllocator.
+ */
+#define cxFreeDefault(...) cxFree(cxDefaultAllocator, __VA_ARGS__)
+
#ifdef __cplusplus
} // extern "C"
#endif
* @endcode
*
*
- * The memory for the array is allocated with stdlib malloc().
+ * The memory for the array is allocated with the cxDefaultAllocator.
+ *
* @param array the name of the array
* @param capacity the initial capacity
* @see cx_array_initialize_a()
#define cx_array_initialize(array, capacity) \
array##_capacity = capacity; \
array##_size = 0; \
- array = malloc(sizeof(array[0]) * capacity)
+ array = cxMallocDefault(sizeof(array[0]) * capacity)
/**
* Initializes an array with the given capacity using the specified allocator.
* cxFree(al, myarray); // don't forget to free with same allocator
* @endcode
*
- * The memory for the array is allocated with stdlib malloc().
* @param allocator (@c CxAllocator*) the allocator
* @param array the name of the array
* @param capacity the initial capacity
* or to transport other additional data.
*
* @param array the array to reallocate
- * @param capacity the new capacity (number of elements)
+ * @param old_capacity the old number of elements
+ * @param new_capacity the new number of elements
* @param elem_size the size of each element
* @param alloc a reference to this allocator
* @return a pointer to the reallocated memory or @c NULL on failure
*/
cx_attr_nodiscard
- cx_attr_nonnull_arg(4)
- cx_attr_allocsize(2, 3)
+ cx_attr_nonnull_arg(5)
+ cx_attr_allocsize(3, 4)
void *(*realloc)(
void *array,
- size_t capacity,
+ size_t old_capacity,
+ size_t new_capacity,
size_t elem_size,
struct cx_array_reallocator_s *alloc
);
typedef struct cx_array_reallocator_s CxArrayReallocator;
/**
- * A default stdlib-based array reallocator.
+ * A default array reallocator that is based on the cxDefaultAllocator.
*/
cx_attr_export
extern CxArrayReallocator *cx_array_default_reallocator;
/**
* Creates a new array reallocator.
*
- * When @p allocator is @c NULL, the stdlib default allocator will be used.
+ * When @p allocator is @c NULL, the cxDefaultAllocator will be used.
*
* When @p stackmem is not @c NULL, the reallocator is supposed to be used
* @em only for the specific array that is initially located at @p stackmem.
* to cx_cmp_ptr(), if none is given.
*
* @param allocator the allocator for allocating the list memory
- * (if @c NULL, a default stdlib allocator will be used)
+ * (if @c NULL, the cxDefaultAllocator will be used)
* @param comparator the comparator for the elements
* (if @c NULL, and the list is not storing pointers, sort and find
* functions will not work)
*
* If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of
* copies of the added elements and the compare function will be automatically set
- * to cx_cmp_ptr(), if none is given.
+ * to cx_cmp_ptr().
*
* @param elem_size (@c size_t) the size of each element in bytes
* @param initial_capacity (@c size_t) the initial number of elements the array can store
* @param capacity the capacity of the buffer
* @param allocator the allocator this buffer shall use for automatic
* memory management
- * (if @c NULL, a default stdlib allocator will be used)
+ * (if @c NULL, the cxDefaultAllocator will be used)
* @param flags buffer features (see cx_buffer_s.flags)
* @return zero on success, non-zero if a required allocation failed
*/
* @param capacity the capacity of the buffer
* @param allocator the allocator to use for allocating the structure and the automatic
* memory management within the buffer
- * (if @c NULL, a default stdlib allocator will be used)
+ * (if @c NULL, the cxDefaultAllocator will be used)
* @param flags buffer features (see cx_buffer_s.flags)
* @return a pointer to the buffer on success, @c NULL if a required allocation failed
*/
*
* If the current capacity is not sufficient, the buffer will be extended.
*
+ * The new capacity will be a power of two until the system's page size is reached.
+ * Then, the new capacity will be a multiple of the page size.
+ *
* @param buffer the buffer
* @param capacity the minimum required capacity for this buffer
* @retval zero the capacity was already sufficient or successfully increased
* @retval non-zero on allocation failure
+ * @see cxBufferShrink()
*/
cx_attr_nonnull
cx_attr_export
size_t capacity
);
+/**
+ * Shrinks the capacity of the buffer to fit its current size.
+ *
+ * If @p reserve is larger than zero, the buffer is shrunk to its size plus
+ * the number of reserved bytes.
+ *
+ * If the current capacity is not larger than the size plus the reserved bytes,
+ * nothing happens.
+ *
+ * If the #CX_BUFFER_COPY_ON_WRITE or #CX_BUFFER_COPY_ON_EXTEND flag is set,
+ * this function does nothing.
+ *
+ * @param buffer the buffer
+ * @param reserve the number of bytes that shall remain reserved
+ * @see cxBufferMinimumCapacity()
+ */
+cx_attr_nonnull
+cx_attr_export
+void cxBufferShrink(
+ CxBuffer *buffer,
+ size_t reserve
+);
+
/**
* Writes data to a CxBuffer.
*
/**
* Writes a terminating zero to a buffer at the current position.
*
- * On successful write, @em neither the position @em nor the size of the buffer is
- * increased.
+ * If successful, sets the size to the current position and advances the position by one.
*
* The purpose of this function is to have the written data ready to be used as
- * a C string.
+ * a C string with the buffer's size being the length of that string.
*
* @param buffer the buffer to write to
* @return zero, if the terminator could be written, non-zero otherwise
* Repositories:<br>
* <a href="https://sourceforge.net/p/ucx/code">https://sourceforge.net/p/ucx/code</a>
* - or -
- * <a href="https://develop.uap-core.de/hg/ucx">https://develop.uap-core.de/hg/ucx</a>
+ * <a href="https://uap-core.de/hg/ucx">https://uap-core.de/hg/ucx</a>
* </p>
*
* <h2>LICENCE</h2>
*/
#define cx_attr_malloc __attribute__((__malloc__))
-#ifndef __clang__
+#if !defined(__clang__) && __GNUC__ >= 11
/**
* The pointer returned by the attributed function is supposed to be freed
* by @p freefunc.
*/
#define cx_attr_access_w(...) cx_attr_access(__write_only__, __VA_ARGS__)
-#if __STDC_VERSION__ >= 202300L
-
-/**
- * Do not warn about unused variable.
- */
-#define cx_attr_unused [[maybe_unused]]
-
-/**
- * Warn about discarded return value.
- */
-#define cx_attr_nodiscard [[nodiscard]]
-
-#else // no C23
-
/**
* Do not warn about unused variable.
*/
*/
#define cx_attr_nodiscard __attribute__((__warn_unused_result__))
-#endif // __STDC_VERSION__
-
// ---------------------------------------------------------------------------
// MSVC specifics
* In other words, when the iterator is finished, @c index==size .
*
* @param allocator the allocator to use
- * (if @c NULL, a default stdlib allocator will be used)
+ * (if @c NULL, the cxDefaultAllocator will be used)
* @param itemsize the size of one element
* @param buckets the initial number of buckets in this hash map
* @return a pointer to the new hash map
* to cx_cmp_ptr(), if none is given.
*
* @param allocator the allocator for allocating the list nodes
- * (if @c NULL, a default stdlib allocator will be used)
+ * (if @c NULL, the cxDefaultAllocator will be used)
* @param comparator the comparator for the elements
* (if @c NULL, and the list is not storing pointers, sort and find
* functions will not work)
*
* If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of
* copies of the added elements and the compare function will be automatically set
- * to cx_cmp_ptr(), if none is given.
+ * to cx_cmp_ptr().
*
* @param elem_size (@c size_t) the size of each element in bytes
* @return (@c CxList*) the created list
* @li @p loc_next and @p loc_prev (ancestor node is determined by using the prev pointer, overall O(1) performance)
* @li @p loc_next and @p begin (ancestor node is determined by list traversal, overall O(n) performance)
*
- * @remark The @c next and @c prev pointers of the removed node are not cleared by this function and may still be used
+ * @remark The @c next and @c prev pointers of the removed chain are not cleared by this function and may still be used
* to traverse to a former adjacent node in the list, or within the chain.
*
* @param begin a pointer to the beginning node pointer (optional)
/**
* Member function for inserting a single element.
+ * The data pointer may be @c NULL in which case the function shall only allocate memory.
+ * Returns a pointer to the data of the inserted element.
*/
- int (*insert_element)(
+ void *(*insert_element)(
struct cx_list_s *list,
size_t index,
const void *data
);
};
+/**
+ * Common type for all list implementations.
+ */
+typedef struct cx_list_s CxList;
+
+/**
+ * A shared instance of an empty list.
+ *
+ * Writing to that list is not allowed.
+ *
+ * You can use this is a placeholder for initializing CxList pointers
+ * for which you do not want to reserve memory right from the beginning.
+ */
+cx_attr_export
+extern CxList *const cxEmptyList;
+
/**
* Default implementation of an array insert.
*
size_t elem_size
);
-/**
- * Common type for all list implementations.
- */
-typedef struct cx_list_s CxList;
-
/**
* Returns the number of elements currently stored in the list.
*
* @retval zero success
* @retval non-zero memory allocation failure
* @see cxListAddArray()
+ * @see cxListEmplace()
*/
cx_attr_nonnull
static inline int cxListAdd(
const void *elem
) {
list->collection.sorted = false;
- return list->cl->insert_element(list, list->collection.size, elem);
+ return list->cl->insert_element(list, list->collection.size, elem) == NULL;
}
/**
* @retval non-zero memory allocation failure or the index is out of bounds
* @see cxListInsertAfter()
* @see cxListInsertBefore()
+ * @see cxListEmplaceAt()
*/
cx_attr_nonnull
static inline int cxListInsert(
const void *elem
) {
list->collection.sorted = false;
- return list->cl->insert_element(list, index, elem);
+ return list->cl->insert_element(list, index, elem) == NULL;
+}
+
+/**
+ * Allocates memory for an element at the specified index and returns a pointer to that memory.
+ *
+ * @remark When the list is storing pointers, this will return a @c void**.
+ *
+ * @param list the list
+ * @param index the index where to emplace the element
+ * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds
+ * @see cxListEmplace()
+ * @see cxListInsert()
+ */
+cx_attr_nonnull
+static inline void *cxListEmplaceAt(CxList *list, size_t index) {
+ list->collection.sorted = false;
+ return list->cl->insert_element(list, index, NULL);
+}
+
+
+/**
+ * Allocates memory for an element at the end of the list and returns a pointer to that memory.
+ *
+ * @remark When the list is storing pointers, this will return a @c void**.
+ *
+ * @param list the list
+ * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds
+ * @see cxListEmplaceAt()
+ * @see cxListAdd()
+ */
+cx_attr_nonnull
+static inline void *cxListEmplace(CxList *list) {
+ list->collection.sorted = false;
+ return list->cl->insert_element(list, list->collection.size, NULL);
}
/**
/**
* Removes and returns the element at the specified index.
*
- * No destructor is called and instead the element is copied to the
+ * No destructor is called, and instead the element is copied to the
* @p targetbuf which MUST be large enough to hold the removed element.
+ * If the list is storing pointers, only the pointer is copied to @p targetbuf.
*
* @param list the list
* @param index the index of the element
return list->cl->remove(list, index, 1, targetbuf) == 0;
}
+/**
+ * Removes and returns the first element of the list.
+ *
+ * No destructor is called, and instead the element is copied to the
+ * @p targetbuf which MUST be large enough to hold the removed element.
+ * If the list is storing pointers, only the pointer is copied to @p targetbuf.
+ *
+ * @param list the list
+ * @param targetbuf a buffer where to copy the element
+ * @retval zero success
+ * @retval non-zero list is empty
+ * @see cxListPopFront()
+ * @see cxListRemoveAndGetLast()
+ */
+cx_attr_nonnull
+cx_attr_access_w(2)
+static inline int cxListRemoveAndGetFirst(
+ CxList *list,
+ void *targetbuf
+) {
+ return list->cl->remove(list, 0, 1, targetbuf) == 0;
+}
+
+/**
+ * Removes and returns the first element of the list.
+ *
+ * Alias for cxListRemoveAndGetFirst().
+ *
+ * No destructor is called, and instead the element is copied to the
+ * @p targetbuf which MUST be large enough to hold the removed element.
+ * If the list is storing pointers, only the pointer is copied to @p targetbuf.
+ *
+ * @param list (@c CxList*) the list
+ * @param targetbuf (@c void*) a buffer where to copy the element
+ * @retval zero success
+ * @retval non-zero list is empty
+ * @see cxListRemoveAndGetFirst()
+ * @see cxListPop()
+ */
+#define cxListPopFront(list, targetbuf) cxListRemoveAndGetFirst((list), (targetbuf))
+
+
+/**
+ * Removes and returns the last element of the list.
+ *
+ * No destructor is called, and instead the element is copied to the
+ * @p targetbuf which MUST be large enough to hold the removed element.
+ * If the list is storing pointers, only the pointer is copied to @p targetbuf.
+ *
+ * @param list the list
+ * @param targetbuf a buffer where to copy the element
+ * @retval zero success
+ * @retval non-zero list is empty
+ */
+cx_attr_nonnull
+cx_attr_access_w(2)
+static inline int cxListRemoveAndGetLast(
+ CxList *list,
+ void *targetbuf
+) {
+ // note: index may wrap - member function will catch that
+ return list->cl->remove(list, list->collection.size - 1, 1, targetbuf) == 0;
+}
+
+/**
+ * Removes and returns the last element of the list.
+ *
+ * Alias for cxListRemoveAndGetLast().
+ *
+ * No destructor is called, and instead the element is copied to the
+ * @p targetbuf which MUST be large enough to hold the removed element.
+ * If the list is storing pointers, only the pointer is copied to @p targetbuf.
+ *
+ * @param list (@c CxList*) the list
+ * @param targetbuf (@c void*) a buffer where to copy the element
+ * @retval zero success
+ * @retval non-zero list is empty
+ * @see cxListRemoveAndGetLast()
+ * @see cxListPopFront()
+ */
+#define cxListPop(list, targetbuf) cxListRemoveAndGetLast((list), (targetbuf))
+
/**
* Removes multiple element starting at the specified index.
*
* If an element destructor function is specified, it is called for each
* element. It is guaranteed that the destructor is called before removing
- * the element, however, due to possible optimizations it is neither guaranteed
+ * the element. However, due to possible optimizations, it is neither guaranteed
* that the destructors are invoked for all elements before starting to remove
* them, nor that the element is removed immediately after the destructor call
* before proceeding to the next element.
}
/**
- * Removes and returns multiple element starting at the specified index.
+ * Removes and returns multiple elements starting at the specified index.
*
- * No destructor is called and instead the elements are copied to the
+ * No destructor is called, and instead the elements are copied to the
* @p targetbuf which MUST be large enough to hold all removed elements.
+ * If the list is storing pointers, @p targetbuf is expected to be an array of pointers.
*
* @param list the list
* @param index the index of the element
/**
* Swaps two items in the list.
*
- * Implementations should only allocate temporary memory for the swap, if
+ * Implementations should only allocate temporary memory for the swap if
* it is necessary.
*
* @param list the list
* @param i the index of the first element
* @param j the index of the second element
* @retval zero success
- * @retval non-zero one of the indices is out of bounds
- * or the swap needed extra memory but allocation failed
+ * @retval non-zero one of the indices is out of bounds,
+ * or the swap needed extra memory, but allocation failed
*/
cx_attr_nonnull
static inline int cxListSwap(
/**
* Returns a pointer to the element at the specified index.
*
+ * If the list is storing pointers, returns the pointer stored at the specified index.
+ *
* @param list the list
* @param index the index of the element
* @return a pointer to the element or @c NULL if the index is out of bounds
return list->cl->at(list, index);
}
+/**
+ * Returns a pointer to the first element.
+ *
+ * If the list is storing pointers, returns the first pointer stored in the list.
+ *
+ * @param list the list
+ * @return a pointer to the first element or @c NULL if the list is empty
+ */
+cx_attr_nonnull
+static inline void *cxListFirst(const CxList *list) {
+ return list->cl->at(list, 0);
+}
+
+/**
+ * Returns a pointer to the last element.
+ *
+ * If the list is storing pointers, returns the last pointer stored in the list.
+ *
+ * @param list the list
+ * @return a pointer to the last element or @c NULL if the list is empty
+ */
+cx_attr_nonnull
+static inline void *cxListLast(const CxList *list) {
+ return list->cl->at(list, list->collection.size - 1);
+}
+
+/**
+ * Sets the element at the specified index in the list
+ *
+ * @param list the list to set the element in
+ * @param index the index to set the element at
+ * @param elem element to set
+ * @retval zero on success
+ * @retval non-zero when index is out of bounds
+ */
+cx_attr_nonnull
+cx_attr_export
+int cxListSet(
+ CxList *list,
+ size_t index,
+ const void *elem
+);
+
/**
* Returns an iterator pointing to the item at the specified index.
*
*
* The returned iterator is position-aware.
*
- * If the list is empty, a past-the-end iterator will be returned.
+ * If the list is empty or @c NULL, a past-the-end iterator will be returned.
*
* @param list the list
* @return a new iterator
*/
-cx_attr_nonnull
cx_attr_nodiscard
static inline CxIterator cxListIterator(const CxList *list) {
+ if (list == NULL) list = cxEmptyList;
return list->cl->iterator(list, 0, false);
}
*
* The returned iterator is position-aware.
*
- * If the list is empty, a past-the-end iterator will be returned.
+ * If the list is empty or @c NULL, a past-the-end iterator will be returned.
*
* @param list the list
* @return a new iterator
*/
-cx_attr_nonnull
cx_attr_nodiscard
static inline CxIterator cxListMutIterator(CxList *list) {
+ if (list == NULL) list = cxEmptyList;
return cxListMutIteratorAt(list, 0);
}
*
* The returned iterator is position-aware.
*
- * If the list is empty, a past-the-end iterator will be returned.
+ * If the list is empty or @c NULL, a past-the-end iterator will be returned.
*
* @param list the list
* @return a new iterator
*/
-cx_attr_nonnull
cx_attr_nodiscard
static inline CxIterator cxListBackwardsIterator(const CxList *list) {
+ if (list == NULL) list = cxEmptyList;
return list->cl->iterator(list, list->collection.size - 1, true);
}
*
* The returned iterator is position-aware.
*
- * If the list is empty, a past-the-end iterator will be returned.
+ * If the list is empty or @c NULL, a past-the-end iterator will be returned.
*
* @param list the list
* @return a new iterator
*/
-cx_attr_nonnull
cx_attr_nodiscard
static inline CxIterator cxListMutBackwardsIterator(CxList *list) {
+ if (list == NULL) list = cxEmptyList;
return cxListMutBackwardsIteratorAt(list, list->collection.size - 1);
}
* @param elem the element to find
* @return the index of the element or the size of the list when the element is not found
* @see cxListIndexValid()
+ * @see cxListContains()
*/
cx_attr_nonnull
cx_attr_nodiscard
return list->cl->find_remove((CxList*)list, elem, false);
}
+/**
+ * Checks, if the list contains the specified element.
+ *
+ * The elements are compared with the list's comparator function.
+ *
+ * @param list the list
+ * @param elem the element to find
+ * @retval true if the element is contained
+ * @retval false if the element is not contained
+ * @see cxListFind()
+ */
+cx_attr_nonnull
+cx_attr_nodiscard
+static inline bool cxListContains(
+ const CxList* list,
+ const void* elem
+) {
+ return list->cl->find_remove((CxList*)list, elem, false) < list->collection.size;
+}
+
/**
* Checks if the specified index is within bounds.
*
*/
cx_attr_nonnull
static inline void cxListSort(CxList *list) {
+ if (list->collection.sorted) return;
list->cl->sort(list);
list->collection.sorted = true;
}
cx_attr_export
void cxListFree(CxList *list);
-/**
- * A shared instance of an empty list.
- *
- * Writing to that list is not allowed.
- *
- * You can use this is a placeholder for initializing CxList pointers
- * for which you do not want to reserve memory right from the beginning.
- */
-cx_attr_export
-extern CxList *const cxEmptyList;
-
#ifdef __cplusplus
} // extern "C"
extern "C" {
#endif
-/** Internal structure for pooled memory. */
-struct cx_mempool_memory_s;
+/** A memory block in a simple memory pool. */
+struct cx_mempool_memory_s {
+ /** The destructor. */
+ cx_destructor_func destructor;
+ /** The actual memory. */
+ char c[];
+};
+
+/** A memory block in an advanced memory pool. */
+struct cx_mempool_memory2_s {
+ /** The destructor. */
+ cx_destructor_func2 destructor;
+ /** Data for the destructor. */
+ void *data;
+ /** The actual memory. */
+ char c[];
+};
+
+/** Represents memory that is not allocated by, but registered with a pool. */
+struct cx_mempool_foreign_memory_s {
+ /** The foreign memory. */
+ void* mem;
+ union {
+ /** Simple destructor. */
+ cx_destructor_func destr;
+ /** Advanced destructor. */
+ cx_destructor_func2 destr2;
+ };
+ /** Data for the advanced destructor. */
+ void *destr2_data;
+};
+
+/** Specifies how individual blocks are allocated. */
+enum cx_mempool_type {
+ /**
+ * Allows registration of cx_destructor_func for each memory block.
+ */
+ CX_MEMPOOL_TYPE_SIMPLE,
+ /**
+ * Allows registration of cx_destructor_func2 for each memory block.
+ */
+ CX_MEMPOOL_TYPE_ADVANCED,
+ /**
+ * No individual destructor registration allowed.
+ *
+ * In this mode, no additional memory per block is allocated.
+ */
+ CX_MEMPOOL_TYPE_PURE,
+};
/**
* The basic structure of a memory pool.
* Should be the first member of an actual memory pool implementation.
*/
struct cx_mempool_s {
+ /** The used allocator, initialized with the cxDefaultAllocator. */
+ const CxAllocator * const base_allocator;
+
/** The provided allocator. */
const CxAllocator *allocator;
- /**
- * A destructor that shall be automatically registered for newly allocated memory.
- * This destructor MUST NOT free the memory.
- */
- cx_destructor_func auto_destr;
-
/** Array of pooled memory. */
- struct cx_mempool_memory_s **data;
+ void **data;
/** Number of pooled memory items. */
size_t size;
/** Memory pool capacity. */
size_t capacity;
+
+ /** Array of registered memory. */
+ struct cx_mempool_foreign_memory_s *registered;
+
+ /** Number of registered memory items. */
+ size_t registered_size;
+
+ /** Capacity for registered memory. */
+ size_t registered_capacity;
+
+ /**
+ * A destructor that shall be called before deallocating a memory block.
+ * This destructor MUST NOT free the memory itself.
+ *
+ * It is guaranteed that this destructor is called after the individual
+ * destructor of the memory block and before @c destr2.
+ */
+ cx_destructor_func destr;
+
+ /**
+ * A destructor that shall be called before deallocating a memory block.
+ * This destructor MUST NOT free the memory itself.
+ *
+ * It is guaranteed that this destructor is called after the individual
+ * destructor of the memory block and @c destr.
+ */
+ cx_destructor_func2 destr2;
+
+ /**
+ * Additional data for the @c destr2.
+ */
+ void *destr2_data;
};
/**
void cxMempoolFree(CxMempool *pool);
/**
- * Creates an array-based memory pool with a shared destructor function.
+ * Creates an array-based memory pool.
*
- * This destructor MUST NOT free the memory.
+ * The type determines how much additional memory is allocated per block
+ * to register a destructor function.
*
- * @param capacity the initial capacity of the pool
- * @param destr optional destructor function to use for allocated memory
+ * @param capacity the initial capacity of the pool (an implementation default if zero)
+ * @param type the type of memory pool
* @return the created memory pool or @c NULL if allocation failed
*/
cx_attr_nodiscard
cx_attr_malloc
cx_attr_dealloc(cxMempoolFree, 1)
cx_attr_export
-CxMempool *cxMempoolCreate(size_t capacity, cx_destructor_func destr);
+CxMempool *cxMempoolCreate(size_t capacity, enum cx_mempool_type type);
/**
* Creates a basic array-based memory pool.
*
+ * Convenience macro to create a memory pool of type #CX_MEMPOOL_TYPE_SIMPLE.
+ *
* @param capacity (@c size_t) the initial capacity of the pool
* @return (@c CxMempool*) the created memory pool or @c NULL if allocation failed
*/
-#define cxMempoolCreateSimple(capacity) cxMempoolCreate(capacity, NULL)
+#define cxMempoolCreateSimple(capacity) cxMempoolCreate(capacity, CX_MEMPOOL_TYPE_SIMPLE)
+
+/**
+ * Creates a basic array-based memory pool.
+ *
+ * Convenience macro to create a memory pool of type #CX_MEMPOOL_TYPE_ADVANCED.
+ *
+ * @param capacity (@c size_t) the initial capacity of the pool
+ * @return (@c CxMempool*) the created memory pool or @c NULL if allocation failed
+ */
+#define cxMempoolCreateAdvanced(capacity) cxMempoolCreate(capacity, CX_MEMPOOL_TYPE_ADVANCED)
+
+/**
+ * Creates a basic array-based memory pool.
+ *
+ * Convenience macro to create a memory pool of type #CX_MEMPOOL_TYPE_PURE.
+ *
+ * @param capacity (@c size_t) the initial capacity of the pool
+ * @return (@c CxMempool*) the created memory pool or @c NULL if allocation failed
+ */
+#define cxMempoolCreatePure(capacity) cxMempoolCreate(capacity, CX_MEMPOOL_TYPE_PURE)
+
+/**
+ * Sets the global destructor for all memory blocks within the specified pool.
+ *
+ * @param pool the memory pool
+ * @param fnc the destructor that shall be applied to all memory blocks
+ */
+cx_attr_nonnull_arg(1)
+cx_attr_export
+void cxMempoolGlobalDestructor(CxMempool *pool, cx_destructor_func fnc);
+
+/**
+ * Sets the global destructor for all memory blocks within the specified pool.
+ *
+ * @param pool the memory pool
+ * @param fnc the destructor that shall be applied to all memory blocks
+ * @param data additional data for the destructor function
+ */
+cx_attr_nonnull_arg(1)
+cx_attr_export
+void cxMempoolGlobalDestructor2(CxMempool *pool, cx_destructor_func2 fnc, void *data);
/**
* Sets the destructor function for a specific allocated memory object.
*
+ * If the type of memory pool is not #CX_MEMPOOL_TYPE_SIMPLE, the behavior is undefined.
* If the memory is not managed by a UCX memory pool, the behavior is undefined.
* The destructor MUST NOT free the memory.
*
);
/**
- * Removes the destructor function for a specific allocated memory object.
+ * Sets the destructor function for a specific allocated memory object.
*
+ * If the type of memory pool is not #CX_MEMPOOL_TYPE_ADVANCED, the behavior is undefined.
* If the memory is not managed by a UCX memory pool, the behavior is undefined.
* The destructor MUST NOT free the memory.
*
* @param memory the object allocated in the pool
+ * @param fnc the destructor function
+ * @param data additional data for the destructor function
+ */
+cx_attr_nonnull
+cx_attr_export
+void cxMempoolSetDestructor2(
+ void *memory,
+ cx_destructor_func2 fnc,
+ void *data
+);
+
+/**
+ * Removes the destructor function for a specific allocated memory object.
+ *
+ * If the type of memory pool is not #CX_MEMPOOL_TYPE_SIMPLE, the behavior is undefined.
+ * If the memory is not managed by a UCX memory pool, the behavior is undefined.
+ *
+ * @param memory the object allocated in the pool
*/
cx_attr_nonnull
cx_attr_export
void cxMempoolRemoveDestructor(void *memory);
+/**
+ * Removes the destructor function for a specific allocated memory object.
+ *
+ * If the type of memory pool is not #CX_MEMPOOL_TYPE_ADVANCED, the behavior is undefined.
+ * If the memory is not managed by a UCX memory pool, the behavior is undefined.
+ *
+ * @param memory the object allocated in the pool
+ */
+cx_attr_nonnull
+cx_attr_export
+void cxMempoolRemoveDestructor2(void *memory);
+
/**
* Registers foreign memory with this pool.
*
* The destructor, in contrast to memory allocated by the pool, MUST free the memory.
+ * This function can be used with any pool of any type, since destructors for registered memory
+ * are entirely independent of the pool's memory management.
*
- * A small portion of memory will be allocated to register the information in the pool.
- * If that allocation fails, this function will return non-zero.
+ * The destructor for the registered memory will be called after all pooled items have been freed.
*
* @param pool the pool
* @param memory the object to register (MUST NOT be already allocated in the pool)
cx_destructor_func destr
);
+
+/**
+ * Registers foreign memory with this pool.
+ *
+ * The destructor, in contrast to memory allocated by the pool, MUST free the memory.
+ * This function can be used with any pool of any type, since destructors for registered memory
+ * are entirely independent of the pool's memory management.
+ *
+ * The destructor for the registered memory will be called after all pooled items have been freed.
+ *
+ * @attention The data pointer MUST NOT be @c NULL.
+ * If you wish to register a destructor without additional data, use cxMempoolRegister().
+ *
+ * @param pool the pool
+ * @param memory the object to register (MUST NOT be already allocated in the pool)
+ * @param destr the destructor function
+ * @param data additional data for the destructor function
+ * @retval zero success
+ * @retval non-zero failure
+ */
+cx_attr_nonnull
+cx_attr_export
+int cxMempoolRegister2(
+ CxMempool *pool,
+ void *memory,
+ cx_destructor_func2 destr,
+ void *data
+);
+
+/**
+ * Transfers all the memory managed by one pool to another.
+ *
+ * The allocator of the source pool will also be transferred and registered with the destination pool
+ * and stays valid, as long as the destination pool is not destroyed.
+ *
+ * The source pool will get a completely new allocator and can be reused or destroyed afterward.
+ *
+ * This function fails when the destination pool has a different type than the source pool.
+ *
+ * @param source the pool to move the memory from
+ * @param dest the pool where to transfer the memory to
+ * @retval zero success
+ * @retval non-zero allocation failure or incompatible pools
+ */
+cx_attr_nonnull
+cx_attr_export
+int cxMempoolTransfer(
+ CxMempool *source,
+ CxMempool *dest
+);
+
+/**
+ * Transfers an object from one pool to another.
+ *
+ * This function fails when the destination pool has a different type than the source pool.
+ *
+ * @attention If the object maintains a reference to the pool's allocator,
+ * you must make sure to update that reference to the allocator of the destination pool.
+ *
+ * @param source the pool to move the memory from
+ * @param dest the pool where to transfer the memory to
+ * @param obj pointer to the object that shall be transferred
+ * @retval zero success
+ * @retval non-zero failure, or the object was not found in the source pool, or the pools are incompatible
+ */
+cx_attr_nonnull
+cx_attr_export
+int cxMempoolTransferObject(
+ CxMempool *source,
+ CxMempool *dest,
+ const void *obj
+);
+
#ifdef __cplusplus
} // extern "C"
#endif
cx_attr_cstr_arg(4)
cx_attr_export
int cx_sprintf_a(
- CxAllocator *alloc,
+ const CxAllocator *alloc,
char **str,
size_t *len,
const char *fmt,
cx_attr_access_rw(3)
cx_attr_export
int cx_vsprintf_a(
- CxAllocator *alloc,
+ const CxAllocator *alloc,
char **str,
size_t *len,
const char *fmt,
cx_attr_access_rw(4)
cx_attr_export
int cx_sprintf_sa(
- CxAllocator *alloc,
+ const CxAllocator *alloc,
char *buf,
size_t *len,
char **str,
cx_attr_cstr_arg(5)
cx_attr_export
int cx_vsprintf_sa(
- CxAllocator *alloc,
+ const CxAllocator *alloc,
char *buf,
size_t *len,
char **str,
/**
* Creates a properties sink for an UCX map.
*
- * The values stored in the map will be pointers to strings allocated
- * by #cx_strdup_a().
- * The default stdlib allocator will be used, unless you specify a custom
- * allocator in the optional @c data of the sink.
+ * The values stored in the map will be pointers to freshly allocated,
+ * zero-terminated C strings (@c char*), which means the @p map should have been
+ * created with #CX_STORE_POINTERS.
+ *
+ * The cxDefaultAllocator will be used unless you specify a custom
+ * allocator in the optional @c data field of the returned sink.
*
* @param map the map that shall consume the k/v-pairs.
* @return the sink
#include "common.h"
#include "allocator.h"
+/** Expands a UCX string as printf arguments. */
+#define CX_SFMT(s) (int) (s).length, (s).ptr
+
+/** Format specifier for a UCX string */
+#define CX_PRIstr ".*s"
+
/**
* The maximum length of the "needle" in cx_strstr() that can use SBO.
*/
*
* @param literal the string literal
*/
-#define CX_STR(literal) (cxstring){literal, sizeof(literal) - 1}
+#define CX_STR(literal) ((cxstring){literal, sizeof(literal) - 1})
#endif
static inline cxstring cx_strcast(cxstring str) {
return str;
}
+cx_attr_nodiscard
+static inline cxstring cx_strcast(const char *str) {
+ return cx_str(str);
+}
extern "C" {
#else
/**
return str;
}
+/**
+ * Internal function, do not use.
+ * @param str
+ * @return
+ * @see cx_strcast()
+ */
+cx_attr_nodiscard
+static inline cxstring cx_strcast_z(const char *str) {
+ return cx_str(str);
+}
+
/**
* Casts a mutable string to an immutable string.
*
*/
#define cx_strcast(str) _Generic((str), \
cxmutstr: cx_strcast_m, \
- cxstring: cx_strcast_c) \
- (str)
+ cxstring: cx_strcast_c, \
+ const char*: cx_strcast_z, \
+ char *: cx_strcast_z) (str)
#endif
/**
- * Passes the pointer in this string to @c free().
+ * Passes the pointer in this string to the cxDefaultAllocator's @c free() function.
*
* The pointer in the struct is set to @c NULL and the length is set to zero
* which means that this function protects you against double-free.
cxmutstr *str
);
+/**
+ * Copies a string.
+ *
+ * The memory in the @p dest structure is either allocated or re-allocated to fit the entire
+ * source string, including a zero-terminator.
+ *
+ * The string in @p dest is guaranteed to be zero-terminated, regardless of whether @p src is.
+ *
+ * @param alloc the allocator
+ * @param dest a pointer to the structure where to copy the contents to
+ * @param src the source string
+ *
+ * @retval zero success
+ * @retval non-zero if re-allocation failed
+ */
+cx_attr_nonnull_arg(1)
+cx_attr_export
+int cx_strcpy_a(
+ const CxAllocator *alloc,
+ cxmutstr *dest,
+ cxstring src
+);
+
+
+/**
+ * Copies a string.
+ *
+ * The memory in the @p dest structure is either allocated or re-allocated to fit the entire
+ * source string, including a zero-terminator.
+ *
+ * The string in @p dest is guaranteed to be zero-terminated, regardless of whether @p src is.
+ *
+ * @param dest (@c cxmutstr*) a pointer to the structure where to copy the contents to
+ * @param src (@c cxstring) the source string
+ *
+ * @retval zero success
+ * @retval non-zero if re-allocation failed
+ */
+#define cx_strcpy(dest, src) cx_strcpy_a(cxDefaultAllocator, dest, src)
+
/**
* Returns the accumulated length of all specified strings.
*
/**
* Concatenates strings and returns a new string.
*
- * The resulting string will be allocated by standard @c malloc().
+ * The resulting string will be allocated by the cxDefaultAllocator.
* So developers @em must pass the return value to cx_strfree() eventually.
*
* If memory allocation fails, the pointer in the returned string will
/**
* Concatenates strings.
*
- * The resulting string will be allocated by standard @c malloc().
+ * The resulting string will be allocated by the cxDefaultAllocator.
* So developers @em must pass the return value to cx_strfree() eventually.
*
* If @p str already contains a string, the memory will be reallocated and
* @see cx_strfree_a()
*/
#define cx_strdup_a(allocator, string) \
- cx_strdup_a_((allocator), cx_strcast((string)))
+ cx_strdup_a_((allocator), cx_strcast(string))
/**
* Creates a duplicate of the specified string.
*
- * The new string will contain a copy allocated by standard
- * @c malloc(). So developers @em must pass the return value to cx_strfree().
+ * The new string will contain a copy allocated by the cxDefaultAllocator.
+ * So developers @em must pass the return value to cx_strfree().
*
* @note The returned string is guaranteed to be zero-terminated.
*
* @see cx_strdup_a()
* @see cx_strfree()
*/
-#define cx_strdup(string) cx_strdup_a_(cxDefaultAllocator, string)
+#define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
/**
* Omits leading and trailing spaces.
*
* Replaces at most @p replmax occurrences.
*
- * The returned string will be allocated by @c malloc() and is guaranteed
+ * The returned string will be allocated by the cxDefaultAllocator and is guaranteed
* to be zero-terminated.
*
* If allocation fails, or the input string is empty,
/**
* Replaces a string with another string.
*
- * The returned string will be allocated by @c malloc() and is guaranteed
+ * The returned string will be allocated by the cxDefaultAllocator and is guaranteed
* to be zero-terminated.
*
* If allocation fails, or the input string is empty,
* @return (@c CxStrtokCtx) a new string tokenization context
*/
#define cx_strtok(str, delim, limit) \
- cx_strtok_(cx_strcast((str)), cx_strcast((delim)), (limit))
+ cx_strtok_(cx_strcast(str), cx_strcast(delim), (limit))
/**
* Returns the next token.
size_t stack_size;
/**
* The current depth in the tree.
+ * The node with which the iteration starts has depth 1.
*/
size_t depth;
};
void *node;
/**
* The depth of the node.
+ * The first visited node has depth 1.
*/
size_t depth;
/**
*/
cx_attr_nonnull
static inline void cxTreeIteratorDispose(CxTreeIterator *iter) {
- free(iter->stack);
+ cxFreeDefault(iter->stack);
iter->stack = NULL;
}
struct cx_tree_visitor_queue_s *q = visitor->queue_next;
while (q != NULL) {
struct cx_tree_visitor_queue_s *next = q->next;
- free(q);
+ cxFreeDefault(q);
q = next;
}
}
* Creates a depth-first iterator for a tree with the specified root node.
*
* @note A tree iterator needs to maintain a stack of visited nodes, which is
- * allocated using stdlib malloc().
+ * allocated using the cxDefaultAllocator.
* When the iterator becomes invalid, this memory is automatically released.
* However, if you wish to cancel the iteration before the iterator becomes
* invalid by itself, you MUST call cxTreeIteratorDispose() manually to release
/**
* Creates a breadth-first iterator for a tree with the specified root node.
*
- * @note A tree visitor needs to maintain a queue of to be visited nodes, which
- * is allocated using stdlib malloc().
+ * @note A tree visitor needs to maintain a queue of to-be visited nodes, which
+ * is allocated using the cxDefaultAllocator.
* When the visitor becomes invalid, this memory is automatically released.
* However, if you wish to cancel the iteration before the visitor becomes
* invalid by itself, you MUST call cxTreeVisitorDispose() manually to release
* will free the nodes with the allocator's free() method.
*
* @param allocator the allocator that shall be used
- * (if @c NULL, a default stdlib allocator will be used)
+ * (if @c NULL, the cxDefaultAllocator will be used)
* @param create_func a function that creates new nodes
* @param search_func a function that compares two nodes
* @param search_data_func a function that compares a node with data
* tree, you need to specify those functions afterwards.
*
* @param allocator the allocator that was used for nodes of the wrapped tree
- * (if @c NULL, a default stdlib allocator is assumed)
+ * (if @c NULL, the cxDefaultAllocator is assumed)
* @param root the root node of the tree that shall be wrapped
* @param loc_parent offset in the node struct for the parent pointer
* @param loc_children offset in the node struct for the children linked list
cx_attr_export
size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root);
+/**
+ * Determines the size of the entire tree.
+ *
+ * @param tree the tree
+ * @return the tree size, counting the root as one
+ */
+cx_attr_nonnull
+cx_attr_nodiscard
+static inline size_t cxTreeSize(CxTree *tree) {
+ return tree->size;
+}
+
/**
* Determines the depth of the entire tree.
*
if (all_printable && escape) {
size_t capa = str.length + 32;
- char *space = malloc(capa);
+ char *space = cxMallocDefault(capa);
if (space == NULL) return cx_mutstrn(NULL, 0);
cxBufferInit(&buf, space, capa, NULL, CX_BUFFER_AUTO_EXTEND);
cxBufferWrite(str.ptr, 1, i, &buf);
void cxJsonDestroy(CxJson *json) {
cxBufferDestroy(&json->buffer);
if (json->states != json->states_internal) {
- free(json->states);
+ cxFreeDefault(json->states);
}
if (json->vbuf != json->vbuf_internal) {
- free(json->vbuf);
+ cxFreeDefault(json->vbuf);
}
cxJsonValueFree(json->parsed);
json->parsed = NULL;
if (values[i] == NULL) break;
cxJsonValueFree(values[i]);
}
- free(values);
+ cxFreeDefault(values);
}
// LCOV_EXCL_STOP
int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) {
- CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+ CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
if (values == NULL) return -1;
for (size_t i = 0; i < count; i++) {
values[i] = cxJsonCreateNumber(arr->allocator, num[i]);
if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
}
int ret = cxJsonArrAddValues(arr, values, count);
- free(values);
+ cxFreeDefault(values);
return ret;
}
int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) {
- CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+ CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
if (values == NULL) return -1;
for (size_t i = 0; i < count; i++) {
values[i] = cxJsonCreateInteger(arr->allocator, num[i]);
if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
}
int ret = cxJsonArrAddValues(arr, values, count);
- free(values);
+ cxFreeDefault(values);
return ret;
}
int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) {
- CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+ CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
if (values == NULL) return -1;
for (size_t i = 0; i < count; i++) {
values[i] = cxJsonCreateString(arr->allocator, str[i]);
if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
}
int ret = cxJsonArrAddValues(arr, values, count);
- free(values);
+ cxFreeDefault(values);
return ret;
}
int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) {
- CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+ CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
if (values == NULL) return -1;
for (size_t i = 0; i < count; i++) {
values[i] = cxJsonCreateCxString(arr->allocator, str[i]);
if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
}
int ret = cxJsonArrAddValues(arr, values, count);
- free(values);
+ cxFreeDefault(values);
return ret;
}
int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) {
- CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+ CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
if (values == NULL) return -1;
for (size_t i = 0; i < count; i++) {
values[i] = cxJsonCreateLiteral(arr->allocator, lit[i]);
if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
}
int ret = cxJsonArrAddValues(arr, values, count);
- free(values);
+ cxFreeDefault(values);
return ret;
}
) {
void *sbo[CX_LINKED_LIST_SORT_SBO_SIZE];
void **sorted = length >= CX_LINKED_LIST_SORT_SBO_SIZE ?
- malloc(sizeof(void *) * length) : sbo;
+ cxMallocDefault(sizeof(void *) * length) : sbo;
if (sorted == NULL) abort();
void *rc, *lc;
*begin = sorted[0];
*end = sorted[length - 1];
if (sorted != sbo) {
- free(sorted);
+ cxFreeDefault(sorted);
}
}
// initialize new new_node
new_node->prev = new_node->next = NULL;
- memcpy(new_node->payload, elem, list->collection.elem_size);
+ if (elem != NULL) {
+ memcpy(new_node->payload, elem, list->collection.elem_size);
+ }
// insert
cx_linked_list *ll = (cx_linked_list *) list;
return n;
}
-static int cx_ll_insert_element(
+static void *cx_ll_insert_element(
struct cx_list_s *list,
size_t index,
const void *element
) {
- return 1 != cx_ll_insert_array(list, index, element, 1);
+ // out-of-bounds check
+ if (index > list->collection.size) return NULL;
+
+ // find position efficiently
+ cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
+
+ // perform first insert
+ if (cx_ll_insert_at(list, node, element)) return NULL;
+
+ // return a pointer to the data of the inserted node
+ if (node == NULL) {
+ return ((cx_linked_list *) list)->begin->payload;
+ } else {
+ return node->next->payload;
+ }
}
static _Thread_local cx_compare_func cx_ll_insert_sorted_cmp_func;
const void *elem,
bool remove
) {
+ if (list->collection.size == 0) return 0;
+
size_t index;
cx_linked_list *ll = ((cx_linked_list *) list);
cx_linked_list_node *node = cx_linked_list_find(
}
return result;
} else {
- int result = cx_ll_insert_element(list, list->collection.size, elem);
- if (result == 0) {
- iter->elem_count++;
- iter->index = list->collection.size;
+ if (cx_ll_insert_element(list, list->collection.size, elem) == NULL) {
+ return 1;
}
- return result;
+ iter->elem_count++;
+ iter->index = list->collection.size;
+ return 0;
}
}
list->climpl->deallocate(list);
}
-static int cx_pl_insert_element(
+static void *cx_pl_insert_element(
struct cx_list_s *list,
size_t index,
const void *element
const char *src = data;
size_t i = 0;
for (; i < n; i++) {
- if (0 != invoke_list_func(
+ if (NULL == invoke_list_func(
insert_element, list, index + i,
src + (i * elem_size))) return i;
}
// insert the elements at location si
if (ins == 1) {
- if (0 != invoke_list_func(
+ if (NULL == invoke_list_func(
insert_element, list, di, src)) return inserted;
} else {
size_t r = invoke_list_func(insert_array, list, di, src, ins);
void cx_list_default_sort(struct cx_list_s *list) {
size_t elem_size = list->collection.elem_size;
size_t list_size = list->collection.size;
- void *tmp = malloc(elem_size * list_size);
+ void *tmp = cxMallocDefault(elem_size * list_size);
if (tmp == NULL) abort();
// copy elements from source array
loc += elem_size;
}
- free(tmp);
+ cxFreeDefault(tmp);
}
int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j) {
size_t elem_size = list->collection.elem_size;
- void *tmp = malloc(elem_size);
+ void *tmp = cxMallocDefault(elem_size);
if (tmp == NULL) return 1;
void *ip = invoke_list_func(at, list, i);
memcpy(ip, jp, elem_size);
memcpy(jp, tmp, elem_size);
- free(tmp);
+ cxFreeDefault(tmp);
return 0;
}
if (list == NULL) return;
list->cl->deallocate(list);
}
+
+int cxListSet(
+ CxList *list,
+ size_t index,
+ const void *elem
+) {
+ if (index >= list->collection.size) {
+ return 1;
+ }
+
+ if (list->collection.store_pointer) {
+ // For pointer collections, always use climpl
+ void **target = list->climpl->at(list, index);
+ *target = (void *)elem;
+ } else {
+ void *target = list->cl->at(list, index);
+ memcpy(target, elem, list->collection.elem_size);
+ }
+
+ return 0;
+}
#include <string.h>
#include <errno.h>
-struct cx_mempool_memory_s {
- /** The destructor. */
- cx_destructor_func destructor;
- /** The actual memory. */
- char c[];
-};
+static int cx_mempool_ensure_capacity(
+ struct cx_mempool_s *pool,
+ size_t needed_capacity
+) {
+ if (needed_capacity <= pool->capacity) return 0;
+ size_t newcap = pool->capacity >= 1000 ?
+ pool->capacity + 1000 : pool->capacity * 2;
+ size_t newmsize;
+ // LCOV_EXCL_START
+ if (pool->capacity > newcap
+ || cx_szmul(newcap, sizeof(void*), &newmsize)) {
+ errno = EOVERFLOW;
+ return 1;
+ } // LCOV_EXCL_STOP
+ void **newdata = cxRealloc(pool->base_allocator, pool->data, newmsize);
+ if (newdata == NULL) return 1;
+ pool->data = newdata;
+ pool->capacity = newcap;
+ return 0;
+}
-static void *cx_mempool_malloc(
+static int cx_mempool_ensure_registered_capacity(
+ struct cx_mempool_s *pool,
+ size_t needed_capacity
+) {
+ if (needed_capacity <= pool->registered_capacity) return 0;
+ // we do not expect so many registrations
+ size_t newcap = pool->registered_capacity + 8;
+ size_t newmsize;
+ // LCOV_EXCL_START
+ if (pool->registered_capacity > newcap || cx_szmul(newcap,
+ sizeof(struct cx_mempool_foreign_memory_s), &newmsize)) {
+ errno = EOVERFLOW;
+ return 1;
+ } // LCOV_EXCL_STOP
+ void *newdata = cxRealloc(pool->base_allocator, pool->registered, newmsize);
+ if (newdata == NULL) return 1;
+ pool->registered = newdata;
+ pool->registered_capacity = newcap;
+ return 0;
+}
+
+static void *cx_mempool_malloc_simple(
void *p,
size_t n
) {
struct cx_mempool_s *pool = p;
- if (pool->size >= pool->capacity) {
- size_t newcap = pool->capacity - (pool->capacity % 16) + 16;
- size_t newmsize;
- if (pool->capacity > newcap || cx_szmul(newcap,
- sizeof(struct cx_mempool_memory_s*), &newmsize)) {
- errno = EOVERFLOW;
- return NULL;
- }
- struct cx_mempool_memory_s **newdata = realloc(pool->data, newmsize);
- if (newdata == NULL) return NULL;
- pool->data = newdata;
- pool->capacity = newcap;
+ if (cx_mempool_ensure_capacity(pool, pool->size + 1)) {
+ return NULL; // LCOV_EXCL_LINE
}
- struct cx_mempool_memory_s *mem = malloc(sizeof(cx_destructor_func) + n);
+ struct cx_mempool_memory_s *mem =
+ cxMalloc(pool->base_allocator, sizeof(struct cx_mempool_memory_s) + n);
if (mem == NULL) return NULL;
-
- mem->destructor = pool->auto_destr;
+ mem->destructor = NULL;
pool->data[pool->size] = mem;
pool->size++;
return mem->c;
}
-static void *cx_mempool_calloc(
+static void *cx_mempool_calloc_simple(
void *p,
size_t nelem,
size_t elsize
errno = EOVERFLOW;
return NULL;
}
- void *ptr = cx_mempool_malloc(p, msz);
+ void *ptr = cx_mempool_malloc_simple(p, msz);
if (ptr == NULL) return NULL;
memset(ptr, 0, nelem * elsize);
return ptr;
}
-static void *cx_mempool_realloc(
+static void cx_mempool_free_simple(
+ void *p,
+ void *ptr
+) {
+ if (!ptr) return;
+ struct cx_mempool_s *pool = p;
+
+ struct cx_mempool_memory_s *mem =
+ (void*) ((char *) ptr - sizeof(struct cx_mempool_memory_s));
+
+ for (size_t i = 0; i < pool->size; i++) {
+ if (mem == pool->data[i]) {
+ if (mem->destructor) {
+ mem->destructor(mem->c);
+ }
+ if (pool->destr) {
+ pool->destr(mem->c);
+ }
+ if (pool->destr2) {
+ pool->destr2(pool->destr2_data, mem->c);
+ }
+ cxFree(pool->base_allocator, mem);
+ size_t last_index = pool->size - 1;
+ if (i != last_index) {
+ pool->data[i] = pool->data[last_index];
+ pool->data[last_index] = NULL;
+ }
+ pool->size--;
+ return;
+ }
+ }
+ abort(); // LCOV_EXCL_LINE
+}
+
+static void *cx_mempool_realloc_simple(
void *p,
void *ptr,
size_t n
) {
+ if (ptr == NULL) {
+ return cx_mempool_malloc_simple(p, n);
+ }
+ if (n == 0) {
+ cx_mempool_free_simple(p, ptr);
+ return NULL;
+ }
struct cx_mempool_s *pool = p;
- struct cx_mempool_memory_s *mem, *newm;
- mem = (struct cx_mempool_memory_s*)(((char *) ptr) - sizeof(cx_destructor_func));
- newm = realloc(mem, n + sizeof(cx_destructor_func));
+ const unsigned overhead = sizeof(struct cx_mempool_memory_s);
+ struct cx_mempool_memory_s *mem =
+ (void *) (((char *) ptr) - overhead);
+ struct cx_mempool_memory_s *newm =
+ cxRealloc(pool->base_allocator, mem, n + overhead);
if (newm == NULL) return NULL;
if (mem != newm) {
for (size_t i = 0; i < pool->size; i++) {
if (pool->data[i] == mem) {
pool->data[i] = newm;
- return ((char*)newm) + sizeof(cx_destructor_func);
+ return ((char*)newm) + overhead;
}
}
abort(); // LCOV_EXCL_LINE
} else {
- return ptr;
+ // unfortunately glibc() realloc seems to always move
+ return ptr; // LCOV_EXCL_LINE
+ }
+}
+
+static void cx_mempool_free_all_simple(const struct cx_mempool_s *pool) {
+ const bool has_destr = pool->destr;
+ const bool has_destr2 = pool->destr2;
+ for (size_t i = 0; i < pool->size; i++) {
+ struct cx_mempool_memory_s *mem = pool->data[i];
+ if (mem->destructor) {
+ mem->destructor(mem->c);
+ }
+ if (has_destr) {
+ pool->destr(mem->c);
+ }
+ if (has_destr2) {
+ pool->destr2(pool->destr2_data, mem->c);
+ }
+ cxFree(pool->base_allocator, mem);
+ }
+}
+
+static cx_allocator_class cx_mempool_simple_allocator_class = {
+ cx_mempool_malloc_simple,
+ cx_mempool_realloc_simple,
+ cx_mempool_calloc_simple,
+ cx_mempool_free_simple
+};
+
+static void *cx_mempool_malloc_advanced(
+ void *p,
+ size_t n
+) {
+ struct cx_mempool_s *pool = p;
+
+ if (cx_mempool_ensure_capacity(pool, pool->size + 1)) {
+ return NULL; // LCOV_EXCL_LINE
+ }
+
+ struct cx_mempool_memory2_s *mem =
+ cxMalloc(pool->base_allocator, sizeof(struct cx_mempool_memory2_s) + n);
+ if (mem == NULL) return NULL;
+ mem->destructor = NULL;
+ mem->data = NULL;
+ pool->data[pool->size] = mem;
+ pool->size++;
+
+ return mem->c;
+}
+
+static void *cx_mempool_calloc_advanced(
+ void *p,
+ size_t nelem,
+ size_t elsize
+) {
+ size_t msz;
+ if (cx_szmul(nelem, elsize, &msz)) {
+ errno = EOVERFLOW;
+ return NULL;
}
+ void *ptr = cx_mempool_malloc_advanced(p, msz);
+ if (ptr == NULL) return NULL;
+ memset(ptr, 0, nelem * elsize);
+ return ptr;
}
-static void cx_mempool_free(
+static void cx_mempool_free_advanced(
void *p,
void *ptr
) {
if (!ptr) return;
struct cx_mempool_s *pool = p;
- struct cx_mempool_memory_s *mem = (struct cx_mempool_memory_s *)
- ((char *) ptr - sizeof(cx_destructor_func));
+ struct cx_mempool_memory2_s *mem =
+ (void*) ((char *) ptr - sizeof(struct cx_mempool_memory2_s));
for (size_t i = 0; i < pool->size; i++) {
if (mem == pool->data[i]) {
if (mem->destructor) {
- mem->destructor(mem->c);
+ mem->destructor(mem->data, mem->c);
+ }
+ if (pool->destr) {
+ pool->destr(mem->c);
}
- free(mem);
+ if (pool->destr2) {
+ pool->destr2(pool->destr2_data, mem->c);
+ }
+ cxFree(pool->base_allocator, mem);
size_t last_index = pool->size - 1;
if (i != last_index) {
pool->data[i] = pool->data[last_index];
abort(); // LCOV_EXCL_LINE
}
-void cxMempoolFree(CxMempool *pool) {
- if (pool == NULL) return;
- struct cx_mempool_memory_s *mem;
+static void *cx_mempool_realloc_advanced(
+ void *p,
+ void *ptr,
+ size_t n
+) {
+ if (ptr == NULL) {
+ return cx_mempool_malloc_advanced(p, n);
+ }
+ if (n == 0) {
+ cx_mempool_free_advanced(p, ptr);
+ return NULL;
+ }
+ struct cx_mempool_s *pool = p;
+
+ const unsigned overhead = sizeof(struct cx_mempool_memory2_s);
+ struct cx_mempool_memory2_s *mem =
+ (void *) (((char *) ptr) - overhead);
+ struct cx_mempool_memory2_s *newm =
+ cxRealloc(pool->base_allocator, mem, n + overhead);
+
+ if (newm == NULL) return NULL;
+ if (mem != newm) {
+ for (size_t i = 0; i < pool->size; i++) {
+ if (pool->data[i] == mem) {
+ pool->data[i] = newm;
+ return ((char*)newm) + overhead;
+ }
+ }
+ abort(); // LCOV_EXCL_LINE
+ } else {
+ // unfortunately glibc() realloc seems to always move
+ return ptr; // LCOV_EXCL_LINE
+ }
+}
+
+static void cx_mempool_free_all_advanced(const struct cx_mempool_s *pool) {
+ const bool has_destr = pool->destr;
+ const bool has_destr2 = pool->destr2;
for (size_t i = 0; i < pool->size; i++) {
- mem = pool->data[i];
+ struct cx_mempool_memory2_s *mem = pool->data[i];
if (mem->destructor) {
- mem->destructor(mem->c);
+ mem->destructor(mem->data, mem->c);
}
- free(mem);
+ if (has_destr) {
+ pool->destr(mem->c);
+ }
+ if (has_destr2) {
+ pool->destr2(pool->destr2_data, mem->c);
+ }
+ cxFree(pool->base_allocator, mem);
+ }
+}
+
+static cx_allocator_class cx_mempool_advanced_allocator_class = {
+ cx_mempool_malloc_advanced,
+ cx_mempool_realloc_advanced,
+ cx_mempool_calloc_advanced,
+ cx_mempool_free_advanced
+};
+
+
+static void *cx_mempool_malloc_pure(
+ void *p,
+ size_t n
+) {
+ struct cx_mempool_s *pool = p;
+
+ if (cx_mempool_ensure_capacity(pool, pool->size + 1)) {
+ return NULL; // LCOV_EXCL_LINE
}
- free(pool->data);
- free((void*) pool->allocator);
- free(pool);
+
+ void *mem = cxMalloc(pool->base_allocator, n);
+ if (mem == NULL) return NULL;
+ pool->data[pool->size] = mem;
+ pool->size++;
+
+ return mem;
+}
+
+static void *cx_mempool_calloc_pure(
+ void *p,
+ size_t nelem,
+ size_t elsize
+) {
+ size_t msz;
+ if (cx_szmul(nelem, elsize, &msz)) {
+ errno = EOVERFLOW;
+ return NULL;
+ }
+ void *ptr = cx_mempool_malloc_pure(p, msz);
+ if (ptr == NULL) return NULL;
+ memset(ptr, 0, nelem * elsize);
+ return ptr;
+}
+
+static void cx_mempool_free_pure(
+ void *p,
+ void *ptr
+) {
+ if (!ptr) return;
+ struct cx_mempool_s *pool = p;
+
+ for (size_t i = 0; i < pool->size; i++) {
+ if (ptr == pool->data[i]) {
+ if (pool->destr) {
+ pool->destr(ptr);
+ }
+ if (pool->destr2) {
+ pool->destr2(pool->destr2_data, ptr);
+ }
+ cxFree(pool->base_allocator, ptr);
+ size_t last_index = pool->size - 1;
+ if (i != last_index) {
+ pool->data[i] = pool->data[last_index];
+ pool->data[last_index] = NULL;
+ }
+ pool->size--;
+ return;
+ }
+ }
+ abort(); // LCOV_EXCL_LINE
+}
+
+static void *cx_mempool_realloc_pure(
+ void *p,
+ void *ptr,
+ size_t n
+) {
+ if (ptr == NULL) {
+ return cx_mempool_malloc_pure(p, n);
+ }
+ if (n == 0) {
+ cx_mempool_free_pure(p, ptr);
+ return NULL;
+ }
+ struct cx_mempool_s *pool = p;
+ void *newm = cxRealloc(pool->base_allocator, ptr, n);
+ if (newm == NULL) return NULL;
+ if (ptr != newm) {
+ for (size_t i = 0; i < pool->size; i++) {
+ if (pool->data[i] == ptr) {
+ pool->data[i] = newm;
+ return newm;
+ }
+ }
+ abort(); // LCOV_EXCL_LINE
+ } else {
+ // unfortunately glibc() realloc seems to always move
+ return ptr; // LCOV_EXCL_LINE
+ }
+}
+
+static void cx_mempool_free_all_pure(const struct cx_mempool_s *pool) {
+ const bool has_destr = pool->destr;
+ const bool has_destr2 = pool->destr2;
+ for (size_t i = 0; i < pool->size; i++) {
+ void *mem = pool->data[i];
+ if (has_destr) {
+ pool->destr(mem);
+ }
+ if (has_destr2) {
+ pool->destr2(pool->destr2_data, mem);
+ }
+ cxFree(pool->base_allocator, mem);
+ }
+}
+
+static cx_allocator_class cx_mempool_pure_allocator_class = {
+ cx_mempool_malloc_pure,
+ cx_mempool_realloc_pure,
+ cx_mempool_calloc_pure,
+ cx_mempool_free_pure
+};
+
+static void cx_mempool_free_foreign(const struct cx_mempool_s *pool) {
+ for (size_t i = 0; i < pool->registered_size; i++) {
+ struct cx_mempool_foreign_memory_s info = pool->registered[i];
+ if (info.destr2_data == NULL) {
+ if (info.destr) {
+ info.destr(info.mem);
+ }
+ } else {
+ info.destr2(info.destr2_data, info.mem);
+ }
+ }
+}
+
+void cxMempoolFree(CxMempool *pool) {
+ if (pool == NULL) return;
+ if (pool->allocator->cl == &cx_mempool_simple_allocator_class) {
+ cx_mempool_free_all_simple(pool);
+ } else if (pool->allocator->cl == &cx_mempool_advanced_allocator_class) {
+ cx_mempool_free_all_advanced(pool);
+ } else {
+ cx_mempool_free_all_pure(pool);
+ }
+ cx_mempool_free_foreign(pool);
+ cxFree(pool->base_allocator, pool->data);
+ cxFree(pool->base_allocator, pool->registered);
+ cxFree(pool->base_allocator, (void*) pool->allocator);
+ cxFree(pool->base_allocator, pool);
}
void cxMempoolSetDestructor(
*(cx_destructor_func *) ((char *) ptr - sizeof(cx_destructor_func)) = func;
}
+void cxMempoolSetDestructor2(
+ void *ptr,
+ cx_destructor_func2 func,
+ void *data
+) {
+ struct cx_mempool_memory2_s *info =
+ (void*)((char *) ptr - sizeof(struct cx_mempool_memory2_s));
+ info->destructor = func;
+ info->data = data;
+}
+
void cxMempoolRemoveDestructor(void *ptr) {
*(cx_destructor_func *) ((char *) ptr - sizeof(cx_destructor_func)) = NULL;
}
-struct cx_mempool_foreign_mem_s {
- cx_destructor_func destr;
- void* mem;
-};
-
-static void cx_mempool_destr_foreign_mem(void* ptr) {
- struct cx_mempool_foreign_mem_s *fm = ptr;
- fm->destr(fm->mem);
+void cxMempoolRemoveDestructor2(void *ptr) {
+ struct cx_mempool_memory2_s *info =
+ (void*)((char *) ptr - sizeof(struct cx_mempool_memory2_s));
+ info->destructor = NULL;
+ info->data = NULL;
}
int cxMempoolRegister(
void *memory,
cx_destructor_func destr
) {
- struct cx_mempool_foreign_mem_s *fm = cx_mempool_malloc(
- pool,
- sizeof(struct cx_mempool_foreign_mem_s)
- );
- if (fm == NULL) return 1;
+ if (cx_mempool_ensure_registered_capacity(pool, pool->registered_size + 1)) {
+ return 1; // LCOV_EXCL_LINE
+ }
- fm->mem = memory;
- fm->destr = destr;
- *(cx_destructor_func *) ((char *) fm - sizeof(cx_destructor_func)) = cx_mempool_destr_foreign_mem;
+ pool->registered[pool->registered_size++] =
+ (struct cx_mempool_foreign_memory_s) {
+ .mem = memory,
+ .destr = destr,
+ .destr2_data = NULL
+ };
return 0;
}
-static cx_allocator_class cx_mempool_allocator_class = {
- cx_mempool_malloc,
- cx_mempool_realloc,
- cx_mempool_calloc,
- cx_mempool_free
-};
+int cxMempoolRegister2(
+ CxMempool *pool,
+ void *memory,
+ cx_destructor_func2 destr,
+ void *data
+) {
+ if (cx_mempool_ensure_registered_capacity(pool, pool->registered_size + 1)) {
+ return 1; // LCOV_EXCL_LINE
+ }
+
+ pool->registered[pool->registered_size++] =
+ (struct cx_mempool_foreign_memory_s) {
+ .mem = memory,
+ .destr2 = destr,
+ .destr2_data = data
+ };
+
+ return 0;
+}
CxMempool *cxMempoolCreate(
size_t capacity,
- cx_destructor_func destr
+ enum cx_mempool_type type
) {
+ if (capacity == 0) capacity = 16;
size_t poolsize;
- if (cx_szmul(capacity, sizeof(struct cx_mempool_memory_s*), &poolsize)) {
+ if (cx_szmul(capacity, sizeof(void*), &poolsize)) {
+ // LCOV_EXCL_START
errno = EOVERFLOW;
return NULL;
- }
-
- struct cx_mempool_s *pool =
- malloc(sizeof(struct cx_mempool_s));
- if (pool == NULL) return NULL;
+ } // LCOV_EXCL_STOP
- CxAllocator *provided_allocator = malloc(sizeof(CxAllocator));
+ CxAllocator *provided_allocator = cxMallocDefault(sizeof(CxAllocator));
if (provided_allocator == NULL) { // LCOV_EXCL_START
- free(pool);
return NULL;
} // LCOV_EXCL_STOP
- provided_allocator->cl = &cx_mempool_allocator_class;
- provided_allocator->data = pool;
+ CxMempool *pool = cxCallocDefault(1, sizeof(CxMempool));
+ if (pool == NULL) { // LCOV_EXCL_START
+ cxFreeDefault(provided_allocator);
+ return NULL;
+ } // LCOV_EXCL_STOP
+
+ provided_allocator->data = pool;
+ *((const CxAllocator**)&pool->base_allocator) = cxDefaultAllocator;
pool->allocator = provided_allocator;
+ if (type == CX_MEMPOOL_TYPE_SIMPLE) {
+ provided_allocator->cl = &cx_mempool_simple_allocator_class;
+ } else if (type == CX_MEMPOOL_TYPE_ADVANCED) {
+ provided_allocator->cl = &cx_mempool_advanced_allocator_class;
+ } else {
+ provided_allocator->cl = &cx_mempool_pure_allocator_class;
+ }
- pool->data = malloc(poolsize);
+ pool->data = cxMallocDefault(poolsize);
if (pool->data == NULL) { // LCOV_EXCL_START
- free(provided_allocator);
- free(pool);
+ cxFreeDefault(provided_allocator);
+ cxFreeDefault(pool);
return NULL;
} // LCOV_EXCL_STOP
pool->size = 0;
pool->capacity = capacity;
- pool->auto_destr = destr;
return pool;
}
+
+void cxMempoolGlobalDestructor(CxMempool *pool, cx_destructor_func fnc) {
+ pool->destr = fnc;
+}
+
+void cxMempoolGlobalDestructor2(CxMempool *pool, cx_destructor_func2 fnc, void *data) {
+ pool->destr2 = fnc;
+ pool->destr2_data = data;
+}
+
+static void cx_mempool_free_transferred_allocator(void *base_al, void *al) {
+ cxFree(base_al, al);
+}
+
+int cxMempoolTransfer(
+ CxMempool *source,
+ CxMempool *dest
+) {
+ // safety checks
+ if (source == dest) return 1;
+ if (source->allocator->cl != dest->allocator->cl) return 1;
+ if (source->base_allocator->cl != dest->base_allocator->cl) return 1;
+
+ // ensure enough capacity in the destination pool
+ if (cx_mempool_ensure_capacity(dest, dest->size + source->size)) {
+ return 1; // LCOV_EXCL_LINE
+ }
+ if (cx_mempool_ensure_registered_capacity(dest,
+ dest->registered_size + source->registered_size)) {
+ return 1; // LCOV_EXCL_LINE
+ }
+
+ // allocate a replacement allocator for the source pool
+ CxAllocator *new_source_allocator =
+ cxMalloc(source->base_allocator, sizeof(CxAllocator));
+ if (new_source_allocator == NULL) { // LCOV_EXCL_START
+ return 1;
+ } // LCOV_EXCL_STOP
+ new_source_allocator->cl = source->allocator->cl;
+ new_source_allocator->data = source;
+
+ // transfer all the data
+ memcpy(&dest->data[dest->size], source->data, sizeof(void*)*source->size);
+ dest->size += source->size;
+
+ // transfer all registered memory
+ memcpy(&dest->registered[dest->registered_size], source->registered,
+ sizeof(struct cx_mempool_foreign_memory_s) * source->size);
+ dest->registered_size += source->registered_size;
+
+ // register the old allocator with the new pool
+ // we have to remove const-ness for this, but that's okay here
+ // also register the base allocator, s.t. the pool knows how to free it
+ CxAllocator *transferred_allocator = (CxAllocator*) source->allocator;
+ transferred_allocator->data = dest;
+ cxMempoolRegister2(dest, transferred_allocator,
+ cx_mempool_free_transferred_allocator, (void*)source->base_allocator);
+
+ // prepare the source pool for re-use
+ source->allocator = new_source_allocator;
+ memset(source->data, 0, source->size * sizeof(void*));
+ memset(source->registered, 0,
+ source->registered_size * sizeof(struct cx_mempool_foreign_memory_s));
+ source->size = 0;
+ source->registered_size = 0;
+
+ return 0;
+}
+
+int cxMempoolTransferObject(
+ CxMempool *source,
+ CxMempool *dest,
+ const void *obj
+) {
+ // safety checks
+ if (source == dest) return 1;
+ if (source->allocator->cl != dest->allocator->cl) return 1;
+ if (source->base_allocator->cl != dest->base_allocator->cl) return 1;
+
+ // search for the object
+ for (size_t i = 0; i < source->size; i++) {
+ struct cx_mempool_memory_s *mem = source->data[i];
+ if (mem->c == obj) {
+ // first, make sure that the dest pool can take the object
+ if (cx_mempool_ensure_capacity(dest, dest->size + 1)) {
+ return 1; // LCOV_EXCL_LINE
+ }
+ // remove from the source pool
+ size_t last_index = source->size - 1;
+ if (i != last_index) {
+ source->data[i] = source->data[last_index];
+ source->data[last_index] = NULL;
+ }
+ source->size--;
+ // add to the target pool
+ dest->data[dest->size++] = mem;
+ return 0;
+ }
+ }
+ // search in the registered objects
+ for (size_t i = 0; i < source->registered_size; i++) {
+ struct cx_mempool_foreign_memory_s *mem = &source->registered[i];
+ if (mem->mem == obj) {
+ // first, make sure that the dest pool can take the object
+ if (cx_mempool_ensure_registered_capacity(dest,
+ dest->registered_size + 1)) {
+ return 1; // LCOV_EXCL_LINE
+ }
+ dest->registered[dest->registered_size++] = *mem;
+ // remove from the source pool
+ size_t last_index = source->registered_size - 1;
+ if (i != last_index) {
+ source->registered[i] = source->registered[last_index];
+ memset(&source->registered[last_index], 0,
+ sizeof(struct cx_mempool_foreign_memory_s));
+ }
+ source->registered_size--;
+ return 0;
+ }
+ }
+ // not found
+ return 1;
+}
return (int) wfc(buf, 1, ret, stream);
} else {
int len = ret + 1;
- char *newbuf = malloc(len);
+ char *newbuf = cxMallocDefault(len);
if (!newbuf) { // LCOV_EXCL_START
va_end(ap2);
return -1;
if (ret > 0) {
ret = (int) wfc(newbuf, 1, ret, stream);
}
- free(newbuf);
+ cxFreeDefault(newbuf);
}
return ret;
}
if (s.ptr) {
ret = vsnprintf(s.ptr, len, fmt, ap2);
if (ret < 0) {
- free(s.ptr);
+ cxFree(a, s.ptr);
s.ptr = NULL;
} else {
s.length = (size_t) ret;
return s;
}
-int cx_sprintf_a(CxAllocator *alloc, char **str, size_t *len, const char *fmt, ... ) {
+int cx_sprintf_a(
+ const CxAllocator *alloc,
+ char **str,
+ size_t *len,
+ const char *fmt,
+ ...
+) {
va_list ap;
va_start(ap, fmt);
int ret = cx_vsprintf_a(alloc, str, len, fmt, ap);
return ret;
}
-int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t *len, const char *fmt, va_list ap) {
+int cx_vsprintf_a(
+ const CxAllocator *alloc,
+ char **str,
+ size_t *len,
+ const char *fmt,
+ va_list ap
+) {
va_list ap2;
va_copy(ap2, ap);
int ret = vsnprintf(*str, *len, fmt, ap);
return ret;
}
-int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t *len, char **str, const char *fmt, ... ) {
+int cx_sprintf_sa(
+ const CxAllocator *alloc,
+ char *buf,
+ size_t *len,
+ char **str,
+ const char *fmt,
+ ...
+) {
va_list ap;
va_start(ap, fmt);
int ret = cx_vsprintf_sa(alloc, buf, len, str, fmt, ap);
return ret;
}
-int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t *len, char **str, const char *fmt, va_list ap) {
+int cx_vsprintf_sa(
+ const CxAllocator *alloc,
+ char *buf,
+ size_t *len,
+ char **str,
+ const char *fmt,
+ va_list ap
+) {
va_list ap2;
va_copy(ap2, ap);
int ret = vsnprintf(buf, *len, fmt, ap);
cx_attr_unused CxProperties *prop,
CxPropertiesSource *src
) {
- src->data_ptr = malloc(src->data_size);
+ src->data_ptr = cxMallocDefault(src->data_size);
if (src->data_ptr == NULL) return 1;
return 0;
}
cx_attr_unused CxProperties *prop,
CxPropertiesSource *src
) {
- free(src->data_ptr);
+ cxFreeDefault(src->data_ptr);
}
CxPropertiesSource cxPropertiesStringSource(cxstring str) {
*/
#include "cx/streams.h"
+#include "cx/allocator.h"
#ifndef CX_STREAM_BCOPY_BUF_SIZE
#define CX_STREAM_BCOPY_BUF_SIZE 8192
lbuf = buf;
} else {
if (bufsize == 0) bufsize = CX_STREAM_BCOPY_BUF_SIZE;
- lbuf = malloc(bufsize);
+ lbuf = cxMallocDefault(bufsize);
if (lbuf == NULL) return 0;
}
}
if (lbuf != buf) {
- free(lbuf);
+ cxFreeDefault(lbuf);
}
return ncp;
void cx_strfree(cxmutstr *str) {
if (str == NULL) return;
- free(str->ptr);
+ cxFreeDefault(str->ptr);
str->ptr = NULL;
str->length = 0;
}
str->length = 0;
}
+int cx_strcpy_a(
+ const CxAllocator *alloc,
+ cxmutstr *dest,
+ cxstring src
+) {
+ if (cxReallocate(alloc, &dest->ptr, src.length + 1)) {
+ return 1;
+ }
+
+ memcpy(dest->ptr, src.ptr, src.length);
+ dest->length = src.length;
+ dest->ptr[dest->length] = '\0';
+
+ return 0;
+}
+
size_t cx_strlen(
size_t count,
...
...
) {
if (count == 0) return str;
-
- cxstring strings_stack[8];
- cxstring *strings;
- if (count > 8) {
- strings = calloc(count, sizeof(cxstring));
- if (strings == NULL) {
- return (cxmutstr) {NULL, 0};
- }
- } else {
- strings = strings_stack;
- }
-
va_list ap;
va_start(ap, count);
+ va_list ap2;
+ va_copy(ap2, ap);
- // get all args and overall length
+ // compute overall length
bool overflow = false;
size_t slen = str.length;
for (size_t i = 0; i < count; i++) {
- cxstring s = va_arg (ap, cxstring);
- strings[i] = s;
+ cxstring s = va_arg(ap, cxstring);
if (slen > SIZE_MAX - str.length) overflow = true;
slen += s.length;
}
// abort in case of overflow
if (overflow) {
+ va_end(ap2);
errno = EOVERFLOW;
- if (strings != strings_stack) {
- free(strings);
- }
return (cxmutstr) { NULL, 0 };
}
newstr = cxRealloc(alloc, str.ptr, slen + 1);
}
if (newstr == NULL) {
- if (strings != strings_stack) {
- free(strings);
- }
+ va_end(ap2);
return (cxmutstr) {NULL, 0};
}
str.ptr = newstr;
size_t pos = str.length;
str.length = slen;
for (size_t i = 0; i < count; i++) {
- cxstring s = strings[i];
+ cxstring s = va_arg(ap2, cxstring);
memcpy(str.ptr + pos, s.ptr, s.length);
pos += s.length;
}
+ va_end(ap2);
// terminate string
str.ptr[str.length] = '\0';
- // free temporary array
- if (strings != strings_stack) {
- free(strings);
- }
-
return str;
}
// check needle length and use appropriate prefix table
// if the pattern exceeds static prefix table, allocate on the heap
const bool useheap = needle.length >= CX_STRSTR_SBO_SIZE;
- register size_t *ptable = useheap ? calloc(needle.length + 1,
- sizeof(size_t)) : s_prefix_table;
+ register size_t *ptable = useheap
+ ? cxCallocDefault(needle.length + 1, sizeof(size_t))
+ : s_prefix_table;
// keep counter in registers
register size_t i, j;
// if prefix table was allocated on the heap, free it
if (useheap) {
- free(ptable);
+ cxFreeDefault(ptable);
}
return result;
#endif
}
-#ifndef CX_STRREPLACE_INDEX_BUFFER_SIZE
-#define CX_STRREPLACE_INDEX_BUFFER_SIZE 64
-#endif
-
-struct cx_strreplace_ibuf {
- size_t *buf;
- struct cx_strreplace_ibuf *next;
- unsigned int len;
-};
-
-static void cx_strrepl_free_ibuf(struct cx_strreplace_ibuf *buf) {
- // remember, the first data is on the stack!
- buf = buf->next;
- while (buf) {
- struct cx_strreplace_ibuf *next = buf->next;
- free(buf->buf);
- free(buf);
- buf = next;
- }
-}
-
cxmutstr cx_strreplacen_a(
const CxAllocator *allocator,
cxstring str,
cxstring replacement,
size_t replmax
) {
-
- if (search.length == 0 || search.length > str.length || replmax == 0)
+ // special cases
+ if (search.length == 0 || search.length > str.length || replmax == 0) {
return cx_strdup_a(allocator, str);
-
- // Compute expected buffer length
- size_t ibufmax = str.length / search.length;
- size_t ibuflen = replmax < ibufmax ? replmax : ibufmax;
- if (ibuflen > CX_STRREPLACE_INDEX_BUFFER_SIZE) {
- ibuflen = CX_STRREPLACE_INDEX_BUFFER_SIZE;
}
- // First index buffer can be on the stack
- struct cx_strreplace_ibuf ibuf, *curbuf = &ibuf;
- size_t ibuf_sbo[CX_STRREPLACE_INDEX_BUFFER_SIZE];
- ibuf.buf = ibuf_sbo;
- ibuf.next = NULL;
- ibuf.len = 0;
+ size_t in_len = str.length;
+ size_t search_len = search.length;
+ size_t repl_len = replacement.length;
- // Search occurrences
- cxstring searchstr = str;
- size_t found = 0;
- do {
- cxstring match = cx_strstr(searchstr, search);
- if (match.length > 0) {
- // Allocate next buffer in chain, if required
- if (curbuf->len == ibuflen) {
- struct cx_strreplace_ibuf *nextbuf =
- calloc(1, sizeof(struct cx_strreplace_ibuf));
- if (!nextbuf) {
- cx_strrepl_free_ibuf(&ibuf);
- return cx_mutstrn(NULL, 0);
- }
- nextbuf->buf = calloc(ibuflen, sizeof(size_t));
- if (!nextbuf->buf) {
- free(nextbuf);
- cx_strrepl_free_ibuf(&ibuf);
- return cx_mutstrn(NULL, 0);
- }
- curbuf->next = nextbuf;
- curbuf = nextbuf;
- }
-
- // Record match index
- found++;
- size_t idx = match.ptr - str.ptr;
- curbuf->buf[curbuf->len++] = idx;
- searchstr.ptr = match.ptr + search.length;
- searchstr.length = str.length - idx - search.length;
- } else {
- break;
- }
- } while (searchstr.length > 0 && found < replmax);
-
- // Allocate result string
- cxmutstr result;
- {
- long long adjlen = (long long) replacement.length - (long long) search.length;
- size_t rcount = 0;
- curbuf = &ibuf;
- do {
- rcount += curbuf->len;
- curbuf = curbuf->next;
- } while (curbuf);
- result.length = str.length + rcount * adjlen;
- result.ptr = cxMalloc(allocator, result.length + 1);
- if (!result.ptr) {
- cx_strrepl_free_ibuf(&ibuf);
- return cx_mutstrn(NULL, 0);
- }
+ // first run, count the occurrences
+ // and remember where the first is
+ size_t occurrences = 1;
+ cxstring first = cx_strstr(str, search);
+ if (first.length == 0) {
+ // special case, no replacements
+ return cx_strdup_a(allocator, str);
+ }
+ cxstring tmp = cx_strsubs(first, search_len);
+ while (occurrences < replmax &&
+ (tmp = cx_strstr(tmp, search)).length > 0) {
+ occurrences++;
+ tmp = cx_strsubs(tmp, search_len);
}
- // Build result string
- curbuf = &ibuf;
- size_t srcidx = 0;
- char *destptr = result.ptr;
- do {
- for (size_t i = 0; i < curbuf->len; i++) {
- // Copy source part up to next match
- size_t idx = curbuf->buf[i];
- size_t srclen = idx - srcidx;
- if (srclen > 0) {
- memcpy(destptr, str.ptr + srcidx, srclen);
- destptr += srclen;
- srcidx += srclen;
- }
-
- // Copy the replacement and skip the source pattern
- srcidx += search.length;
- memcpy(destptr, replacement.ptr, replacement.length);
- destptr += replacement.length;
- }
- curbuf = curbuf->next;
- } while (curbuf);
- memcpy(destptr, str.ptr + srcidx, str.length - srcidx);
-
- // Result is guaranteed to be zero-terminated
- result.ptr[result.length] = '\0';
+ // calculate necessary memory
+ signed long long diff_len = (signed long long) repl_len - search_len;
+ size_t out_len = in_len + diff_len * occurrences;
+ cxmutstr out = {
+ cxMalloc(allocator, out_len + 1),
+ out_len
+ };
+ if (out.ptr == NULL) return out;
+
+ // second run: perform the replacements
+ // but start where we found the first occurrence
+ const char *inp = str.ptr;
+ tmp = first;
+ char *outp = out.ptr;
+ while (occurrences-- > 0 && (tmp = cx_strstr(tmp, search)).length > 0) {
+ size_t copylen = tmp.ptr - inp;
+ memcpy(outp, inp, copylen);
+ outp += copylen;
+ memcpy(outp, replacement.ptr, repl_len);
+ outp += repl_len;
+ inp += copylen + search_len;
+ tmp = cx_strsubs(tmp, search_len);
+ }
- // Free index buffer
- cx_strrepl_free_ibuf(&ibuf);
+ // add the remaining string
+ size_t copylen = in_len - (inp - str.ptr);
+ memcpy(outp, inp, copylen);
+ out.ptr[out_len] = '\0';
- return result;
+ return out;
}
CxStrtokCtx cx_strtok_(
int ret_elem = sfunc(elem, node);
if (ret_elem == 0) {
// if found, exit the search
- *result = (void *) elem;
+ *result = elem;
ret = 0;
break;
} else if (ret_elem > 0 && ret_elem < ret) {
// new distance is better
*result = elem;
ret = ret_elem;
- } else {
+ } else if (ret_elem < 0 || ret_elem > ret) {
// not contained or distance is worse, skip entire subtree
cxTreeIteratorContinue(iter);
}
if (children == NULL) {
// search for the next node
- void *next;
+ void *next = NULL;
cx_tree_iter_search_next:
- // check if there is a sibling
+ // check if there is a sibling, but only if we are not a (subtree-)root
if (iter->exiting) {
next = iter->node_next;
- } else {
+ } else if (iter->depth > 1) {
next = tree_next(iter->node);
iter->node_next = next;
}
// invalidate the iterator and free the node stack
iter->node = iter->node_next = NULL;
iter->stack_capacity = iter->depth = 0;
- free(iter->stack);
+ cxFreeDefault(iter->stack);
iter->stack = NULL;
} else {
// the parent node can be obtained from the top of stack
iter.node = root;
if (root != NULL) {
iter.stack_capacity = 16;
- iter.stack = malloc(sizeof(void *) * 16);
+ iter.stack = cxMallocDefault(sizeof(void *) * 16);
iter.stack[0] = root;
iter.counter = 1;
iter.depth = 1;
node = tree_next(node);
while (node != NULL) {
struct cx_tree_visitor_queue_s *q;
- q = malloc(sizeof(struct cx_tree_visitor_queue_s));
+ q = cxMallocDefault(sizeof(struct cx_tree_visitor_queue_s));
q->depth = iter->queue_last->depth;
q->node = node;
iter->queue_last->next = q;
}
if (children != NULL) {
struct cx_tree_visitor_queue_s *q;
- q = malloc(sizeof(struct cx_tree_visitor_queue_s));
+ q = cxMallocDefault(sizeof(struct cx_tree_visitor_queue_s));
q->depth = iter->depth + 1;
q->node = children;
if (iter->queue_last == NULL) {
assert(iter->queue_last == q);
iter->queue_last = NULL;
}
- free(q);
+ cxFreeDefault(q);
}
// increment the node counter
include common/objs.mk
-UI_LIB = ../build/lib/$(LIB_PREFIX)uitk$(LIB_EXT)
+UI_LIB = ../build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)uitk$(LIB_EXT)
+UI_SHLIB = ../build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)uitk$(SHLIB_EXT)
include $(TOOLKIT)/objs.mk
OBJ = $(TOOLKITOBJS) $(COMMONOBJS)
-all: $(UI_LIB)
+all: $(UI_LIB) $(UI_SHLIB)
include $(TOOLKIT)/Makefile
$(COMMON_OBJPRE)uic_%$(OBJ_EXT): common/%.c
- $(CC) -o $@ -c -I../ucx/ $(CFLAGS) $(TK_CFLAGS) $<
+ $(CC) -o $@ -c -I../ucx/ $(CFLAGS) $(SHLIB_CFLAGS) $(TK_CFLAGS) $<
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "args.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "../ui/container.h"
+
+/* ---------------------------- UiMenuItemArgs ---------------------------- */
+
+UiMenuItemArgs* ui_menuitem_args_new(void) {
+ UiMenuItemArgs *args = malloc(sizeof(UiMenuItemArgs));
+ memset(args, 0, sizeof(UiMenuItemArgs));
+ return args;
+}
+
+void ui_menuitem_args_set_label(UiMenuItemArgs *args, const char *label) {
+ args->label = strdup(label);
+}
+
+void ui_menuitem_args_set_stockid(UiMenuItemArgs *args, const char *stockid) {
+ args->stockid = strdup(stockid);
+}
+
+void ui_menuitem_args_set_icon(UiMenuItemArgs *args, const char *icon) {
+ args->icon = strdup(icon);
+}
+
+void ui_menuitem_args_set_onclick(UiMenuItemArgs *args, ui_callback callback) {
+ args->onclick = callback;
+}
+
+void ui_menuitem_args_set_onclickdata(UiMenuItemArgs *args, void *onclickdata) {
+ args->onclickdata = onclickdata;
+}
+
+void ui_menuitem_args_free(UiMenuItemArgs *args) {
+ free((void*)args->label);
+ free((void*)args->stockid);
+ free((void*)args->icon);
+ free(args);
+}
+
+
+/* ---------------------------- UiMenuToggleItemArgs ---------------------------- */
+
+UiMenuToggleItemArgs* ui_menutoggleitem_args_new(void) {
+ UiMenuToggleItemArgs *args = malloc(sizeof(UiMenuToggleItemArgs));
+ memset(args, 0, sizeof(UiMenuToggleItemArgs));
+ return args;
+}
+
+void ui_menutoggleitem_args_set_label(UiMenuToggleItemArgs *args, const char *label) {
+ args->label = strdup(label);
+}
+
+void ui_menutoggleitem_args_set_stockid(UiMenuToggleItemArgs *args, const char *stockid) {
+ args->stockid = strdup(stockid);
+}
+
+void ui_menutoggleitem_args_set_icon(UiMenuToggleItemArgs *args, const char *icon) {
+ args->icon = strdup(icon);
+}
+
+void ui_menutoggleitem_args_set_varname(UiMenuToggleItemArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_menutoggleitem_args_set_onchange(UiMenuToggleItemArgs *args, ui_callback callback) {
+ args->onchange = callback;
+}
+
+void ui_menutoggleitem_args_set_onchangedata(UiMenuToggleItemArgs *args, void *onclickdata) {
+ args->onchangedata = onclickdata;
+}
+
+void ui_menutoggleitem_args_free(UiMenuToggleItemArgs *args) {
+ free((void*)args->label);
+ free((void*)args->stockid);
+ free((void*)args->icon);
+ free((void*)args->varname);
+ free(args);
+}
+
+/* --------------------------- UiMenuItemListArgs --------------------------- */
+
+UiMenuItemListArgs* ui_menuitemlist_args_new(void) {
+ UiMenuItemListArgs *args = malloc(sizeof(UiMenuItemListArgs));
+ memset(args, 0, sizeof(UiMenuItemListArgs));
+ return args;
+}
+
+void ui_menuitemlist_args_set_varname(UiMenuItemListArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_menuitemlist_args_set_getvalue(UiMenuItemListArgs *args, ui_getvaluefunc func) {
+ args->getvalue = func;
+}
+
+void ui_menuitemlist_args_set_onselect(UiMenuItemListArgs *args, ui_callback callback) {
+ args->onselect = callback;
+}
+
+void ui_menuitemlist_args_set_onselectdata(UiMenuItemListArgs *args, void *data){
+ args->onselectdata = data;
+}
+
+void ui_menuitemlist_args_set_addseparator(UiMenuItemListArgs *args, UiBool value) {
+ args->addseparator = value;
+}
+
+void ui_menuitemlist_args_free(UiMenuItemListArgs *args){
+ free((void*)args->varname);
+ free(args);
+}
+
+/* --------------------------- UiToolbarItemArgs --------------------------- */
+
+UiToolbarItemArgs* ui_toolbar_item_args_new(void) {
+ UiToolbarItemArgs *args = malloc(sizeof(UiToolbarItemArgs));
+ memset(args, 0, sizeof(UiToolbarItemArgs));
+ return args;
+}
+
+void ui_toolbar_item_args_set_label(UiToolbarItemArgs *args, const char *label) {
+ args->label = strdup(label);
+}
+
+void ui_toolbar_item_args_set_stockid(UiToolbarItemArgs *args, const char *stockid) {
+ args->stockid = strdup(stockid);
+}
+
+void ui_toolbar_item_args_set_icon(UiToolbarItemArgs *args, const char *icon) {
+ args->icon = strdup(icon);
+}
+
+void ui_toolbar_item_args_set_onclick(UiToolbarItemArgs *args, ui_callback callback) {
+ args->onclick = callback;
+}
+
+void ui_toolbar_item_args_set_onclickdata(UiToolbarItemArgs *args, void *onclickdata) {
+ args->onclickdata = onclickdata;
+}
+
+void ui_toolbar_item_args_set_groups(UiToolbarItemArgs *args, int *groups) {
+ // TODO
+}
+void ui_toolbar_item_args_free(UiToolbarItemArgs *args) {
+ free((void*)args->label);
+ free((void*)args->stockid);
+ free((void*)args->icon);
+ free(args);
+}
+
+/* ---------------------------- UiToolbarToggleItemArgs ---------------------------- */
+
+UiToolbarToggleItemArgs* ui_toolbar_toggleitem_args_new(void) {
+ UiToolbarToggleItemArgs *args = malloc(sizeof(UiToolbarToggleItemArgs));
+ memset(args, 0, sizeof(UiToolbarToggleItemArgs));
+ return args;
+}
+
+
+void ui_toolbar_toggleitem_args_set_label(UiToolbarToggleItemArgs *args, const char *label) {
+ args->label = strdup(label);
+}
+
+
+void ui_toolbar_toggleitem_args_set_stockid(UiToolbarToggleItemArgs *args, const char *stockid) {
+ args->stockid = strdup(stockid);
+}
+
+
+void ui_toolbar_toggleitem_args_set_icon(UiToolbarToggleItemArgs *args, const char *icon) {
+ args->icon = strdup(icon);
+}
+
+
+void ui_toolbar_toggleitem_args_set_varname(UiToolbarToggleItemArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+
+void ui_toolbar_toggleitem_args_set_onchange(UiToolbarToggleItemArgs *args, ui_callback callback) {
+ args->onchange = callback;
+}
+
+
+void ui_toolbar_toggleitem_args_set_onchangedata(UiToolbarToggleItemArgs *args, void *onchangedata) {
+ args->onchangedata = onchangedata;
+}
+
+
+void ui_toolbar_toggleitem_args_set_groups(UiToolbarToggleItemArgs *args, int *groups) {
+ // TODO
+}
+
+
+void ui_toolbar_toggleitem_args_free(UiToolbarToggleItemArgs *args) {
+ free((void*)args->label);
+ free((void*)args->stockid);
+ free((void*)args->icon);
+ free((void*)args->varname);
+ free(args);
+}
+
+/* ---------------------------- UiToolbarMenuArgs ---------------------------- */
+
+
+UiToolbarMenuArgs* ui_toolbar_menu_args_new(void) {
+ UiToolbarMenuArgs *args = malloc(sizeof(UiToolbarMenuArgs));
+ memset(args, 0, sizeof(UiToolbarMenuArgs));
+ return args;
+}
+
+
+void ui_toolbar_menu_args_set_label(UiToolbarMenuArgs *args, const char *label) {
+ args->label = strdup(label);
+}
+
+
+void ui_toolbar_menu_args_set_stockid(UiToolbarMenuArgs *args, const char *stockid) {
+ args->stockid = strdup(stockid);
+}
+
+
+void ui_toolbar_menu_args_set_icon(UiToolbarMenuArgs *args, const char *icon) {
+ args->icon = strdup(icon);
+}
+
+
+void ui_toolbar_menu_args_free(UiToolbarMenuArgs *args) {
+ free((void*)args->label);
+ free((void*)args->stockid);
+ free((void*)args->icon);
+ free(args);
+}
+
+
+/* ---------------------------- UiContainerArgs ---------------------------- */
+
+UiContainerArgs* ui_container_args_new(void) {
+ UiContainerArgs *args = malloc(sizeof(UiContainerArgs));
+ memset(args, 0, sizeof(UiContainerArgs));
+ return args;
+}
+
+void ui_container_args_set_fill(UiContainerArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+void ui_container_args_set_hexpand(UiContainerArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_container_args_set_vexpand(UiContainerArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_container_args_set_hfill(UiContainerArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_container_args_set_vfill(UiContainerArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_container_args_set_override_defaults(UiContainerArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_container_args_set_colspan(UiContainerArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_container_args_set_rowspan(UiContainerArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_container_args_set_def_hexpand(UiContainerArgs *args, UiBool value) {
+ args->def_hexpand = value;
+}
+
+
+void ui_container_args_set_def_vexpand(UiContainerArgs *args, UiBool value) {
+ args->def_vexpand = value;
+}
+
+
+void ui_container_args_set_def_hfill(UiContainerArgs *args, UiBool value) {
+ args->def_hfill = value;
+}
+
+
+void ui_container_args_set_def_vfill(UiContainerArgs *args, UiBool value) {
+ args->def_vfill = value;
+}
+
+
+void ui_container_args_set_name(UiContainerArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_container_args_set_style_class(UiContainerArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+
+void ui_container_args_set_margin(UiContainerArgs *args, int value) {
+ args->margin = value;
+}
+
+
+void ui_container_args_set_spacing(UiContainerArgs *args, int value) {
+ args->spacing = value;
+}
+
+
+void ui_container_args_set_columnspacing(UiContainerArgs *args, int value) {
+ args->columnspacing = value;
+}
+
+
+void ui_container_args_set_rowspacing(UiContainerArgs *args, int value) {
+ args->rowspacing = value;
+}
+
+
+void ui_container_args_free(UiContainerArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free(args);
+}
+
+
+/* ------------------------------- UiFrameArgs ------------------------------*/
+
+UiFrameArgs* ui_frame_args_new(void) {
+ UiFrameArgs *args = malloc(sizeof(UiFrameArgs));
+ memset(args, 0, sizeof(UiContainerArgs));
+ return args;
+}
+
+
+void ui_frame_args_set_fill(UiFrameArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_frame_args_set_hexpand(UiFrameArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_frame_args_set_vexpand(UiFrameArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_frame_args_set_hfill(UiFrameArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_frame_args_set_vfill(UiFrameArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_frame_args_set_override_defaults(UiFrameArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_frame_args_set_colspan(UiFrameArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_frame_args_set_rowspan(UiFrameArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_frame_args_set_name(UiFrameArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_frame_args_set_style_class(UiFrameArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+
+void ui_frame_args_set_margin(UiFrameArgs *args, int value) {
+ args->margin = value;
+}
+
+
+void ui_frame_args_set_spacing(UiFrameArgs *args, int value) {
+ args->spacing = value;
+}
+
+
+void ui_frame_args_set_columnspacing(UiFrameArgs *args, int value) {
+ args->columnspacing = value;
+}
+
+
+void ui_frame_args_set_rowspacing(UiFrameArgs *args, int value) {
+ args->rowspacing = value;
+}
+
+
+void ui_frame_args_set_expanded(UiFrameArgs *args, UiBool value) {
+ args->isexpanded = value;
+}
+
+
+void ui_frame_args_set_label(UiFrameArgs *args, const char *label) {
+ args->label = strdup(label);
+}
+
+
+void ui_frame_args_free(UiFrameArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->label);
+ free(args);
+}
+
+
+/* ---------------------------- UiSidebarArgs -------------------------------*/
+
+UiSidebarArgs* ui_sidebar_args_new(void) {
+ UiSidebarArgs *args = malloc(sizeof(UiSidebarArgs));
+ memset(args, 0, sizeof(UiSidebarArgs));
+ return args;
+}
+
+
+void ui_sidebar_args_set_name(UiSidebarArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_sidebar_args_set_style_class(UiSidebarArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+
+void ui_sidebar_args_set_margin(UiSidebarArgs *args, int value) {
+ args->margin = value;
+}
+
+
+void ui_sidebar_args_set_spacing(UiSidebarArgs *args, int value) {
+ args->spacing = value;
+}
+
+
+void ui_sidebar_args_free(UiSidebarArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free(args);
+}
+
+
+/* --------------------------- UiSplitPaneArgs ------------------------------*/
+
+UiSplitPaneArgs* ui_splitpane_args_new(void) {
+ UiSplitPaneArgs *args = malloc(sizeof(UiSplitPaneArgs));
+ memset(args, 0, sizeof(UiSplitPaneArgs));
+ return args;
+}
+
+
+void ui_splitpane_args_set_fill(UiSplitPaneArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_splitpane_args_set_hexpand(UiSplitPaneArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_splitpane_args_set_vexpand(UiSplitPaneArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_splitpane_args_set_hfill(UiSplitPaneArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_splitpane_args_set_vfill(UiSplitPaneArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_splitpane_args_set_override_defaults(UiSplitPaneArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_splitpane_args_set_colspan(UiSplitPaneArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_splitpane_args_set_rowspan(UiSplitPaneArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_splitpane_args_set_name(UiSplitPaneArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_splitpane_args_set_style_class(UiSplitPaneArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+
+void ui_splitpane_args_set_margin(UiSplitPaneArgs *args, int value) {
+ args->margin = value;
+}
+
+
+void ui_splitpane_args_set_spacing(UiSplitPaneArgs *args, int value) {
+ args->spacing = value;
+}
+
+
+void ui_splitpane_args_set_columnspacing(UiSplitPaneArgs *args, int value) {
+ args->columnspacing = value;
+}
+
+
+void ui_splitpane_args_set_rowspacing(UiSplitPaneArgs *args, int value) {
+ args->rowspacing = value;
+}
+
+
+void ui_splitpane_args_set_initial_position(UiSplitPaneArgs *args, int pos) {
+ args->initial_position = pos;
+}
+
+
+void ui_splitpane_args_set_varname(UiSplitPaneArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+
+void ui_splitpane_args_set_value(UiSplitPaneArgs *args, UiInteger *value) {
+ args->value = value;
+}
+
+void ui_splitpane_args_set_max_panes(UiSplitPaneArgs *args, int max) {
+ args->max_panes = max;
+}
+
+
+void ui_splitpane_args_free(UiSplitPaneArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->varname);
+ free(args);
+}
+
+
+/* ------------------------- UiLabelArgs ----------------------------*/
+
+
+UiLabelArgs* ui_label_args_new(void) {
+ UiLabelArgs *args = malloc(sizeof(UiLabelArgs));
+ memset(args, 0, sizeof(UiLabelArgs));
+ return args;
+}
+
+
+void ui_label_args_set_fill(UiLabelArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_label_args_set_hexpand(UiLabelArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_label_args_set_vexpand(UiLabelArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_label_args_set_hfill(UiLabelArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_label_args_set_vfill(UiLabelArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_label_args_set_override_defaults(UiLabelArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_label_args_set_colspan(UiLabelArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_label_args_set_rowspan(UiLabelArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_label_args_set_name(UiLabelArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_label_args_set_style_class(UiLabelArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_label_args_set_label(UiLabelArgs *args, const char *label){
+ args->label = strdup(label);
+}
+
+
+void ui_label_args_set_align(UiLabelArgs *args, UiAlignment align) {
+ args->align = align;
+}
+
+void ui_label_args_set_style(UiLabelArgs *args, UiLabelStyle style) {
+ args->style = style;
+}
+
+void ui_label_args_set_varname(UiLabelArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_label_args_set_value(UiLabelArgs *args, UiString *value) {
+ args->value = value;
+}
+
+void ui_label_args_free(UiLabelArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->label);
+ free((void*)args->varname);
+ free(args);
+}
+
+
+/* ------------------------- UiProgressbarArgs ----------------------------*/
+
+
+UiProgressbarArgs* ui_progressbar_args_new(void) {
+ UiProgressbarArgs *args = malloc(sizeof(UiProgressbarArgs));
+ memset(args, 0, sizeof(UiProgressbarArgs));
+ return args;
+}
+
+
+void ui_progressbar_args_set_fill(UiProgressbarArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_progressbar_args_set_hexpand(UiProgressbarArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_progressbar_args_set_vexpand(UiProgressbarArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_progressbar_args_set_hfill(UiProgressbarArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_progressbar_args_set_vfill(UiProgressbarArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_progressbar_args_set_override_defaults(UiProgressbarArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_progressbar_args_set_colspan(UiProgressbarArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_progressbar_args_set_rowspan(UiProgressbarArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_progressbar_args_set_name(UiProgressbarArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_progressbar_args_set_style_class(UiProgressbarArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_progressbar_args_set_min(UiProgressbarArgs *args, double min) {
+ args->min = min;
+}
+
+void ui_progressbar_args_set_max(UiProgressbarArgs *args, double max) {
+ args->max = max;
+}
+
+void ui_progressbar_args_set_varname(UiProgressbarArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_progressbar_args_set_value(UiProgressbarArgs *args, UiDouble *value) {
+ args->value = value;
+}
+
+void ui_progressbar_args_free(UiProgressbarArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->varname);
+ free(args);
+}
+
+
+/* ------------------------- UiProgressbarSpinnerArgs ----------------------------*/
+
+UiProgressbarSpinnerArgs* ui_progress_spinner_args_new(void) {
+ UiProgressbarSpinnerArgs *args = malloc(sizeof(UiProgressbarSpinnerArgs));
+ memset(args, 0, sizeof(UiProgressbarSpinnerArgs));
+ return args;
+}
+
+void ui_progress_spinner_args_set_fill(UiProgressbarSpinnerArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+void ui_progress_spinner_args_set_hexpand(UiProgressbarSpinnerArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+void ui_progress_spinner_args_set_vexpand(UiProgressbarSpinnerArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+void ui_progress_spinner_args_set_hfill(UiProgressbarSpinnerArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+void ui_progress_spinner_args_set_vfill(UiProgressbarSpinnerArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+void ui_progress_spinner_args_set_override_defaults(UiProgressbarSpinnerArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+void ui_progress_spinner_args_set_colspan(UiProgressbarSpinnerArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+void ui_progress_spinner_args_set_rowspan(UiProgressbarSpinnerArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+void ui_progress_spinner_args_set_name(UiProgressbarSpinnerArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+void ui_progress_spinner_args_set_style_class(UiProgressbarSpinnerArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_progress_spinner_args_set_varname(UiProgressbarSpinnerArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_progress_spinner_args_set_value(UiProgressbarSpinnerArgs *args, UiInteger *value) {
+ args->value = value;
+}
+
+void ui_progress_spinner_args_free(UiProgressbarSpinnerArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->varname);
+ free(args);
+}
+
+
+/* ---------------------------- UiButtonArgs -------------------------------*/
+
+UiButtonArgs* ui_button_args_new(void) {
+ UiButtonArgs *args = malloc(sizeof(UiButtonArgs));
+ memset(args, 0, sizeof(UiButtonArgs));
+ return args;
+}
+
+
+void ui_button_args_set_fill(UiButtonArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_button_args_set_hexpand(UiButtonArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_button_args_set_vexpand(UiButtonArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_button_args_set_hfill(UiButtonArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_button_args_set_vfill(UiButtonArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_button_args_set_override_defaults(UiButtonArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_button_args_set_colspan(UiButtonArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_button_args_set_rowspan(UiButtonArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_button_args_set_name(UiButtonArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_button_args_set_style_class(UiButtonArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_button_args_set_label(UiButtonArgs *args, const char *label){
+ args->label = strdup(label);
+}
+
+
+void ui_button_args_set_stockid(UiButtonArgs *args, const char *stockid){
+ args->stockid = strdup(stockid);
+}
+
+
+void ui_button_args_set_icon(UiButtonArgs *args, const char *icon){
+ args->icon = strdup(icon);
+}
+
+
+void ui_button_args_set_labeltype(UiButtonArgs *args, int labeltype){
+ args->labeltype = labeltype;
+}
+
+void ui_button_args_set_onclick(UiButtonArgs *args, ui_callback callback){
+ args->onclick = callback;
+}
+
+
+void ui_button_args_set_onclickdata(UiButtonArgs *args, void *onclickdata){
+ args->onclickdata = onclickdata;
+}
+
+void ui_button_args_set_groups(UiButtonArgs *args, int *groups){
+ // TODO
+}
+
+void ui_button_args_free(UiButtonArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->label);
+ free((void*)args->stockid);
+ free((void*)args->icon);
+ free((void*)args->groups);
+ free(args);
+}
+
+
+/* ------------------------- UiToggleArgs ----------------------------*/
+
+
+UiToggleArgs* ui_toggle_args_new(void) {
+ UiToggleArgs *args = malloc(sizeof(UiToggleArgs));
+ memset(args, 0, sizeof(UiToggleArgs));
+ return args;
+}
+
+
+void ui_toggle_args_set_fill(UiToggleArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_toggle_args_set_hexpand(UiToggleArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_toggle_args_set_vexpand(UiToggleArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_toggle_args_set_hfill(UiToggleArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_toggle_args_set_vfill(UiToggleArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_toggle_args_set_override_defaults(UiToggleArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_toggle_args_set_colspan(UiToggleArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_toggle_args_set_rowspan(UiToggleArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_toggle_args_set_name(UiToggleArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_toggle_args_set_style_class(UiToggleArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_toggle_args_set_label(UiToggleArgs *args, const char *label){
+ args->label = strdup(label);
+}
+
+
+void ui_toggle_args_set_stockid(UiToggleArgs *args, const char *stockid){
+ args->stockid = strdup(stockid);
+}
+
+
+void ui_toggle_args_set_icon(UiToggleArgs *args, const char *icon){
+ args->icon = strdup(icon);
+}
+
+
+void ui_toggle_args_set_labeltype(UiToggleArgs *args, int labeltype){
+ args->labeltype = labeltype;
+}
+
+void ui_toggle_args_set_onchange(UiToggleArgs *args, ui_callback callback){
+ args->onchange = callback;
+}
+
+
+void ui_toggle_args_set_onchangedata(UiToggleArgs *args, void *onchangedata){
+ args->onchangedata = onchangedata;
+}
+
+void ui_toggle_args_set_varname(UiToggleArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_toggle_args_set_value(UiToggleArgs *args, UiInteger *value) {
+ args->value = value;
+}
+
+void ui_toggle_args_set_enablegroup(UiToggleArgs *args, int group) {
+ args->enable_group = group;
+}
+
+void ui_toggle_args_set_groups(UiToggleArgs *args, int *groups){
+ // TODO
+}
+
+void ui_toggle_args_free(UiToggleArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->label);
+ free((void*)args->stockid);
+ free((void*)args->icon);
+ free((void*)args->varname);
+ free((void*)args->groups);
+ free(args);
+}
+
+
+/* ------------------------- UiListArgs ----------------------------*/
+
+UiListArgs* ui_list_args_new(void) {
+ UiListArgs *args = malloc(sizeof(UiListArgs));
+ memset(args, 0, sizeof(UiListArgs));
+ return args;
+}
+
+void ui_list_args_set_fill(UiListArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+void ui_list_args_set_hexpand(UiListArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+void ui_list_args_set_vexpand(UiListArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+void ui_list_args_set_hfill(UiListArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+void ui_list_args_set_vfill(UiListArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+void ui_list_args_set_override_defaults(UiListArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+void ui_list_args_set_colspan(UiListArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+void ui_list_args_set_rowspan(UiListArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+void ui_list_args_set_name(UiListArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+void ui_list_args_set_style_class(UiListArgs *args, const char *classname) {
+ args->style_class = classname;
+}
+
+void ui_list_args_set_varname(UiListArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_list_args_set_value(UiListArgs *args, UiList *value) {
+ args->list = value;
+}
+
+void ui_list_args_set_model(UiListArgs *args, UiModel *model) {
+ args->model = model;
+}
+
+void ui_list_args_set_static_elements(UiListArgs *args, char **strarray, size_t nelm) {
+ char **array = calloc(nelm, sizeof(char*));
+ for(int i=0;i<nelm;i++) {
+ array[i] = strdup(strarray[i]);
+ }
+ args->static_elements = array;
+ args->static_nelm = nelm;
+}
+
+void ui_list_args_set_getvalue_func(UiListArgs *args, ui_getvaluefunc getvalue) {
+ args->getvalue = getvalue;
+}
+
+void ui_list_args_set_getvalue_func2(UiListArgs *args, ui_getvaluefunc2 getvalue) {
+ args->getvalue2 = getvalue;
+}
+
+void ui_list_args_set_getvalue_data(UiListArgs *args, void *userdata) {
+ args->getvalue2data = userdata;
+}
+
+void ui_list_args_set_onactivate(UiListArgs *args, ui_callback callback) {
+ args->onactivate = callback;
+}
+
+void ui_list_args_set_onactivatedata(UiListArgs *args, void *userdata) {
+ args->onactivatedata = userdata;
+}
+
+void ui_list_args_set_onselection(UiListArgs *args, ui_callback callback) {
+ args->onselection = callback;
+}
+
+void ui_list_args_set_onselectiondata(UiListArgs *args, void *userdata) {
+ args->onselectiondata = userdata;
+}
+
+void ui_list_args_set_ondragstart(UiListArgs *args, ui_callback callback) {
+ args->ondragstart = callback;
+}
+
+void ui_list_args_set_ondragstartdata(UiListArgs *args, void *userdata) {
+ args->ondragstartdata = userdata;
+}
+
+void ui_list_args_set_ondragcomplete(UiListArgs *args, ui_callback callback) {
+ args->ondragcomplete = callback;
+}
+
+void ui_list_args_set_ondragcompletedata(UiListArgs *args, void *userdata) {
+ args->ondragcompletedata = userdata;
+}
+
+void ui_list_args_set_ondrop(UiListArgs *args, ui_callback callback) {
+ args->ondrop = callback;
+}
+
+void ui_list_args_set_ondropdata(UiListArgs *args, void *userdata) {
+ args->ondropdata = userdata;
+}
+
+void ui_list_args_set_multiselection(UiListArgs *args, UiBool multiselection) {
+ args->multiselection = multiselection;
+}
+
+void ui_list_args_set_contextmenu(UiListArgs *args, UiMenuBuilder *menubuilder) {
+ args->contextmenu = menubuilder;
+}
+
+void ui_list_args_set_groups(UiListArgs *args, int *groups) {
+ // TODO
+}
+
+void ui_list_args_free(UiListArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->varname);
+ if(args->static_elements) {
+ for(int i=0;i<args->static_nelm;i++) {
+ free(args->static_elements[i]);
+ }
+ free(args->static_elements);
+ }
+ free(args);
+}
+
+
+
+/* ---------------------- SurceList ------------------------------------- */
+
+UiSourceListArgs* ui_sourcelist_args_new(void) {
+ UiSourceListArgs *args = malloc(sizeof(UiSourceListArgs));
+ memset(args, 0, sizeof(UiSourceListArgs));
+ return args;
+}
+
+
+void ui_sourcelist_args_set_fill(UiSourceListArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_sourcelist_args_set_hexpand(UiSourceListArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_sourcelist_args_set_vexpand(UiSourceListArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_sourcelist_args_set_hfill(UiSourceListArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_sourcelist_args_set_vfill(UiSourceListArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_sourcelist_args_set_override_defaults(UiSourceListArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_sourcelist_args_set_colspan(UiSourceListArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_sourcelist_args_set_rowspan(UiSourceListArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_sourcelist_args_set_name(UiSourceListArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_sourcelist_args_set_style_class(UiSourceListArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+UIEXPORT void ui_sourcelist_args_set_static_sublists(UiSourceListArgs *args, UiSubList *sublists, size_t numsublists) {
+ args->sublists = calloc(numsublists, sizeof(UiSubList));
+ memcpy(args->sublists, sublists, numsublists * sizeof(UiSubList));
+ args->numsublists = numsublists;
+}
+
+void ui_sourcelist_args_set_varname(UiSourceListArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+
+void ui_sourcelist_args_set_dynamic_sublists(UiSourceListArgs *args, UiList *value) {
+ args->dynamic_sublist = value;
+}
+
+
+void ui_sourcelist_args_set_getvalue_func(UiSourceListArgs *args, ui_sublist_getvalue_func getvalue) {
+ args->getvalue = getvalue;
+}
+
+void ui_sourcelist_args_set_getvalue_userdata(UiSourceListArgs *args, void *userdata) {
+ args->getvaluedata = userdata;
+}
+
+void ui_sourcelist_args_set_onactivate(UiSourceListArgs *args, ui_callback callback) {
+ args->onactivate = callback;
+}
+
+
+void ui_sourcelist_args_set_onactivatedata(UiSourceListArgs *args, void *userdata) {
+ args->onactivatedata = userdata;
+}
+
+
+void ui_sourcelist_args_set_onbuttonclick(UiSourceListArgs *args, ui_callback callback) {
+ args->onbuttonclick = callback;
+
+}
+
+
+void ui_sourcelist_args_set_onbuttonclickdata(UiSourceListArgs *args, void *userdata) {
+ args->onbuttonclickdata = userdata;
+}
+
+
+void ui_sourcelist_args_free(UiSourceListArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->varname);
+ free((void*)args->sublists);
+ free(args);
+}
+
+
+/* ------------------------- UiTextAreaArgs ----------------------------*/
+
+UiTextAreaArgs* ui_textarea_args_new(void) {
+ UiTextAreaArgs *args = malloc(sizeof(UiTextAreaArgs));
+ memset(args, 0, sizeof(UiTextAreaArgs));
+ return args;
+}
+
+
+void ui_textarea_args_set_fill(UiTextAreaArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_textarea_args_set_hexpand(UiTextAreaArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_textarea_args_set_vexpand(UiTextAreaArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_textarea_args_set_hfill(UiTextAreaArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_textarea_args_set_vfill(UiTextAreaArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_textarea_args_set_override_defaults(UiTextAreaArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_textarea_args_set_colspan(UiTextAreaArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_textarea_args_set_rowspan(UiTextAreaArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_textarea_args_set_name(UiTextAreaArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_textarea_args_set_style_class(UiTextAreaArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_textarea_args_set_onchange(UiTextAreaArgs *args, ui_callback callback){
+ args->onchange = callback;
+}
+
+
+void ui_textarea_args_set_onchangedata(UiTextAreaArgs *args, void *onchangedata){
+ args->onchangedata = onchangedata;
+}
+
+void ui_textarea_args_set_varname(UiTextAreaArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_textarea_args_set_value(UiTextAreaArgs *args, UiText *value) {
+ args->value = value;
+}
+
+void ui_textarea_args_set_groups(UiTextAreaArgs *args, int *groups){
+ // TODO
+}
+
+void ui_textarea_args_free(UiTextAreaArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->varname);
+ free((void*)args->groups);
+ free(args);
+}
+
+
+
+/* ------------------------- UiTextFieldArgs ----------------------------*/
+
+UiTextFieldArgs* ui_textfield_args_new(void) {
+ UiTextFieldArgs *args = malloc(sizeof(UiTextFieldArgs));
+ memset(args, 0, sizeof(UiTextFieldArgs));
+ return args;
+}
+
+
+void ui_textfield_args_set_fill(UiTextFieldArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_textfield_args_set_hexpand(UiTextFieldArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_textfield_args_set_vexpand(UiTextFieldArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_textfield_args_set_hfill(UiTextFieldArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_textfield_args_set_vfill(UiTextFieldArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_textfield_args_set_override_defaults(UiTextFieldArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_textfield_args_set_colspan(UiTextFieldArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_textfield_args_set_rowspan(UiTextFieldArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_textfield_args_set_name(UiTextFieldArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_textfield_args_set_style_class(UiTextFieldArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_textfield_args_set_onchange(UiTextFieldArgs *args, ui_callback callback){
+ args->onchange = callback;
+}
+
+
+void ui_textfield_args_set_onchangedata(UiTextFieldArgs *args, void *onchangedata){
+ args->onchangedata = onchangedata;
+}
+
+void ui_textfield_args_set_onactivate(UiTextFieldArgs *args, ui_callback callback){
+ args->onactivate = callback;
+}
+
+
+void ui_textfield_args_set_onactivatedata(UiTextFieldArgs *args, void *onactivatedata){
+ args->onactivatedata = onactivatedata;
+}
+
+void ui_textfield_args_set_varname(UiTextFieldArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_textfield_args_set_value(UiTextFieldArgs *args, UiString *value) {
+ args->value = value;
+}
+
+void ui_textfield_args_set_groups(UiTextFieldArgs *args, int *groups){
+ // TODO
+}
+
+void ui_textfield_args_free(UiTextFieldArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->varname);
+ free((void*)args->groups);
+ free(args);
+}
+
+
+/* ------------------------- UiWebviewArgs ----------------------------*/
+
+UiWebviewArgs* ui_webview_args_new(void) {
+ UiWebviewArgs *args = malloc(sizeof(UiWebviewArgs));
+ memset(args, 0, sizeof(UiWebviewArgs));
+ return args;
+}
+
+
+void ui_webview_args_set_fill(UiWebviewArgs *args, UiBool fill) {
+ args->fill = fill ? UI_ON : UI_OFF;
+}
+
+
+void ui_webview_args_set_hexpand(UiWebviewArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+
+void ui_webview_args_set_vexpand(UiWebviewArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+
+void ui_webview_args_set_hfill(UiWebviewArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+
+void ui_webview_args_set_vfill(UiWebviewArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+
+void ui_webview_args_set_override_defaults(UiWebviewArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+
+void ui_webview_args_set_colspan(UiWebviewArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+
+void ui_webview_args_set_rowspan(UiWebviewArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_webview_args_set_name(UiWebviewArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+
+void ui_webview_args_set_style_class(UiWebviewArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_webview_args_set_varname(UiWebviewArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_webview_args_set_value(UiWebviewArgs *args, UiGeneric *value) {
+ args->value = value;
+}
+
+void ui_webview_args_set_groups(UiWebviewArgs *args, int *groups){
+ // TODO
+}
+
+void ui_webview_args_free(UiWebviewArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->varname);
+ free((void*)args->groups);
+ free(args);
+}
+
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UIC_ARGS_H
+#define UIC_ARGS_H
+
+#include "../ui/container.h"
+#include "../ui/display.h"
+#include "../ui/button.h"
+#include "../ui/menu.h"
+#include "../ui/toolbar.h"
+#include "../ui/tree.h"
+#include "../ui/text.h"
+#include "../ui/webview.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+UIEXPORT UiMenuItemArgs* ui_menuitem_args_new(void);
+UIEXPORT void ui_menuitem_args_set_label(UiMenuItemArgs *args, const char *label);
+UIEXPORT void ui_menuitem_args_set_stockid(UiMenuItemArgs *args, const char *stockid);
+UIEXPORT void ui_menuitem_args_set_icon(UiMenuItemArgs *args, const char *icon);
+UIEXPORT void ui_menuitem_args_set_onclick(UiMenuItemArgs *args, ui_callback callback);
+UIEXPORT void ui_menuitem_args_set_onclickdata(UiMenuItemArgs *args, void *onclickdata);
+UIEXPORT void ui_menuitem_args_free(UiMenuItemArgs *args);
+
+UIEXPORT UiMenuToggleItemArgs* ui_menutoggleitem_args_new(void);
+UIEXPORT void ui_menutoggleitem_args_set_label(UiMenuToggleItemArgs *args, const char *label);
+UIEXPORT void ui_menutoggleitem_args_set_stockid(UiMenuToggleItemArgs *args, const char *stockid);
+UIEXPORT void ui_menutoggleitem_args_set_icon(UiMenuToggleItemArgs *args, const char *icon);
+UIEXPORT void ui_menutoggleitem_args_set_varname(UiMenuToggleItemArgs *args, const char *varname);
+UIEXPORT void ui_menutoggleitem_args_set_onchange(UiMenuToggleItemArgs *args, ui_callback callback);
+UIEXPORT void ui_menutoggleitem_args_set_onchangedata(UiMenuToggleItemArgs *args, void *onchangedata);
+UIEXPORT void ui_menutoggleitem_args_free(UiMenuToggleItemArgs *args);
+
+UIEXPORT UiMenuItemListArgs* ui_menuitemlist_args_new(void);
+UIEXPORT void ui_menuitemlist_args_set_varname(UiMenuItemListArgs *args, const char *varname);
+UIEXPORT void ui_menuitemlist_args_set_getvalue(UiMenuItemListArgs *args, ui_getvaluefunc func);
+UIEXPORT void ui_menuitemlist_args_set_onselect(UiMenuItemListArgs *args, ui_callback callback);
+UIEXPORT void ui_menuitemlist_args_set_onselectdata(UiMenuItemListArgs *args, void *data);
+UIEXPORT void ui_menuitemlist_args_set_addseparator(UiMenuItemListArgs *args, UiBool value);
+UIEXPORT void ui_menuitemlist_args_free(UiMenuItemListArgs *args);
+
+UIEXPORT UiToolbarItemArgs* ui_toolbar_item_args_new(void);
+UIEXPORT void ui_toolbar_item_args_set_label(UiToolbarItemArgs *args, const char *label);
+UIEXPORT void ui_toolbar_item_args_set_stockid(UiToolbarItemArgs *args, const char *stockid);
+UIEXPORT void ui_toolbar_item_args_set_icon(UiToolbarItemArgs *args, const char *icon);
+UIEXPORT void ui_toolbar_item_args_set_onclick(UiToolbarItemArgs *args, ui_callback callback);
+UIEXPORT void ui_toolbar_item_args_set_onclickdata(UiToolbarItemArgs *args, void *onclickdata);
+UIEXPORT void ui_toolbar_item_args_set_groups(UiToolbarItemArgs *args, int *groups);
+UIEXPORT void ui_toolbar_item_args_free(UiToolbarItemArgs *args);
+
+UIEXPORT UiToolbarToggleItemArgs* ui_toolbar_toggleitem_args_new(void);
+UIEXPORT void ui_toolbar_toggleitem_args_set_label(UiToolbarToggleItemArgs *args, const char *label);
+UIEXPORT void ui_toolbar_toggleitem_args_set_stockid(UiToolbarToggleItemArgs *args, const char *stockid);
+UIEXPORT void ui_toolbar_toggleitem_args_set_icon(UiToolbarToggleItemArgs *args, const char *icon);
+UIEXPORT void ui_toolbar_toggleitem_args_set_varname(UiToolbarToggleItemArgs *args, const char *varname);
+UIEXPORT void ui_toolbar_toggleitem_args_set_onchange(UiToolbarToggleItemArgs *args, ui_callback callback);
+UIEXPORT void ui_toolbar_toggleitem_args_set_onchangedata(UiToolbarToggleItemArgs *args, void *onchangedata);
+UIEXPORT void ui_toolbar_toggleitem_args_set_groups(UiToolbarToggleItemArgs *args, int *groups);
+UIEXPORT void ui_toolbar_toggleitem_args_free(UiToolbarToggleItemArgs *args);
+
+UIEXPORT UiToolbarMenuArgs* ui_toolbar_menu_args_new(void);
+UIEXPORT void ui_toolbar_menu_args_set_label(UiToolbarMenuArgs *args, const char *label);
+UIEXPORT void ui_toolbar_menu_args_set_stockid(UiToolbarMenuArgs *args, const char *stockid);
+UIEXPORT void ui_toolbar_menu_args_set_icon(UiToolbarMenuArgs *args, const char *icon);
+UIEXPORT void ui_toolbar_menu_args_free(UiToolbarMenuArgs *args);
+
+UIEXPORT UiContainerArgs* ui_container_args_new(void);
+UIEXPORT void ui_container_args_set_fill(UiContainerArgs *args, UiBool fill);
+UIEXPORT void ui_container_args_set_hexpand(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_vexpand(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_hfill(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_vfill(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_override_defaults(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_colspan(UiContainerArgs *args, int colspan);
+UIEXPORT void ui_container_args_set_rowspan(UiContainerArgs *args, int rowspan);
+UIEXPORT void ui_container_args_set_def_hexpand(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_def_vexpand(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_def_hfill(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_def_vfill(UiContainerArgs *args, UiBool value);
+UIEXPORT void ui_container_args_set_name(UiContainerArgs *args, const char *name);
+UIEXPORT void ui_container_args_set_style_class(UiContainerArgs *args, const char *classname);
+UIEXPORT void ui_container_args_set_margin(UiContainerArgs *args, int value);
+UIEXPORT void ui_container_args_set_spacing(UiContainerArgs *args, int value);
+UIEXPORT void ui_container_args_set_columnspacing(UiContainerArgs *args, int value);
+UIEXPORT void ui_container_args_set_rowspacing(UiContainerArgs *args, int value);
+UIEXPORT void ui_container_args_free(UiContainerArgs *args);
+
+
+UIEXPORT UiFrameArgs* ui_frame_args_new(void);
+UIEXPORT void ui_frame_args_set_fill(UiFrameArgs *args, UiBool fill);
+UIEXPORT void ui_frame_args_set_hexpand(UiFrameArgs *args, UiBool value);
+UIEXPORT void ui_frame_args_set_vexpand(UiFrameArgs *args, UiBool value);
+UIEXPORT void ui_frame_args_set_hfill(UiFrameArgs *args, UiBool value);
+UIEXPORT void ui_frame_args_set_vfill(UiFrameArgs *args, UiBool value);
+UIEXPORT void ui_frame_args_set_override_defaults(UiFrameArgs *args, UiBool value);
+UIEXPORT void ui_frame_args_set_colspan(UiFrameArgs *args, int colspan);
+UIEXPORT void ui_frame_args_set_rowspan(UiFrameArgs *args, int rowspan);
+UIEXPORT void ui_frame_args_set_name(UiFrameArgs *args, const char *name);
+UIEXPORT void ui_frame_args_set_style_class(UiFrameArgs *args, const char *classname);
+UIEXPORT void ui_frame_args_set_margin(UiFrameArgs *args, int value);
+UIEXPORT void ui_frame_args_set_spacing(UiFrameArgs *args, int value);
+UIEXPORT void ui_frame_args_set_columnspacing(UiFrameArgs *args, int value);
+UIEXPORT void ui_frame_args_set_rowspacing(UiFrameArgs *args, int value);
+UIEXPORT void ui_frame_args_set_expanded(UiFrameArgs *args, UiBool value);
+UIEXPORT void ui_frame_args_set_label(UiFrameArgs *args, const char *label);
+UIEXPORT void ui_frame_args_free(UiFrameArgs *args);
+
+UIEXPORT UiSidebarArgs* ui_sidebar_args_new(void);
+UIEXPORT void ui_sidebar_args_set_name(UiSidebarArgs *args, const char *name);
+UIEXPORT void ui_sidebar_args_set_style_class(UiSidebarArgs *args, const char *classname);
+UIEXPORT void ui_sidebar_args_set_margin(UiSidebarArgs *args, int value);
+UIEXPORT void ui_sidebar_args_set_spacing(UiSidebarArgs *args, int value);
+UIEXPORT void ui_sidebar_args_free(UiSidebarArgs *args);
+
+UIEXPORT UiSplitPaneArgs* ui_splitpane_args_new(void);
+UIEXPORT void ui_splitpane_args_set_fill(UiSplitPaneArgs *args, UiBool fill);
+UIEXPORT void ui_splitpane_args_set_hexpand(UiSplitPaneArgs *args, UiBool value);
+UIEXPORT void ui_splitpane_args_set_vexpand(UiSplitPaneArgs *args, UiBool value);
+UIEXPORT void ui_splitpane_args_set_hfill(UiSplitPaneArgs *args, UiBool value);
+UIEXPORT void ui_splitpane_args_set_vfill(UiSplitPaneArgs *args, UiBool value);
+UIEXPORT void ui_splitpane_args_set_override_defaults(UiSplitPaneArgs *args, UiBool value);
+UIEXPORT void ui_splitpane_args_set_colspan(UiSplitPaneArgs *args, int colspan);
+UIEXPORT void ui_splitpane_args_set_rowspan(UiSplitPaneArgs *args, int rowspan);
+UIEXPORT void ui_splitpane_args_set_name(UiSplitPaneArgs *args, const char *name);
+UIEXPORT void ui_splitpane_args_set_style_class(UiSplitPaneArgs *args, const char *classname);
+UIEXPORT void ui_splitpane_args_set_margin(UiSplitPaneArgs *args, int value);
+UIEXPORT void ui_splitpane_args_set_spacing(UiSplitPaneArgs *args, int value);
+UIEXPORT void ui_splitpane_args_set_columnspacing(UiSplitPaneArgs *args, int value);
+UIEXPORT void ui_splitpane_args_set_rowspacing(UiSplitPaneArgs *args, int value);
+UIEXPORT void ui_splitpane_args_set_initial_position(UiSplitPaneArgs *args, int pos);
+UIEXPORT void ui_splitpane_args_set_varname(UiSplitPaneArgs *args, const char *varname);
+UIEXPORT void ui_splitpane_args_set_value(UiSplitPaneArgs *args, UiInteger *value);
+UIEXPORT void ui_splitpane_args_set_max_panes(UiSplitPaneArgs *args, int max);
+UIEXPORT void ui_splitpane_args_free(UiSplitPaneArgs *args);
+
+UIEXPORT UiLabelArgs* ui_label_args_new(void);
+UIEXPORT void ui_label_args_set_fill(UiLabelArgs *args, UiBool fill);
+UIEXPORT void ui_label_args_set_hexpand(UiLabelArgs *args, UiBool value);
+UIEXPORT void ui_label_args_set_vexpand(UiLabelArgs *args, UiBool value);
+UIEXPORT void ui_label_args_set_hfill(UiLabelArgs *args, UiBool value);
+UIEXPORT void ui_label_args_set_vfill(UiLabelArgs *args, UiBool value);
+UIEXPORT void ui_label_args_set_override_defaults(UiLabelArgs *args, UiBool value);
+UIEXPORT void ui_label_args_set_colspan(UiLabelArgs *args, int colspan);
+UIEXPORT void ui_label_args_set_rowspan(UiLabelArgs *args, int rowspan);
+UIEXPORT void ui_label_args_set_name(UiLabelArgs *args, const char *name);
+UIEXPORT void ui_label_args_set_style_class(UiLabelArgs *args, const char *classname);
+UIEXPORT void ui_label_args_set_label(UiLabelArgs *args, const char *label);
+UIEXPORT void ui_label_args_set_align(UiLabelArgs *args, UiAlignment align);
+UIEXPORT void ui_label_args_set_style(UiLabelArgs *args, UiLabelStyle style);
+UIEXPORT void ui_label_args_set_value(UiLabelArgs *args, UiString *value);
+UIEXPORT void ui_label_args_set_varname(UiLabelArgs *args, const char *varname);
+UIEXPORT void ui_label_args_free(UiLabelArgs *args);
+
+UIEXPORT UiProgressbarArgs* ui_progressbar_args_new(void);
+UIEXPORT void ui_progressbar_args_set_fill(UiProgressbarArgs *args, UiBool fill);
+UIEXPORT void ui_progressbar_args_set_hexpand(UiProgressbarArgs *args, UiBool value);
+UIEXPORT void ui_progressbar_args_set_vexpand(UiProgressbarArgs *args, UiBool value);
+UIEXPORT void ui_progressbar_args_set_hfill(UiProgressbarArgs *args, UiBool value);
+UIEXPORT void ui_progressbar_args_set_vfill(UiProgressbarArgs *args, UiBool value);
+UIEXPORT void ui_progressbar_args_set_override_defaults(UiProgressbarArgs *args, UiBool value);
+UIEXPORT void ui_progressbar_args_set_colspan(UiProgressbarArgs *args, int colspan);
+UIEXPORT void ui_progressbar_args_set_rowspan(UiProgressbarArgs *args, int rowspan);
+UIEXPORT void ui_progressbar_args_set_name(UiProgressbarArgs *args, const char *name);
+UIEXPORT void ui_progressbar_args_set_style_class(UiProgressbarArgs *args, const char *classname);
+UIEXPORT void ui_progressbar_args_set_min(UiProgressbarArgs *args, double min);
+UIEXPORT void ui_progressbar_args_set_max(UiProgressbarArgs *args, double max);
+UIEXPORT void ui_progressbar_args_set_value(UiProgressbarArgs *args, UiDouble *value);
+UIEXPORT void ui_progressbar_args_set_varname(UiProgressbarArgs *args, const char *varname);
+UIEXPORT void ui_progressbar_args_free(UiProgressbarArgs *args);
+
+UIEXPORT UiProgressbarSpinnerArgs* ui_progress_spinner_args_new(void);
+UIEXPORT void ui_progress_spinner_args_set_fill(UiProgressbarSpinnerArgs *args, UiBool fill);
+UIEXPORT void ui_progress_spinner_args_set_hexpand(UiProgressbarSpinnerArgs *args, UiBool value);
+UIEXPORT void ui_progress_spinner_args_set_vexpand(UiProgressbarSpinnerArgs *args, UiBool value);
+UIEXPORT void ui_progress_spinner_args_set_hfill(UiProgressbarSpinnerArgs *args, UiBool value);
+UIEXPORT void ui_progress_spinner_args_set_vfill(UiProgressbarSpinnerArgs *args, UiBool value);
+UIEXPORT void ui_progress_spinner_args_set_override_defaults(UiProgressbarSpinnerArgs *args, UiBool value);
+UIEXPORT void ui_progress_spinner_args_set_colspan(UiProgressbarSpinnerArgs *args, int colspan);
+UIEXPORT void ui_progress_spinner_args_set_rowspan(UiProgressbarSpinnerArgs *args, int rowspan);
+UIEXPORT void ui_progress_spinner_args_set_name(UiProgressbarSpinnerArgs *args, const char *name);
+UIEXPORT void ui_progress_spinner_args_set_style_class(UiProgressbarSpinnerArgs *args, const char *classname);
+UIEXPORT void ui_progress_spinner_args_set_value(UiProgressbarSpinnerArgs *args, UiInteger *value);
+UIEXPORT void ui_progress_spinner_args_set_varname(UiProgressbarSpinnerArgs *args, const char *varname);
+UIEXPORT void ui_progress_spinner_args_free(UiProgressbarSpinnerArgs *args);
+
+UIEXPORT UiButtonArgs* ui_button_args_new(void);
+UIEXPORT void ui_button_args_set_fill(UiButtonArgs *args, UiBool fill);
+UIEXPORT void ui_button_args_set_hexpand(UiButtonArgs *args, UiBool value);
+UIEXPORT void ui_button_args_set_vexpand(UiButtonArgs *args, UiBool value);
+UIEXPORT void ui_button_args_set_hfill(UiButtonArgs *args, UiBool value);
+UIEXPORT void ui_button_args_set_vfill(UiButtonArgs *args, UiBool value);
+UIEXPORT void ui_button_args_set_override_defaults(UiButtonArgs *args, UiBool value);
+UIEXPORT void ui_button_args_set_colspan(UiButtonArgs *args, int colspan);
+UIEXPORT void ui_button_args_set_rowspan(UiButtonArgs *args, int rowspan);
+UIEXPORT void ui_button_args_set_name(UiButtonArgs *args, const char *name);
+UIEXPORT void ui_button_args_set_style_class(UiButtonArgs *args, const char *classname);
+UIEXPORT void ui_button_args_set_label(UiButtonArgs *args, const char *label);
+UIEXPORT void ui_button_args_set_stockid(UiButtonArgs *args, const char *stockid);
+UIEXPORT void ui_button_args_set_icon(UiButtonArgs *args, const char *icon);
+UIEXPORT void ui_button_args_set_labeltype(UiButtonArgs *args, int labeltype);
+UIEXPORT void ui_button_args_set_onclick(UiButtonArgs *args, ui_callback callback);
+UIEXPORT void ui_button_args_set_onclickdata(UiButtonArgs *args, void *onclickdata);
+UIEXPORT void ui_button_args_set_groups(UiButtonArgs *args, int *groups);
+UIEXPORT void ui_button_args_free(UiButtonArgs *args);
+
+UIEXPORT UiToggleArgs* ui_toggle_args_new(void);
+UIEXPORT void ui_toggle_args_set_fill(UiToggleArgs *args, UiBool fill);
+UIEXPORT void ui_toggle_args_set_hexpand(UiToggleArgs *args, UiBool value);
+UIEXPORT void ui_toggle_args_set_vexpand(UiToggleArgs *args, UiBool value);
+UIEXPORT void ui_toggle_args_set_hfill(UiToggleArgs *args, UiBool value);
+UIEXPORT void ui_toggle_args_set_vfill(UiToggleArgs *args, UiBool value);
+UIEXPORT void ui_toggle_args_set_override_defaults(UiToggleArgs *args, UiBool value);
+UIEXPORT void ui_toggle_args_set_colspan(UiToggleArgs *args, int colspan);
+UIEXPORT void ui_toggle_args_set_rowspan(UiToggleArgs *args, int rowspan);
+UIEXPORT void ui_toggle_args_set_name(UiToggleArgs *args, const char *name);
+UIEXPORT void ui_toggle_args_set_style_class(UiToggleArgs *args, const char *classname);
+UIEXPORT void ui_toggle_args_set_label(UiToggleArgs *args, const char *label);
+UIEXPORT void ui_toggle_args_set_stockid(UiToggleArgs *args, const char *stockid);
+UIEXPORT void ui_toggle_args_set_icon(UiToggleArgs *args, const char *icon);
+UIEXPORT void ui_toggle_args_set_labeltype(UiToggleArgs *args, int labeltype);
+UIEXPORT void ui_toggle_args_set_onchange(UiToggleArgs *args, ui_callback callback);
+UIEXPORT void ui_toggle_args_set_onchangedata(UiToggleArgs *args, void *onchangedata);
+UIEXPORT void ui_toggle_args_set_varname(UiToggleArgs *args, const char *varname);
+UIEXPORT void ui_toggle_args_set_value(UiToggleArgs *args, UiInteger *value);
+UIEXPORT void ui_toggle_args_set_enablegroup(UiToggleArgs *args, int group);
+UIEXPORT void ui_toggle_args_set_groups(UiToggleArgs *args, int *groups);
+UIEXPORT void ui_toggle_args_free(UiToggleArgs *args);
+
+UIEXPORT UiListArgs* ui_list_args_new(void);
+UIEXPORT void ui_list_args_set_fill(UiListArgs *args, UiBool fill);
+UIEXPORT void ui_list_args_set_hexpand(UiListArgs *args, UiBool value);
+UIEXPORT void ui_list_args_set_vexpand(UiListArgs *args, UiBool value);
+UIEXPORT void ui_list_args_set_hfill(UiListArgs *args, UiBool value);
+UIEXPORT void ui_list_args_set_vfill(UiListArgs *args, UiBool value);
+UIEXPORT void ui_list_args_set_override_defaults(UiListArgs *args, UiBool value);
+UIEXPORT void ui_list_args_set_colspan(UiListArgs *args, int colspan);
+UIEXPORT void ui_list_args_set_rowspan(UiListArgs *args, int rowspan);
+UIEXPORT void ui_list_args_set_name(UiListArgs *args, const char *name);
+UIEXPORT void ui_list_args_set_style_class(UiListArgs *args, const char *classname);
+UIEXPORT void ui_list_args_set_varname(UiListArgs *args, const char *varname);
+UIEXPORT void ui_list_args_set_value(UiListArgs *args, UiList *value);
+UIEXPORT void ui_list_args_set_model(UiListArgs *args, UiModel *model);
+UIEXPORT void ui_list_args_set_static_elements(UiListArgs *args, char **strarray, size_t nelm);
+UIEXPORT void ui_list_args_set_getvalue_func(UiListArgs *args, ui_getvaluefunc getvalue);
+UIEXPORT void ui_list_args_set_getvalue_func2(UiListArgs *args, ui_getvaluefunc2 getvalue);
+UIEXPORT void ui_list_args_set_getvalue_data(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_onactivate(UiListArgs *args, ui_callback callback);
+UIEXPORT void ui_list_args_set_onactivatedata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_onselection(UiListArgs *args, ui_callback callback);
+UIEXPORT void ui_list_args_set_onselectiondata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondragstart(UiListArgs *args, ui_callback callback);
+UIEXPORT void ui_list_args_set_ondragstartdata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondragcomplete(UiListArgs *args, ui_callback callback);
+UIEXPORT void ui_list_args_set_ondragcompletedata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondrop(UiListArgs *args, ui_callback callback);
+UIEXPORT void ui_list_args_set_ondropdata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_multiselection(UiListArgs *args, UiBool multiselection);
+UIEXPORT void ui_list_args_set_contextmenu(UiListArgs *args, UiMenuBuilder *menubuilder);
+UIEXPORT void ui_list_args_set_groups(UiListArgs *args, int *groups);
+UIEXPORT void ui_list_args_free(UiListArgs *args);
+
+UIEXPORT UiSourceListArgs* ui_sourcelist_args_new(void);
+UIEXPORT void ui_sourcelist_args_set_fill(UiSourceListArgs *args, UiBool fill);
+UIEXPORT void ui_sourcelist_args_set_hexpand(UiSourceListArgs *args, UiBool value);
+UIEXPORT void ui_sourcelist_args_set_vexpand(UiSourceListArgs *args, UiBool value);
+UIEXPORT void ui_sourcelist_args_set_hfill(UiSourceListArgs *args, UiBool value);
+UIEXPORT void ui_sourcelist_args_set_vfill(UiSourceListArgs *args, UiBool value);
+UIEXPORT void ui_sourcelist_args_set_override_defaults(UiSourceListArgs *args, UiBool value);
+UIEXPORT void ui_sourcelist_args_set_colspan(UiSourceListArgs *args, int colspan);
+UIEXPORT void ui_sourcelist_args_set_rowspan(UiSourceListArgs *args, int rowspan);
+UIEXPORT void ui_sourcelist_args_set_name(UiSourceListArgs *args, const char *name);
+UIEXPORT void ui_sourcelist_args_set_style_class(UiSourceListArgs *args, const char *classname);
+UIEXPORT void ui_sourcelist_args_set_static_sublists(UiSourceListArgs *args, UiSubList *sublists, size_t numsublists);
+UIEXPORT void ui_sourcelist_args_set_varname(UiSourceListArgs *args, const char *varname);
+UIEXPORT void ui_sourcelist_args_set_dynamic_sublists(UiSourceListArgs *args, UiList *value);
+UIEXPORT void ui_sourcelist_args_set_getvalue_func(UiSourceListArgs *args, ui_sublist_getvalue_func getvalue);
+UIEXPORT void ui_sourcelist_args_set_getvalue_userdata(UiSourceListArgs *args, void *userdata);
+UIEXPORT void ui_sourcelist_args_set_onactivate(UiSourceListArgs *args, ui_callback callback);
+UIEXPORT void ui_sourcelist_args_set_onactivatedata(UiSourceListArgs *args, void *userdata);
+UIEXPORT void ui_sourcelist_args_set_onbuttonclick(UiSourceListArgs *args, ui_callback callback);
+UIEXPORT void ui_sourcelist_args_set_onbuttonclickdata(UiSourceListArgs *args, void *userdata);
+UIEXPORT void ui_sourcelist_args_free(UiSourceListArgs *args);
+
+UIEXPORT UiTextAreaArgs* ui_textarea_args_new(void);
+UIEXPORT void ui_textarea_args_set_fill(UiTextAreaArgs *args, UiBool fill);
+UIEXPORT void ui_textarea_args_set_hexpand(UiTextAreaArgs *args, UiBool value);
+UIEXPORT void ui_textarea_args_set_vexpand(UiTextAreaArgs *args, UiBool value);
+UIEXPORT void ui_textarea_args_set_hfill(UiTextAreaArgs *args, UiBool value);
+UIEXPORT void ui_textarea_args_set_vfill(UiTextAreaArgs *args, UiBool value);
+UIEXPORT void ui_textarea_args_set_override_defaults(UiTextAreaArgs *args, UiBool value);
+UIEXPORT void ui_textarea_args_set_colspan(UiTextAreaArgs *args, int colspan);
+UIEXPORT void ui_textarea_args_set_rowspan(UiTextAreaArgs *args, int rowspan);
+UIEXPORT void ui_textarea_args_set_name(UiTextAreaArgs *args, const char *name);
+UIEXPORT void ui_textarea_args_set_style_class(UiTextAreaArgs *args, const char *classname);
+UIEXPORT void ui_textarea_args_set_onchange(UiTextAreaArgs *args, ui_callback callback);
+UIEXPORT void ui_textarea_args_set_onchangedata(UiTextAreaArgs *args, void *onchangedata);
+UIEXPORT void ui_textarea_args_set_varname(UiTextAreaArgs *args, const char *varname);
+UIEXPORT void ui_textarea_args_set_value(UiTextAreaArgs *args, UiText *value);
+UIEXPORT void ui_textarea_args_set_groups(UiTextAreaArgs *args, int *groups);
+UIEXPORT void ui_textarea_args_free(UiTextAreaArgs *args);
+
+UIEXPORT UiTextFieldArgs* ui_textfield_args_new(void);
+UIEXPORT void ui_textfield_args_set_fill(UiTextFieldArgs *args, UiBool fill);
+UIEXPORT void ui_textfield_args_set_hexpand(UiTextFieldArgs *args, UiBool value);
+UIEXPORT void ui_textfield_args_set_vexpand(UiTextFieldArgs *args, UiBool value);
+UIEXPORT void ui_textfield_args_set_hfill(UiTextFieldArgs *args, UiBool value);
+UIEXPORT void ui_textfield_args_set_vfill(UiTextFieldArgs *args, UiBool value);
+UIEXPORT void ui_textfield_args_set_override_defaults(UiTextFieldArgs *args, UiBool value);
+UIEXPORT void ui_textfield_args_set_colspan(UiTextFieldArgs *args, int colspan);
+UIEXPORT void ui_textfield_args_set_rowspan(UiTextFieldArgs *args, int rowspan);
+UIEXPORT void ui_textfield_args_set_name(UiTextFieldArgs *args, const char *name);
+UIEXPORT void ui_textfield_args_set_style_class(UiTextFieldArgs *args, const char *classname);
+UIEXPORT void ui_textfield_args_set_onchange(UiTextFieldArgs *args, ui_callback callback);
+UIEXPORT void ui_textfield_args_set_onchangedata(UiTextFieldArgs *args, void *onchangedata);
+UIEXPORT void ui_textfield_args_set_onactivate(UiTextFieldArgs *args, ui_callback callback);
+UIEXPORT void ui_textfield_args_set_onactivatedata(UiTextFieldArgs *args, void *onactivatedata);
+UIEXPORT void ui_textfield_args_set_varname(UiTextFieldArgs *args, const char *varname);
+UIEXPORT void ui_textfield_args_set_value(UiTextFieldArgs *args, UiString *value);
+UIEXPORT void ui_textfield_args_set_groups(UiTextFieldArgs *args, int *groups);
+UIEXPORT void ui_textfield_args_free(UiTextFieldArgs *args);
+
+UIEXPORT UiWebviewArgs* ui_webview_args_new(void);
+UIEXPORT void ui_webview_args_set_fill(UiWebviewArgs *args, UiBool fill);
+UIEXPORT void ui_webview_args_set_hexpand(UiWebviewArgs *args, UiBool value);
+UIEXPORT void ui_webview_args_set_vexpand(UiWebviewArgs *args, UiBool value);
+UIEXPORT void ui_webview_args_set_hfill(UiWebviewArgs *args, UiBool value);
+UIEXPORT void ui_webview_args_set_vfill(UiWebviewArgs *args, UiBool value);
+UIEXPORT void ui_webview_args_set_override_defaults(UiWebviewArgs *args, UiBool value);
+UIEXPORT void ui_webview_args_set_colspan(UiWebviewArgs *args, int colspan);
+UIEXPORT void ui_webview_args_set_rowspan(UiWebviewArgs *args, int rowspan);
+UIEXPORT void ui_webview_args_set_name(UiWebviewArgs *args, const char *name);
+UIEXPORT void ui_webview_args_set_style_class(UiWebviewArgs *args, const char *classname);
+UIEXPORT void ui_webview_args_set_varname(UiWebviewArgs *args, const char *varname);
+UIEXPORT void ui_webview_args_set_value(UiWebviewArgs *args, UiGeneric *value);
+UIEXPORT void ui_webview_args_set_groups(UiWebviewArgs *args, int *groups);
+UIEXPORT void ui_webview_args_free(UiWebviewArgs *args);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UIC_ARGS_H */
+
ctx->groups = cxArrayListCreate(mp->allocator, cx_cmp_int, sizeof(int), 32);
ctx->attach_document = uic_context_attach_document;
- ctx->detach_document2 = uic_context_detach_document2;
+ ctx->detach_document2 = uic_context_detach_document;
#if UI_GTK2 || UI_GTK3
if(toplevel && toplevel->widget) {
}
}
-void uic_context_detach_document2(UiContext *ctx, void *document) {
+void uic_context_detach_document(UiContext *ctx, void *document) {
// find the document in the documents list
size_t docIndex = cxListFind(ctx->documents, document);
if(!cxListIndexValid(ctx->documents, docIndex)) {
}
}
-void uic_reg_var(UiContext *ctx, char *name, UiVarType type, void *value) {
+void uic_reg_var(UiContext *ctx, const char *name, UiVarType type, void *value) {
// TODO: do we need/want this? Why adding vars to a context after
// widgets reference these? Workarounds:
// 1. add vars to ctx before creating ui
uic_context_attach_document(ctx, document);
}
-void ui_detach_document2(UiContext *ctx, void *document) {
- uic_context_detach_document2(ctx, document);
+void ui_detach_document(UiContext *ctx, void *document) {
+ uic_context_detach_document(ctx, document);
}
void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata) {
ctx->close_data = udata;
}
-UIEXPORT void ui_context_destroy(UiContext *ctx) {
+void ui_context_destroy(UiContext *ctx) {
CxIterator i = cxListIterator(ctx->destroy_handler);
cx_foreach(UiDestroyHandler *, h, i) {
h->destructor(h->data);
cxMempoolFree(ctx->mp);
}
+UiContext* ui_context_parent(UiContext *ctx) {
+ return ctx->parent;
+}
+
void ui_set_group(UiContext *ctx, int group) {
if(!cxListIndexValid(ctx->groups, cxListFind(ctx->groups, &group))) {
UiContext* uic_context(UiObject *toplevel, CxMempool *mp);
UiContext* uic_root_context(UiContext *ctx);
void uic_context_add_destructor(UiContext *ctx, cx_destructor_func func, void *data);
-void uic_context_set_document(UiContext *ctx, void *document); // deprecated
-void uic_context_detach_document(UiContext *ctx); // deprecated
void uic_context_prepare_close(UiContext *ctx);
void uic_context_attach_document(UiContext *ctx, void *document);
-void uic_context_detach_document2(UiContext *ctx, void *document);
-void uic_context_attach_context(UiContext *ctx, UiContext *doc_ctx);
-void uic_context_detach_context(UiContext *ctx, UiContext *doc_ctx);
+void uic_context_detach_document(UiContext *ctx, void *document);
+void uic_context_attach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
+void uic_context_detach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
void uic_context_detach_all(UiContext *ctx);
UiVar* uic_get_var(UiContext *ctx, const char *name);
void uic_save_var2(UiVar *var);
void uic_unbind_var(UiVar *var);
-void uic_reg_var(UiContext *ctx, char *name, UiVarType type, void *value);
+void uic_reg_var(UiContext *ctx, const char *name, UiVarType type, void *value);
void uic_remove_bound_var(UiContext *ctx, UiVar *var);
}
}
-void ui_set_document(UiObject *obj, void *document) {
- uic_context_detach_all(obj->ctx);
- obj->ctx->attach_document(obj->ctx, document);
-}
-
-void ui_detach_document(UiObject *obj) {
- uic_context_detach_all(obj->ctx);
-}
-
-void* ui_get_document(UiObject *obj) {
- return obj->ctx->document;
-}
-
-void ui_set_subdocument(void *document, void *sub) {
- UiContext *ctx = ui_document_context(document);
- if(!ctx) {
- fprintf(stderr, "UI Error: pointer is not a document\n");
- }
- // TODO
-}
-
-void ui_detach_subdocument(void *document, void *sub) {
- UiContext *ctx = ui_document_context(document);
- if(!ctx) {
- fprintf(stderr, "UI Error: pointer is not a document\n");
- }
- // TODO
-}
-
-void* ui_get_subdocument(void *document) {
- UiContext *ctx = ui_document_context(document);
- if(!ctx) {
- fprintf(stderr, "UI Error: pointer is not a document\n");
- }
- // TODO
- return NULL;
-}
-
void* ui_document_new(size_t size) {
CxMempool *mp = cxMempoolCreateSimple(256);
const CxAllocator *a = mp->allocator;
ev.document = doc;
ev.obj = NULL;
ev.eventdata = NULL;
+ ev.eventdatatype = 0;
ev.intval = 0;
if(ctx->close_callback) {
-void ui_menuitem_create(UiMenuItemArgs args) {
+void ui_menuitem_create(UiMenuItemArgs *args) {
UiMenuItem* item = malloc(sizeof(UiMenuItem));
mitem_set_id(&item->item);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_ITEM;
- item->label = nl_strdup(args.label);
- item->stockid = nl_strdup(args.stockid);
- item->icon = nl_strdup(args.icon);
- item->userdata = args.onclickdata;
- item->callback = args.onclick;
- item->groups = uic_copy_groups(args.groups, &item->ngroups);
+ item->label = nl_strdup(args->label);
+ item->stockid = nl_strdup(args->stockid);
+ item->icon = nl_strdup(args->icon);
+ item->userdata = args->onclickdata;
+ item->callback = args->onclick;
+ item->groups = uic_copy_groups(args->groups, &item->ngroups);
add_item((UiMenuItemI*)item);
}
add_item((UiMenuItemI*)item);
}
-void ui_menu_toggleitem_create(UiMenuToggleItemArgs args) {
+void ui_menu_toggleitem_create(UiMenuToggleItemArgs *args) {
UiMenuCheckItem *item = malloc(sizeof(UiMenuCheckItem));
mitem_set_id(&item->item);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_CHECK_ITEM;
- item->label = nl_strdup(args.label);
- item->stockid = nl_strdup(args.stockid);
- item->icon = nl_strdup(args.icon);
- item->varname = nl_strdup(args.varname);
- item->userdata = args.onchangedata;
- item->callback = args.onchange;
- item->groups = uic_copy_groups(args.groups, &item->ngroups);
+ item->label = nl_strdup(args->label);
+ item->stockid = nl_strdup(args->stockid);
+ item->icon = nl_strdup(args->icon);
+ item->varname = nl_strdup(args->varname);
+ item->userdata = args->onchangedata;
+ item->callback = args->onchange;
+ item->groups = uic_copy_groups(args->groups, &item->ngroups);
add_item((UiMenuItemI*)item);
}
-void ui_menu_radioitem_create(UiMenuToggleItemArgs args) {
+void ui_menu_radioitem_create(UiMenuToggleItemArgs *args) {
UiMenuCheckItem* item = malloc(sizeof(UiMenuCheckItem));
mitem_set_id(&item->item);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_RADIO_ITEM;
- item->label = nl_strdup(args.label);
- item->stockid = nl_strdup(args.stockid);
- item->icon = nl_strdup(args.icon);
- item->varname = nl_strdup(args.varname);
- item->userdata = args.onchangedata;
- item->callback = args.onchange;
- item->groups = uic_copy_groups(args.groups, &item->ngroups);
+ item->label = nl_strdup(args->label);
+ item->stockid = nl_strdup(args->stockid);
+ item->icon = nl_strdup(args->icon);
+ item->varname = nl_strdup(args->varname);
+ item->userdata = args->onchangedata;
+ item->callback = args->onchange;
+ item->groups = uic_copy_groups(args->groups, &item->ngroups);
add_item((UiMenuItemI*)item);
}
-void ui_menu_itemlist_create(UiMenuItemListArgs args) {
+void ui_menu_itemlist_create(UiMenuItemListArgs *args) {
UiMenuItemList*item = malloc(sizeof(UiMenuItemList));
mitem_set_id(&item->item);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_ITEM_LIST;
- item->getvalue = args.getvalue;
- item->callback = args.onselect;
- item->userdata = args.onselectdata;
- item->varname = nl_strdup(args.varname);
- item->addseparator = args.addseparator;
+ item->getvalue = args->getvalue;
+ item->callback = args->onselect;
+ item->userdata = args->onselectdata;
+ item->varname = nl_strdup(args->varname);
+ item->addseparator = args->addseparator;
add_item((UiMenuItemI*)item);
}
-void ui_menu_checkitemlist_create(UiMenuItemListArgs args) {
+void ui_menu_checkitemlist_create(UiMenuItemListArgs *args) {
UiMenuItemList* item = malloc(sizeof(UiMenuItemList));
mitem_set_id(&item->item);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_CHECKITEM_LIST;
- item->callback = args.onselect;
- item->userdata = args.onselectdata;
- item->varname = nl_strdup(args.varname);
+ item->callback = args->onselect;
+ item->userdata = args->onselectdata;
+ item->varname = nl_strdup(args->varname);
add_item((UiMenuItemI*)item);
}
-void ui_menu_radioitemlist_create(UiMenuItemListArgs args) {
+void ui_menu_radioitemlist_create(UiMenuItemListArgs *args) {
UiMenuItemList* item = malloc(sizeof(UiMenuItemList));
mitem_set_id(&item->item);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_RADIOITEM_LIST;
- item->callback = args.onselect;
- item->userdata = args.onselectdata;
- item->varname = nl_strdup(args.varname);
+ item->callback = args->onselect;
+ item->userdata = args->onselectdata;
+ item->varname = nl_strdup(args->varname);
add_item((UiMenuItemI*)item);
}
#include "object.h"
#include "context.h"
+#include <cx/linked_list.h>
+
#include "../ui/container.h"
+static CxList *creation_callbacks;
+static CxList *destruction_callbacks;
+
+typedef struct objcallback {
+ ui_object_callback func;
+ void *userdata;
+} objcallback;
+
+void ui_register_object_creation_callback(ui_object_callback func, void *userdata) {
+ if(!creation_callbacks) {
+ creation_callbacks = cxLinkedListCreateSimple(sizeof(objcallback));
+ }
+ objcallback cb = { func, userdata };
+ cxListAdd(creation_callbacks, &cb);
+}
+
+void ui_register_object_destruction_callback(ui_object_callback func, void *userdata) {
+ if(!destruction_callbacks) {
+ destruction_callbacks = cxLinkedListCreateSimple(sizeof(objcallback));
+ }
+ objcallback cb = { func, userdata };
+ cxListAdd(destruction_callbacks, &cb);
+}
+
+void uic_object_created(UiObject *obj) {
+ CxIterator i = cxListIterator(creation_callbacks);
+ cx_foreach(objcallback *, cb, i) {
+ cb->func(obj, cb->userdata);
+ }
+}
+
+void uic_object_destroyed(UiObject *obj) {
+ CxIterator i = cxListIterator(destruction_callbacks);
+ cx_foreach(objcallback *, cb, i) {
+ cb->func(obj, cb->userdata);
+ }
+}
+
void ui_end(UiObject *obj) {
if(!obj->next) {
return;
ev.document = obj->ctx->document;
ev.obj = obj;
ev.eventdata = NULL;
+ ev.eventdatatype = 0;
ev.intval = 0;
obj->ctx->close_callback(&ev, obj->ctx->close_data);
}
+ uic_object_destroyed(obj);
cxMempoolFree(obj->ctx->mp);
}
+UiObject* uic_object_new_toplevel(void) {
+ CxMempool *mp = cxMempoolCreateSimple(256);
+ UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject));
+ obj->ctx = uic_context(obj, mp);
+ uic_object_created(obj);
+ return obj;
+}
+
UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget) {
return uic_ctx_object_new(toplevel->ctx, widget);
}
UiObject *newobj = cxCalloc(ctx->allocator, 1, sizeof(UiObject));
newobj->ctx = ctx;
newobj->widget = widget;
-
+ uic_object_created(newobj);
return newobj;
}
extern "C" {
#endif
+typedef void (*ui_object_callback)(UiObject *obj, void *userdata);
+
+void ui_register_object_creation_callback(ui_object_callback func, void *userdata);
+void ui_register_object_destruction_callback(ui_object_callback func, void *userdata);
+
+void uic_object_created(UiObject *obj);
+void uic_object_destroyed(UiObject *obj);
+
void uic_object_destroy(UiObject *obj);
+UiObject* uic_object_new_toplevel(void);
UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget);
UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget);
void uic_obj_add(UiObject *toplevel, UiObject *ctobj);
COMMON_OBJ += document$(OBJ_EXT)
COMMON_OBJ += object$(OBJ_EXT)
COMMON_OBJ += types$(OBJ_EXT)
-COMMON_OBJ += menu$(OBJ_EXT)
COMMON_OBJ += properties$(OBJ_EXT)
COMMON_OBJ += menu$(OBJ_EXT)
COMMON_OBJ += toolbar$(OBJ_EXT)
COMMON_OBJ += ucx_properties$(OBJ_EXT)
COMMON_OBJ += threadpool$(OBJ_EXT)
COMMON_OBJ += condvar$(OBJ_EXT)
+COMMON_OBJ += args$(OBJ_EXT)
+COMMON_OBJ += wrapper$(OBJ_EXT)
TOOLKITOBJS += $(COMMON_OBJ:%=$(COMMON_OBJPRE)uic_%)
TOOLKITSOURCE += $(COMMON_OBJ:%$(OBJ_EXT)=common/%.c)
event.document = job->obj->ctx->document;
event.intval = 0;
event.eventdata = NULL;
+ event.eventdatatype = 0;
job->finish_callback(&event, job->finish_data);
free(job);
return 0;
return str ? strdup(str) : NULL;\r
}\r
\r
-static UiToolbarItemArgs itemargs_copy(UiToolbarItemArgs args, size_t *ngroups) {\r
+static UiToolbarItemArgs itemargs_copy(UiToolbarItemArgs *args, size_t *ngroups) {\r
UiToolbarItemArgs newargs;\r
- newargs.label = nl_strdup(args.label);\r
- newargs.stockid = nl_strdup(args.stockid);\r
- newargs.icon = nl_strdup(args.icon);\r
- newargs.onclick = args.onclick;\r
- newargs.onclickdata = args.onclickdata;\r
- newargs.groups = uic_copy_groups(args.groups, ngroups);\r
+ newargs.label = nl_strdup(args->label);\r
+ newargs.stockid = nl_strdup(args->stockid);\r
+ newargs.icon = nl_strdup(args->icon);\r
+ newargs.onclick = args->onclick;\r
+ newargs.onclickdata = args->onclickdata;\r
+ newargs.groups = uic_copy_groups(args->groups, ngroups);\r
return newargs;\r
}\r
\r
-void ui_toolbar_item_create(const char* name, UiToolbarItemArgs args) {\r
+void ui_toolbar_item_create(const char* name, UiToolbarItemArgs *args) {\r
UiToolbarItem* item = malloc(sizeof(UiToolbarItem));\r
item->item.type = UI_TOOLBAR_ITEM;\r
item->args = itemargs_copy(args, &item->ngroups);\r
}\r
\r
\r
-static UiToolbarToggleItemArgs toggleitemargs_copy(UiToolbarToggleItemArgs args, size_t *ngroups) {\r
+static UiToolbarToggleItemArgs toggleitemargs_copy(UiToolbarToggleItemArgs *args, size_t *ngroups) {\r
UiToolbarToggleItemArgs newargs;\r
- newargs.label = nl_strdup(args.label);\r
- newargs.stockid = nl_strdup(args.stockid);\r
- newargs.icon = nl_strdup(args.icon);\r
- newargs.varname = nl_strdup(args.varname);\r
- newargs.onchange = args.onchange;\r
- newargs.onchangedata = args.onchangedata;\r
- newargs.groups = uic_copy_groups(args.groups, ngroups);\r
+ newargs.label = nl_strdup(args->label);\r
+ newargs.stockid = nl_strdup(args->stockid);\r
+ newargs.icon = nl_strdup(args->icon);\r
+ newargs.varname = nl_strdup(args->varname);\r
+ newargs.onchange = args->onchange;\r
+ newargs.onchangedata = args->onchangedata;\r
+ newargs.groups = uic_copy_groups(args->groups, ngroups);\r
return newargs;\r
}\r
\r
-void ui_toolbar_toggleitem_create(const char* name, UiToolbarToggleItemArgs args) {\r
+void ui_toolbar_toggleitem_create(const char* name, UiToolbarToggleItemArgs *args) {\r
UiToolbarToggleItem* item = malloc(sizeof(UiToolbarToggleItem));\r
item->item.type = UI_TOOLBAR_TOGGLEITEM;\r
item->args = toggleitemargs_copy(args, &item->ngroups);\r
cxMapPut(toolbar_items, name, item);\r
}\r
\r
-static UiToolbarMenuArgs menuargs_copy(UiToolbarMenuArgs args) {\r
+static UiToolbarMenuArgs menuargs_copy(UiToolbarMenuArgs *args) {\r
UiToolbarMenuArgs newargs;\r
- newargs.label = nl_strdup(args.label);\r
- newargs.stockid = nl_strdup(args.stockid);\r
- newargs.icon = nl_strdup(args.icon);\r
+ newargs.label = nl_strdup(args->label);\r
+ newargs.stockid = nl_strdup(args->stockid);\r
+ newargs.icon = nl_strdup(args->icon);\r
return newargs;\r
}\r
\r
-UIEXPORT void ui_toolbar_menu_create(const char* name, UiToolbarMenuArgs args) {\r
+UIEXPORT void ui_toolbar_menu_create(const char* name, UiToolbarMenuArgs *args) {\r
UiToolbarMenuItem* item = malloc(sizeof(UiToolbarMenuItem));\r
item->item.type = UI_TOOLBAR_MENU;\r
memset(&item->menu, 0, sizeof(UiMenu));\r
#include "../ui/tree.h"
#include "types.h"
#include "context.h"
+#include "../ui/image.h"
-
+static ui_list_init_func default_list_init;
+static void *default_list_init_userdata;
UiObserver* ui_observer_new(ui_callback f, void *data) {
UiObserver *observer = malloc(sizeof(UiObserver));
evt.window = NULL;
evt.document = NULL;
evt.eventdata = data;
+ evt.eventdatatype = UI_EVENT_DATA_POINTER;
evt.intval = 0;
while(observer) {
/* --------------------------- UiList --------------------------- */
-UiList* ui_list_new(UiContext *ctx, char *name) {
- UiList *list = malloc(sizeof(UiList));
+void uic_ucx_list_init(UiContext *ctx, UiList *list, void *unused) {
+ list->data = cxArrayListCreate(ctx->mp->allocator, NULL, CX_STORE_POINTERS, 32);
list->first = ui_list_first;
list->next = ui_list_next;
list->get = ui_list_get;
list->count = ui_list_count;
- list->observers = NULL;
-
- list->data = cxArrayListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS, 32);
- list->iter = NULL;
-
- list->update = NULL;
- list->getselection = NULL;
- list->obj = NULL;
+}
+
+UiList* ui_list_new(UiContext *ctx, const char *name) {
+ return ui_list_new2(ctx, name, default_list_init ? default_list_init : uic_ucx_list_init, default_list_init_userdata);
+}
+
+UiList* ui_list_new2(UiContext *ctx, const char *name, ui_list_init_func listinit, void *userdata) {
+ UiList *list = cxMalloc(ctx->mp->allocator, sizeof(UiList));
+ memset(list, 0, sizeof(UiList));
+ listinit(ctx, list, userdata);
if(name) {
uic_reg_var(ctx, name, UI_VAR_LIST, list);
// types
// public functions
-UiInteger* ui_int_new(UiContext *ctx, char *name) {
+UiInteger* ui_int_new(UiContext *ctx, const char *name) {
UiInteger *i = ui_malloc(ctx, sizeof(UiInteger));
memset(i, 0, sizeof(UiInteger));
if(name) {
return i;
}
-UiDouble* ui_double_new(UiContext *ctx, char *name) {
+UiDouble* ui_double_new(UiContext *ctx, const char *name) {
UiDouble *d = ui_malloc(ctx, sizeof(UiDouble));
memset(d, 0, sizeof(UiDouble));
if(name) {
return d;
}
-UiString* ui_string_new(UiContext *ctx, char *name) {
+UiString* ui_string_new(UiContext *ctx, const char *name) {
UiString *s = ui_malloc(ctx, sizeof(UiString));
memset(s, 0, sizeof(UiString));
if(name) {
return s;
}
-UiText* ui_text_new(UiContext *ctx, char *name) {
+UiText* ui_text_new(UiContext *ctx, const char *name) {
UiText *t = ui_malloc(ctx, sizeof(UiText));
memset(t, 0, sizeof(UiText));
if(name) {
return t;
}
-UiRange* ui_range_new(UiContext *ctx, char *name) {
+UiRange* ui_range_new(UiContext *ctx, const char *name) {
UiRange *r = ui_malloc(ctx, sizeof(UiRange));
memset(r, 0, sizeof(UiRange));
if(name) {
return r;
}
-UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, char *name) {
+UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, const char *name) {
UiGeneric *g = ui_malloc(ctx, sizeof(UiGeneric));
memset(g, 0, sizeof(UiGeneric));
if(name) {
}
}
+void ui_generic_set_image(UiGeneric *g, void *img) {
+ if(g->set) {
+ g->set(g, img, UI_IMAGE_OBJECT_TYPE);
+ } else {
+ if(g->value) {
+ ui_image_unref(g->value);
+ }
+ ui_image_ref(img);
+ g->value = img;
+ g->type = UI_IMAGE_OBJECT_TYPE;
+ }
+}
+
+void* ui_generic_get_image(UiGeneric *g) {
+ if(g->type) {
+ if(!strcmp(g->type, UI_IMAGE_OBJECT_TYPE)) {
+ return g->value;
+ } else {
+ return NULL;
+ }
+ }
+ return g->value;
+}
+
// private functions
void uic_int_copy(UiInteger *from, UiInteger *to) {
int ui_get_setop(void) {
return ui_set_op;
}
+
+/* ---------------- List initializers and wrapper functions ---------------- */
+
+void ui_global_list_initializer(ui_list_init_func func, void *userdata) {
+ default_list_init = func;
+ default_list_init_userdata = userdata;
+}
+
+void ui_list_class_set_first(UiList *list, void*(*first)(UiList *list)) {
+ list->first = first;
+}
+
+void ui_list_class_set_next(UiList *list, void*(*next)(UiList *list)) {
+ list->next = next;
+}
+
+void ui_list_class_set_get(UiList *list, void*(*get)(UiList *list, int i)) {
+ list->get = get;
+}
+
+void ui_list_class_set_count(UiList *list, int(*count)(UiList *list)) {
+ list->count = count;
+}
+
+void ui_list_class_set_data(UiList *list, void *data) {
+ list->data = data;
+}
+
+void ui_list_class_set_iter(UiList *list, void *iter) {
+ list->iter = iter;
+}
#ifdef __cplusplus
extern "C" {
#endif
-
-
+
+void uic_ucx_list_init(UiContext *ctx, UiList *list, void *unused);
+
void uic_int_copy(UiInteger *from, UiInteger *to);
void uic_double_copy(UiDouble *from, UiDouble *to);
void uic_string_copy(UiString *from, UiString *to);
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "wrapper.h"
+#include "types.h"
+#include <cx/list.h>
+#include <string.h>
+
+/* ---------------------------- UiObject ---------------------------- */
+
+UiContext* ui_object_get_context(UiObject *obj) {
+ return obj->ctx;
+}
+
+void* ui_object_get_windowdata(UiObject *obj) {
+ return obj->window;
+}
+
+void ui_object_set_windowdata(UiObject *obj, void *windowdata) {
+ obj->window = windowdata;
+}
+
+
+/* ---------------------------- UiList ---------------------------- */
+
+void* ui_list_get_data(UiList *list) {
+ return list->data;
+}
+
+void ui_list_set_data(UiList *list, void *data) {
+ list->data = data;
+}
+
+void* ui_list_get_iter(UiList *list) {
+ return list->iter;
+}
+
+void ui_list_set_iter(UiList *list, void *iter) {
+ list->iter = iter;
+}
+
+
+/* ------------------------------ UiSublist ------------------------------ */
+
+UiSubList* ui_sublist_new(void) {
+ UiSubList *sublist = malloc(sizeof(UiSubList));
+ memset(sublist, 0, sizeof(UiSubList));
+ return sublist;
+}
+
+void ui_sublist_set_value(UiSubList *sublist, UiList *value) {
+ sublist->value = value;
+}
+
+void ui_sublist_set_varname(UiSubList *sublist, const char *varname) {
+ free((void*)sublist->varname);
+ sublist->varname = strdup(varname);
+}
+
+void ui_sublist_set_header(UiSubList *sublist, const char *header) {
+ free((void*)sublist->header);
+ sublist->header = strdup(header);
+}
+
+void ui_sublist_set_separator(UiSubList *sublist, UiBool separator) {
+ sublist->separator = separator;
+}
+
+void ui_sublist_set_userdata(UiSubList *sublist, void *userdata) {
+ sublist->userdata = userdata;
+}
+
+void ui_sublist_free(UiSubList *sublist) {
+ free((void*)sublist->varname);
+ free((void*)sublist->header);
+ free(sublist);
+}
+
+
+/* -------------------- Source list (UiList<UiSublist>) -------------------- */
+
+UiList* ui_srclist_new(UiContext *ctx, const char *name) {
+ UiList *list = ui_list_new2(ctx, name, uic_ucx_list_init, NULL);
+ CxList *cxlist = list->data;
+ cxlist->collection.simple_destructor = (cx_destructor_func)ui_sublist_free;
+ return list;
+}
+
+void ui_srclist_add(UiList *list, UiSubList *item) {
+ ui_list_append(list, item);
+}
+
+void ui_srclist_insert(UiList *list, int index, UiSubList *item) {
+ CxList *cxlist = list->data;
+ cxListInsert(cxlist, index, item);
+}
+
+void ui_srclist_remove(UiList *list, int index) {
+ CxList *cxlist = list->data;
+ cxListRemove(cxlist, index);
+}
+
+void ui_srclist_clear(UiList *list) {
+ CxList *cxlist = list->data;
+ cxListClear(cxlist);
+}
+
+int ui_srclist_size(UiList *list) {
+ return ui_list_count(list);
+}
+
+
+/* ---------------------------- UiSubListEventData ---------------------------- */
+
+UiList* ui_sublist_event_get_list(UiSubListEventData *event) {
+ return event->list;
+}
+
+int ui_sublist_event_get_sublist_index(UiSubListEventData *event) {
+ return event->sublist_index;
+}
+
+int ui_sublist_event_get_row_index(UiSubListEventData *event) {
+ return event->row_index;
+}
+
+void* ui_sublist_event_get_row_data(UiSubListEventData *event) {
+ return event->row_data;
+}
+
+void* ui_sublist_event_get_sublist_userdata(UiSubListEventData *event) {
+ return event->sublist_userdata;
+}
+
+void* ui_sublist_event_get_event_data(UiSubListEventData *event) {
+ return event->event_data;
+}
+
+
+/* ---------------------------- UiEvent ---------------------------- */
+
+UiObject* ui_event_get_obj(UiEvent *event) {
+ return event->obj;
+}
+
+void* ui_event_get_document(UiEvent *event) {
+ return event->document;
+}
+
+void* ui_event_get_windowdata(UiEvent *event) {
+ return event->window;
+}
+
+void* ui_event_get_eventdata(UiEvent *event) {
+ return event->eventdata;
+}
+
+int ui_event_get_eventdatatype(UiEvent *event) {
+ return event->eventdatatype;
+}
+
+int ui_event_get_int(UiEvent *event) {
+ return event->intval;
+}
+
+int ui_event_get_set(UiEvent *event) {
+ return event->set;
+}
+
+
+/* ------------------------- SubListItem (public) ------------------------- */
+
+void ui_sublist_item_set_icon(UiSubListItem *item, const char *icon) {
+ item->icon = icon ? strdup(icon) : NULL;
+}
+
+void ui_sublist_item_set_label(UiSubListItem *item, const char *label) {
+ item->label = label ? strdup(label) : NULL;
+}
+
+void ui_sublist_item_set_button_icon(UiSubListItem *item, const char *button_icon) {
+ item->button_icon = button_icon ? strdup(button_icon) : NULL;
+}
+
+void ui_sublist_item_set_button_label(UiSubListItem *item, const char *button_label) {
+ item->button_label = button_label ? strdup(button_label) : NULL;
+}
+
+void ui_sublist_item_set_badge(UiSubListItem *item, const char *badge) {
+ item->badge = badge ? strdup(badge) : NULL;
+}
+
+void ui_sublist_item_set_eventdata(UiSubListItem *item, void *eventdata) {
+ item->eventdata = NULL;
+}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UIC_WRAPPER_H
+#define UIC_WRAPPER_H
+
+#include "../ui/toolkit.h"
+#include "../ui/tree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UIEXPORT UiContext* ui_object_get_context(UiObject *obj);
+UIEXPORT void* ui_object_get_windowdata(UiObject *obj);
+UIEXPORT void ui_object_set_windowdata(UiObject *obj, void *windowdata);
+
+UIEXPORT void* ui_list_get_data(UiList *list);
+UIEXPORT void* ui_list_get_iter(UiList *list);
+UIEXPORT void ui_list_set_iter(UiList *list, void *iter);
+
+UIEXPORT UiSubList* ui_sublist_new(void);
+UIEXPORT void ui_sublist_set_value(UiSubList *sublist, UiList *value);
+UIEXPORT void ui_sublist_set_varname(UiSubList *sublist, const char *varname);
+UIEXPORT void ui_sublist_set_header(UiSubList *sublist, const char *header);
+UIEXPORT void ui_sublist_set_separator(UiSubList *sublist, UiBool separator);
+UIEXPORT void ui_sublist_set_userdata(UiSubList *sublist, void *userdata);
+UIEXPORT void ui_sublist_free(UiSubList *sublist);
+
+UIEXPORT UiList* ui_srclist_new(UiContext *ctx, const char *name);
+UIEXPORT void ui_srclist_add(UiList *list, UiSubList *item);
+UIEXPORT void ui_srclist_insert(UiList *list, int index, UiSubList *item);
+UIEXPORT void ui_srclist_remove(UiList *list, int index);
+UIEXPORT void ui_srclist_clear(UiList *list);
+UIEXPORT int ui_srclist_size(UiList *list);
+
+UIEXPORT UiList* ui_sublist_event_get_list(UiSubListEventData *event);
+UIEXPORT int ui_sublist_event_get_sublist_index(UiSubListEventData *event);
+UIEXPORT int ui_sublist_event_get_row_index(UiSubListEventData *event);
+UIEXPORT void* ui_sublist_event_get_row_data(UiSubListEventData *event);
+UIEXPORT void* ui_sublist_event_get_sublist_userdata(UiSubListEventData *event);
+UIEXPORT void* ui_sublist_event_get_event_data(UiSubListEventData *event);
+
+UIEXPORT UiObject* ui_event_get_obj(UiEvent *event);
+UIEXPORT void* ui_event_get_document(UiEvent *event);
+UIEXPORT void* ui_event_get_windowdata(UiEvent *event);
+UIEXPORT void* ui_event_get_eventdata(UiEvent *event);
+UIEXPORT int ui_event_get_eventdatatype(UiEvent *event);
+UIEXPORT int ui_event_get_int(UiEvent *event);
+UIEXPORT int ui_event_get_set(UiEvent *event);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UIC_WRAPPER_H */
+
#
$(GTK_OBJPRE)%.o: gtk/%.c
- $(CC) -o $@ -c -I../ucx $(CFLAGS) $(TK_CFLAGS) $<
+ $(CC) -o $@ -c -I../ucx $(CFLAGS) $(SHLIB_CFLAGS) $(TK_CFLAGS) $<
$(UI_LIB): $(OBJ)
$(AR) $(ARFLAGS) $(UI_LIB) $(OBJ)
-
+
+$(UI_SHLIB): $(OBJ)
+ $(CC) -o $(UI_SHLIB) $(LDFLAGS) $(SHLIB_LDFLAGS) $(TK_LDFLAGS) $(OBJ) -L../build/lib -lucx
event->callback = onclick;
event->value = event_value;
event->customdata = NULL;
+ event->customint = 0;
g_signal_connect(
button,
return button;
}
-UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs args) {
+UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs *args) {
UiObject* current = uic_current_obj(obj);
- GtkWidget *button = ui_create_button(obj, args.label, args.icon, args.onclick, args.onclickdata, 0, FALSE);
- ui_set_name_and_style(button, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, button, args.groups);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, button, FALSE);
+ GtkWidget *button = ui_create_button(obj, args->label, args->icon, args->onclick, args->onclickdata, 0, FALSE);
+ ui_set_name_and_style(button, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, button, args->groups);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, button);
return button;
}
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = event->value;
e.set = ui_get_setop();
event->callback(&e, event->userdata);
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = event->var->value;
+ e.eventdatatype = UI_EVENT_DATA_INTEGER_VALUE;
e.intval = i->get(i);
e.set = ui_get_setop();
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = gtk_toggle_button_get_active(widget);
e.set = ui_get_setop();
event->callback(&e, event->userdata);
event->callback = onchange;
event->value = 0;
event->customdata = NULL;
+ event->customint = 0;
g_signal_connect(
widget,
event->callback = NULL;
event->value = enable_state;
event->customdata = NULL;
+ event->customint = 0;
g_signal_connect(
widget,
}
}
-static UIWIDGET togglebutton_create(UiObject *obj, GtkWidget *widget, UiToggleArgs args) {
+static UIWIDGET togglebutton_create(UiObject *obj, GtkWidget *widget, UiToggleArgs *args) {
UiObject* current = uic_current_obj(obj);
ui_setup_togglebutton(
obj,
widget,
- args.label,
- args.icon,
- args.varname,
- args.value,
- args.onchange,
- args.onchangedata,
- args.enable_group);
- ui_set_name_and_style(widget, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, widget, args.groups);
+ args->label,
+ args->icon,
+ args->varname,
+ args->value,
+ args->onchange,
+ args->onchangedata,
+ args->enable_group);
+ ui_set_name_and_style(widget, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, widget, args->groups);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, widget, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, widget);
return widget;
}
-UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args) {
+UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs *args) {
return togglebutton_create(obj, gtk_toggle_button_new(), args);
}
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = gtk_check_button_get_active(widget);
e.set = ui_get_setop();
event->callback(&e, event->userdata);
}
}
-UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
+UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs *args) {
UiObject* current = uic_current_obj(obj);
- GtkWidget *widget = gtk_check_button_new_with_label(args.label);
+ GtkWidget *widget = gtk_check_button_new_with_label(args->label);
ui_bind_togglebutton(
obj,
widget,
ui_check_button_get,
ui_check_button_set,
- args.varname,
- args.value,
+ args->varname,
+ args->value,
(ui_toggled_func)ui_checkbox_callback,
- args.onchange,
- args.onchangedata,
+ args->onchange,
+ args->onchangedata,
(ui_toggled_func)ui_checkbox_enable_state,
- args.enable_group);
+ args->enable_group);
- ui_set_name_and_style(widget, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, widget, args.groups);
+ ui_set_name_and_style(widget, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, widget, args->groups);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, widget, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, widget);
return widget;
}
#else
-UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
+UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs *args) {
return togglebutton_create(obj, gtk_check_button_new(), args);
}
#endif
-UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) {
+UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs *args) {
#ifdef UI_GTK3
return NULL; // TODO
#else
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = RADIOBUTTON_GET_ACTIVE(widget);
e.set = ui_get_setop();
event->callback(&e, event->userdata);
free(data);
}
-UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs args) {
+UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args) {
UiObject* current = uic_current_obj(obj);
GSList *rg = NULL;
UiInteger *rgroup;
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER);
UiBool first = FALSE;
if(var) {
}
}
- GtkWidget *rbutton = RADIOBUTTON_NEW(rg, args.label);
- ui_set_name_and_style(rbutton, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, rbutton, args.groups);
+ GtkWidget *rbutton = RADIOBUTTON_NEW(rg, args->label);
+ ui_set_name_and_style(rbutton, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, rbutton, args->groups);
if(rgroup) {
#if GTK_MAJOR_VERSION >= 4
if(rg) {
rbdata);
}
- if(args.onchange) {
+ if(args->onchange) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
- event->userdata = args.onchangedata;
- event->callback = args.onchange;
+ event->userdata = args->onchangedata;
+ event->callback = args->onchange;
event->value = 0;
event->customdata = NULL;
+ event->customint = 0;
g_signal_connect(
rbutton,
event);
}
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, rbutton, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, rbutton);
return rbutton;
}
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = i->get(i);
ui_notify_evt(i->observers, &e);
return (UiContainer*)ct;
}
-void ui_box_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_box_container_add(UiContainer *ct, GtkWidget *widget) {
UiBoxContainer *bc = (UiBoxContainer*)ct;
- if(ct->layout.fill != UI_LAYOUT_UNDEFINED) {
- fill = ui_lb2bool(ct->layout.fill);
- }
-
+ UiBool fill = ct->layout.fill;
if(bc->has_fill && fill) {
fprintf(stderr, "UiError: container has 2 filled widgets");
fill = FALSE;
}
#if GTK_MAJOR_VERSION >= 3
-void ui_grid_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_grid_container_add(UiContainer *ct, GtkWidget *widget) {
UiGridContainer *grid = (UiGridContainer*)ct;
if(ct->layout.newline) {
}
}
- if(ct->layout.fill != UI_LAYOUT_UNDEFINED) {
- fill = ui_lb2bool(ct->layout.fill);
- }
+ UiBool fill = ct->layout.fill;
if(ct->layout.hexpand) {
hexpand = TRUE;
hfill = TRUE;
}
#endif
#ifdef UI_GTK2
-void ui_grid_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_grid_container_add(UiContainer *ct, GtkWidget *widget) {
UiGridContainer *grid = (UiGridContainer*)ct;
if(ct->layout.newline) {
}
}
- if(ct->layout.fill != UI_LAYOUT_UNDEFINED) {
- fill = ui_lb2bool(ct->layout.fill);
- }
+ UiBool fill = ct->layout.fill;
if(ct->layout.hexpand) {
hexpand = TRUE;
hfill = TRUE;
return ct;
}
-void ui_frame_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_frame_container_add(UiContainer *ct, GtkWidget *widget) {
FRAME_SET_CHILD(ct->widget, widget);
}
return ct;
}
-void ui_expander_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_expander_container_add(UiContainer *ct, GtkWidget *widget) {
EXPANDER_SET_CHILD(ct->widget, widget);
}
-void ui_scrolledwindow_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_scrolledwindow_container_add(UiContainer *ct, GtkWidget *widget) {
// TODO: check if the widget implements GtkScrollable
SCROLLEDWINDOW_SET_CHILD(ct->widget, widget);
ui_reset_layout(ct->layout);
return (UiContainer*)ct;
}
-void ui_tabview_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_tabview_container_add(UiContainer *ct, GtkWidget *widget) {
UiGtkTabView *data = ui_widget_get_tabview_data(ct->widget);
if(!data) {
fprintf(stderr, "UI Error: widget is not a tabview");
return ret;
}
-UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs args, UiSubContainerType type) {
+UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type) {
UiObject *current = uic_current_obj(obj);
UiContainer *ct = current->container;
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
- GtkWidget *box = type == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args.spacing) : ui_gtk_hbox_new(args.spacing);
- ui_set_name_and_style(box, args.name, args.style_class);
- GtkWidget *widget = args.margin > 0 ? ui_box_set_margin(box, args.margin) : box;
- ct->add(ct, widget, TRUE);
+ GtkWidget *box = type == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args->spacing) : ui_gtk_hbox_new(args->spacing);
+ ui_set_name_and_style(box, args->name, args->style_class);
+ GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box;
+ ct->add(ct, widget);
UiObject *newobj = uic_object_new(obj, box);
newobj->container = ui_box_container(obj, box, type);
return widget;
}
-UIEXPORT UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs args) {
+UIEXPORT UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs *args) {
return ui_box_create(obj, args, UI_CONTAINER_VBOX);
}
-UIEXPORT UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs args) {
+UIEXPORT UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs *args) {
return ui_box_create(obj, args, UI_CONTAINER_HBOX);
}
return grid;
}
-UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs args) {
+UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) {
UiObject* current = uic_current_obj(obj);
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
GtkWidget *widget;
- GtkWidget *grid = ui_create_grid_widget(args.columnspacing, args.rowspacing);
- ui_set_name_and_style(grid, args.name, args.style_class);
- widget = ui_box_set_margin(grid, args.margin);
- current->container->add(current->container, widget, TRUE);
+ GtkWidget *grid = ui_create_grid_widget(args->columnspacing, args->rowspacing);
+ ui_set_name_and_style(grid, args->name, args->style_class);
+ widget = ui_box_set_margin(grid, args->margin);
+ current->container->add(current->container, widget);
UiObject *newobj = uic_object_new(obj, grid);
- newobj->container = ui_grid_container(obj, grid, args.def_hexpand, args.def_vexpand, args.def_hfill, args.def_vfill);
+ newobj->container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill);
uic_obj_add(obj, newobj);
return widget;
}
-UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs args) {
+UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) {
UiObject* current = uic_current_obj(obj);
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
- GtkWidget *frame = gtk_frame_new(args.label);
+ GtkWidget *frame = gtk_frame_new(args->label);
UiObject *newobj = uic_object_new(obj, frame);
- GtkWidget *sub = ui_subcontainer_create(args.subcontainer, newobj, args.spacing, args.columnspacing, args.rowspacing, args.margin);
+ GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin);
if(sub) {
FRAME_SET_CHILD(frame, sub);
} else {
newobj->widget = frame;
newobj->container = ui_frame_container(obj, frame);
}
- current->container->add(current->container, frame, FALSE);
+ current->container->add(current->container, frame);
uic_obj_add(obj, newobj);
return frame;
}
-UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs args) {
+UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs *args) {
UiObject* current = uic_current_obj(obj);
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
- GtkWidget *expander = gtk_expander_new(args.label);
- gtk_expander_set_expanded(GTK_EXPANDER(expander), args.isexpanded);
+ GtkWidget *expander = gtk_expander_new(args->label);
+ gtk_expander_set_expanded(GTK_EXPANDER(expander), args->isexpanded);
UiObject *newobj = uic_object_new(obj, expander);
- GtkWidget *sub = ui_subcontainer_create(args.subcontainer, newobj, args.spacing, args.columnspacing, args.rowspacing, args.margin);
+ GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin);
if(sub) {
EXPANDER_SET_CHILD(expander, sub);
} else {
newobj->widget = expander;
newobj->container = ui_expander_container(obj, expander);
}
- current->container->add(current->container, expander, FALSE);
+ current->container->add(current->container, expander);
uic_obj_add(obj, newobj);
return expander;
}
-UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs args) {
+UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) {
UiObject* current = uic_current_obj(obj);
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
GtkWidget *sw = SCROLLEDWINDOW_NEW();
- ui_set_name_and_style(sw, args.name, args.style_class);
- GtkWidget *widget = ui_box_set_margin(sw, args.margin);
- current->container->add(current->container, widget, TRUE);
+ ui_set_name_and_style(sw, args->name, args->style_class);
+ GtkWidget *widget = ui_box_set_margin(sw, args->margin);
+ current->container->add(current->container, widget);
UiObject *newobj = uic_object_new(obj, sw);
- GtkWidget *sub = ui_subcontainer_create(args.subcontainer, newobj, args.spacing, args.columnspacing, args.rowspacing, args.margin);
+ GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin);
if(sub) {
SCROLLEDWINDOW_SET_CHILD(sw, sub);
} else {
return g_object_get_data(G_OBJECT(tabview), "ui_tabview");
}
+static void tabview_switch_page(
+ GtkNotebook *self,
+ GtkWidget *page,
+ guint page_num,
+ gpointer userdata)
+{
+ UiGtkTabView *tabview = userdata;
+ if(!tabview->onchange) {
+ return;
+ }
+
+ UiEvent event;
+ event.obj = tabview->obj;
+ event.window = event.obj->window;
+ event.document = event.obj->ctx->document;
+ event.set = ui_get_setop();
+ event.eventdata = NULL;
+ event.eventdatatype = 0;
+ event.intval = page_num;
+
+ tabview->onchange(&event, tabview->onchange);
+}
+
+#if GTK_CHECK_VERSION(3, 10, 0)
+
+static void tabview_stack_changed(
+ GObject *object,
+ GParamSpec *pspec,
+ UiGtkTabView *tabview)
+{
+ if(!tabview->onchange) {
+ return;
+ }
+
+ UiEvent event;
+ event.obj = tabview->obj;
+ event.window = event.obj->window;
+ event.document = event.obj->ctx->document;
+ event.set = ui_get_setop();
+ event.eventdata = NULL;
+ event.eventdatatype = 0;
+ event.intval = 0;
+
+ tabview->onchange(&event, tabview->onchange);
+}
+
+#endif
+
typedef int64_t(*ui_tabview_get_func)(UiInteger*);
typedef void (*ui_tabview_set_func)(UiInteger*, int64_t);
-UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs args) {
+UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) {
UiGtkTabView *data = malloc(sizeof(UiGtkTabView));
- data->margin = args.margin;
- data->spacing = args.spacing;
- data->columnspacing = args.columnspacing;
- data->rowspacing = args.rowspacing;
+ memset(data, 0, sizeof(UiGtkTabView));
+ data->margin = args->margin;
+ data->spacing = args->spacing;
+ data->columnspacing = args->columnspacing;
+ data->rowspacing = args->rowspacing;
ui_tabview_get_func getfunc = NULL;
ui_tabview_set_func setfunc = NULL;
GtkWidget *widget = NULL;
GtkWidget *data_widget = NULL;
- switch(args.tabview) {
+ switch(args->tabview) {
case UI_TABVIEW_DOC: {
// TODO
break;
GtkWidget *sidebar = gtk_stack_sidebar_new();
BOX_ADD(widget, sidebar);
GtkWidget *stack = gtk_stack_new();
+ g_signal_connect(stack, "notify::visible-child", G_CALLBACK(tabview_stack_changed), data);
gtk_stack_set_transition_type (GTK_STACK(stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN);
gtk_stack_sidebar_set_stack(GTK_STACK_SIDEBAR(sidebar), GTK_STACK(stack));
BOX_ADD_EXPAND(widget, stack);
case UI_TABVIEW_INVISIBLE: /* fall through */
case UI_TABVIEW_NAVIGATION_TOP2: {
widget = gtk_notebook_new();
+ g_signal_connect(
+ widget,
+ "switch-page",
+ G_CALLBACK(tabview_switch_page),
+ data);
data_widget = widget;
data->select_tab = ui_notebook_tab_select;
data->remove_tab = ui_notebook_tab_remove;
data->add_tab = ui_notebook_tab_add;
getfunc = ui_notebook_get;
setfunc = ui_notebook_set;
- if(args.tabview == UI_TABVIEW_INVISIBLE) {
+ if(args->tabview == UI_TABVIEW_INVISIBLE) {
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(widget), FALSE);
gtk_notebook_set_show_border(GTK_NOTEBOOK(widget), FALSE);
}
}
UiObject* current = uic_current_obj(obj);
- if(args.value || args.varname) {
- UiVar *var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER);
+ if(args->value || args->varname) {
+ UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER);
UiInteger *i = var->value;
i->get = getfunc;
i->set = setfunc;
g_object_set_data(G_OBJECT(widget), "ui_tabview", data);
data->widget = data_widget;
- data->subcontainer = args.subcontainer;
+ data->subcontainer = args->subcontainer;
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, widget, TRUE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, widget);
UiObject *newobj = uic_object_new(obj, widget);
newobj->container = ui_tabview_container(obj, widget);
hb_set_part(obj, 1);
}
-UIWIDGET ui_headerbar_fallback_create(UiObject *obj, UiHeaderbarArgs args) {
+UIWIDGET ui_headerbar_fallback_create(UiObject *obj, UiHeaderbarArgs *args) {
UiObject *current = uic_current_obj(obj);
UiContainer *ct = current->container;
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
- GtkWidget *box = ui_gtk_hbox_new(args.alt_spacing);
- ui_set_name_and_style(box, args.name, args.style_class);
- ct->add(ct, box, FALSE);
+ GtkWidget *box = ui_gtk_hbox_new(args->alt_spacing);
+ ui_set_name_and_style(box, args->name, args->style_class);
+ ct->add(ct, box);
UiObject *newobj = uic_object_new(obj, box);
newobj->container = ui_headerbar_fallback_container(obj, box);
return (UiContainer*)ct;
}
-void ui_headerbar_fallback_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_headerbar_fallback_container_add(UiContainer *ct, GtkWidget *widget) {
UiHeaderbarContainer *hb = (UiHeaderbarContainer*)ct;
BOX_ADD(ct->widget, widget);
}
#if GTK_CHECK_VERSION(3, 10, 0)
-UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs args) {
+UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) {
GtkWidget *headerbar = g_object_get_data(G_OBJECT(obj->widget), "ui_headerbar");
if(!headerbar) {
return ui_headerbar_fallback_create(obj, args);
return (UiContainer*)ct;
}
-void ui_headerbar_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_headerbar_container_add(UiContainer *ct, GtkWidget *widget) {
UiHeaderbarContainer *hb = (UiHeaderbarContainer*)ct;
if(hb->part == 0) {
UI_HEADERBAR_PACK_START(ct->widget, widget);
#else
-UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs args) {
+UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) {
return ui_headerbar_fallback_create(obj, args);
}
/* -------------------- Sidebar -------------------- */
#ifdef UI_LIBADWAITA
-UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs args) {
+UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args) {
GtkWidget *sidebar_toolbar_view = g_object_get_data(G_OBJECT(obj->widget), "ui_sidebar");
if(!sidebar_toolbar_view) {
fprintf(stderr, "Error: window is not configured for sidebar\n");
return NULL;
}
- GtkWidget *box = ui_gtk_vbox_new(args.spacing);
- ui_box_set_margin(box, args.margin);
+ GtkWidget *box = ui_gtk_vbox_new(args->spacing);
+ ui_box_set_margin(box, args->margin);
adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(sidebar_toolbar_view), box);
UiObject *newobj = uic_object_new(obj, box);
return box;
}
#else
-UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs args) {
+UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args) {
GtkWidget *sidebar_vbox = g_object_get_data(G_OBJECT(obj->widget), "ui_sidebar");
- GtkWidget *box = ui_gtk_vbox_new(args.spacing);
- ui_box_set_margin(box, args.margin);
+ GtkWidget *box = ui_gtk_vbox_new(args->spacing);
+ ui_box_set_margin(box, args->margin);
BOX_ADD_EXPAND(sidebar_vbox, box);
UiObject *newobj = uic_object_new(obj, box);
-static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSplitPaneArgs args) {
+static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSplitPaneArgs *args) {
UiObject* current = uic_current_obj(obj);
GtkWidget *pane0 = create_paned(orientation);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, pane0, TRUE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, pane0);
- int max = args.max_panes == 0 ? 2 : args.max_panes;
+ int max = args->max_panes == 0 ? 2 : args->max_panes;
UiObject *newobj = uic_object_new(obj, pane0);
- newobj->container = ui_splitpane_container(obj, pane0, orientation, max, args.initial_position);
+ newobj->container = ui_splitpane_container(obj, pane0, orientation, max, args->initial_position);
uic_obj_add(obj, newobj);
g_object_set_data(G_OBJECT(pane0), "ui_splitpane", newobj->container);
return pane0;
}
-UIWIDGET ui_hsplitpane_create(UiObject *obj, UiSplitPaneArgs args) {
+UIWIDGET ui_hsplitpane_create(UiObject *obj, UiSplitPaneArgs *args) {
return splitpane_create(obj, UI_HORIZONTAL, args);
}
-UIWIDGET ui_vsplitpane_create(UiObject *obj, UiSplitPaneArgs args) {
+UIWIDGET ui_vsplitpane_create(UiObject *obj, UiSplitPaneArgs *args) {
return splitpane_create(obj, UI_VERTICAL, args);
}
return (UiContainer*)ct;
}
-void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
+void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget) {
UiSplitPaneContainer *s = (UiSplitPaneContainer*)ct;
if(s->nchildren >= s->max) {
UiObject *item_obj = cxMapGet(ct->current_items, key);
if(item_obj) {
// re-add previously created widget
- ui_box_container_add(ct->container, item_obj->widget, FALSE);
+ ui_box_container_add(ct->container, item_obj->widget);
} else {
// create new widget and object for this list element
CxMempool *mp = cxMempoolCreateSimple(256);
ct->columnspacing,
ct->rowspacing,
ct->margin);
- ui_box_container_add(ct->container, obj->widget, FALSE);
+ ui_box_container_add(ct->container, obj->widget);
if(ct->create_ui) {
ct->create_ui(obj, index, elm, ct->userdata);
}
free(container);
}
-UIWIDGET ui_itemlist_create(UiObject *obj, UiItemListContainerArgs args) {
+UIWIDGET ui_itemlist_create(UiObject *obj, UiItemListContainerArgs *args) {
UiObject *current = uic_current_obj(obj);
UiContainer *ct = current->container;
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
- GtkWidget *box = args.container == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args.spacing) : ui_gtk_hbox_new(args.spacing);
- ui_set_name_and_style(box, args.name, args.style_class);
- GtkWidget *widget = args.margin > 0 ? ui_box_set_margin(box, args.margin) : box;
- ct->add(ct, widget, TRUE);
+ GtkWidget *box = args->container == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args->spacing) : ui_gtk_hbox_new(args->spacing);
+ ui_set_name_and_style(box, args->name, args->style_class);
+ GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box;
+ ct->add(ct, widget);
UiGtkItemListContainer *container = malloc(sizeof(UiGtkItemListContainer));
container->parent = obj;
container->widget = box;
- container->container = ui_box_container(current, box, args.container);
- container->create_ui = args.create_ui;
- container->userdata = args.userdata;
- container->subcontainer = args.subcontainer;
+ container->container = ui_box_container(current, box, args->container);
+ container->create_ui = args->create_ui;
+ container->userdata = args->userdata;
+ container->subcontainer = args->subcontainer;
container->current_items = cxHashMapCreateSimple(CX_STORE_POINTERS);
container->current_items->collection.advanced_destructor = remove_item;
container->current_items->collection.destructor_data = container;
- container->margin = args.sub_margin;
- container->spacing = args.sub_spacing;
- container->columnspacing = args.sub_columnspacing;
- container->rowspacing = args.sub_rowspacing;
+ container->margin = args->sub_margin;
+ container->spacing = args->sub_spacing;
+ container->columnspacing = args->sub_columnspacing;
+ container->rowspacing = args->sub_rowspacing;
container->remove_items = TRUE;
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_LIST);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_LIST);
if(var) {
UiList *list = var->value;
list->obj = container;
void ui_layout_fill(UiObject *obj, UiBool fill) {
UiContainer *ct = uic_get_current_container(obj);
- ct->layout.fill = ui_bool2lb(fill);
+ ct->layout.fill = fill;
}
void ui_layout_hexpand(UiObject *obj, UiBool expand) {
#endif
#define ui_reset_layout(layout) memset(&(layout), 0, sizeof(UiLayout))
-#define ui_lb2bool(b) ((b) == UI_LAYOUT_TRUE ? TRUE : FALSE)
-#define ui_bool2lb(b) ((b) ? UI_LAYOUT_TRUE : UI_LAYOUT_FALSE)
-typedef void (*ui_container_add_f)(UiContainer*, GtkWidget*, UiBool);
+typedef void (*ui_container_add_f)(UiContainer*, GtkWidget*);
typedef struct UiDocumentView UiDocumentView;
-typedef enum UiLayoutBool {
- UI_LAYOUT_UNDEFINED = 0,
- UI_LAYOUT_TRUE,
- UI_LAYOUT_FALSE,
-} UiLayoutBool;
-
typedef struct UiLayout UiLayout;
struct UiLayout {
- UiLayoutBool fill;
+ UiBool fill;
UiBool newline;
char *label;
UiBool hexpand;
UIMENU menu;
GtkWidget *current;
- void (*add)(UiContainer*, GtkWidget*, UiBool);
+ void (*add)(UiContainer*, GtkWidget*);
UiLayout layout;
int close;
int spacing;
int columnspacing;
int rowspacing;
+ ui_callback onchange;
+ void *onchangedata;
} UiGtkTabView;
int margin);
UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame);
-void ui_frame_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_frame_container_add(UiContainer *ct, GtkWidget *widget);
GtkWidget* ui_box_set_margin(GtkWidget *box, int margin);
-UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs args, UiSubContainerType type);
+UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type);
UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type);
-void ui_box_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_box_container_add(UiContainer *ct, GtkWidget *widget);
GtkWidget* ui_create_grid_widget(int colspacing, int rowspacing);
UiContainer* ui_grid_container(
UiBool def_vexpand,
UiBool def_hfill,
UiBool def_vfill);
-void ui_grid_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_grid_container_add(UiContainer *ct, GtkWidget *widget);
UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame);
-void ui_frame_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_frame_container_add(UiContainer *ct, GtkWidget *widget);
UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander);
-void ui_expander_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_expander_container_add(UiContainer *ct, GtkWidget *widget);
UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow);
-void ui_scrolledwindow_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_scrolledwindow_container_add(UiContainer *ct, GtkWidget *widget);
UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview);
-void ui_tabview_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_tabview_container_add(UiContainer *ct, GtkWidget *widget);
UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiOrientation orientation, int max, int init);
-void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget);
UiGtkTabView* ui_widget_get_tabview_data(UIWIDGET tabview);
#if GTK_CHECK_VERSION(3, 10, 0)
UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar);
-void ui_headerbar_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_headerbar_container_add(UiContainer *ct, GtkWidget *widget);
#endif
UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar);
-void ui_headerbar_fallback_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill);
+void ui_headerbar_fallback_container_add(UiContainer *ct, GtkWidget *widget);
#ifdef __cplusplus
}
#endif
}
-UIWIDGET ui_label_create(UiObject *obj, UiLabelArgs args) {
+UIWIDGET ui_label_create(UiObject *obj, UiLabelArgs *args) {
UiObject* current = uic_current_obj(obj);
const char *css_class = NULL;
char *markup = NULL;
- if(args.label) {
+ if(args->label) {
#if GTK_MAJOR_VERSION < 3
- switch(args.style) {
+ switch(args->style) {
case UI_LABEL_STYLE_DEFAULT: break;
case UI_LABEL_STYLE_TITLE: {
- cxmutstr m = cx_asprintf("<b>%s</b>", args.label);
+ cxmutstr m = cx_asprintf("<b>%s</b>", args->label);
markup = m.ptr;
- args.label = NULL;
+ args->label = NULL;
}
case UI_LABEL_STYLE_SUBTITLE: {
break;
}
}
# else
- switch(args.style) {
+ switch(args->style) {
case UI_LABEL_STYLE_DEFAULT: break;
case UI_LABEL_STYLE_TITLE: {
css_class = "ui_label_title";
}
- GtkWidget *widget = gtk_label_new(args.label);
+ GtkWidget *widget = gtk_label_new(args->label);
if(markup) {
gtk_label_set_markup(GTK_LABEL(widget), markup);
free(markup);
WIDGET_ADD_CSS_CLASS(widget, css_class);
}
- switch(args.align) {
+ switch(args->align) {
case UI_ALIGN_DEFAULT: break;
case UI_ALIGN_LEFT: set_alignment(widget, 0, .5); break;
case UI_ALIGN_RIGHT: set_alignment(widget, 1, .5); break;
}
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_STRING);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING);
if(var) {
UiString* value = (UiString*)var->value;
value->obj = widget;
value->set = ui_label_set;
}
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, widget, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, widget);
return widget;
}
-UIWIDGET ui_llabel_create(UiObject* obj, UiLabelArgs args) {
- args.align = UI_ALIGN_LEFT;
+UIWIDGET ui_llabel_create(UiObject* obj, UiLabelArgs *args) {
+ args->align = UI_ALIGN_LEFT;
return ui_label_create(obj, args);
}
-UIWIDGET ui_rlabel_create(UiObject* obj, UiLabelArgs args) {
- args.align = UI_ALIGN_RIGHT;
+UIWIDGET ui_rlabel_create(UiObject* obj, UiLabelArgs *args) {
+ args->align = UI_ALIGN_RIGHT;
return ui_label_create(obj, args);
}
UIWIDGET ui_space_deprecated(UiObject *obj) {
GtkWidget *widget = gtk_label_new("");
UiContainer *ct = uic_get_current_container(obj);
- ct->add(ct, widget, TRUE);
+ ct->add(ct, widget);
return widget;
}
GtkWidget *widget = gtk_hseparator_new();
#endif
UiContainer *ct = uic_get_current_container(obj);
- ct->add(ct, widget, FALSE);
+ ct->add(ct, widget);
return widget;
}
double max;
} UiProgressBarRange;
-UIWIDGET ui_progressbar_create(UiObject *obj, UiProgressbarArgs args) {
+UIWIDGET ui_progressbar_create(UiObject *obj, UiProgressbarArgs *args) {
UiObject* current = uic_current_obj(obj);
GtkWidget *progressbar = gtk_progress_bar_new();
- if(args.max > args.min) {
+ if(args->max > args->min) {
UiProgressBarRange *range = malloc(sizeof(UiProgressBarRange));
- range->min = args.min;
- range->max = args.max;
+ range->min = args->min;
+ range->max = args->max;
g_signal_connect(
progressbar,
"destroy",
}
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_DOUBLE);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_DOUBLE);
if(var && var->value) {
UiDouble *value = var->value;
value->get = ui_progressbar_get;
ui_progressbar_set(value, value->value);
}
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, progressbar, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, progressbar);
return progressbar;
}
/* ------------------------- progress spinner ------------------------- */
-UIWIDGET ui_progressspinner_create(UiObject* obj, UiProgressbarSpinnerArgs args) {
+UIWIDGET ui_progressspinner_create(UiObject* obj, UiProgressbarSpinnerArgs *args) {
UiObject* current = uic_current_obj(obj);
GtkWidget *spinner = gtk_spinner_new();
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER);
if(var && var->value) {
UiInteger *value = var->value;
value->get = ui_spinner_get;
ui_spinner_set(value, value->value);
}
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, spinner, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, spinner);
return spinner;
}
#include "entry.h"
-UIWIDGET ui_spinner_create(UiObject *obj, UiSpinnerArgs args) {
+UIWIDGET ui_spinner_create(UiObject *obj, UiSpinnerArgs *args) {
double min = 0;
double max = 1000;
UiObject* current = uic_current_obj(obj);
UiVar *var = NULL;
- if(args.varname) {
- var = uic_get_var(obj->ctx, args.varname);
+ if(args->varname) {
+ var = uic_get_var(obj->ctx, args->varname);
}
if(!var) {
- if(args.intvalue) {
- var = uic_widget_var(obj->ctx, current->ctx, args.intvalue, NULL, UI_VAR_INTEGER);
- } else if(args.doublevalue) {
- var = uic_widget_var(obj->ctx, current->ctx, args.doublevalue, NULL, UI_VAR_DOUBLE);
- } else if(args.rangevalue) {
- var = uic_widget_var(obj->ctx, current->ctx, args.rangevalue, NULL, UI_VAR_RANGE);
+ if(args->intvalue) {
+ var = uic_widget_var(obj->ctx, current->ctx, args->intvalue, NULL, UI_VAR_INTEGER);
+ } else if(args->doublevalue) {
+ var = uic_widget_var(obj->ctx, current->ctx, args->doublevalue, NULL, UI_VAR_DOUBLE);
+ } else if(args->rangevalue) {
+ var = uic_widget_var(obj->ctx, current->ctx, args->rangevalue, NULL, UI_VAR_RANGE);
}
}
min = r->min;
max = r->max;
}
- if(args.step == 0) {
- args.step = 1;
+ if(args->step == 0) {
+ args->step = 1;
}
#ifdef UI_GTK2LEGACY
if(min == max) {
max = min + 1;
}
#endif
- GtkWidget *spin = gtk_spin_button_new_with_range(min, max, args.step);
- ui_set_name_and_style(spin, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, spin, args.groups);
- gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), args.digits);
+ GtkWidget *spin = gtk_spin_button_new_with_range(min, max, args->step);
+ ui_set_name_and_style(spin, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, spin, args->groups);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), args->digits);
UiObserver **obs = NULL;
if(var) {
double value = 0;
event->obj = obj;
event->var = var;
event->observers = obs;
- event->callback = args.onchange;
- event->userdata = args.onchangedata;
+ event->callback = args->onchange;
+ event->userdata = args->onchangedata;
g_signal_connect(
spin,
G_CALLBACK(ui_destroy_vardata),
event);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, spin, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, spin);
return spin;
}
e.obj = event->obj;
e.window = event->obj->window;
e.document = event->obj->ctx->document;
- e.eventdata = &value;
+ e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = (int64_t)value;
if(event->callback) {
}
UiContainer *ct = uic_get_current_container(obj);
- ct->add(ct, widget, TRUE);
+ ct->add(ct, widget);
return widget;
}
#endif
-UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args) {
+UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs *args) {
UiObject *current = uic_current_obj(obj);
GtkWidget *drawingarea = gtk_drawing_area_new();
widget = eventbox;
#endif
- if(args.scrollarea) {
+ if(args->scrollarea) {
toplevel = SCROLLEDWINDOW_NEW();
SCROLLEDWINDOW_SET_CHILD(toplevel, widget);
- args.adjustwidgetsize = TRUE;
+ args->adjustwidgetsize = TRUE;
} else {
toplevel = widget;
}
UiImageViewer *imgviewer = malloc(sizeof(UiImageViewer));
memset(imgviewer, 0, sizeof(UiImageViewer));
imgviewer->obj = obj;
- imgviewer->onbuttonpress = args.onbuttonpress;
- imgviewer->onbuttonpressdata = args.onbuttonpressdata;
- imgviewer->onbuttonrelease = args.onbuttonrelease;
- imgviewer->onbuttonreleasedata = args.onbuttonreleasedata;
- if(args.image_padding > 0) {
- imgviewer->padding_left = args.image_padding;
- imgviewer->padding_right = args.image_padding;
- imgviewer->padding_top = args.image_padding;
- imgviewer->padding_bottom = args.image_padding;
+ imgviewer->onbuttonpress = args->onbuttonpress;
+ imgviewer->onbuttonpressdata = args->onbuttonpressdata;
+ imgviewer->onbuttonrelease = args->onbuttonrelease;
+ imgviewer->onbuttonreleasedata = args->onbuttonreleasedata;
+ if(args->image_padding > 0) {
+ imgviewer->padding_left = args->image_padding;
+ imgviewer->padding_right = args->image_padding;
+ imgviewer->padding_top = args->image_padding;
+ imgviewer->padding_bottom = args->image_padding;
} else {
- imgviewer->padding_left = args.image_padding_left;
- imgviewer->padding_right = args.image_padding_right;
- imgviewer->padding_top = args.image_padding_top;
- imgviewer->padding_bottom = args.image_padding_bottom;
+ imgviewer->padding_left = args->image_padding_left;
+ imgviewer->padding_right = args->image_padding_right;
+ imgviewer->padding_top = args->image_padding_top;
+ imgviewer->padding_bottom = args->image_padding_bottom;
}
- imgviewer->adjustwidgetsize = args.adjustwidgetsize;
- imgviewer->autoscale = args.autoscale;
- imgviewer->useradjustable = args.useradjustable;
+ imgviewer->adjustwidgetsize = args->adjustwidgetsize;
+ imgviewer->autoscale = args->autoscale;
+ imgviewer->useradjustable = args->useradjustable;
imgviewer->zoom_scale = 20;
g_object_set_data_full(G_OBJECT(drawingarea), "uiimageviewer", imgviewer, (GDestroyNotify)imageviewer_destroy);
- UiVar *var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_GENERIC);
+ UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_GENERIC);
imgviewer->var = var;
imgviewer->widget = drawingarea;
imgviewer,
NULL);
- if(args.useradjustable) {
+ if(args->useradjustable) {
gtk_widget_set_focusable(drawingarea, TRUE);
}
#endif
- if(args.contextmenu) {
- UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, widget);
+ if(args->contextmenu) {
+ UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, widget);
ui_widget_set_contextmenu(widget, menu);
}
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, toplevel, TRUE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, toplevel);
return toplevel;
}
event.window = event.obj->window;
event.document = event.obj->ctx->document;
event.eventdata = NULL;
+ event.eventdatatype = 0;
event.intval = gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture));
event.set = 0;
callback(&event, userdata);
return column == 0 ? elm : NULL;
}
+static void* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col, UiBool *freeResult) {
+ if(model->getvalue2) {
+ return model->getvalue2(list, elm, row, col, model->getvalue2data, freeResult);
+ } else if(model->getvalue) {
+ return model->getvalue(elm, col);
+ }
+ return NULL;
+}
+
/*
static GtkTargetEntry targetentries[] =
{
typedef struct _ObjWrapper {
GObject parent_instance;
void *data;
+ int i;
} ObjWrapper;
typedef struct _ObjWrapperClass {
self->data = NULL;
}
-ObjWrapper* obj_wrapper_new(void* data) {
+ObjWrapper* obj_wrapper_new(void* data, int i) {
ObjWrapper *obj = g_object_new(obj_wrapper_get_type(), NULL);
obj->data = data;
+ obj->i = i;
return obj;
}
static void column_factory_bind( GtkListItemFactory *factory, GtkListItem *item, gpointer userdata) {
UiColData *col = userdata;
+ UiList *list = col->listview->var ? col->listview->var->value : NULL;
ObjWrapper *obj = gtk_list_item_get_item(item);
UiModel *model = col->listview->model;
UiModelType type = model->types[col->model_column];
- void *data = model->getvalue(obj->data, col->data_column);
+ UiBool freevalue = FALSE;
+ void *data = model_getvalue(model, list, obj->data, obj->i, col->data_column, &freevalue);
GtkWidget *child = gtk_list_item_get_child(item);
- bool freevalue = TRUE;
switch(type) {
- case UI_STRING: {
- freevalue = FALSE;
- }
case UI_STRING_FREE: {
+ freevalue = TRUE;
+ }
+ case UI_STRING: {
gtk_label_set_label(GTK_LABEL(child), data);
if(freevalue) {
free(data);
break;
}
case UI_ICON_TEXT: {
- freevalue = FALSE;
+
}
case UI_ICON_TEXT_FREE: {
- void *data2 = model->getvalue(obj->data, col->data_column+1);
+ void *data2 = model_getvalue(model, list, obj->data, obj->i, col->data_column+1, &freevalue);
+ if(type == UI_ICON_TEXT_FREE) {
+ freevalue = TRUE;
+ }
GtkWidget *image = g_object_get_data(G_OBJECT(child), "image");
GtkWidget *label = g_object_get_data(G_OBJECT(child), "label");
if(data && image) {
return selection_model;
}
-static UiListView* create_listview(UiObject *obj, UiListArgs args) {
+static UiListView* create_listview(UiObject *obj, UiListArgs *args) {
UiListView *tableview = malloc(sizeof(UiListView));
memset(tableview, 0, sizeof(UiListView));
tableview->obj = obj;
- tableview->model = args.model;
- tableview->onactivate = args.onactivate;
- tableview->onactivatedata = args.onactivatedata;
- tableview->onselection = args.onselection;
- tableview->onselectiondata = args.onselectiondata;
- tableview->ondragstart = args.ondragstart;
- tableview->ondragstartdata = args.ondragstartdata;
- tableview->ondragcomplete = args.ondragcomplete;
- tableview->ondragcompletedata = args.ondragcompletedata;
- tableview->ondrop = args.ondrop;
- tableview->ondropdata = args.ondropsdata;
+ tableview->model = args->model;
+ tableview->onactivate = args->onactivate;
+ tableview->onactivatedata = args->onactivatedata;
+ tableview->onselection = args->onselection;
+ tableview->onselectiondata = args->onselectiondata;
+ tableview->ondragstart = args->ondragstart;
+ tableview->ondragstartdata = args->ondragstartdata;
+ tableview->ondragcomplete = args->ondragcomplete;
+ tableview->ondragcompletedata = args->ondragcompletedata;
+ tableview->ondrop = args->ondrop;
+ tableview->ondropdata = args->ondropdata;
tableview->selection.count = 0;
tableview->selection.rows = NULL;
return tableview;
}
-UIWIDGET ui_listview_create(UiObject *obj, UiListArgs args) {
+UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) {
UiObject* current = uic_current_obj(obj);
// to simplify things and share code with ui_table_create, we also
// use a UiModel for the listview
UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
- model->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue;
- args.model = model;
+ if(args->getvalue2) {
+ model->getvalue2 = args->getvalue2;
+ model->getvalue2data = args->getvalue2data;
+ } else if(args->getvalue) {
+ model->getvalue = args->getvalue;
+ } else {
+ model->getvalue = ui_strmodel_getvalue;
+ }
+ args->model = model;
GListStore *ls = g_list_store_new(G_TYPE_OBJECT);
UiListView *listview = create_listview(obj, args);
g_signal_connect(factory, "setup", G_CALLBACK(column_factory_setup), listview->columns);
g_signal_connect(factory, "bind", G_CALLBACK(column_factory_bind), listview->columns);
- GtkSelectionModel *selection_model = create_selection_model(listview, ls, args.multiselection);
+ GtkSelectionModel *selection_model = create_selection_model(listview, ls, args->multiselection);
GtkWidget *view = gtk_list_view_new(GTK_SELECTION_MODEL(selection_model), factory);
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
// init listview
listview->widget = view;
list->setselection = ui_listview_setselection2;
ui_update_liststore(ls, list);
- } else if (args.static_elements && args.static_nelm > 0) {
- listview_copy_static_elements(listview, args.static_elements, args.static_nelm);
+ } else if (args->static_elements && args->static_nelm > 0) {
+ listview_copy_static_elements(listview, args->static_elements, args->static_nelm);
listview->model->getvalue = ui_strmodel_getvalue; // force strmodel
ui_update_liststore_static(ls, listview->elements, listview->nelm);
}
// event handling
- if(args.onactivate) {
+ if(args->onactivate) {
// columnview and listview can use the same callback function, because
// the first parameter (which is technically a different pointer type)
// is ignored
g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), listview);
}
- if(args.contextmenu) {
- UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, view);
+ if(args->contextmenu) {
+ UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, view);
ui_widget_set_contextmenu(view, menu);
}
GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS
SCROLLEDWINDOW_SET_CHILD(scroll_area, view);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, scroll_area, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, scroll_area);
// ct->current should point to view, not scroll_area, to make it possible
// to add a context menu
return scroll_area;
}
-UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs args) {
+UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) {
UiObject* current = uic_current_obj(obj);
// to simplify things and share code with ui_tableview_create, we also
// use a UiModel for the listview
UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
- model->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue;
- args.model = model;
+ if(args->getvalue2) {
+ model->getvalue2 = args->getvalue2;
+ model->getvalue2data = args->getvalue2data;
+ } else if(args->getvalue) {
+ model->getvalue = args->getvalue;
+ } else {
+ model->getvalue = ui_strmodel_getvalue;
+ }
+ args->model = model;
GListStore *ls = g_list_store_new(G_TYPE_OBJECT);
UiListView *listview = create_listview(obj, args);
GtkWidget *view = gtk_drop_down_new(G_LIST_MODEL(ls), NULL);
gtk_drop_down_set_factory(GTK_DROP_DOWN(view), factory);
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
// init listview
listview->widget = view;
list->setselection = ui_combobox_setselection;
ui_update_liststore(ls, list);
- } else if (args.static_elements && args.static_nelm > 0) {
- listview_copy_static_elements(listview, args.static_elements, args.static_nelm);
+ } else if (args->static_elements && args->static_nelm > 0) {
+ listview_copy_static_elements(listview, args->static_elements, args->static_nelm);
listview->model->getvalue = ui_strmodel_getvalue; // force strmodel
ui_update_liststore_static(ls, listview->elements, listview->nelm);
}
// event handling
- if(args.onactivate) {
+ if(args->onactivate) {
g_signal_connect(view, "notify::selected", G_CALLBACK(ui_dropdown_notify), listview);
}
// add widget to parent
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, view, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, view);
return view;
}
gtk_drop_down_set_selected(GTK_DROP_DOWN(dropdown), index);
}
-UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
+UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) {
UiObject* current = uic_current_obj(obj);
GListStore *ls = g_list_store_new(G_TYPE_OBJECT);
// and list updates
UiListView *tableview = create_listview(obj, args);
- GtkSelectionModel *selection_model = create_selection_model(tableview, ls, args.multiselection);
+ GtkSelectionModel *selection_model = create_selection_model(tableview, ls, args->multiselection);
GtkWidget *view = gtk_column_view_new(GTK_SELECTION_MODEL(selection_model));
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
// init tableview
tableview->widget = view;
// create columns from UiModel
- UiModel *model = args.model;
+ UiModel *model = args->model;
int columns = model ? model->columns : 0;
tableview->columns = calloc(columns, sizeof(UiColData));
}
// event handling
- if(args.onactivate) {
+ if(args->onactivate) {
g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), tableview);
}
- if(args.contextmenu) {
- UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, view);
+ if(args->contextmenu) {
+ UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, view);
ui_widget_set_contextmenu(view, menu);
}
GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS
SCROLLEDWINDOW_SET_CHILD(scroll_area, view);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, scroll_area, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, scroll_area);
// ct->current should point to view, not scroll_area, to make it possible
// to add a context menu
event.window = event.obj->window;
event.intval = view->selection.count;
event.eventdata = &view->selection;
+ event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
event.set = ui_get_setop();
if(cb) {
cb(&event, cbdata);
event.window = event.obj->window;
event.intval = index;
event.eventdata = eventdata->data;
+ event.eventdatatype = UI_EVENT_DATA_LIST_ELM;
event.set = ui_get_setop();
view->onactivate(&event, view->onactivatedata);
}
event.window = event.obj->window;
event.intval = view->selection.count;
event.eventdata = &view->selection;
+ event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
event.set = ui_get_setop();
view->onactivate(&event, view->onactivatedata);
}
void ui_update_liststore(GListStore *liststore, UiList *list) {
g_list_store_remove_all(liststore);
+ int i = 0;
void *elm = list->first(list);
while(elm) {
- ObjWrapper *obj = obj_wrapper_new(elm);
+ ObjWrapper *obj = obj_wrapper_new(elm, i++);
g_list_store_append(liststore, obj);
elm = list->next(list);
}
void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) {
g_list_store_remove_all(liststore);
for(int i=0;i<nelm;i++) {
- ObjWrapper *obj = obj_wrapper_new(elm[i]);
+ ObjWrapper *obj = obj_wrapper_new(elm[i], i);
g_list_store_append(liststore, obj);
}
}
} else {
void *value = list->get(list, i);
if(value) {
- ObjWrapper *obj = obj_wrapper_new(value);
+ ObjWrapper *obj = obj_wrapper_new(value, i);
// TODO: if index i is selected, the selection is lost
// is it possible to update the item without removing it?
int count = g_list_model_get_n_items(G_LIST_MODEL(view->liststore));
#else
-static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, void *elm) {
+static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, UiList *list, void *elm, int row) {
// set column values
int c = 0;
for(int i=0;i<model->columns;i++,c++) {
- void *data = model->getvalue(elm, c);
+ UiBool freevalue = FALSE;
+ void *data = model_getvalue(model, list, elm, row, c, &freevalue);
GValue value = G_VALUE_INIT;
switch(model->types[i]) {
- case UI_STRING:
case UI_STRING_FREE: {
+ freevalue = TRUE;
+ }
+ case UI_STRING: {
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, data);
- if(model->types[i] == UI_STRING_FREE) {
+ if(freevalue) {
free(data);
}
break;
}
#endif
c++;
-
- char *str = model->getvalue(elm, c);
+
+ freevalue = FALSE;
+ char *str = model_getvalue(model, list, elm, row, c, &freevalue);
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, str);
- if(model->types[i] == UI_ICON_TEXT_FREE) {
+ if(model->types[i] == UI_ICON_TEXT_FREE || freevalue) {
free(str);
}
break;
if(list) {
void *elm = list->first(list);
+ int i = 0;
while(elm) {
// insert new row
GtkTreeIter iter;
gtk_list_store_insert (store, &iter, -1);
- update_list_row(store, &iter, model, elm);
+ update_list_row(store, &iter, model, list, elm, i++);
// next row
elm = list->next(list);
}
-UIWIDGET ui_listview_create(UiObject *obj, UiListArgs args) {
+UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) {
UiObject* current = uic_current_obj(obj);
// create treeview
GtkWidget *view = gtk_tree_view_new();
- ui_set_name_and_style(view, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, view, args.groups);
+ ui_set_name_and_style(view, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, view, args->groups);
GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "text", 0, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
#endif
UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
- model->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue;
+ if(args->getvalue2) {
+ model->getvalue2 = args->getvalue2;
+ model->getvalue2data = args->getvalue2data;
+ } else if(args->getvalue) {
+ model->getvalue = args->getvalue;
+ } else {
+ model->getvalue = ui_strmodel_getvalue;
+ }
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
UiList *list = var ? var->value : NULL;
GtkListStore *listmodel = create_list_store(list, model);
// add callback
UiTreeEventData *event = malloc(sizeof(UiTreeEventData));
event->obj = obj;
- event->activate = args.onactivate;
- event->activatedata = args.onactivatedata;
- event->selection = args.onselection;
- event->selectiondata = args.onselectiondata;
+ event->activate = args->onactivate;
+ event->activatedata = args->onactivatedata;
+ event->selection = args->onselection;
+ event->selectiondata = args->onselectiondata;
g_signal_connect(
view,
"destroy",
G_CALLBACK(ui_destroy_userdata),
event);
- if(args.onactivate) {
+ if(args->onactivate) {
g_signal_connect(
view,
"row-activated",
G_CALLBACK(ui_listview_activate_event),
event);
}
- if(args.onselection) {
+ if(args->onselection) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(
GTK_TREE_VIEW(view));
g_signal_connect(
G_CALLBACK(ui_listview_selection_event),
event);
}
- if(args.contextmenu) {
- UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, view);
+ if(args->contextmenu) {
+ UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, view);
ui_widget_set_contextmenu(view, menu);
}
GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS
SCROLLEDWINDOW_SET_CHILD(scroll_area, view);
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
current->container->add(current->container, scroll_area, FALSE);
// ct->current should point to view, not scroll_area, to make it possible
gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), index);
}
-UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
+UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) {
UiObject* current = uic_current_obj(obj);
// create treeview
GtkWidget *view = gtk_tree_view_new();
- UiModel *model = args.model;
+ UiModel *model = args->model;
int columns = model ? model->columns : 0;
int addi = 0;
#endif
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
UiList *list = var ? var->value : NULL;
GtkListStore *listmodel = create_list_store(list, model);
tableview->widget = view;
tableview->var = var;
tableview->model = model;
- tableview->ondragstart = args.ondragstart;
- tableview->ondragstartdata = args.ondragstartdata;
- tableview->ondragcomplete = args.ondragcomplete;
- tableview->ondragcompletedata = args.ondragcompletedata;
- tableview->ondrop = args.ondrop;
- tableview->ondropdata = args.ondropsdata;
+ tableview->ondragstart = args->ondragstart;
+ tableview->ondragstartdata = args->ondragstartdata;
+ tableview->ondragcomplete = args->ondragcomplete;
+ tableview->ondragcompletedata = args->ondragcompletedata;
+ tableview->ondrop = args->ondrop;
+ tableview->ondropdata = args->ondropdata;
tableview->selection.count = 0;
tableview->selection.rows = NULL;
g_signal_connect(
// add callback
UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData));
event->obj = obj;
- event->activate = args.onactivate;
- event->selection = args.onselection;
- event->activatedata = args.onactivatedata;
- event->selectiondata = args.onselectiondata;
- if(args.onactivate) {
+ event->activate = args->onactivate;
+ event->selection = args->onselection;
+ event->activatedata = args->onactivatedata;
+ event->selectiondata = args->onselectiondata;
+ if(args->onactivate) {
g_signal_connect(
view,
"row-activated",
G_CALLBACK(ui_listview_activate_event),
event);
}
- if(args.onselection) {
+ if(args->onselection) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(
GTK_TREE_VIEW(view));
g_signal_connect(
// TODO: destroy callback
- if(args.ondragstart) {
- ui_listview_add_dnd(tableview, &args);
+ if(args->ondragstart) {
+ ui_listview_add_dnd(tableview, args);
}
- if(args.ondrop) {
- ui_listview_enable_drop(tableview, &args);
+ if(args->ondrop) {
+ ui_listview_enable_drop(tableview, args);
}
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
- if(args.multiselection) {
+ if(args->multiselection) {
gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
}
GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS
SCROLLEDWINDOW_SET_CHILD(scroll_area, view);
- if(args.contextmenu) {
- UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, scroll_area);
+ if(args->contextmenu) {
+ UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, scroll_area);
#if GTK_MAJOR_VERSION >= 4
ui_widget_set_contextmenu(scroll_area, menu);
#else
#endif
}
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
current->container->add(current->container, scroll_area, FALSE);
// ct->current should point to view, not scroll_area, to make it possible
GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget));
GtkTreeIter iter;
if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) {
- update_list_row(GTK_LIST_STORE(store), &iter, view->model, elm);
+ update_list_row(GTK_LIST_STORE(store), &iter, view->model, list, elm, i);
}
}
}
/* --------------------------- ComboBox --------------------------- */
-UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs args) {
+UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) {
UiObject* current = uic_current_obj(obj);
UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
- model->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue;
+ if(args->getvalue2) {
+ model->getvalue2 = args->getvalue2;
+ model->getvalue2data = args->getvalue2data;
+ } else if(args->getvalue) {
+ model->getvalue = args->getvalue;
+ } else {
+ model->getvalue = ui_strmodel_getvalue;
+ }
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
- GtkWidget *combobox = ui_create_combobox(obj, model, var, args.static_elements, args.static_nelm, args.onactivate, args.onactivatedata);
- ui_set_name_and_style(combobox, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, combobox, args.groups);
- UI_APPLY_LAYOUT1(current, args);
+ GtkWidget *combobox = ui_create_combobox(obj, model, var, args->static_elements, args->static_nelm, args->onactivate, args->onactivatedata);
+ ui_set_name_and_style(combobox, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, combobox, args->groups);
+ UI_APPLY_LAYOUT2(current, args);
current->container->add(current->container, combobox, FALSE);
current->container->current = combobox;
return combobox;
event.window = event.obj->window;
event.document = event.obj->ctx->document;
event.eventdata = dnd;
+ event.eventdatatype = UI_EVENT_DATA_DND;
event.intval = 0;
event.set = ui_get_setop();
listview->ondragstart(&event, listview->ondragstartdata);
event.window = event.obj->window;
event.document = event.obj->ctx->document;
event.eventdata = &dnd;
+ event.eventdatatype = UI_EVENT_DATA_DND;
event.intval = 0;
event.set = ui_get_setop();
listview->ondragcomplete(&event, listview->ondragcompletedata);
event.window = event.obj->window;
event.document = event.obj->ctx->document;
event.eventdata = &dnd;
+ event.eventdatatype = UI_EVENT_DATA_DND;
event.intval = 0;
event.set = ui_get_setop();
listview->ondrop(&event, listview->ondropdata);
cxListAdd(sublists, &uisublist);
}
-UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs args) {
+UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs *args) {
UiObject* current = uic_current_obj(obj);
#ifdef UI_GTK3
#else
GtkWidget *listbox = gtk_list_box_new();
#endif
- if(!args.style_class) {
+ if(!args->style_class) {
#if GTK_MAJOR_VERSION >= 4
WIDGET_ADD_CSS_CLASS(listbox, "navigation-sidebar");
#else
GtkWidget *scroll_area = SCROLLEDWINDOW_NEW();
SCROLLEDWINDOW_SET_CHILD(scroll_area, listbox);
- ui_set_name_and_style(listbox, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, listbox, args.groups);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, scroll_area, TRUE);
+ ui_set_name_and_style(listbox, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, listbox, args->groups);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, scroll_area);
UiListBox *uilistbox = malloc(sizeof(UiListBox));
uilistbox->obj = obj;
uilistbox->listbox = GTK_LIST_BOX(listbox);
- uilistbox->getvalue = args.getvalue;
- uilistbox->onactivate = args.onactivate;
- uilistbox->onactivatedata = args.onactivatedata;
- uilistbox->onbuttonclick = args.onbuttonclick;
- uilistbox->onbuttonclickdata = args.onbuttonclickdata;
+ uilistbox->getvalue = args->getvalue;
+ uilistbox->getvaluedata = args->getvaluedata;
+ uilistbox->onactivate = args->onactivate;
+ uilistbox->onactivatedata = args->onactivatedata;
+ uilistbox->onbuttonclick = args->onbuttonclick;
+ uilistbox->onbuttonclickdata = args->onbuttonclickdata;
uilistbox->sublists = cxArrayListCreateSimple(sizeof(UiListBoxSubList), 4);
uilistbox->sublists->collection.advanced_destructor = (cx_destructor_func2)sublist_destroy;
uilistbox->sublists->collection.destructor_data = obj;
uilistbox->first_row = NULL;
- if(args.sublists) {
+ if(args->sublists) {
// static sublist initalization
- if(args.numsublists == 0 && args.sublists) {
- args.numsublists = INT_MAX;
+ if(args->numsublists == 0 && args->sublists) {
+ args->numsublists = INT_MAX;
}
- for(int i=0;i<args.numsublists;i++) {
- UiSubList sublist = args.sublists[i];
+ for(int i=0;i<args->numsublists;i++) {
+ UiSubList sublist = args->sublists[i];
if(!sublist.varname && !sublist.value) {
break;
}
// fill items
ui_listbox_update(uilistbox, 0, cxListSize(uilistbox->sublists));
} else {
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.dynamic_sublist, args.varname, UI_VAR_LIST);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->dynamic_sublist, args->varname, UI_VAR_LIST);
if(var) {
UiList *list = var->value;
list->obj = uilistbox;
G_CALLBACK(ui_destroy_sourcelist),
uilistbox);
- if(args.onactivate) {
+ if(args->onactivate) {
g_signal_connect(
listbox,
"row-activated",
void *elm = list->first(list);
while(elm) {
UiSubListItem item = { NULL, NULL, NULL, NULL, NULL, NULL };
- listbox->getvalue(sublist->userdata, elm, index, &item);
+ if(listbox->getvalue) {
+ listbox->getvalue(list, sublist->userdata, elm, index, &item, listbox->getvaluedata);
+ } else {
+ item.label = strdup(elm);
+ }
// create listbox item
GtkWidget *row = create_listbox_row(listbox, sublist, &item, (int)index);
eventdata.sublist_index = sublist->index;
eventdata.row_index = data->value0;
eventdata.sublist_userdata = sublist->userdata;
- eventdata.row_data = ui_list_get(eventdata.list, eventdata.row_index);
+ eventdata.row_data = eventdata.list->get(eventdata.list, eventdata.row_index);
eventdata.event_data = data->customdata2;
UiEvent event;
event.window = event.obj->window;
event.document = event.obj->ctx->document;
event.eventdata = &eventdata;
+ event.eventdatatype = UI_EVENT_DATA_SUBLIST;
event.intval = data->value0;
event.set = ui_get_setop();
GtkListBox *listbox;
CxList *sublists; // contains UiListBoxSubList elements
ui_sublist_getvalue_func getvalue;
+ void *getvaluedata;
ui_callback onactivate;
void *onactivatedata;
ui_callback onbuttonclick;
event->callback = i->callback;
event->value = 0;
event->customdata = NULL;
+ event->customint = 0;
g_signal_connect(
action,
event->userdata = il->userdata;
event->callback = il->callback;
event->customdata = var;
+ event->customint = 0;
event->value = 0;
g_signal_connect(
evt.window = event->obj->window;
evt.document = event->obj->ctx->document;
evt.eventdata = event->customdata;
+ evt.eventdatatype = event->customint;
evt.intval = intval;
event->callback(&evt, event->userdata);
}
evt.window = event->obj->window;
evt.document = event->obj->ctx->document;
evt.eventdata = ui_list_get(list, index);
+ evt.eventdatatype = UI_EVENT_DATA_LIST_ELM;
evt.intval = index;
event->callback(&evt, event->userdata);
event->callback = f;
event->value = 0;
event->customdata = NULL;
+ event->customint = 0;
g_signal_connect(
G_OBJECT(scrollbar),
}
UiContainer *ct = uic_get_current_container(obj);
- ct->add(ct, scrollbar, FALSE);
+ ct->add(ct, scrollbar);
return scrollbar;
}
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = event->value;
event->callback(&e, event->userdata);
return TRUE;
return buf;
}
-UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args) {
+UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args) {
UiObject* current = uic_current_obj(obj);
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_TEXT);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_TEXT);
GtkWidget *text_area = gtk_text_view_new();
- ui_set_name_and_style(text_area, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, text_area, args.groups);
+ ui_set_name_and_style(text_area, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, text_area, args->groups);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_area), GTK_WRAP_WORD_CHAR);
g_signal_connect(
uitext->ctx = obj->ctx;
uitext->var = var;
uitext->last_selection_state = 0;
- uitext->onchange = args.onchange;
- uitext->onchangedata = args.onchangedata;
+ uitext->onchange = args->onchange;
+ uitext->onchangedata = args->onchangedata;
g_object_set_data(G_OBJECT(text_area), "ui_textarea", uitext);
gtk_text_view_set_right_margin(GTK_TEXT_VIEW(text_area), 2);
// add
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, scroll_area, TRUE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, scroll_area);
// bind value
if(var) {
e.window = e.obj->window;
e.document = textarea->ctx->document;
e.eventdata = value;
+ e.eventdatatype = UI_EVENT_DATA_TEXT_VALUE;
e.intval = 0;
e.set = ui_get_setop();
-static UIWIDGET create_textfield(UiObject *obj, UiBool frameless, UiBool password, UiTextFieldArgs args) {
+static UIWIDGET create_textfield(UiObject *obj, UiBool frameless, UiBool password, UiTextFieldArgs *args) {
GtkWidget *textfield = gtk_entry_new();
- ui_set_name_and_style(textfield, args.name, args.style_class);
- ui_set_widget_groups(obj->ctx, textfield, args.groups);
+ ui_set_name_and_style(textfield, args->name, args->style_class);
+ ui_set_widget_groups(obj->ctx, textfield, args->groups);
UiObject* current = uic_current_obj(obj);
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_STRING);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING);
UiTextField *uitext = malloc(sizeof(UiTextField));
uitext->obj = obj;
uitext->var = var;
- uitext->onchange = args.onchange;
- uitext->onchangedata = args.onchangedata;
- uitext->onactivate = args.onactivate;
- uitext->onactivatedata = args.onactivatedata;
+ uitext->onchange = args->onchange;
+ uitext->onchangedata = args->onchangedata;
+ uitext->onactivate = args->onactivate;
+ uitext->onactivatedata = args->onactivatedata;
g_signal_connect(
textfield,
G_CALLBACK(ui_textfield_destroy),
uitext);
- if(args.width > 0) {
+ if(args->width > 0) {
// TODO: gtk4
#if GTK_MAJOR_VERSION <= 3
- gtk_entry_set_width_chars(GTK_ENTRY(textfield), args.width);
+ gtk_entry_set_width_chars(GTK_ENTRY(textfield), args->width);
#endif
}
if(frameless) {
gtk_entry_set_visibility(GTK_ENTRY(textfield), FALSE);
}
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, textfield, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, textfield);
if(var) {
UiString *value = var->value;
value->obj = GTK_ENTRY(textfield);
}
- if(args.onchange || var) {
+ if(args->onchange || var) {
g_signal_connect(
textfield,
"changed",
uitext);
}
- if(args.onactivate) {
+ if(args->onactivate) {
g_signal_connect(
textfield,
"activate",
return textfield;
}
-UIWIDGET ui_textfield_create(UiObject *obj, UiTextFieldArgs args) {
+UIWIDGET ui_textfield_create(UiObject *obj, UiTextFieldArgs *args) {
return create_textfield(obj, FALSE, FALSE, args);
}
-UIWIDGET ui_frameless_textfield_create(UiObject* obj, UiTextFieldArgs args) {
+UIWIDGET ui_frameless_textfield_create(UiObject* obj, UiTextFieldArgs *args) {
return create_textfield(obj, TRUE, FALSE, args);
}
-UIWIDGET ui_passwordfield_create(UiObject* obj, UiTextFieldArgs args) {
+UIWIDGET ui_passwordfield_create(UiObject* obj, UiTextFieldArgs *args) {
return create_textfield(obj, FALSE, TRUE, args);
}
e.window = e.obj->window;
e.document = textfield->obj->ctx->document;
e.eventdata = value;
+ e.eventdatatype = UI_EVENT_DATA_TEXT_VALUE;
e.intval = 0;
e.set = ui_get_setop();
e.window = e.obj->window;
e.document = textfield->obj->ctx->document;
e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = 0;
e.set = ui_get_setop();
textfield->onactivate(&e, textfield->onactivatedata);
evt.window = evt.obj->window;
evt.document = evt.obj->ctx->document;
evt.eventdata = elm->path;
+ evt.eventdatatype = UI_EVENT_DATA_STRING;
evt.intval = event->value0;
evt.set = ui_get_setop();
event->callback(&evt, event->userdata);
evt.window = obj->window;
evt.document = obj->ctx->document;
evt.eventdata = (char*)text;
+ evt.eventdatatype = UI_EVENT_DATA_STRING;
evt.intval = -1;
pathtf->onactivate(&evt, pathtf->onactivatedata);
}
return FALSE;
}
-UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs args) {
+UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs *args) {
UiObject* current = uic_current_obj(obj);
UiPathTextField *pathtf = malloc(sizeof(UiPathTextField));
memset(pathtf, 0, sizeof(UiPathTextField));
pathtf->obj = obj;
- pathtf->getpathelm = args.getpathelm;
- pathtf->getpathelmdata = args.getpathelmdata;
- pathtf->onactivate = args.onactivate;
- pathtf->onactivatedata = args.onactivatedata;
- pathtf->ondragcomplete = args.ondragcomplete;
- pathtf->ondragcompletedata = args.ondragcompletedata;
- pathtf->ondragstart = args.ondragstart;
- pathtf->ondragstartdata = args.ondragstartdata;
- pathtf->ondrop = args.ondrop;
- pathtf->ondropdata = args.ondropsdata;
+ pathtf->getpathelm = args->getpathelm;
+ pathtf->getpathelmdata = args->getpathelmdata;
+ pathtf->onactivate = args->onactivate;
+ pathtf->onactivatedata = args->onactivatedata;
+ pathtf->ondragcomplete = args->ondragcomplete;
+ pathtf->ondragcompletedata = args->ondragcompletedata;
+ pathtf->ondragstart = args->ondragstart;
+ pathtf->ondragstartdata = args->ondragstartdata;
+ pathtf->ondrop = args->ondrop;
+ pathtf->ondropdata = args->ondropsdata;
if(!pathtf->getpathelm) {
pathtf->getpathelm = default_pathelm_func;
pathtf->stack = gtk_stack_new();
gtk_widget_set_name(pathtf->stack, "path-textfield-box");
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, pathtf->stack, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, pathtf->stack);
pathtf->entry_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
pathtf->entry = gtk_entry_new();
gtk_stack_set_visible_child(GTK_STACK(pathtf->stack), pathtf->entry_box);
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_STRING);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING);
if (var) {
UiString* value = (UiString*)var->value;
value->obj = pathtf;
return bb;
}
-UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs args) {
+UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs *args) {
UiObject* current = uic_current_obj(obj);
UiPathTextField *pathtf = malloc(sizeof(UiPathTextField));
memset(pathtf, 0, sizeof(UiPathTextField));
pathtf->obj = obj;
- pathtf->getpathelm = args.getpathelm;
- pathtf->getpathelmdata = args.getpathelmdata;
- pathtf->onactivate = args.onactivate;
- pathtf->onactivatedata = args.onactivatedata;
- pathtf->ondragcomplete = args.ondragcomplete;
- pathtf->ondragcompletedata = args.ondragcompletedata;
- pathtf->ondragstart = args.ondragstart;
- pathtf->ondragstartdata = args.ondragstartdata;
- pathtf->ondrop = args.ondrop;
- pathtf->ondropdata = args.ondropsdata;
+ pathtf->getpathelm = args->getpathelm;
+ pathtf->getpathelmdata = args->getpathelmdata;
+ pathtf->onactivate = args->onactivate;
+ pathtf->onactivatedata = args->onactivatedata;
+ pathtf->ondragcomplete = args->ondragcomplete;
+ pathtf->ondragcompletedata = args->ondragcompletedata;
+ pathtf->ondragstart = args->ondragstart;
+ pathtf->ondragstartdata = args->ondragstartdata;
+ pathtf->ondrop = args->ondrop;
+ pathtf->ondropdata = args->ondropsdata;
if(!pathtf->getpathelm) {
pathtf->getpathelm = default_pathelm_func;
G_CALLBACK(ui_path_textfield_destroy),
pathtf);
- UI_APPLY_LAYOUT1(current, args);
+ UI_APPLY_LAYOUT2(current, args);
current->container->add(current->container, eventbox, FALSE);
// hbox as parent for the GtkEntry and GtkButtonBox
G_CALLBACK(ui_path_textfield_key_press),
pathtf);
- UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_STRING);
+ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING);
if (var) {
UiString* value = (UiString*)var->value;
value->obj = pathtf;
event->callback = item->args.onclick;
event->userdata = item->args.onclickdata;
event->customdata = NULL;
+ event->customint = 0;
event->value = 0;
g_signal_connect(
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = NULL;
+ e.eventdatatype = 0;
e.intval = gtk_toggle_tool_button_get_active(widget);
if(event->callback) {
event.document = job->obj->ctx->document;
event.intval = 0;
event.eventdata = NULL;
+ event.eventdatatype = 0;
job->finish_callback(&event, job->finish_data);
free(job);
ui_callback callback;
void *userdata;
int value;
+ int customint;
void *customdata;
} UiEventData;
#ifdef UI_WEBVIEW
-UIWIDGET ui_webview_create(UiObject *obj, UiWebviewArgs args) {
+UIWIDGET ui_webview_create(UiObject *obj, UiWebviewArgs *args) {
UiObject* current = uic_current_obj(obj);
GtkWidget *webview = webkit_web_view_new();
- ui_set_name_and_style(webview, args.name, args.style_class);
+ ui_set_name_and_style(webview, args->name, args->style_class);
- UiVar *var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_GENERIC);
+ UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_GENERIC);
if(var) {
WebViewData *data = malloc(sizeof(WebViewData));
memset(data, 0, sizeof(WebViewData));
}
}
- ui_set_widget_groups(obj->ctx, webview, args.groups);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, webview, FALSE);
+ ui_set_widget_groups(obj->ctx, webview, args->groups);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, webview);
return webview;
}
const char *mimetype,
const char *encoding)
{
+ WebViewData *data0 = g->obj;
+ if(!data0) {
+ return;
+ }
+
WebViewData data;
+ memset(&data, 0, sizeof(WebViewData));
+ data.webview = data0->webview;
data.uri = (char*)uri;
data.content = (char*)content;
data.contentlength = contentlength;
#include "../common/object.h"
-UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs args) {
+UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs *args) {
UiObject* current = uic_current_obj(obj);
UIWIDGET widget = create_widget(obj, args, userdata);
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, widget, FALSE);
+ UI_APPLY_LAYOUT2(current, args);
+ current->container->add(current->container, widget);
return widget;
}
GtkWidget *widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
ui_set_name_and_style(widget, args->name, args->style_class);
UI_APPLY_LAYOUT1(current, (*args));
- current->container->add(current->container, widget, FALSE);
+ current->container->add(current->container, widget);
return widget;
}
#endif
static UiObject* create_window(const char *title, void *window_data, UiBool sidebar, UiBool simple) {
- CxMempool *mp = cxMempoolCreateSimple(256);
- UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject));
- obj->ref = 0;
+ UiObject *obj = uic_object_new_toplevel();
#ifdef UI_LIBADWAITA
obj->widget = adw_application_window_new(ui_get_application());
obj->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#endif
-
- obj->ctx = uic_context(obj, mp);
obj->window = window_data;
#if GTK_CHECK_VERSION(4, 0, 0)
evt.document = evt.obj->ctx->document;
evt.window = evt.obj->window;
evt.eventdata = NULL;
+ evt.eventdatatype = 0;
+ evt.eventdatatype = 0;
evt.intval = 0;
if(!strcmp(response, "btn1")) {
if(data->customdata) {
GtkWidget *entry = data->customdata;
evt.eventdata = (void*)ENTRY_GET_TEXT(GTK_ENTRY(entry));
+ evt.eventdatatype = UI_EVENT_DATA_STRING;
}
if(data->callback) {
event->callback = args.result;
event->userdata = args.resultdata;
event->customdata = NULL;
+ event->customint = 0;
event->value = 0;
event->obj = parent;
}
adw_alert_dialog_set_extra_child(ADW_ALERT_DIALOG(dialog), entry);
event->customdata = entry;
+ event->customint = 0;
}
g_signal_connect(
flist.files = NULL;
flist.nfiles = 0;
evt.eventdata = &flist;
+ evt.eventdatatype = UI_EVENT_DATA_FILE_LIST;
if(selection) {
flist = listmodel2filelist(selection);
event->callback = file_selected_callback;
event->userdata = cbdata;
event->customdata = NULL;
+ event->customint = 0;
event->value = mode;
event->obj = obj;
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
}
- CxMempool *mp = cxMempoolCreateSimple(256);
- UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject));
- obj->ctx = uic_context(obj, mp);
+ UiObject *obj = uic_object_new_toplevel();
obj->widget = dialog;
obj->ref = 0;
obj->destroy = ui_window_widget_destroy;
#endif
typedef struct UiButtonArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiButtonArgs;
typedef struct UiToggleArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
const int* groups;
} UiToggleArgs;
-#define ui_button(obj, ...) ui_button_create(obj, (UiButtonArgs){ __VA_ARGS__ } )
-#define ui_togglebutton(obj, ...) ui_togglebutton_create(obj, (UiToggleArgs){ __VA_ARGS__ } )
-#define ui_checkbox(obj, ...) ui_checkbox_create(obj, (UiToggleArgs){ __VA_ARGS__ } )
-#define ui_switch(obj, ...) ui_switch_create(obj, (UiToggleArgs){ __VA_ARGS__ } )
-#define ui_radiobutton(obj, ...) ui_radiobutton_create(obj, (UiToggleArgs){ __VA_ARGS__ } )
+#define ui_button(obj, ...) ui_button_create(obj, &(UiButtonArgs){ __VA_ARGS__ } )
+#define ui_togglebutton(obj, ...) ui_togglebutton_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
+#define ui_checkbox(obj, ...) ui_checkbox_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
+#define ui_switch(obj, ...) ui_switch_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
+#define ui_radiobutton(obj, ...) ui_radiobutton_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
-UIEXPORT UIWIDGET ui_button_create(UiObject* obj, UiButtonArgs args);
-UIEXPORT UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args);
-UIEXPORT UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args);
-UIEXPORT UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args);
-UIEXPORT UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args);
+UIEXPORT UIWIDGET ui_button_create(UiObject* obj, UiButtonArgs *args);
+UIEXPORT UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs *args);
+UIEXPORT UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs *args);
+UIEXPORT UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs *args);
+UIEXPORT UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs *args);
typedef struct UiContainerArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiContainerArgs;
typedef struct UiFrameArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiFrameArgs;
typedef struct UiTabViewArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
const char *style_class;
UiTabViewType tabview;
+ ui_callback onchange;
+ void *onchangedata;
UiSubContainerType subcontainer;
} UiTabViewArgs;
typedef struct UiHeaderbarArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiSidebarArgs;
typedef struct UiSplitPaneArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiSplitPaneArgs;
typedef struct UiItemListContainerArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
#define UI_CTN(obj, ctn) for(ctn;ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_vbox(obj, ...) for(ui_vbox_create(obj, (UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_hbox(obj, ...) for(ui_hbox_create(obj, (UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_grid(obj, ...) for(ui_grid_create(obj, (UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_frame(obj, ...) for(ui_frame_create(obj, (UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_expander(obj, ...) for(ui_expander_create(obj, (UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_scrolledwindow(obj, ...) for(ui_scrolledwindow_create(obj, (UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_tabview(obj, ...) for(ui_tabview_create(obj, (UiTabViewArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_headerbar(obj, ...) for(ui_headerbar_create(obj, (UiHeaderbarArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_sidebar(obj, ...) for(ui_sidebar_create(obj, (UiSidebarArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-
-#define ui_vbox0(obj) for(ui_vbox_create(obj, (UiContainerArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_hbox0(obj) for(ui_hbox_create(obj, (UiContainerArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_grid0(obj) for(ui_grid_create(obj, (UiContainerArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_frame0(obj) for(ui_frame_create(obj, (UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_expander0(obj) for(ui_expande_create(obj, (UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_scrolledwindow0(obj) for(ui_scrolledwindow_create(obj, (UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_tabview0(obj) for(ui_tabview_create(obj, (UiTabViewArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_headerbar0(obj) for(ui_headerbar_create(obj, (UiHeaderbarArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_sidebar0(obj) for(ui_sidebar_create(obj, (UiSidebarArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-
-#define ui_vbox_w(obj, w, ...) for(w = ui_vbox_create(obj, (UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_hbox_w(obj, w, ...) for(w = ui_hbox_create(obj, (UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_grid_w(obj, w, ...) for(w = ui_grid_create(obj, (UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_tabview_w(obj, w, ...) for(w = ui_tabview_create(obj, (UiTabViewArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_scrolledwindow_w(obj, w, ...) for(w = ui_scrolledwindow_create(obj, (UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-
-#define ui_hsplitpane(obj, ...) for(ui_hsplitpane_create(obj, (UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_vsplitpane(obj, ...) for(ui_vsplitpane_create(obj, (UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_hsplitpane0(obj) for(ui_hsplitpane_create(obj, (UiSplitPaneArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_vsplitpane0(obj) for(ui_vsplitpane_create(obj, (UiSplitPaneArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
-
-#define ui_hsplitpane_w(obj, w, ...) for(w = ui_hsplitpane_create(obj, (UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_vsplitpane_w(obj, w, ...) for(w = ui_vsplitpane_create(obj, (UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_vbox(obj, ...) for(ui_vbox_create(obj, &(UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_hbox(obj, ...) for(ui_hbox_create(obj, &(UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_grid(obj, ...) for(ui_grid_create(obj, &(UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_frame(obj, ...) for(ui_frame_create(obj, &(UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_expander(obj, ...) for(ui_expander_create(obj, &(UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_scrolledwindow(obj, ...) for(ui_scrolledwindow_create(obj, &(UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_tabview(obj, ...) for(ui_tabview_create(obj, &(UiTabViewArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_headerbar(obj, ...) for(ui_headerbar_create(obj, &(UiHeaderbarArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_sidebar(obj, ...) for(ui_sidebar_create(obj, &(UiSidebarArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+
+#define ui_vbox0(obj) for(ui_vbox_create(obj, &(UiContainerArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_hbox0(obj) for(ui_hbox_create(obj, &(UiContainerArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_grid0(obj) for(ui_grid_create(obj, &(UiContainerArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_frame0(obj) for(ui_frame_create(obj, &(UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_expander0(obj) for(ui_expande_create(obj, &(UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_scrolledwindow0(obj) for(ui_scrolledwindow_create(obj, &(UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_tabview0(obj) for(ui_tabview_create(obj, &(UiTabViewArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_headerbar0(obj) for(ui_headerbar_create(obj, &(UiHeaderbarArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_sidebar0(obj) for(ui_sidebar_create(obj, &(UiSidebarArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+
+#define ui_vbox_w(obj, w, ...) for(w = ui_vbox_create(obj, &(UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_hbox_w(obj, w, ...) for(w = ui_hbox_create(obj, &(UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_grid_w(obj, w, ...) for(w = ui_grid_create(obj, &(UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_tabview_w(obj, w, ...) for(w = ui_tabview_create(obj, &(UiTabViewArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_scrolledwindow_w(obj, w, ...) for(w = ui_scrolledwindow_create(obj, &(UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+
+#define ui_hsplitpane(obj, ...) for(ui_hsplitpane_create(obj, &(UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_vsplitpane(obj, ...) for(ui_vsplitpane_create(obj, &(UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_hsplitpane0(obj) for(ui_hsplitpane_create(obj, &(UiSplitPaneArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_vsplitpane0(obj) for(ui_vsplitpane_create(obj, &(UiSplitPaneArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj))
+
+#define ui_hsplitpane_w(obj, w, ...) for(w = ui_hsplitpane_create(obj, &(UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_vsplitpane_w(obj, w, ...) for(w = ui_vsplitpane_create(obj, &(UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
#define ui_tab(obj, label) for(ui_tab_create(obj, label);ui_container_finish(obj);ui_container_begin_close(obj))
#define ui_headerbar_center(obj) for(ui_headerbar_center_create(obj);ui_container_finish(obj);ui_container_begin_close(obj))
#define ui_headerbar_end(obj) for(ui_headerbar_end_create(obj);ui_container_finish(obj);ui_container_begin_close(obj))
-#define ui_itemlist(obj, ...) ui_itemlist_create(obj, (UiItemListContainerArgs) { __VA_ARGS__} )
+#define ui_itemlist(obj, ...) ui_itemlist_create(obj, &(UiItemListContainerArgs) { __VA_ARGS__} )
UIEXPORT void ui_end(UiObject *obj); // deprecated
UIEXPORT void ui_end_new(UiObject *obj); // TODO: rename to ui_end
-UIEXPORT UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs args);
-UIEXPORT UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs args);
-UIEXPORT UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs args);
-UIEXPORT UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs args);
-UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs args);
-UIEXPORT UIWIDGET ui_scrolledwindow_create(UiObject *obj, UiFrameArgs args);
-
-UIEXPORT UIWIDGET ui_tabview_create(UiObject *obj, UiTabViewArgs args);
+UIEXPORT UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs *args);
+UIEXPORT UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs *args);
+UIEXPORT UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args);
+UIEXPORT UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args);
+UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs *args);
+UIEXPORT UIWIDGET ui_scrolledwindow_create(UiObject *obj, UiFrameArgs *args);
+
+UIEXPORT UIWIDGET ui_tabview_create(UiObject *obj, UiTabViewArgs *args);
UIEXPORT void ui_tab_create(UiObject *obj, const char* title);
UIEXPORT void ui_tabview_select(UIWIDGET tabview, int tab);
UIEXPORT void ui_tabview_remove(UIWIDGET tabview, int tab);
UIEXPORT UiObject* ui_tabview_add(UIWIDGET tabview, const char *name, int tab_index);
-UIEXPORT UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs args);
+UIEXPORT UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args);
UIEXPORT void ui_headerbar_start_create(UiObject *obj);
UIEXPORT void ui_headerbar_center_create(UiObject *obj);
UIEXPORT void ui_headerbar_end_create(UiObject *obj);
-UIEXPORT UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs args);
+UIEXPORT UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args);
-UIEXPORT UIWIDGET ui_itemlist_create(UiObject *obj, UiItemListContainerArgs args);
+UIEXPORT UIWIDGET ui_itemlist_create(UiObject *obj, UiItemListContainerArgs *args);
-UIEXPORT UIWIDGET ui_hsplitpane_create(UiObject *obj, UiSplitPaneArgs args);
-UIEXPORT UIWIDGET ui_vsplitpane_create(UiObject *obj, UiSplitPaneArgs args);
+UIEXPORT UIWIDGET ui_hsplitpane_create(UiObject *obj, UiSplitPaneArgs *args);
+UIEXPORT UIWIDGET ui_vsplitpane_create(UiObject *obj, UiSplitPaneArgs *args);
UIEXPORT void ui_splitpane_set_visible(UIWIDGET splitpane, int child_index, UiBool visible);
if(args.rowspan > 0) ui_layout_rowspan(obj, args.rowspan); \
/*force caller to add ';'*/(void)0
+#define UI_APPLY_LAYOUT2(obj, args) \
+ if(args->fill != UI_DEFAULT) ui_layout_fill(obj, args->fill == UI_ON ? 1 : 0 ); \
+ if(args->hexpand) ui_layout_hexpand(obj, 1); \
+ if(args->vexpand) ui_layout_vexpand(obj, 1); \
+ if(args->hfill) ui_layout_hfill(obj, 1); \
+ if(args->vfill) ui_layout_vfill(obj, 1); \
+ if(args->override_defaults) ui_layout_override_defaults(obj, 1); \
+ if(args->colspan > 0) ui_layout_colspan(obj, args->colspan); \
+ if(args->rowspan > 0) ui_layout_rowspan(obj, args->rowspan); \
+ /*force caller to add ';'*/(void)0
+
#ifdef __cplusplus
}
typedef enum UiLabelStyle UiLabelStyle;
typedef struct UiLabelArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiLabelArgs;
typedef struct UiProgressbarArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiProgressbarArgs;
typedef struct UiProgressbarSpinnerArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
/* label widgets */
-#define ui_label(obj, ...) ui_label_create(obj, (UiLabelArgs) { __VA_ARGS__ })
-#define ui_llabel(obj, ...) ui_llabel_create(obj, (UiLabelArgs) { __VA_ARGS__ })
-#define ui_rlabel(obj, ...) ui_rlabel_create(obj, (UiLabelArgs) { __VA_ARGS__ })
+#define ui_label(obj, ...) ui_label_create(obj, &(UiLabelArgs) { __VA_ARGS__ })
+#define ui_llabel(obj, ...) ui_llabel_create(obj, &(UiLabelArgs) { __VA_ARGS__ })
+#define ui_rlabel(obj, ...) ui_rlabel_create(obj, &(UiLabelArgs) { __VA_ARGS__ })
-UIEXPORT UIWIDGET ui_label_create(UiObject* obj, UiLabelArgs args);
-UIEXPORT UIWIDGET ui_llabel_create(UiObject* obj, UiLabelArgs args);
-UIEXPORT UIWIDGET ui_rlabel_create(UiObject* obj, UiLabelArgs args);
+UIEXPORT UIWIDGET ui_label_create(UiObject* obj, UiLabelArgs *args);
+UIEXPORT UIWIDGET ui_llabel_create(UiObject* obj, UiLabelArgs *args);
+UIEXPORT UIWIDGET ui_rlabel_create(UiObject* obj, UiLabelArgs *args);
UIWIDGET ui_space_deprecated(UiObject *obj);
/* progress bar/spinner */
-#define ui_progressbar(obj, ...) ui_progressbar_create(obj, (UiProgressbarArgs) { __VA_ARGS__ } )
-#define ui_progressspinner(obj, ...) ui_progressspinner_create(obj, (UiProgressbarSpinnerArgs) { __VA_ARGS__ } )
+#define ui_progressbar(obj, ...) ui_progressbar_create(obj, &(UiProgressbarArgs) { __VA_ARGS__ } )
+#define ui_progressspinner(obj, ...) ui_progressspinner_create(obj, &(UiProgressbarSpinnerArgs) { __VA_ARGS__ } )
-UIEXPORT UIWIDGET ui_progressbar_create(UiObject *obj, UiProgressbarArgs args);
-UIEXPORT UIWIDGET ui_progressspinner_create(UiObject* obj, UiProgressbarSpinnerArgs args);
+UIEXPORT UIWIDGET ui_progressbar_create(UiObject *obj, UiProgressbarArgs *args);
+UIEXPORT UIWIDGET ui_progressspinner_create(UiObject* obj, UiProgressbarSpinnerArgs *args);
#ifdef __cplusplus
typedef struct UiSpinnerArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
-UIWIDGET ui_spinner_create(UiObject *obj, UiSpinnerArgs args);
+UIWIDGET ui_spinner_create(UiObject *obj, UiSpinnerArgs *args);
-#define ui_spinner(obj, ...) ui_spinner_create(obj, (UiSpinnerArgs){ __VA_ARGS__ } )
+#define ui_spinner(obj, ...) ui_spinner_create(obj, &(UiSpinnerArgs){ __VA_ARGS__ } )
void ui_spinner_setrange(UIWIDGET spinner, double min, double max);
void ui_spinner_setdigits(UIWIDGET spinner, int digits);
#define UI_ICON_DOCK_RIGHT ""
#define UI_ICON_GO_BACK "go-previous"
#define UI_ICON_GO_FORWARD "go-next"
+#define UI_ICON_GO_UP "go-up"
+#define UI_ICON_GO_DOWN "go-down"
#endif /* UI_GTK */
#define UI_ICON_DOCK_RIGHT "DockRight"
#define UI_ICON_GO_BACK "Back"
#define UI_ICON_GO_FORWARD "Forward"
+#define UI_ICON_GO_UP "Up"
+#define UI_ICON_GO_DOWN "" // TODO: implement workaround for missing down symbol
#endif /* UI_WINUI */
typedef struct UiImageViewerArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
void *onbuttonreleasedata;
} UiImageViewerArgs;
-#define ui_imageviewer(obj, ...) ui_imageviewer_create(obj, (UiImageViewerArgs){ __VA_ARGS__ } )
+#define ui_imageviewer(obj, ...) ui_imageviewer_create(obj, &(UiImageViewerArgs){ __VA_ARGS__ } )
-UIEXPORT UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args);
+UIEXPORT UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs *args);
UIEXPORT UIWIDGET ui_imageviewer_reset(UIWIDGET w);
UIEXPORT UIWIDGET ui_imageviewer_set_autoscale(UIWIDGET w, UiBool set);
#define ui_menu(label) for(ui_menu_create(label);ui_menu_is_open();ui_menu_close())
-#define ui_menuitem(...) ui_menuitem_create((UiMenuItemArgs){ __VA_ARGS__ })
-#define ui_menu_toggleitem(...) ui_menu_toggleitem_create((UiMenuToggleItemArgs){ __VA_ARGS__ })
-#define ui_menu_radioitem(...) ui_menu_radioitem_create((UiMenuToggleItemArgs){ __VA_ARGS__ })
-#define ui_menu_itemlist(...) ui_menu_itemlist_create((UiMenuItemListArgs) { __VA_ARGS__ } )
-#define ui_menu_togglelist(...) ui_menu_itemlist_create((UiMenuItemListArgs) { __VA_ARGS} )
-#define ui_menu_radiolist(...) ui_menu_itemlist_create((UiMenuItemListArgs) { __VA_ARGS} )
+#define ui_menuitem(...) ui_menuitem_create(&(UiMenuItemArgs){ __VA_ARGS__ })
+#define ui_menu_toggleitem(...) ui_menu_toggleitem_create(&(UiMenuToggleItemArgs){ __VA_ARGS__ })
+#define ui_menu_radioitem(...) ui_menu_radioitem_create(&(UiMenuToggleItemArgs){ __VA_ARGS__ })
+#define ui_menu_itemlist(...) ui_menu_itemlist_create(&(UiMenuItemListArgs) { __VA_ARGS__ } )
+#define ui_menu_togglelist(...) ui_menu_itemlist_create(&(UiMenuItemListArgs) { __VA_ARGS} )
+#define ui_menu_radiolist(...) ui_menu_itemlist_create(&(UiMenuItemListArgs) { __VA_ARGS} )
UIEXPORT void ui_menu_create(const char* label);
-UIEXPORT void ui_menuitem_create(UiMenuItemArgs args);
-UIEXPORT void ui_menu_toggleitem_create(UiMenuToggleItemArgs args);
-UIEXPORT void ui_menu_radioitem_create(UiMenuToggleItemArgs args);
+UIEXPORT void ui_menuitem_create(UiMenuItemArgs *args);
+UIEXPORT void ui_menu_toggleitem_create(UiMenuToggleItemArgs *args);
+UIEXPORT void ui_menu_radioitem_create(UiMenuToggleItemArgs *args);
UIEXPORT void ui_menuseparator();
-UIEXPORT void ui_menu_itemlist_create(UiMenuItemListArgs args);
-UIEXPORT void ui_menu_toggleitemlist_create(UiMenuItemListArgs args);
-UIEXPORT void ui_menu_radioitemlist_create(UiMenuItemListArgs args);
+UIEXPORT void ui_menu_itemlist_create(UiMenuItemListArgs *args);
+UIEXPORT void ui_menu_toggleitemlist_create(UiMenuItemListArgs *args);
+UIEXPORT void ui_menu_radioitemlist_create(UiMenuItemListArgs *args);
UIEXPORT void ui_menu_end(void); // TODO: private
#endif
typedef struct UiTextAreaArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiTextAreaArgs;
typedef struct UiTextFieldArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
typedef struct UiPathTextFieldArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
void *ondropsdata;
} UiPathTextFieldArgs;
-#define ui_textarea(obj, ...) ui_textarea_create(obj, (UiTextAreaArgs) { __VA_ARGS__ })
+#define ui_textarea(obj, ...) ui_textarea_create(obj, &(UiTextAreaArgs) { __VA_ARGS__ })
-UIEXPORT UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args);
+UIEXPORT UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args);
UIEXPORT UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea);
UIEXPORT void ui_text_undo(UiText *value);
UIEXPORT void ui_text_redo(UiText *value);
-#define ui_textfield(obj, ...) ui_textfield_create(obj, (UiTextFieldArgs) { __VA_ARGS__ })
-#define ui_frameless_textfield(obj, ...) ui_frameless_field_create(obj, (UiTextFieldArgs) { __VA_ARGS__ })
-#define ui_passwordfield(obj, ...) ui_passwordfield_create(obj, (UiTextFieldArgs) { __VA_ARGS__ })
-#define ui_path_textfield(obj, ...) ui_path_textfield_create(obj, (UiPathTextFieldArgs) { __VA_ARGS__ } )
+#define ui_textfield(obj, ...) ui_textfield_create(obj, &(UiTextFieldArgs) { __VA_ARGS__ })
+#define ui_frameless_textfield(obj, ...) ui_frameless_field_create(obj, &(UiTextFieldArgs) { __VA_ARGS__ })
+#define ui_passwordfield(obj, ...) ui_passwordfield_create(obj, &(UiTextFieldArgs) { __VA_ARGS__ })
+#define ui_path_textfield(obj, ...) ui_path_textfield_create(obj, &(UiPathTextFieldArgs) { __VA_ARGS__ } )
-UIEXPORT UIWIDGET ui_textfield_create(UiObject *obj, UiTextFieldArgs args);
-UIEXPORT UIWIDGET ui_frameless_textfield_create(UiObject* obj, UiTextFieldArgs args);
-UIEXPORT UIWIDGET ui_passwordfield_create(UiObject* obj, UiTextFieldArgs args);
+UIEXPORT UIWIDGET ui_textfield_create(UiObject *obj, UiTextFieldArgs *args);
+UIEXPORT UIWIDGET ui_frameless_textfield_create(UiObject* obj, UiTextFieldArgs *args);
+UIEXPORT UIWIDGET ui_passwordfield_create(UiObject* obj, UiTextFieldArgs *args);
-UIEXPORT UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs args);
+UIEXPORT UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs *args);
#ifdef __cplusplus
}
UI_TOOLBAR_RIGHT
};
-#define ui_toolbar_item(name, ...) ui_toolbar_item_create(name, (UiToolbarItemArgs){ __VA_ARGS__ } )
-#define ui_toolbar_toggleitem(name, ...) ui_toolbar_toggleitem_create(name, (UiToolbarToggleItemArgs){ __VA_ARGS__ } )
+#define ui_toolbar_item(name, ...) ui_toolbar_item_create(name, &(UiToolbarItemArgs){ __VA_ARGS__ } )
+#define ui_toolbar_toggleitem(name, ...) ui_toolbar_toggleitem_create(name, &(UiToolbarToggleItemArgs){ __VA_ARGS__ } )
-#define ui_toolbar_menu(name, ...) for(ui_toolbar_menu_create(name, (UiToolbarMenuArgs){ __VA_ARGS__ });ui_menu_is_open();ui_menu_close())
-#define ui_toolbar_appmenu() for(ui_toolbar_menu_create(NULL, (UiToolbarMenuArgs){ 0 });ui_menu_is_open();ui_menu_close())
+#define ui_toolbar_menu(name, ...) for(ui_toolbar_menu_create(name, &(UiToolbarMenuArgs){ __VA_ARGS__ });ui_menu_is_open();ui_menu_close())
+#define ui_toolbar_appmenu() for(ui_toolbar_menu_create(NULL, &(UiToolbarMenuArgs){ 0 });ui_menu_is_open();ui_menu_close())
-UIEXPORT void ui_toolbar_item_create(const char* name, UiToolbarItemArgs args);
-UIEXPORT void ui_toolbar_toggleitem_create(const char* name, UiToolbarToggleItemArgs args);
-UIEXPORT void ui_toolbar_menu_create(const char* name, UiToolbarMenuArgs args);
+UIEXPORT void ui_toolbar_item_create(const char* name, UiToolbarItemArgs *args);
+UIEXPORT void ui_toolbar_toggleitem_create(const char* name, UiToolbarToggleItemArgs *args);
+UIEXPORT void ui_toolbar_menu_create(const char* name, UiToolbarMenuArgs *args);
UIEXPORT void ui_toolbar_add_default(const char *name, enum UiToolbarPos pos);
#define UIEXPORT __declspec(dllexport)
-#define UIWIDGET void*
+typedef struct W32Widget {
+ HWND hwnd;
+} W32Widget;
+
+#define UIWIDGET W32Widget*
#define UIWINDOW void*
#define UIMENU void*
UI_OFF
} UiTri;
-
enum UiMouseEventType { UI_PRESS = 0, UI_PRESS2 };
typedef enum UiLabelType {
typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */
-typedef void*(*ui_getvaluefunc)(void*, int);
+typedef void*(*ui_getvaluefunc)(void *elm, int col);
+typedef void*(*ui_getvaluefunc2)(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult);
typedef int(*ui_threadfunc)(void*);
void *document;
void *window;
void *eventdata;
+ int eventdatatype;
int intval;
int set;
};
UiObserver *observers;
};
+typedef void (*ui_list_init_func)(UiContext *ctx, UiList *list, void *userdata);
+
/*
* abstract list
*/
int intdata;
} UiCondVar;
+enum UiEventType {
+ UI_EVENT_DATA_NULL = 0,
+ UI_EVENT_DATA_POINTER,
+ UI_EVENT_DATA_STRING,
+ UI_EVENT_DATA_INTEGER_VALUE,
+ UI_EVENT_DATA_STRING_VALUE,
+ UI_EVENT_DATA_TEXT_VALUE,
+ UI_EVENT_DATA_DOUBLE_VALUE,
+ UI_EVENT_DATA_RANGE_VALUE,
+ UI_EVENT_DATA_LIST_SELECTION,
+ UI_EVENT_DATA_LIST_ELM,
+ UI_EVENT_DATA_DND,
+ UI_EVENT_DATA_SUBLIST,
+ UI_EVENT_DATA_FILE_LIST
+};
+
UIEXPORT void ui_init(const char *appname, int argc, char **argv);
UIEXPORT const char* ui_appname();
UIEXPORT void ui_context_destroy(UiContext *ctx);
+UIEXPORT UiContext* ui_context_parent(UiContext *ctx);
+
UIEXPORT void ui_object_ref(UiObject *obj);
UIEXPORT int ui_object_unref(UiObject *obj);
UIEXPORT void* ui_document_new(size_t size);
UIEXPORT void ui_document_destroy(void *doc);
-UIEXPORT void ui_set_document(UiObject *obj, void *document); // deprecated
-UIEXPORT void ui_detach_document(UiObject *obj); // deprecated
-UIEXPORT void* ui_get_document(UiObject *obj); // deprecated
-UIEXPORT void ui_set_subdocument(void *document, void *sub); // deprecated
-UIEXPORT void ui_detach_subdocument(void *document, void *sub); // deprecated
UIEXPORT void* ui_get_subdocument(void *document); // deprecated
UIEXPORT UiContext* ui_document_context(void *doc);
UIEXPORT void ui_attach_document(UiContext *ctx, void *document);
-UIEXPORT void ui_detach_document2(UiContext *ctx, void *document);
+UIEXPORT void ui_detach_document(UiContext *ctx, void *document);
UIEXPORT void ui_widget_set_groups(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...);
// types
-UIEXPORT UiInteger* ui_int_new(UiContext *ctx, char *name);
-UIEXPORT UiDouble* ui_double_new(UiContext *ctx, char *name);
-UIEXPORT UiString* ui_string_new(UiContext *ctx, char *name);
-UIEXPORT UiText* ui_text_new(UiContext *ctx, char *name);
-UIEXPORT UiRange* ui_range_new(UiContext *ctx, char *name);
-UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, char *name);
+UIEXPORT UiInteger* ui_int_new(UiContext *ctx, const char *name);
+UIEXPORT UiDouble* ui_double_new(UiContext *ctx, const char *name);
+UIEXPORT UiString* ui_string_new(UiContext *ctx, const char *name);
+UIEXPORT UiText* ui_text_new(UiContext *ctx, const char *name);
+UIEXPORT UiRange* ui_range_new(UiContext *ctx, const char *name);
+UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, const char *name);
#define ui_get(v) _Generic(v, \
UiInteger*: ui_int_get, \
UIEXPORT char* ui_string_get(UiString *s);
UIEXPORT void ui_text_set(UiText *s, const char* value);
UIEXPORT char* ui_text_get(UiText *s);
+UIEXPORT void ui_generic_set_image(UiGeneric *g, void *img);
+UIEXPORT void* ui_generic_get_image(UiGeneric *g);
UIEXPORT void ui_var_set_int(UiContext *ctx, const char *name, int64_t value);
UIEXPORT int64_t ui_var_get_int(UiContext *ctx, const char *name);
UIEXPORT void ui_notify_evt(UiObserver *observer, UiEvent *event);
-UIEXPORT UiList* ui_list_new(UiContext *ctx, char *name);
+UIEXPORT UiList* ui_list_new(UiContext *ctx, const char *name);
+UIEXPORT UiList* ui_list_new2(UiContext *ctx, const char *name, ui_list_init_func init, void *userdata);
UIEXPORT void ui_list_free(UiList *list);
UIEXPORT void* ui_list_first(UiList *list);
UIEXPORT void* ui_list_next(UiList *list);
UIEXPORT void ui_setop_enable(int set);
UIEXPORT int ui_get_setop(void);
+
+UIEXPORT void ui_global_list_initializer(ui_list_init_func func, void *userdata);
+UIEXPORT void ui_list_class_set_first(UiList *list, void*(*first)(UiList *list));
+UIEXPORT void ui_list_class_set_next(UiList *list, void*(*next)(UiList *list));
+UIEXPORT void ui_list_class_set_get(UiList *list, void*(*get)(UiList *list, int i));
+UIEXPORT void ui_list_class_set_count(UiList *list, int(*count)(UiList *list));
+UIEXPORT void ui_list_class_set_data(UiList *list, void *data);
+UIEXPORT void ui_list_class_set_iter(UiList *list, void *iter);
+
#ifdef __cplusplus
}
#endif
int *columnsize;
/*
+ * void*(*ui_getvaluefunc)(void *elm, int col);
+ *
* function for translating model data to view data
- * first argument is the pointer returned by UiList->get or UiTree->get
+ * first argument is the pointer returned by UiList first|next|get
* second argument is the column index
* TODO: return
*/
- void*(*getvalue)(void*, int);
+ ui_getvaluefunc getvalue;
+
+ /*
+ * void*(*ui_getvaluefunc2)(UiList *list, void *elm, int row, int col, void *userdata)
+ *
+ * alternative for getvalue
+ */
+ ui_getvaluefunc2 getvalue2;
+
+ void *getvalue2data;
};
struct UiListCallbacks {
};
struct UiListArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
char **static_elements;
size_t static_nelm;
ui_getvaluefunc getvalue;
+ ui_getvaluefunc2 getvalue2;
+ void *getvalue2data;
ui_callback onactivate;
void* onactivatedata;
ui_callback onselection;
ui_callback ondragcomplete;
void* ondragcompletedata;
ui_callback ondrop;
- void* ondropsdata;
+ void* ondropdata;
UiBool multiselection;
UiMenuBuilder *contextmenu;
const int *groups;
};
-typedef void (*ui_sublist_getvalue_func)(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item);
+typedef void (*ui_sublist_getvalue_func)(UiList *list, void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata);
struct UiSubList {
UiList *value;
};
struct UiSourceListArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
*/
ui_sublist_getvalue_func getvalue;
+ /*
+ * getvalue_func userdata
+ */
+ void *getvaluedata;
+
/*
* activated when a list item is selected
*/
UIEXPORT UiModel* ui_model_copy(UiContext *ctx, UiModel* model);
UIEXPORT void ui_model_free(UiContext *ctx, UiModel *mi);
-#define ui_listview(obj, ...) ui_listview_create(obj, (UiListArgs) { __VA_ARGS__ } )
-#define ui_table(obj, ...) ui_table_create(obj, (UiListArgs) { __VA_ARGS__ } )
-#define ui_combobox(obj, ...) ui_combobox_create(obj, (UiListArgs) { __VA_ARGS__ } )
-#define ui_breadcrumbbar(obj, ...) ui_breadcrumbbar_create(obj, (UiListArgs) { __VA_ARGS__ } )
-#define ui_sourcelist(obj, ...) ui_sourcelist_create(obj, (UiSourceListArgs) { __VA_ARGS__ } )
+#define ui_listview(obj, ...) ui_listview_create(obj, &(UiListArgs) { __VA_ARGS__ } )
+#define ui_table(obj, ...) ui_table_create(obj, &(UiListArgs) { __VA_ARGS__ } )
+#define ui_combobox(obj, ...) ui_combobox_create(obj, &(UiListArgs) { __VA_ARGS__ } )
+#define ui_breadcrumbbar(obj, ...) ui_breadcrumbbar_create(obj, &(UiListArgs) { __VA_ARGS__ } )
+#define ui_sourcelist(obj, ...) ui_sourcelist_create(obj, &(UiSourceListArgs) { __VA_ARGS__ } )
-UIEXPORT UIWIDGET ui_listview_create(UiObject* obj, UiListArgs args);
-UIEXPORT UIWIDGET ui_table_create(UiObject* obj, UiListArgs args);
-UIEXPORT UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs args);
-UIEXPORT UIWIDGET ui_breadcrumbbar_create(UiObject* obj, UiListArgs args);
+UIEXPORT UIWIDGET ui_listview_create(UiObject* obj, UiListArgs *args);
+UIEXPORT UIWIDGET ui_table_create(UiObject* obj, UiListArgs *args);
+UIEXPORT UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs *args);
+UIEXPORT UIWIDGET ui_breadcrumbbar_create(UiObject* obj, UiListArgs *args);
UIEXPORT void ui_listview_select(UIWIDGET listview, int index);
UIEXPORT void ui_combobox_select(UIWIDGET dropdown, int index);
-UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs args);
+UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs *args);
+
+UIEXPORT void ui_sublist_item_set_icon(UiSubListItem *item, const char *icon);
+UIEXPORT void ui_sublist_item_set_label(UiSubListItem *item, const char *label);
+UIEXPORT void ui_sublist_item_set_button_icon(UiSubListItem *item, const char *button_icon);
+UIEXPORT void ui_sublist_item_set_button_label(UiSubListItem *item, const char *button_label);
+UIEXPORT void ui_sublist_item_set_badge(UiSubListItem *item, const char *badge);
+UIEXPORT void ui_sublist_item_set_eventdata(UiSubListItem *item, void *eventdata);
#ifdef __cplusplus
const int* groups;
} UiWebviewArgs;
-#define ui_webview(obj, ...) ui_webview_create(obj, (UiWebviewArgs){ __VA_ARGS__ } )
+#define ui_webview(obj, ...) ui_webview_create(obj, &(UiWebviewArgs){ __VA_ARGS__ } )
-UIWIDGET ui_webview_create(UiObject *obj, UiWebviewArgs args);
+UIWIDGET ui_webview_create(UiObject *obj, UiWebviewArgs *args);
void ui_webview_load_url(UiGeneric *g, const char *url);
#endif
typedef struct UiWidgetArgs {
- UiTri fill;
+ UiBool fill;
UiBool hexpand;
UiBool vexpand;
UiBool hfill;
} UiWidgetArgs;
#ifdef UI_GTK
-typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
+typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs *args, void *userdata);
#elif defined(UI_QT)
-typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
+typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs *args, void *userdata);
#elif defined(UI_MOTIF)
-typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata, Widget parent, Arg *a, int n);
+typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs *args, void *userdata, Widget parent, Arg *a, int n);
#elif defined(UI_COCOA)
-typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
+typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs *args, void *userdata);
#elif defined(UI_WINUI)
-typedef UIWIDGET(*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
+typedef UIWIDGET(*ui_createwidget_func)(UiObject *obj, UiWidgetArgs *args, void *userdata);
#elif defined(UI_WIN32)
-typedef UIWIDGET(*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
+typedef UIWIDGET(*ui_createwidget_func)(UiObject *obj, UiWidgetArgs *args, void *userdata);
#endif
-UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs args);
+UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs *args);
-#define ui_customwidget(obj, create_widget, userdata, ...) ui_customwidget_create(obj, create_widget, userdata, (UiWidgetArgs) { __VA_ARGS__ })
+#define ui_customwidget(obj, create_widget, userdata, ...) ui_customwidget_create(obj, create_widget, userdata, &(UiWidgetArgs) { __VA_ARGS__ })
UIEXPORT UIWIDGET ui_separator_create(UiObject *obj, UiWidgetArgs *args);