Added experimental android support

0.8
Bruno Van de Velde 2015-01-30 16:39:05 +01:00
parent 977e239dae
commit 967f5a39d3
35 changed files with 2697 additions and 132 deletions

2
.gitignore vendored
View File

@ -2,5 +2,7 @@
/build
/form-builder/tgui-form-builder
/_site
/examples/Android/libs
/examples/Android/obj
.DS_Store
*~

View File

@ -3,10 +3,12 @@ compiler: clang
install:
- sudo apt-get update -qq
- sudo apt-get install -y libpthread-stubs0-dev libgl1-mesa-dev libx11-dev libxrandr-dev libfreetype6-dev libglew1.5-dev libjpeg8-dev libgpgme11-dev libsndfile1-dev libopenal-dev libudev-dev libjpeg62
- wget -O SFML.tar.gz https://www.dropbox.com/s/o1ab52jekbb1x62/SFML-2.2-linux-gcc-64-bit.tar.gz?dl=1
- sudo apt-get install -y libpthread-stubs0-dev libgl1-mesa-dev libx11-dev libxrandr-dev libfreetype6-dev libglew-dev libjpeg8-dev libgpgme11-dev libsndfile1-dev libopenal-dev libudev-dev libjpeg62
- wget -O SFML.tar.gz https://github.com/LaurentGomila/SFML/archive/2.2.tar.gz
- tar -xzf SFML.tar.gz
- sudo cp -r SFML-2.2/lib/* /usr/local/lib/
- sudo cp -r SFML-2.2/include/* /usr/local/include/
- cd SFML-2.2
- cmake .
- make && sudo make install
- cd ..
script: cmake . && make

59
Android.mk Normal file
View File

@ -0,0 +1,59 @@
LOCAL_PATH := $(call my-dir)
# TGUI library in release mode
include $(CLEAR_VARS)
LOCAL_MODULE := tgui
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libtgui.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES := sfml-graphics sfml-window sfml-system
prebuilt_path := $(call local-prebuilt-path,$(LOCAL_SRC_FILES))
prebuilt := $(strip $(wildcard $(prebuilt_path)))
ifdef prebuilt
include $(PREBUILT_SHARED_LIBRARY)
endif
# TGUI library in debug mode
include $(CLEAR_VARS)
LOCAL_MODULE := tgui-d
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libtgui-d.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES := sfml-graphics-d sfml-window-d sfml-system-d
prebuilt_path := $(call local-prebuilt-path,$(LOCAL_SRC_FILES))
prebuilt := $(strip $(wildcard $(prebuilt_path)))
ifdef prebuilt
include $(PREBUILT_SHARED_LIBRARY)
endif
# TGUI Activity library in release mode
include $(CLEAR_VARS)
LOCAL_MODULE := tgui-activity
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libtgui-activity.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
prebuilt_path := $(call local-prebuilt-path,$(LOCAL_SRC_FILES))
prebuilt := $(strip $(wildcard $(prebuilt_path)))
ifdef prebuilt
include $(PREBUILT_SHARED_LIBRARY)
endif
# TGUI Activity library in debug mode
include $(CLEAR_VARS)
LOCAL_MODULE := tgui-activity-d
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libtgui-activity-d.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
prebuilt_path := $(call local-prebuilt-path,$(LOCAL_SRC_FILES))
prebuilt := $(strip $(wildcard $(prebuilt_path)))
ifdef prebuilt
include $(PREBUILT_SHARED_LIBRARY)
endif
$(call import-module,sfml)

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 2.8)
# define a macro that helps defining an option
# Define a macro that helps defining an option
macro(tgui_set_option var default type docstring)
if(NOT DEFINED ${var})
set(${var} ${default})
@ -8,16 +8,11 @@ macro(tgui_set_option var default type docstring)
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
endmacro()
# Specify default build type if none provided
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build (Debug or Release)" FORCE)
endif()
# Specify default cmake module path if none provided
if(NOT CMAKE_MODULE_PATH)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules CACHE STRING "The path to the cmake modules. This path must contain the FindSFML.cmake file." FORCE)
endif()
# Set a default build type and module path if none was provided
tgui_set_option(CMAKE_BUILD_TYPE Release STRING "Choose the type of build (Debug or Release)")
tgui_set_option(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" STRING "The path to the cmake modules. This path must contain the FindSFML.cmake file.")
# Project name
project(tgui)
# project version
@ -29,37 +24,108 @@ SET( PATCH_VERSION 0 )
configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/include/TGUI/Config.hpp.in"
"${CMAKE_CURRENT_SOURCE_DIR}/include/TGUI/Config.hpp")
# include the configuration file
# Include the configuration file
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake)
# project options
# Add an option for choosing the build type (shared or static)
if(NOT (SFML_OS_IOS OR SFML_OS_ANDROID))
tgui_set_option(TGUI_SHARED_LIBS TRUE BOOL "TRUE to build TGUI as a shared library, FALSE to build it as a static library")
else()
if(SFML_OS_IOS)
set(TGUI_SHARED_LIBS FALSE)
elseif(SFML_OS_ANDROID)
set(TGUI_SHARED_LIBS TRUE)
endif()
endif()
# TODO: Add option to build the examples
#if(SFML_OS_IOS OR SFML_OS_ANDROID)
# set(TGUI_BUILD_EXAMPLES FALSE)
#else()
# tgui_set_option(TGUI_BUILD_EXAMPLES FALSE BOOL "TRUE to build the TGUI examples, FALSE to ignore them")
#endif()
# Add an option for choosing the OpenGL implementation
tgui_set_option(TGUI_OPENGL_ES ${OPENGL_ES} BOOL "TRUE to use an OpenGL ES implementation, FALSE to use a desktop OpenGL implementation")
# Add an option to build the documentation
tgui_set_option( TGUI_BUILD_DOC FALSE BOOL "TRUE to generate the API documentation, FALSE to ignore it")
tgui_set_option( TGUI_SHARED_LIBS TRUE BOOL "Build shared libraries (Set to OFF to build static libraries)" )
# Set some useful compile flags.
if( SFML_COMPILER_GCC )
if( NOT CMAKE_CXX_FLAGS )
set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wshadow -Wno-long-long -pedantic -std=c++11" CACHE STRING "C++ compiler flags" FORCE )
set( CMAKE_C_FLAGS "-Wall -Wextra -Wshadow -Wno-long-long -pedantic" CACHE STRING "C compiler flags" FORCE )
# Add options to build the form builder if not on android
if (NOT SFML_OS_ANDROID)
if (SFML_OS_WINDOWS)
tgui_set_option( TGUI_BUILD_FORM_BUILDER FALSE BOOL "Build the TGUI Form Builder" )
else()
tgui_set_option( TGUI_BUILD_FORM_BUILDER TRUE BOOL "Build the TGUI Form Builder" )
endif()
elseif ( SFML_COMPILER_CLANG )
if (SFML_OS_LINUX)
tgui_set_option( TGUI_FORM_BUILDER_USE_LOCAL_FILES FALSE BOOL "Use resources from current directory instead of from installed files." )
endif()
endif()
if( NOT CMAKE_CXX_FLAGS )
set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wshadow -Wno-long-long -pedantic -std=c++11" CACHE STRING "C++ compiler flags" FORCE )
set( CMAKE_C_FLAGS "-Wall -Wextra -Wshadow -Wno-long-long -pedantic" CACHE STRING "C compiler flags" FORCE )
# Set compile flags for gcc and clang
if (SFML_OS_ANDROID)
set(TGUI_ACTIVITY_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
string(REPLACE " " ";" TGUI_CXX_FLAGS_LIST ${CMAKE_CXX_FLAGS})
# Remove "-fno-exceptions" from the CMAKE_CXX_FLAGS
set(TGUI_TEMP_CXX_FLAGS "")
foreach (flag ${TGUI_CXX_FLAGS_LIST})
if (NOT (${flag} STREQUAL "-fno-exceptions"))
set(TGUI_TEMP_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS} ${flag}")
endif()
endforeach(flag)
# Detect if we have "-std=c++11" and "-fexceptions" flags already
set(TGUI_CPP11_SET FALSE)
set(TGUI_EXCEPTIONS_SET FALSE)
foreach (flag ${TGUI_CXX_FLAGS_LIST})
if (${flag} STREQUAL "-std=c++11")
set(TGUI_CPP11_SET TRUE)
endif()
if (${flag} STREQUAL "-fexceptions")
set(TGUI_EXCEPTIONS_SET TRUE)
endif()
endforeach(flag)
# Add the "-std=c++11" flag if it wasn't there already
if (NOT TGUI_CPP11_SET)
set(TGUI_TEMP_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS} -std=c++11")
endif()
# Add the "-fexceptions" flag if it wasn't there already
if (NOT TGUI_EXCEPTIONS_SET)
set(TGUI_TEMP_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS} -fexceptions")
endif()
set(CMAKE_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS}")
elseif(SFML_COMPILER_GCC)
if (NOT CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wshadow -Wno-long-long -pedantic -std=c++11" CACHE STRING "C++ compiler flags" FORCE)
set(CMAKE_C_FLAGS "-Wall -Wextra -Wshadow -Wno-long-long -pedantic" CACHE STRING "C compiler flags" FORCE)
endif()
elseif (SFML_COMPILER_CLANG)
if (NOT CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wshadow -Wno-long-long -pedantic -std=c++11" CACHE STRING "C++ compiler flags" FORCE)
set(CMAKE_C_FLAGS "-Wall -Wextra -Wshadow -Wno-long-long -pedantic" CACHE STRING "C compiler flags" FORCE)
# On mac, clang needs another parameter
if (SFML_OS_MACOSX)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" CACHE STRING "C++ compiler flags" FORCE )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" CACHE STRING "C++ compiler flags" FORCE)
endif()
endif()
endif()
# Define an option for choosing between static and dynamic C runtime (VC++ only)
if(SFML_OS_WINDOWS)
if (SFML_OS_WINDOWS)
tgui_set_option(TGUI_USE_STATIC_STD_LIBS FALSE BOOL "TRUE to statically link to the standard libraries, FALSE to use them as DLLs. This option has to match with the one from sfml.")
# The following combination of flags is not valid
@ -79,11 +145,31 @@ if(SFML_OS_WINDOWS)
endif()
endif()
# Set the correct architecture on mac
if ( SFML_OS_MACOSX )
if( NOT CMAKE_OSX_ARCHITECTURES )
set( CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "Build architectures for OSX" FORCE )
# Mac OS X specific options
if (SFML_OS_MACOSX)
# Set the correct architecture
tgui_set_option(CMAKE_OSX_ARCHITECTURES "x86_64" STRING "Build architectures for OSX")
# TODO: Support frameworks
endif()
# Android options
if(SFML_OS_ANDROID)
# Force usage of the STL port
set(ANDROID_USE_STLPORT TRUE)
# Make sure there's the android library available
if (${ANDROID_NATIVE_API_LEVEL} LESS 9)
message(FATAL_ERROR "API level must be equal or greater than 9")
endif()
# Install everything in $NDK/sources/ because this path is appended by the NDK (convenient)
set(CMAKE_INSTALL_PREFIX ${ANDROID_NDK}/sources/tgui)
# We install libs in a subdirectory named after the ABI (e.g. lib/armeabi/libtgui.so)
set(LIB_SUFFIX "/${ANDROID_ABI}")
endif()
# Link to the static sfml libraries when building tgui statically
@ -112,15 +198,19 @@ if(NOT TGUI_SHARED_LIBS)
elseif(SFML_OS_MACOSX)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${SFML_ROOT}/extlibs/headers")
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${SFML_ROOT}/extlibs/libs-osx/lib/")
elseif(SFML_OS_ANDROID)
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${ANDROID_NDK}/sources/sfml/extlibs/lib/armeabi/")
endif()
endif()
endif()
# Find sfml (also look for the main component when using Visual Studio)
if (SFML_OS_WINDOWS AND SFML_COMPILER_MSVC)
find_package( SFML 2 COMPONENTS main graphics window system )
find_package(SFML 2 COMPONENTS main graphics window system)
elseif (SFML_OS_ANDROID)
find_host_package(SFML 2 COMPONENTS graphics window system)
else()
find_package( SFML 2 COMPONENTS graphics window system )
find_package(SFML 2 COMPONENTS graphics window system)
endif()
# FindSFML couldn't find SFML.
@ -153,3 +243,7 @@ if(NOT SFML_OS_ANDROID)
install(FILES cmake/Modules/FindTGUI.cmake DESTINATION "${INSTALL_MISC_DIR}/cmake/Modules")
endif()
# Install Android.mk so the NDK knows how to set up TGUI
if(SFML_OS_ANDROID)
install(FILES Android.mk DESTINATION .)
endif()

View File

@ -2,6 +2,9 @@
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(SFML_OS_WINDOWS 1)
# don't use the OpenGL ES implementation on Windows
set(OPENGL_ES 0)
# detect the architecture (note: this test won't work for cross-compilation)
include(CheckTypeSize)
check_type_size(void* SIZEOF_VOID_PTR)
@ -14,19 +17,53 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
return()
endif()
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(SFML_OS_LINUX 1)
set(SFML_OS_UNIX 1)
if(ANDROID)
set(SFML_OS_ANDROID 1)
# use the OpenGL ES implementation on Android
set(OPENGL_ES 1)
else()
set(SFML_OS_LINUX 1)
# don't use the OpenGL ES implementation on Linux
set(OPENGL_ES 0)
endif()
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(SFML_OS_FREEBSD 1)
# don't use the OpenGL ES implementation on FreeBSD
set(OPENGL_ES 0)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(SFML_OS_MACOSX 1)
if(IOS)
set(SFML_OS_IOS 1)
# detect OS X version. (use '/usr/bin/sw_vers -productVersion' to extract V from '10.V.x'.)
EXEC_PROGRAM(/usr/bin/sw_vers ARGS -productVersion OUTPUT_VARIABLE MACOSX_VERSION_RAW)
STRING(REGEX REPLACE "10\\.([0-9]+).*" "\\1" MACOSX_VERSION "${MACOSX_VERSION_RAW}")
if(${MACOSX_VERSION} LESS 5)
message(FATAL_ERROR "Unsupported version of OS X : ${MACOSX_VERSION_RAW}")
return()
# set the target framework and platforms
set(CMAKE_OSX_SYSROOT "iphoneos")
set(CMAKE_OSX_ARCHITECTURES "armv6;armv7;i386")
set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos;-iphonesimulator")
# help the compiler detection script below
set(CMAKE_COMPILER_IS_GNUCXX 1)
# use the OpenGL ES implementation on iOS
set(OPENGL_ES 1)
else()
set(SFML_OS_MACOSX 1)
# don't use the OpenGL ES implementation on Mac OS X
set(OPENGL_ES 0)
# detect OS X version. (use '/usr/bin/sw_vers -productVersion' to extract V from '10.V.x'.)
EXEC_PROGRAM(/usr/bin/sw_vers ARGS -productVersion OUTPUT_VARIABLE MACOSX_VERSION_RAW)
STRING(REGEX REPLACE "10\\.([0-9]+).*" "\\1" MACOSX_VERSION "${MACOSX_VERSION_RAW}")
if(${MACOSX_VERSION} LESS 7)
message(FATAL_ERROR "Unsupported version of OS X: ${MACOSX_VERSION_RAW}")
return()
endif()
endif()
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android")
set(SFML_OS_ANDROID 1)
# use the OpenGL ES implementation on Android
set(OPENGL_ES 1)
else()
message(FATAL_ERROR "Unsupported operating system")
return()
@ -71,8 +108,10 @@ else()
endif()
# define the install directory for miscellaneous files
if(SFML_OS_WINDOWS)
if(SFML_OS_WINDOWS OR SFML_OS_IOS)
set(INSTALL_MISC_DIR .)
elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OS_MACOSX)
set(INSTALL_MISC_DIR share/tgui-${MAJOR_VERSION}.${MINOR_VERSION})
elseif(SFML_OS_ANDROID)
set(INSTALL_MISC_DIR ${ANDROID_NDK}/sources/tgui)
endif()

View File

@ -70,6 +70,10 @@ endif()
set(FIND_SFML_PATHS
${SFML_ROOT}
$ENV{SFML_ROOT}
${ANDROID_NDK}/sources/sfml
$ENV{ANDROID_NDK}/sources/sfml
${ANDROID_NDK}/sources/sfml/lib/${ANDROID_ABI}
$ENV{ANDROID_NDK}/sources/sfml/lib/${ANDROID_ABI}
~/Library/Frameworks
/Library/Frameworks
/usr/local

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
</content>
<orderEntry type="jdk" jdkName="Android API 9 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tgui"
android:versionCode="1"
android:versionName="1.0" >
<uses-feature android:glEsVersion="0x00010001" />
<uses-sdk android:minSdkVersion="9"
android:targetSdkVersion="19" />
<application android:label="@string/app_name"
android:icon="@drawable/tgui_logo"
android:hasCode="false"
android:allowBackup="true">
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:icon="@drawable/tgui_logo"
android:configChanges="keyboardHidden|orientation">
<meta-data android:name="android.app.lib_name" android:value="sfml-activity" />
<meta-data android:name="sfml.app.lib_name" android:value="tgui-activity" />
<meta-data android:name="tgui.app.lib_name" android:value="tgui-example" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

View File

@ -0,0 +1,158 @@
Button:
NormalImage = "Black.png" Part( 0, 64, 45, 50) Middle(10, 0, 25, 50)
HoverImage = "Black.png" Part(45, 64, 45, 50) Middle(10, 0, 25, 50)
DownImage = "Black.png" Part(90, 64, 45, 50) Middle(10, 0, 25, 50)
TextColorNormal = (190, 190, 190)
TextColorHover = (250, 250, 250)
TextColorDown = (250, 250, 250)
ChatBox:
BackgroundImage = "Black.png" Part(0, 154, 48, 48) Middle(16, 16, 16, 16)
Scrollbar = "Scrollbar"
Padding = (3, 3, 3, 3)
Checkbox:
UncheckedImage = "Black.png" Part(124, 0, 32, 32)
CheckedImage = "Black.png" Part(156, 0, 32, 32)
UncheckedHoverImage = "Black.png" Part(188, 0, 32, 32)
CheckedHoverImage = "Black.png" Part(220, 0, 32, 32)
TextColorNormal = (190, 190, 190)
TextColorHover = (250, 250, 250)
ChildWindow:
TitlebarImage = "Black.png" Part(48, 154, 75, 25) Middle(25, 0, 25, 25)
TitleColor = (190, 190, 190)
BackgroundColor = ( 80, 80, 80)
Borders = (1, 1, 1, 1)
BorderColor = (0, 0, 0)
DistanceToSide = 5
CloseButton = "ChildWindowCloseButton"
ChildWindowCloseButton:
NormalImage = "Black.png" Part(48, 179, 15, 15)
HoverImage = "Black.png" Part(63, 179, 15, 15)
DownImage = "Black.png" Part(78, 179, 15, 15)
ComboBox:
BackgroundImage = "Black.png" Part(0, 154, 48, 48) Middle(16, 16, 16, 16)
ArrowDownNormalImage = "Black.png" Part(60, 0, 32, 32)
ArrowDownHoverImage = "Black.png" Part(60, 32, 32, 32)
ArrowUpNormalImage = "Black.png" Part(92, 0, 32, 32)
ArrowUpHoverImage = "Black.png" Part(92, 32, 32, 32)
TextColor = (190, 190, 190)
Padding = (3, 3, 3, 3)
ListBox = "ListBox"
EditBox:
NormalImage = "Black.png" Part(0, 114, 60, 40) Middle(15, 0, 30, 40)
HoverImage = "Black.png" Part(0, 114, 60, 40) Middle(15, 0, 30, 40)
TextColor = (190, 190, 190)
SelectedTextColor = (255, 255, 255)
SelectedTextBackgroundColor = ( 10, 110, 255)
DefaultTextColor = (120, 120, 120)
CaretColor = (110, 110, 255)
Padding = (6, 4, 6, 4)
Label:
TextColor = (190, 190, 190)
ListBox:
BackgroundImage = "Black.png" Part(0, 154, 48, 48) Middle(16, 16, 16, 16)
TextColorNormal = (190, 190, 190)
TextColorHover = (250, 250, 250)
HoverBackgroundColor = (255, 255, 255, 20)
SelectedBackgroundColor = ( 10, 110, 255)
SelectedTextColor = (255, 255, 255)
Padding = (3, 3, 3, 3)
Scrollbar = "Scrollbar"
ProgressBar:
BackImage = "Black.png" Part(180, 64, 90, 40) Middle(20, 0, 50, 40)
FrontImage = "Black.png" Part(180, 108, 82, 32) Middle(16, 0, 50, 32)
TextColorBack = (190, 190, 190)
TextColorFront = (250, 250, 250)
MenuBar:
BackgroundImage = "Black.png" Part(115, 179, 8, 6) Middle(2, 2, 4, 2)
ItemBackgroundImage = "Black.png" Part(115, 181, 8, 4) Middle(2, 0, 4, 2)
SelectedItemBackgroundImage = "Black.png" Part(115, 185, 8, 6) Middle(2, 2, 4, 2)
TextColor = (190, 190, 190)
SelectedTextColor = (255, 255, 255)
DistanceToSide = 5
MessageBox:
ChildWindow = "ChildWindow"
Button = "Button"
TextColor = (190, 190, 190)
RadioButton:
UncheckedImage = "Black.png" Part(124, 32, 32, 32)
CheckedImage = "Black.png" Part(156, 32, 32, 32)
UncheckedHoverImage = "Black.png" Part(188, 32, 32, 32)
CheckedHoverImage = "Black.png" Part(220, 32, 32, 32)
TextColorNormal = (190, 190, 190)
TextColorHover = (250, 250, 250)
Scrollbar:
TrackNormalImage = "Black.png" Part(123, 154, 20, 20)
ThumbNormalImage = "Black.png" Part(143, 154, 20, 20)
ThumbHoverImage = "Black.png" Part(143, 174, 20, 20)
ArrowUpNormalImage = "Black.png" Part(163, 154, 20, 20) Middle(0, 0, 20, 19)
ArrowUpHoverImage = "Black.png" Part(183, 154, 20, 20) Middle(0, 0, 20, 19)
ArrowDownNormalImage = "Black.png" Part(163, 174, 20, 20) Middle(0, 1, 20, 19)
ArrowDownHoverImage = "Black.png" Part(183, 174, 20, 20) Middle(0, 1, 20, 19)
Slider:
TrackNormalImage = "Black.png" Part(203, 150, 20, 45) Middle(0, 15, 20, 15)
TrackHoverImage = "Black.png" Part(223, 150, 20, 45) Middle(0, 15, 20, 15)
ThumbNormalImage = "Black.png" Part(243, 150, 30, 30)
SpinButton:
ArrowUpNormalImage = "Black.png" Part(163, 154, 20, 20) Middle(0, 0, 20, 19)
ArrowUpHoverImage = "Black.png" Part(183, 154, 20, 20) Middle(0, 0, 20, 19)
ArrowDownNormalImage = "Black.png" Part(163, 174, 20, 20) Middle(0, 1, 20, 19)
ArrowDownHoverImage = "Black.png" Part(183, 174, 20, 20) Middle(0, 1, 20, 19)
SpaceBetweenArrows = 0
Tab:
NormalImage = "Black.png" Part(0, 0, 60, 32) Middle(16, 0, 28, 32)
SelectedImage = "Black.png" Part(0, 32, 60, 32) Middle(16, 0, 28, 32)
TextColor = (190, 190, 190)
SelectedTextColor = (255, 255, 255)
BorderColor = ( 0, 0, 0)
DistanceToSide = 8
TextBox:
BackgroundImage = "Black.png" Part(0, 154, 48, 48) Middle(16, 16, 16, 16)
TextColor = (190, 190, 190)
SelectedTextColor = (255, 255, 255)
SelectedTextBackgroundColor = ( 10, 110, 255)
CaretColor = (110, 110, 255)
Padding = (3, 3, 3, 3)
Scrollbar = "Scrollbar"
Tooltip:
TextColor = (190, 190, 190)
BackgroundColor = ( 80, 80, 80)
BorderColor = ( 0, 0, 0)
Borders = (1, 1, 1, 1)
Padding = (2, 2, 2, 2)

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,19 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := tgui-example
LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES := sfml-system
LOCAL_SHARED_LIBRARIES += sfml-window
LOCAL_SHARED_LIBRARIES += sfml-graphics
LOCAL_SHARED_LIBRARIES += sfml-audio
LOCAL_SHARED_LIBRARIES += sfml-network
LOCAL_SHARED_LIBRARIES += tgui
LOCAL_WHOLE_STATIC_LIBRARIES := sfml-main
include $(BUILD_SHARED_LIBRARY)
$(call import-module,tgui)

View File

@ -0,0 +1,6 @@
NDK_TOOLCHAIN_VERSION := 4.8
APP_PLATFORM := android-9
APP_STL := c++_shared
APP_ABI := armeabi
APP_MODULES := sfml-activity tgui-activity tgui-example
APP_CPPFLAGS += -fexceptions

View File

@ -0,0 +1,70 @@
#include <TGUI/TGUI.hpp>
void setBackground(tgui::Gui& gui, sf::View view)
{
gui.get("Landscape")->setSize(view.getSize().x, view.getSize().y);
gui.get("Portrait")->setSize(view.getSize().x, view.getSize().y);
if (view.getSize().x > view.getSize().y)
{
gui.get("Landscape")->show();
gui.get("Portrait")->hide();
}
else
{
gui.get("Landscape")->hide();
gui.get("Portrait")->show();
}
}
int main(int argc, char *argv[])
{
sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");
tgui::Gui gui(window);
gui.setGlobalFont("fonts/DejaVuSans.ttf");
auto picLandscape = tgui::Picture::create("Background-Landscape.png");
gui.add(picLandscape, "Landscape");
auto picPortrait = tgui::Picture::create("Background-Portrait.png");
gui.add(picPortrait, "Portrait");
auto button = tgui::Button::create("widgets/Black.conf");
button->setText("Quit");
button->setPosition(50, 50);
button->setSize(200, 50);
button->connect("clicked", [&](){ window.close(); });
gui.add(button);
setBackground(gui, window.getDefaultView());
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
else if (event.type == sf::Event::Resized)
{
sf::View view = window.getView();
view.setSize(event.size.width, event.size.height);
view.setCenter(event.size.width/2, event.size.height/2);
window.setView(view);
setBackground(gui, window.getDefaultView());
}
gui.handleEvent(event);
}
window.clear(sf::Color::Blue);
gui.draw();
window.display();
}
}

View File

@ -0,0 +1 @@
target=android-9

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TGUI demo</string>
</resources>

View File

@ -0,0 +1,101 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2013 Jonathan De Wachter (dewachter.jonathan@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_ACTIVITY_HPP
#define SFML_ACTIVITY_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Event.hpp>
#include <SFML/Window/EglContext.hpp>
#include <SFML/System/Mutex.hpp>
#include <android/native_activity.h>
#include <android/configuration.h>
#include <EGL/egl.h>
#include <vector>
#include <map>
#include <string>
#include <fstream>
class SFML_SYSTEM_API LogcatStream : public std::streambuf
{
public:
LogcatStream();
std::streambuf::int_type overflow (std::streambuf::int_type c);
private:
std::string m_message;
};
namespace sf
{
namespace priv
{
struct ActivityStates
{
ANativeActivity* activity;
ANativeWindow* window;
ALooper* looper;
AInputQueue* inputQueue;
AConfiguration* config;
EGLDisplay display;
EglContext* context;
void* savedState;
size_t savedStateSize;
Mutex mutex;
void (*forwardEvent)(const Event& event);
int (*processEvent)(int fd, int events, void* data);
std::map<int, Vector2i> touchEvents;
Vector2i mousePosition;
bool isButtonPressed[Mouse::ButtonCount];
bool mainOver;
Vector2i screenSize;
bool initialized;
bool terminated;
bool fullscreen;
bool updated;
LogcatStream logcat;
};
SFML_SYSTEM_API ActivityStates* getActivity(ActivityStates* initializedStates=NULL, bool reset=false);
} // namespace priv
} // namespace sf
#endif // SFML_ACTIVITY_HPP

View File

@ -0,0 +1,68 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2013 Jonathan De Wachter (dewachter.jonathan@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_EGLCHECK_HPP
#define SFML_EGLCHECK_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <EGL/egl.h>
#include <string>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Let's define a macro to quickly check every EGL API call
////////////////////////////////////////////////////////////
#ifdef SFML_DEBUG
//// In debug mode, perform a test on every EGL call
#define eglCheck(x) x; sf::priv::eglCheckError(__FILE__, __LINE__);
#else
// Else, we don't add any overhead
#define eglCheck(x) (x)
#endif
////////////////////////////////////////////////////////////
/// \brief Check the last EGL error
///
/// \param file Source file where the call is located
/// \param line Line number of the source file where the call is located
///
////////////////////////////////////////////////////////////
void eglCheckError(const char* file, unsigned int line);
} // namespace priv
} // namespace sf
#endif // SFML_EGLCHECK_HPP

View File

@ -0,0 +1,183 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2013 Jonathan De Wachter (dewachter.jonathan@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_EGLCONTEXT_HPP
#define SFML_EGLCONTEXT_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/Window/EGLCheck.hpp>
#include <SFML/Window/GlContext.hpp>
#include <SFML/OpenGL.hpp>
namespace sf
{
namespace priv
{
class EglContext : public GlContext
{
public:
////////////////////////////////////////////////////////////
/// \brief Create a new context, not associated to a window
///
/// \param shared Context to share the new one with (can be NULL)
///
////////////////////////////////////////////////////////////
EglContext(EglContext* shared);
////////////////////////////////////////////////////////////
/// \brief Create a new context attached to a window
///
/// \param shared Context to share the new one with
/// \param settings Creation parameters
/// \param owner Pointer to the owner window
/// \param bitsPerPixel Pixel depth, in bits per pixel
///
////////////////////////////////////////////////////////////
EglContext(EglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target
///
/// \param shared Context to share the new one with
/// \param settings Creation parameters
/// \param width Back buffer width, in pixels
/// \param height Back buffer height, in pixels
///
////////////////////////////////////////////////////////////
EglContext(EglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~EglContext();
////////////////////////////////////////////////////////////
/// \brief Activate the context as the current target
/// for rendering
///
/// \return True on success, false if any error happened
///
////////////////////////////////////////////////////////////
virtual bool makeCurrent();
////////////////////////////////////////////////////////////
/// \brief Display what has been rendered to the context so far
///
////////////////////////////////////////////////////////////
virtual void display();
////////////////////////////////////////////////////////////
/// \brief Enable or disable vertical synchronization
///
/// Activating vertical synchronization will limit the number
/// of frames displayed to the refresh rate of the monitor.
/// This can avoid some visual artifacts, and limit the framerate
/// to a good value (but not constant across different computers).
///
/// \param enabled: True to enable v-sync, false to deactivate
///
////////////////////////////////////////////////////////////
virtual void setVerticalSyncEnabled(bool enabled);
////////////////////////////////////////////////////////////
/// \brief Create the context
///
/// \param shared Context to share the new one with (can be NULL)
/// \param bitsPerPixel Pixel depth, in bits per pixel
/// \param settings Creation parameters
///
////////////////////////////////////////////////////////////
void createContext(EglContext* shared);
////////////////////////////////////////////////////////////
/// \brief Create the EGL surface
///
/// This function must be called when the activity (re)start, or
/// when the orientation change.
///
/// \param window: The native window type
///
////////////////////////////////////////////////////////////
void createSurface(EGLNativeWindowType window);
////////////////////////////////////////////////////////////
/// \brief Destroy the EGL surface
///
/// This function must be called when the activity is stopped, or
/// when the orientation change.
///
////////////////////////////////////////////////////////////
void destroySurface();
////////////////////////////////////////////////////////////
/// \brief Get the best EGL visual for a given set of video settings
///
/// \param display EGL display
/// \param bitsPerPixel Pixel depth, in bits per pixel
/// \param settings Requested context settings
///
/// \return The best EGL config
///
////////////////////////////////////////////////////////////
static EGLConfig getBestConfig(EGLDisplay display, unsigned int bitsPerPixel, const ContextSettings& settings);
#ifdef SFML_SYSTEM_LINUX
////////////////////////////////////////////////////////////
/// \brief Select the best EGL visual for a given set of settings
///
/// \param display X display
/// \param bitsPerPixel Pixel depth, in bits per pixel
/// \param settings Requested context settings
///
/// \return The best visual
///
////////////////////////////////////////////////////////////
static XVisualInfo selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings);
#endif
private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
EGLDisplay m_display; ///< The internal EGL display
EGLContext m_context; ///< The internal EGL context
EGLSurface m_surface; ///< The internal EGL surface
EGLConfig m_config; ///< The internal EGL config
};
} // namespace priv
} // namespace sf
#endif // SFML_EGLCONTEXT_HPP

View File

@ -0,0 +1,234 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_GLCONTEXT_HPP
#define SFML_GLCONTEXT_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/System/NonCopyable.hpp>
namespace sf
{
namespace priv
{
class WindowImpl;
////////////////////////////////////////////////////////////
/// \brief Abstract class representing an OpenGL context
///
////////////////////////////////////////////////////////////
class GlContext : NonCopyable
{
public:
////////////////////////////////////////////////////////////
/// \brief Perform the global initialization
///
/// This function is called once, before the very first OpenGL
/// resource is created. It makes sure that everything is ready
/// for contexts to work properly.
/// Note: this function doesn't need to be thread-safe, as it
/// can be called only once.
///
////////////////////////////////////////////////////////////
static void globalInit();
////////////////////////////////////////////////////////////
/// \brief Perform the global cleanup
///
/// This function is called after the very last OpenGL resource
/// is destroyed. It makes sure that everything that was
/// created by initialize() is properly released.
/// Note: this function doesn't need to be thread-safe, as it
/// can be called only once.
///
////////////////////////////////////////////////////////////
static void globalCleanup();
////////////////////////////////////////////////////////////
/// \brief Ensures that an OpenGL context is active in the current thread
///
////////////////////////////////////////////////////////////
static void ensureContext();
////////////////////////////////////////////////////////////
/// \brief Create a new context, not associated to a window
///
/// This function automatically chooses the specialized class
/// to use according to the OS.
///
/// \return Pointer to the created context (don't forget to delete it)
///
////////////////////////////////////////////////////////////
static GlContext* create();
////////////////////////////////////////////////////////////
/// \brief Create a new context attached to a window
///
/// This function automatically chooses the specialized class
/// to use according to the OS.
///
/// \param settings Creation parameters
/// \param owner Pointer to the owner window
/// \param bitsPerPixel Pixel depth (in bits per pixel)
///
/// \return Pointer to the created context
///
////////////////////////////////////////////////////////////
static GlContext* create(const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target
///
/// This function automatically chooses the specialized class
/// to use according to the OS.
///
/// \param settings Creation parameters
/// \param width Back buffer width
/// \param height Back buffer height
///
/// \return Pointer to the created context
///
////////////////////////////////////////////////////////////
static GlContext* create(const ContextSettings& settings, unsigned int width, unsigned int height);
public:
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
virtual ~GlContext();
////////////////////////////////////////////////////////////
/// \brief Get the settings of the context
///
/// Note that these settings may be different than the ones
/// passed to the constructor; they are indeed adjusted if the
/// original settings are not directly supported by the system.
///
/// \return Structure containing the settings
///
////////////////////////////////////////////////////////////
const ContextSettings& getSettings() const;
////////////////////////////////////////////////////////////
/// \brief Activate or deactivate the context as the current target for rendering
///
/// A context is active only on the current thread, if you want to
/// make it active on another thread you have to deactivate it
/// on the previous thread first if it was active.
/// Only one context can be active on a thread at a time, thus
/// the context previously active (if any) automatically gets deactivated.
///
/// \param active True to activate, false to deactivate
///
/// \return True if operation was successful, false otherwise
///
////////////////////////////////////////////////////////////
bool setActive(bool active);
////////////////////////////////////////////////////////////
/// \brief Display what has been rendered to the context so far
///
////////////////////////////////////////////////////////////
virtual void display() = 0;
////////////////////////////////////////////////////////////
/// \brief Enable or disable vertical synchronization
///
/// Activating vertical synchronization will limit the number
/// of frames displayed to the refresh rate of the monitor.
/// This can avoid some visual artifacts, and limit the framerate
/// to a good value (but not constant across different computers).
///
/// \param enabled True to enable v-sync, false to deactivate
///
////////////////////////////////////////////////////////////
virtual void setVerticalSyncEnabled(bool enabled) = 0;
protected:
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// This constructor is meant for derived classes only.
///
////////////////////////////////////////////////////////////
GlContext();
////////////////////////////////////////////////////////////
/// \brief Activate the context as the current target
/// for rendering
///
/// \return True on success, false if any error happened
///
////////////////////////////////////////////////////////////
virtual bool makeCurrent() = 0;
////////////////////////////////////////////////////////////
/// \brief Evaluate a pixel format configuration
///
/// This functions can be used by implementations that have
/// several valid formats and want to get the best one.
/// A score is returned for the given configuration: the
/// lower the score is, the better the configuration is.
///
/// \param bitsPerPixel Requested pixel depth (bits per pixel)
/// \param settings Requested additional settings
/// \param colorBits Color bits of the configuration to evaluate
/// \param depthBits Depth bits of the configuration to evaluate
/// \param stencilBits Stencil bits of the configuration to evaluate
/// \param antialiasing Antialiasing level of the configuration to evaluate
///
/// \return Score of the configuration
///
////////////////////////////////////////////////////////////
static int evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
ContextSettings m_settings; ///< Creation settings of the context
private:
////////////////////////////////////////////////////////////
/// \brief Perform various initializations after the context construction
///
////////////////////////////////////////////////////////////
void initialize();
};
} // namespace priv
} // namespace sf
#endif // SFML_GLCONTEXT_HPP

View File

@ -25,6 +25,7 @@
#ifndef TGUI_CONFIG_HPP
#define TGUI_CONFIG_HPP
#include <SFML/Config.hpp>
#include <SFML/Config.hpp>

View File

@ -95,7 +95,7 @@ namespace tgui
std::string m_section;
std::vector<std::pair<std::string, std::string>> m_properties;
static std::map<std::pair<std::string, std::string>, std::vector<std::pair<std::string, std::string>>> m_cache;
static std::map<std::string, std::map<std::string, std::vector<std::pair<std::string, std::string>>>> m_cache;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,34 @@
# Create the target
add_library(tgui-activity SHARED TGUIActivity.cpp)
# Define the export symbol of the module
string(REPLACE "-" "_" NAME_UPPER "tgui-activity")
string(TOUPPER "${NAME_UPPER}" NAME_UPPER)
set_target_properties(tgui-activity PROPERTIES DEFINE_SYMBOL ${NAME_UPPER}_EXPORTS)
# Add a -d suffix when in debug mode
set_target_properties(tgui-activity PROPERTIES DEBUG_POSTFIX -d)
# If using gcc >= 4.0 or clang >= 3.0 on a non-Windows platform, we must hide public symbols by default (exported ones are explicitly marked)
if((SFML_COMPILER_GCC AND NOT SFML_GCC_VERSION VERSION_LESS "4") OR (SFML_COMPILER_CLANG AND NOT SFML_CLANG_VERSION VERSION_LESS "3"))
set_target_properties(tgui-activity PROPERTIES COMPILE_FLAGS -fvisibility=hidden)
endif()
# tgui-activity library is our bootstrap activity and must not depend on stlport_shared (otherwise Android will fail to load it)
if (SFML_OS_ANDROID)
set_target_properties(tgui-activity PROPERTIES COMPILE_FLAGS -fpermissive)
set_target_properties(tgui-activity PROPERTIES LINK_FLAGS "-landroid -llog")
# Restore the original compiler flags
set(CMAKE_CXX_FLAGS "${TGUI_ACTIVITY_CMAKE_CXX_FLAGS}" CACHE STRING "C++ compiler flags" FORCE)
# This is a workaround to compile tgui-activity without stlport_shared as dependency
set(CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
endif()
# Install rule
install(TARGETS tgui-activity
RUNTIME DESTINATION bin COMPONENT bin
LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT bin
ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT devel
FRAMEWORK DESTINATION ${CMAKE_INSTALL_FRAMEWORK_PREFIX} COMPONENT bin)

View File

@ -0,0 +1,212 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus's Graphical User Interface
// Copyright (C) 2012-2015 Bruno Van de Velde (vdv_b@tgui.eu)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Original file was taken from SFML and adapted to load TGUI instead of SFML libraries.
// All credits for this code should go to SFML developers.
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2013 Jonathan De Wachter (dewachter.jonathan@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <string>
#include <android/native_activity.h>
#include <android/log.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <jni.h>
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_INFO, "tgui-activity", __VA_ARGS__))
namespace {
typedef void (*activityOnCreatePointer)(ANativeActivity*, void*, size_t);
}
std::string getLibraryName(JNIEnv* lJNIEnv, jobject& objectActivityInfo)
{
// This function reads the value of meta-data "tgui.app.lib_name"
// found in the Android Manifest file and returns it. It performs the
// following Java code using the JNI interface:
//
// ai.metaData.getString("tgui.app.lib_name");
// Get metaData instance from the ActivityInfo object
jclass classActivityInfo = lJNIEnv->FindClass("android/content/pm/ActivityInfo");
jfieldID fieldMetaData = lJNIEnv->GetFieldID(classActivityInfo, "metaData", "Landroid/os/Bundle;");
jobject objectMetaData = lJNIEnv->GetObjectField(objectActivityInfo, fieldMetaData);
// Create a java string object containing "tgui.app.lib_name"
jobject objectName = lJNIEnv->NewStringUTF("tgui.app.lib_name");
// Get the value of meta-data named "tgui.app.lib_name"
jclass classBundle = lJNIEnv->FindClass("android/os/Bundle");
jmethodID methodGetString = lJNIEnv->GetMethodID(classBundle, "getString", "(Ljava/lang/String;)Ljava/lang/String;");
jstring valueString = (jstring)lJNIEnv->CallObjectMethod(objectMetaData, methodGetString, objectName);
// No meta-data "tgui.app.lib_name" was found so we abord and inform the user
if (valueString == NULL)
{
LOGE("No meta-data 'tgui.app.lib_name' found in AndroidManifest.xml file");
exit(1);
}
// Convert the application name to a C++ string and return it
const jsize applicationNameLength = lJNIEnv->GetStringUTFLength(valueString);
const char* applicationName = lJNIEnv->GetStringUTFChars(valueString, NULL);
std::string ret(applicationName, applicationNameLength);
lJNIEnv->ReleaseStringUTFChars(valueString, applicationName);
return ret;
}
void* loadLibrary(const char* libraryName, JNIEnv* lJNIEnv, jobject& ObjectActivityInfo)
{
// Find out the absolute path of the library
jclass ClassActivityInfo = lJNIEnv->FindClass("android/content/pm/ActivityInfo");
jfieldID FieldApplicationInfo = lJNIEnv->GetFieldID(ClassActivityInfo, "applicationInfo", "Landroid/content/pm/ApplicationInfo;");
jobject ObjectApplicationInfo = lJNIEnv->GetObjectField(ObjectActivityInfo, FieldApplicationInfo);
jclass ClassApplicationInfo = lJNIEnv->FindClass("android/content/pm/ApplicationInfo");
jfieldID FieldNativeLibraryDir = lJNIEnv->GetFieldID(ClassApplicationInfo, "nativeLibraryDir", "Ljava/lang/String;");
jobject ObjectDirPath = lJNIEnv->GetObjectField(ObjectApplicationInfo, FieldNativeLibraryDir);
jclass ClassSystem = lJNIEnv->FindClass("java/lang/System");
jmethodID StaticMethodMapLibraryName = lJNIEnv->GetStaticMethodID(ClassSystem, "mapLibraryName", "(Ljava/lang/String;)Ljava/lang/String;");
jstring LibNameObject = lJNIEnv->NewStringUTF(libraryName);
jobject ObjectName = lJNIEnv->CallStaticObjectMethod(ClassSystem, StaticMethodMapLibraryName, LibNameObject);
jclass ClassFile = lJNIEnv->FindClass("java/io/File");
jmethodID FileConstructor = lJNIEnv->GetMethodID(ClassFile, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
jobject ObjectFile = lJNIEnv->NewObject(ClassFile, FileConstructor, ObjectDirPath, ObjectName);
// Get the library absolute path and convert it
jmethodID MethodGetPath = lJNIEnv->GetMethodID(ClassFile, "getPath", "()Ljava/lang/String;");
jstring javaLibraryPath = static_cast<jstring>(lJNIEnv->CallObjectMethod(ObjectFile, MethodGetPath));
const char* libraryPath = lJNIEnv->GetStringUTFChars(javaLibraryPath, NULL);
// Manually load the library
void * handle = dlopen(libraryPath, RTLD_NOW | RTLD_GLOBAL);
if (!handle)
{
LOGE("dlopen(\"%s\"): %s", libraryPath, dlerror());
exit(1);
}
// Release the Java string
lJNIEnv->ReleaseStringUTFChars(javaLibraryPath, libraryPath);
return handle;
}
void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize)
{
// Before we can load a library, we need to find out its location. As
// we're powerless here in C/C++, we need the JNI interface to communicate
// with the attached Java virtual machine and perform some Java calls in
// order to retrieve the absolute path of our libraries.
//
// Here's the snippet of Java code it performs:
// --------------------------------------------
// ai = getPackageManager().getActivityInfo(getIntent().getComponent(), PackageManager.GET_META_DATA);
// File libraryFile = new File(ai.applicationInfo.nativeLibraryDir, System.mapLibraryName(libname));
// String path = libraryFile.getPath();
//
// With libname being the library name such as "jpeg".
// Retrieve JNI environment and JVM instance
JavaVM* lJavaVM = activity->vm;
JNIEnv* lJNIEnv = activity->env;
// Retrieve the NativeActivity
jobject ObjectNativeActivity = activity->clazz;
jclass ClassNativeActivity = lJNIEnv->GetObjectClass(ObjectNativeActivity);
// Retrieve the ActivityInfo
jmethodID MethodGetPackageManager = lJNIEnv->GetMethodID(ClassNativeActivity, "getPackageManager", "()Landroid/content/pm/PackageManager;");
jobject ObjectPackageManager = lJNIEnv->CallObjectMethod(ObjectNativeActivity, MethodGetPackageManager);
jmethodID MethodGetIndent = lJNIEnv->GetMethodID(ClassNativeActivity, "getIntent", "()Landroid/content/Intent;");
jobject ObjectIntent = lJNIEnv->CallObjectMethod(ObjectNativeActivity, MethodGetIndent);
jclass ClassIntent = lJNIEnv->FindClass("android/content/Intent");
jmethodID MethodGetComponent = lJNIEnv->GetMethodID(ClassIntent, "getComponent", "()Landroid/content/ComponentName;");
jobject ObjectComponentName = lJNIEnv->CallObjectMethod(ObjectIntent, MethodGetComponent);
jclass ClassPackageManager = lJNIEnv->FindClass("android/content/pm/PackageManager");
jfieldID FieldGET_META_DATA = lJNIEnv->GetStaticFieldID(ClassPackageManager, "GET_META_DATA", "I");
jint GET_META_DATA = lJNIEnv->GetStaticIntField(ClassPackageManager, FieldGET_META_DATA);
jmethodID MethodGetActivityInfo = lJNIEnv->GetMethodID(ClassPackageManager, "getActivityInfo", "(Landroid/content/ComponentName;I)Landroid/content/pm/ActivityInfo;");
jobject ObjectActivityInfo = lJNIEnv->CallObjectMethod(ObjectPackageManager, MethodGetActivityInfo, ObjectComponentName, GET_META_DATA);
// Load our libraries in reverse order
loadLibrary("c++_shared", lJNIEnv, ObjectActivityInfo);
loadLibrary("sndfile", lJNIEnv, ObjectActivityInfo);
loadLibrary("openal", lJNIEnv, ObjectActivityInfo);
#if !defined(SFML_DEBUG)
loadLibrary("tgui", lJNIEnv, ObjectActivityInfo);
#else
loadLibrary("tgui-d", lJNIEnv, ObjectActivityInfo);
#endif
std::string libName = getLibraryName(lJNIEnv, ObjectActivityInfo);
void* handle = loadLibrary(libName.c_str(), lJNIEnv, ObjectActivityInfo);
// Call the original ANativeActivity_onCreate function
activityOnCreatePointer ANativeActivity_onCreate = (activityOnCreatePointer)dlsym(handle, "ANativeActivity_onCreate");
if (!ANativeActivity_onCreate)
{
LOGE("tgui-activity: Undefined symbol ANativeActivity_onCreate");
exit(1);
}
ANativeActivity_onCreate(activity, savedState, savedStateSize);
}

View File

@ -6,18 +6,39 @@ include_directories( "${PROJECT_SOURCE_DIR}/include" )
include_directories( ${SFML_INCLUDE_DIR} )
# OpenGL is required (due to a temporary fix)
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
if (NOT TGUI_OPENGL_ES)
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
set(TGUI_EXT_LIBS ${OPENGL_gl_LIBRARY} ${SFML_LIBRARIES})
else()
if (SFML_OS_LINUX)
find_package(EGL REQUIRED)
find_package(GLES REQUIRED)
include_directories(${EGL_INCLUDE_DIR} ${GLES_INCLUDE_DIR})
elseif(SFML_OS_ANDROID)
set(TGUI_EXT_LIBS ${SFML_LIBRARIES} "-lEGL -lGLESv1_CM")
endif()
endif()
# We need to link to an extra library on android (to use the asset manager)
if(SFML_OS_ANDROID)
set(TGUI_EXT_LIBS ${TGUI_EXT_LIBS} "-landroid")
endif()
# Determine library suffixes depending on static/shared configuration
if(TGUI_SHARED_LIBS)
add_library(${PROJECT_NAME} SHARED ${TGUI_SRC})
set_target_properties( ${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX -d )
set_target_properties( ${PROJECT_NAME} PROPERTIES VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION} )
# the library should be linked to sfml, unless you are on linux
# Set the version and soversion of the target (for compatible systems -- mostly Linuxes)
# Except for Android which strips soversion suffixes
if(NOT SFML_OS_ANDROID)
set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION})
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION})
endif()
# The library should be linked to sfml, unless you are on linux
if (NOT SFML_OS_LINUX)
set(TGUI_EXT_LIBS ${OPENGL_gl_LIBRARY} ${SFML_LIBRARIES})
target_link_libraries( ${PROJECT_NAME} ${TGUI_EXT_LIBS} )
# on Windows/gcc get rid of "lib" prefix for shared libraries,
@ -59,7 +80,11 @@ if(SFML_OS_WINDOWS)
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
else()
install( TARGETS ${PROJECT_NAME}
DESTINATION lib
DESTINATION lib${LIB_SUFFIX}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
endif()
# Build tgui-activity on android
if (SFML_OS_ANDROID)
add_subdirectory(Android)
endif()

View File

@ -622,8 +622,11 @@ namespace tgui
bool Container::handleEvent(sf::Event& event)
{
// Check if a mouse button has moved
if (event.type == sf::Event::MouseMoved)
if ((event.type == sf::Event::MouseMoved) || ((event.type == sf::Event::TouchMoved) && (event.touch.finger == 0)))
{
float mouseX = (event.type == sf::Event::MouseMoved) ? static_cast<float>(event.mouseMove.x) : static_cast<float>(event.touch.x);
float mouseY = (event.type == sf::Event::MouseMoved) ? static_cast<float>(event.mouseMove.y) : static_cast<float>(event.touch.y);
// Loop through all widgets
for (unsigned int i = 0; i < m_widgets.size(); ++i)
{
@ -633,18 +636,18 @@ namespace tgui
// Some widgets should always receive mouse move events while dragging them, even if the mouse is no longer on top of them.
if ((m_widgets[i]->m_draggableWidget) || (m_widgets[i]->m_containerWidget))
{
m_widgets[i]->mouseMoved(static_cast<float>(event.mouseMove.x), static_cast<float>(event.mouseMove.y));
m_widgets[i]->mouseMoved(mouseX, mouseY);
return true;
}
}
}
// Check if the mouse is on top of a widget
Widget::Ptr widget = mouseOnWhichWidget(static_cast<float>(event.mouseMove.x), static_cast<float>(event.mouseMove.y));
Widget::Ptr widget = mouseOnWhichWidget(mouseX, mouseY);
if (widget != nullptr)
{
// Send the event to the widget
widget->mouseMoved(static_cast<float>(event.mouseMove.x), static_cast<float>(event.mouseMove.y));
widget->mouseMoved(mouseX, mouseY);
return true;
}
@ -652,13 +655,16 @@ namespace tgui
}
// Check if a mouse button was pressed
else if (event.type == sf::Event::MouseButtonPressed)
else if ((event.type == sf::Event::MouseButtonPressed) || ((event.type == sf::Event::TouchBegan) && (event.touch.finger == 0)))
{
float mouseX = (event.type == sf::Event::MouseButtonPressed) ? static_cast<float>(event.mouseButton.x) : static_cast<float>(event.touch.x);
float mouseY = (event.type == sf::Event::MouseButtonPressed) ? static_cast<float>(event.mouseButton.y) : static_cast<float>(event.touch.y);
// Check if the left mouse was pressed
if (event.mouseButton.button == sf::Mouse::Left)
{
// Check if the mouse is on top of a widget
Widget::Ptr widget = mouseOnWhichWidget(static_cast<float>(event.mouseButton.x), static_cast<float>(event.mouseButton.y));
Widget::Ptr widget = mouseOnWhichWidget(mouseX, mouseY);
if (widget != nullptr)
{
// Focus the widget
@ -676,7 +682,7 @@ namespace tgui
}
}
widget->leftMousePressed(static_cast<float>(event.mouseButton.x), static_cast<float>(event.mouseButton.y));
widget->leftMousePressed(mouseX, mouseY);
return true;
}
else // The mouse did not went down on a widget, so unfocus the focused widget
@ -687,15 +693,18 @@ namespace tgui
}
// Check if a mouse button was released
else if (event.type == sf::Event::MouseButtonReleased)
else if ((event.type == sf::Event::MouseButtonReleased) || ((event.type == sf::Event::TouchEnded) && (event.touch.finger == 0)))
{
float mouseX = (event.type == sf::Event::MouseButtonReleased) ? static_cast<float>(event.mouseButton.x) : static_cast<float>(event.touch.x);
float mouseY = (event.type == sf::Event::MouseButtonReleased) ? static_cast<float>(event.mouseButton.y) : static_cast<float>(event.touch.y);
// Check if the left mouse was released
if (event.mouseButton.button == sf::Mouse::Left)
{
// Check if the mouse is on top of a widget
Widget::Ptr widget = mouseOnWhichWidget(static_cast<float>(event.mouseButton.x), static_cast<float>(event.mouseButton.y));
Widget::Ptr widget = mouseOnWhichWidget(mouseX, mouseY);
if (widget != nullptr)
widget->leftMouseReleased(static_cast<float>(event.mouseButton.x), static_cast<float>(event.mouseButton.y));
widget->leftMouseReleased(mouseX, mouseY);
// Tell all the other widgets that the mouse has gone up
for (std::vector<Widget::Ptr>::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it)

View File

@ -23,19 +23,28 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <cctype>
#include <functional>
#include <TGUI/ThemeFileParser.hpp>
#include <TGUI/Texture.hpp>
#include <TGUI/Global.hpp>
#include <algorithm>
#include <cctype>
#include <functional>
#include <cassert>
#ifdef SFML_SYSTEM_ANDROID
#include "SFML/System/Android/Activity.hpp"
#include <android/asset_manager_jni.h>
#include <android/asset_manager.h>
#include <android/native_activity.h>
#include <android/configuration.h>
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
std::map<std::pair<std::string, std::string>, std::vector<std::pair<std::string, std::string>>> ThemeFileParser::m_cache;
std::map<std::string, std::map<std::string, std::vector<std::pair<std::string, std::string>>>> ThemeFileParser::m_cache;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -61,87 +70,109 @@ namespace tgui
m_filename(filename),
m_section (section)
{
// Don't read and parse the file every time
if (!m_cache[{filename, section}].empty())
{
m_properties = m_cache[{filename, section}];
return;
}
std::ifstream file{filename};
if (!file.is_open())
throw Exception{"Failed to open theme file '" + filename + "'."};
bool sectionFound = false;
unsigned int lineNumber = 0;
std::stringstream fileContents;
std::string lowercaseSection = toLower(section);
// Stop reading when we reach the end of the file
while (!file.eof())
// The file may be cached
if (m_cache.find(m_filename) == m_cache.end())
{
// Get the next line
std::string line;
std::getline(file, line);
lineNumber++;
if (line.empty())
continue;
// If the lines contains a '\r' at the end then remove it
if (line[line.size()-1] == '\r')
line.erase(line.size()-1);
std::string::const_iterator c = line.begin();
// Check if we are reading a section
std::string sectionName;
if (isSection(line, c, sectionName))
#ifdef SFML_SYSTEM_ANDROID
// If the file does not start with a slash then load it from the assets
if (!filename.empty() && (filename[0] != '/'))
{
// If we already found our section then this would be the next section
if (sectionFound)
break;
/// TODO: Workaround until SFML makes native activity publically accessible
/// When this happens, extra SFML folder in include can be removed as well.
ANativeActivity* activity = sf::priv::getActivity(NULL)->activity;
// If this is the section we were looking for then start reading the properties
if ((lowercaseSection + ":") == toLower(sectionName))
sectionFound = true;
JNIEnv* env = 0;
activity->vm->AttachCurrentThread(&env, NULL);
jclass clazz = env->GetObjectClass(activity->clazz);
jmethodID methodID = env->GetMethodID(clazz, "getAssets", "()Landroid/content/res/AssetManager;");
jobject assetManagerObject = env->CallObjectMethod(activity->clazz, methodID);
jobject globalAssetManagerRef = env->NewGlobalRef(assetManagerObject);
AAssetManager* assetManager = AAssetManager_fromJava(env, globalAssetManagerRef);
assert(assetManager);
AAsset* asset = AAssetManager_open(assetManager, filename.c_str(), AASSET_MODE_UNKNOWN);
if (!asset)
throw Exception{"Failed to open theme file '" + filename + "' from assets."};
off_t assetLength = AAsset_getLength(asset);
char* buffer = new char[assetLength + 1];
AAsset_read(asset, buffer, assetLength);
buffer[assetLength] = 0;
fileContents << buffer;
AAsset_close(asset);
delete[] buffer;
activity->vm->DetachCurrentThread();
}
else // This isn't a section
else
#endif
{
// We are only interested in one section
if (!sectionFound)
std::ifstream file{filename};
if (!file.is_open())
throw Exception{"Failed to open theme file '" + filename + "'."};
fileContents << file.rdbuf();
file.close();
}
std::string sectionName;
unsigned int lineNumber = 0;
// Stop reading when we reach the end of the file
while (!fileContents.eof())
{
// Get the next line
std::string line;
std::getline(fileContents, line);
lineNumber++;
// If the lines contains a '\r' at the end then remove it
if (!line.empty() && line[line.size()-1] == '\r')
line.erase(line.size()-1);
std::string::const_iterator c = line.begin();
// Skip empty lines
if (!removeWhitespace(line, c))
continue;
if (!removeWhitespace(line, c))
continue; // empty line
if (!isSection(line, c, sectionName))
{
// Read the property in lowercase
std::string property = toLower(readWord(line, c));
// Read the property in lowercase
std::string property = toLower(readWord(line, c));
if (!removeWhitespace(line, c))
throw Exception{"Failed to parse line " + tgui::to_string(lineNumber) + " in section " + section + " in file " + filename + "."};
if (!removeWhitespace(line, c))
throw Exception{"Failed to parse line " + tgui::to_string(lineNumber) + " in section " + section + " in file " + filename + "."};
// There has to be an assignment character
if (*c == '=')
++c;
else
throw Exception{"Failed to parse line " + tgui::to_string(lineNumber) + " in section " + section + " in file " + filename + "."};
// There has to be an assignment character
if (*c == '=')
++c;
else
throw Exception{"Failed to parse line " + tgui::to_string(lineNumber) + " in section " + section + " in file " + filename + "."};
if (!removeWhitespace(line, c))
throw Exception{"Failed to parse line " + tgui::to_string(lineNumber) + " in section " + section + " in file " + filename + "."};
if (!removeWhitespace(line, c))
throw Exception{"Failed to parse line " + tgui::to_string(lineNumber) + " in section " + section + " in file " + filename + "."};
int pos = c - line.begin();
std::string value = line.substr(pos, line.length() - pos);
int pos = c - line.begin();
std::string value = line.substr(pos, line.length() - pos);
m_properties.push_back(std::make_pair(property, value));
m_cache[m_filename][toLower(sectionName)].push_back(std::make_pair(property, value));
}
}
}
// Throw an exception when the section wasn't found
if (!sectionFound)
throw Exception{"Section '" + section + "' was not found in " + filename + "."};
else
m_cache[{filename, section}] = m_properties;
// The section should be in the cache now
if (m_cache[m_filename].find(lowercaseSection) == m_cache[m_filename].end())
throw Exception{"Section '" + m_section + "' was not found in " + m_filename + "."};
m_properties = m_cache[m_filename][lowercaseSection];
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -177,15 +208,18 @@ namespace tgui
if (!removeWhitespace(line, c))
return false;
sectionName = readWord(line, c);
std::string name = readWord(line, c);
removeWhitespace(line, c);
if (c != line.end())
return false;
if (sectionName[sectionName.length()-1] == ':')
if (name[name.length()-1] == ':')
{
sectionName = toLower(name.substr(0, name.length()-1));
return true;
}
else
return false;
}