Guichan library and few examples, by Lubomyr
This commit is contained in:
233
project/jni/application/guichan-widgets/AndroidAppSettings.cfg
Normal file
233
project/jni/application/guichan-widgets/AndroidAppSettings.cfg
Normal file
@@ -0,0 +1,233 @@
|
||||
# The application settings for Android libSDL port
|
||||
|
||||
AppSettingVersion=19
|
||||
|
||||
# libSDL version to use (1.2 or 1.3, specify 1.3 for SDL2)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="GuiChan"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=com.guichan.sdl
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
|
||||
AppDataDownloadUrl="data file|files.zip"
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=16
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=y
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacks=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=y
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
|
||||
|
||||
# Application uses SDL_UpdateRects() properly, and does not draw in any region outside those rects.
|
||||
# This improves drawing speed, but I know only one application that does that, and it's written by me (y)/(n)
|
||||
CompatibilityHacksProperUsageOfSDL_UpdateRects=
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=y
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=y
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n)
|
||||
GenerateSubframeTouchEvents=
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n)
|
||||
AppNeedsArrowKeys=n
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
AppUsesJoystick=n
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=n
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=n
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=n
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=n
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=y
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="SPACE"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=0
|
||||
|
||||
# Number of virtual keyboard keys that support autofire (currently 2 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="1 2 3 4 5 6 1 2 3 4"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="1 2 3 4 5 6 1 2 3 4"
|
||||
|
||||
# On-screen keys theme
|
||||
# 0 = Ultimate Droid by Sean Stieber (green, with gamepad joystick)
|
||||
# 1 = Simple Theme by Beholder (white, with gamepad joystick)
|
||||
# 2 = Sun by Sirea (yellow, with round joystick)
|
||||
# 3 = Keen by Gerstrong (multicolor, with round joystick)
|
||||
TouchscreenKeysTheme=2
|
||||
|
||||
# Redefine gamepad keys to SDL keysyms, button order is:
|
||||
# A B X Y L1 R1 L2 R2 LThumb RThumb
|
||||
RedefinedKeysGamepad="1 2 3 4 5 6 1 2 3 4"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=3000
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout
|
||||
HiddenMenuOptions=''
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default
|
||||
# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout
|
||||
FirstStartMenuOptions=''
|
||||
|
||||
# Enable multi-ABI binary, with hardware FPU support - it will also work on old devices,
|
||||
# but .apk size is 2x bigger (y) / (n) / (x86) / (all)
|
||||
MultiABI=all
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=256
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=101
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="1.01"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="%"
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="sdl_image guichan"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=n
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-Wall -Wno-unused'
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags=''
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild=''
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \\\\n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on (that's four backslashes, nice isn't it?)
|
||||
ReadmeText='^Readme text'
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=s
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/IAB_BANNER/IAB_LEADERBOARD/IAB_MRECT/IAB_WIDE_SKYSCRAPER/SMART_BANNER)
|
||||
AdmobBannerSize=
|
||||
|
||||
BIN
project/jni/application/guichan-widgets/AndroidData/files.zip
Normal file
BIN
project/jni/application/guichan-widgets/AndroidData/files.zip
Normal file
Binary file not shown.
23
project/jni/application/guichan-widgets/gui.xml
Normal file
23
project/jni/application/guichan-widgets/gui.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<container name="top" width="640" height="480">
|
||||
<label name="logo_text" caption="Simple example of using XmlGui" />
|
||||
<button x="5" y="20" name="exit" caption="Please click to exit" />
|
||||
<icon name="logo" x="250" y="160" image="darkbitslogo_by_haiko.bmp" />
|
||||
<dropdown name="dp" x="100" y="100">
|
||||
<li>Item 1</li>
|
||||
<li>Item 2</li>
|
||||
<li>Item 3</li>
|
||||
</dropdown>
|
||||
<listbox name="lb" x="200" y="100">
|
||||
<li>Item 1</li>
|
||||
<li>Item 2</li>
|
||||
<li>Item 3</li>
|
||||
</listbox>
|
||||
<textfield name="tf" text="simple text" x="5" y="300" />
|
||||
<scrollarea name="sc" x="300" y="5" width="100" height="100">
|
||||
<textbox name="tb" text="simple textbox
|
||||
ddjdjd" />
|
||||
</scrollarea>
|
||||
<window name="wnd" caption="Drag me!" x="100" y="200">
|
||||
<icon name="logo_in_wnd" x="0" y="0" image="darkbitslogo_by_haiko.bmp" />
|
||||
</window>
|
||||
</container>
|
||||
BIN
project/jni/application/guichan-widgets/icon.png
Normal file
BIN
project/jni/application/guichan-widgets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
120
project/jni/application/guichan-widgets/sdl.hpp
Normal file
120
project/jni/application/guichan-widgets/sdl.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Code that sets up an SDL application with Guichan using the
|
||||
* Guichan SDL back end.
|
||||
*/
|
||||
|
||||
#include <guichan.hpp>
|
||||
#include <guichan/sdl.hpp>
|
||||
|
||||
namespace sdl
|
||||
{
|
||||
bool running = true;
|
||||
SDL_Surface* screen;
|
||||
|
||||
// All back ends contain objects to make Guichan work on a
|
||||
// specific target - in this case SDL - and they are a Graphics
|
||||
// object to make Guichan able to draw itself using SDL, an
|
||||
// input objec to make Guichan able to get user input using SDL
|
||||
// and an ImageLoader object to make Guichan able to load images
|
||||
// using SDL.
|
||||
gcn::SDLGraphics* graphics;
|
||||
gcn::SDLInput* input;
|
||||
gcn::SDLImageLoader* imageLoader;
|
||||
|
||||
/**
|
||||
* Initialises the SDL application. This function creates the global
|
||||
* Gui object that can be populated by various examples.
|
||||
*/
|
||||
void init()
|
||||
{
|
||||
// We simply initialise SDL as we would do with any SDL application.
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
|
||||
// We want unicode for the SDLInput object to function properly.
|
||||
SDL_EnableUNICODE(1);
|
||||
// We also want to enable key repeat.
|
||||
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
|
||||
// Now it's time to initialise the Guichan SDL back end.
|
||||
|
||||
imageLoader = new gcn::SDLImageLoader();
|
||||
// The ImageLoader Guichan should use needs to be passed to the Image object
|
||||
// using a static function.
|
||||
gcn::Image::setImageLoader(imageLoader);
|
||||
graphics = new gcn::SDLGraphics();
|
||||
// The Graphics object needs a target to draw to, in this case it's the
|
||||
// screen surface, but any surface will do, it doesn't have to be the screen.
|
||||
graphics->setTarget(screen);
|
||||
input = new gcn::SDLInput();
|
||||
|
||||
// Now we create the Gui object to be used with this SDL application.
|
||||
globals::gui = new gcn::Gui();
|
||||
// The Gui object needs a Graphics to be able to draw itself and an Input
|
||||
// object to be able to check for user input. In this case we provide the
|
||||
// Gui object with SDL implementations of these objects hence making Guichan
|
||||
// able to utilise SDL.
|
||||
globals::gui->setGraphics(graphics);
|
||||
globals::gui->setInput(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Halts the SDL application.
|
||||
*/
|
||||
void halt()
|
||||
{
|
||||
delete globals::gui;
|
||||
|
||||
delete imageLoader;
|
||||
delete input;
|
||||
delete graphics;
|
||||
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the SDL application.
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
// The main loop
|
||||
while(running)
|
||||
{
|
||||
// Check user input
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event))
|
||||
{
|
||||
if (event.type == SDL_KEYDOWN)
|
||||
{
|
||||
if (event.key.keysym.sym == SDLK_ESCAPE)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_f)
|
||||
{
|
||||
if (event.key.keysym.mod & KMOD_CTRL)
|
||||
{
|
||||
// Works with X11 only
|
||||
SDL_WM_ToggleFullScreen(screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(event.type == SDL_QUIT)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
// After we have manually checked user input with SDL for
|
||||
// any attempt by the user to halt the application we feed
|
||||
// the input to Guichan by pushing the input to the Input
|
||||
// object.
|
||||
input->pushInput(event);
|
||||
}
|
||||
// Now we let the Gui object perform its logic.
|
||||
globals::gui->logic();
|
||||
// Now we let the Gui object draw itself.
|
||||
globals::gui->draw();
|
||||
// Finally we update the screen.
|
||||
SDL_Flip(screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
project/jni/application/guichan-widgets/sdlwidgets.cpp
Normal file
58
project/jni/application/guichan-widgets/sdlwidgets.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* This is an example that shows of the widgets present in
|
||||
* Guichan. The example uses the SDL back end.
|
||||
*/
|
||||
|
||||
#include <guichan.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// Here we store a global Gui object. We make it global
|
||||
// so it's easily accessable. Of course, global variables
|
||||
// should normally be avioded when it comes to OOP, but
|
||||
// this examples is not an example that shows how to make a
|
||||
// good and clean C++ application but merely an example
|
||||
// that shows how to use Guichan.
|
||||
namespace globals
|
||||
{
|
||||
gcn::Gui* gui;
|
||||
}
|
||||
|
||||
// Include code to set up an SDL application with Guichan.
|
||||
// The sdl.hpp file is responsible for creating and deleting
|
||||
// the global Gui object.
|
||||
#include "sdl.hpp"
|
||||
// Include code to set up a Guichan GUI with all the widgets
|
||||
// of Guichan. The code populates the global Gui object.
|
||||
#include "widgets.hpp"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
sdl::init();
|
||||
widgets::init();
|
||||
sdl::run();
|
||||
widgets::halt();
|
||||
sdl::halt();
|
||||
}
|
||||
// Catch all Guichan exceptions.
|
||||
catch (gcn::Exception e)
|
||||
{
|
||||
std::cerr << e.getMessage() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// Catch all Std exceptions.
|
||||
catch (std::exception e)
|
||||
{
|
||||
std::cerr << "Std exception: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// Catch all unknown exceptions.
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "Unknown exception" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
182
project/jni/application/guichan-widgets/widgets.hpp
Normal file
182
project/jni/application/guichan-widgets/widgets.hpp
Normal file
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Code to populate a global Gui object with all the widgets
|
||||
* of Guichan.
|
||||
*/
|
||||
|
||||
namespace widgets
|
||||
{
|
||||
gcn::ImageFont* font;
|
||||
gcn::Container* top;
|
||||
gcn::Label* label;
|
||||
gcn::Icon* icon;
|
||||
gcn::Button* button;
|
||||
gcn::TextField* textField;
|
||||
gcn::TextBox* textBox;
|
||||
gcn::ScrollArea* textBoxScrollArea;
|
||||
gcn::ListBox* listBox;
|
||||
gcn::DropDown* dropDown;
|
||||
gcn::CheckBox* checkBox1;
|
||||
gcn::CheckBox* checkBox2;
|
||||
gcn::RadioButton* radioButton1;
|
||||
gcn::RadioButton* radioButton2;
|
||||
gcn::RadioButton* radioButton3;
|
||||
gcn::Slider* slider;
|
||||
gcn::Image *image;
|
||||
gcn::Window *window;
|
||||
gcn::Image *darkbitsImage;
|
||||
gcn::Icon* darkbitsIcon;
|
||||
gcn::TabbedArea* tabbedArea;
|
||||
gcn::Button* tabOneButton;
|
||||
gcn::CheckBox* tabTwoCheckBox;
|
||||
|
||||
/*
|
||||
* List boxes and drop downs need an instance of a list model
|
||||
* in order to display a list.
|
||||
*/
|
||||
class DemoListModel : public gcn::ListModel
|
||||
{
|
||||
public:
|
||||
int getNumberOfElements()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
std::string getElementAt(int i)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case 0:
|
||||
return std::string("zero");
|
||||
case 1:
|
||||
return std::string("one");
|
||||
case 2:
|
||||
return std::string("two");
|
||||
case 3:
|
||||
return std::string("three");
|
||||
case 4:
|
||||
return std::string("four");
|
||||
default: // Just to keep warnings away
|
||||
return std::string("");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DemoListModel demoListModel;
|
||||
|
||||
/**
|
||||
* Initialises the widgets example by populating the global Gui
|
||||
* object.
|
||||
*/
|
||||
void init()
|
||||
{
|
||||
// We first create a container to be used as the top widget.
|
||||
// The top widget in Guichan can be any kind of widget, but
|
||||
// in order to make the Gui contain more than one widget we
|
||||
// make the top widget a container.
|
||||
top = new gcn::Container();
|
||||
// We set the dimension of the top container to match the screen.
|
||||
top->setDimension(gcn::Rectangle(0, 0, 640, 480));
|
||||
// Finally we pass the top widget to the Gui object.
|
||||
globals::gui->setTop(top);
|
||||
|
||||
// Now we load the font used in this example.
|
||||
font = new gcn::ImageFont("fixedfont.bmp", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
// Widgets may have a global font so we don't need to pass the
|
||||
// font object to every created widget. The global font is static.
|
||||
gcn::Widget::setGlobalFont(font);
|
||||
|
||||
// Now we create the widgets
|
||||
|
||||
label = new gcn::Label("Label");
|
||||
|
||||
image = gcn::Image::load("gui-chan.bmp");
|
||||
icon = new gcn::Icon(image);
|
||||
|
||||
button = new gcn::Button("Button");
|
||||
|
||||
textField = new gcn::TextField("Text field");
|
||||
|
||||
textBox = new gcn::TextBox("Multiline\nText box");
|
||||
textBoxScrollArea = new gcn::ScrollArea(textBox);
|
||||
textBoxScrollArea->setWidth(200);
|
||||
textBoxScrollArea->setHeight(100);
|
||||
textBoxScrollArea->setFrameSize(1);
|
||||
|
||||
listBox = new gcn::ListBox(&demoListModel);
|
||||
listBox->setFrameSize(1);
|
||||
dropDown = new gcn::DropDown(&demoListModel);
|
||||
|
||||
checkBox1 = new gcn::CheckBox("Checkbox 1");
|
||||
checkBox2 = new gcn::CheckBox("Checkbox 2");
|
||||
|
||||
radioButton1 = new gcn::RadioButton("RadioButton 1", "radiogroup", true);
|
||||
radioButton2 = new gcn::RadioButton("RadioButton 2", "radiogroup");
|
||||
radioButton3 = new gcn::RadioButton("RadioButton 3", "radiogroup");
|
||||
|
||||
slider = new gcn::Slider(0, 10);
|
||||
slider->setSize(100, 10);
|
||||
|
||||
window = new gcn::Window("I am a window Drag me");
|
||||
window->setBaseColor(gcn::Color(255, 150, 200, 190));
|
||||
|
||||
darkbitsImage = gcn::Image::load("darkbitslogo_by_haiko.bmp");
|
||||
darkbitsIcon = new gcn::Icon(darkbitsImage);
|
||||
window->add(darkbitsIcon);
|
||||
window->resizeToContent();
|
||||
|
||||
tabbedArea = new gcn::TabbedArea();
|
||||
tabbedArea->setSize(200, 100);
|
||||
tabOneButton = new gcn::Button("A button in tab 1");
|
||||
tabbedArea->addTab("Tab 1", tabOneButton);
|
||||
tabTwoCheckBox = new gcn::CheckBox("A check box in tab 2");
|
||||
tabbedArea->addTab("Tab 2", tabTwoCheckBox);
|
||||
|
||||
// Now it's time to add the widgets to the top container
|
||||
// so they will be conected to the GUI.
|
||||
|
||||
top->add(label, 10, 10);
|
||||
top->add(icon, 10, 30);
|
||||
top->add(button, 200, 10);
|
||||
top->add(textField, 250, 10);
|
||||
top->add(textBoxScrollArea, 200, 50);
|
||||
top->add(listBox, 200, 200);
|
||||
top->add(dropDown, 500, 10);
|
||||
top->add(checkBox1, 500, 130);
|
||||
top->add(checkBox2, 500, 150);
|
||||
top->add(radioButton1, 500, 200);
|
||||
top->add(radioButton2, 500, 220);
|
||||
top->add(radioButton3, 500, 240);
|
||||
top->add(slider, 500, 300);
|
||||
top->add(window, 50, 350);
|
||||
top->add(tabbedArea, 400, 350);
|
||||
}
|
||||
|
||||
/**
|
||||
* Halts the widgets example.
|
||||
*/
|
||||
void halt()
|
||||
{
|
||||
delete font;
|
||||
delete top;
|
||||
delete label;
|
||||
delete icon;
|
||||
delete button;
|
||||
delete textField;
|
||||
delete textBox;
|
||||
delete textBoxScrollArea;
|
||||
delete listBox;
|
||||
delete dropDown;
|
||||
delete checkBox1;
|
||||
delete checkBox2;
|
||||
delete radioButton1;
|
||||
delete radioButton2;
|
||||
delete radioButton3;
|
||||
delete slider;
|
||||
delete window;
|
||||
delete darkbitsIcon;
|
||||
delete darkbitsImage;
|
||||
delete tabbedArea;
|
||||
delete tabOneButton;
|
||||
delete tabTwoCheckBox;
|
||||
}
|
||||
}
|
||||
226
project/jni/application/guichan-xml/AndroidAppSettings.cfg
Normal file
226
project/jni/application/guichan-xml/AndroidAppSettings.cfg
Normal file
@@ -0,0 +1,226 @@
|
||||
# The application settings for Android libSDL port
|
||||
|
||||
AppSettingVersion=19
|
||||
|
||||
# libSDL version to use (1.2 or 1.3, specify 1.3 for SDL2)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="XMLGuiChan"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=com.guichan.xml
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
|
||||
AppDataDownloadUrl="data file|files.zip"
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=16
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=y
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacks=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=y
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=y
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=y
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n)
|
||||
AppNeedsArrowKeys=n
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
AppUsesJoystick=n
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=n
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=n
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=n
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=n
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=y
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="SPACE"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=0
|
||||
|
||||
# Number of virtual keyboard keys that support autofire (currently 2 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="1 2 3 4 5 6 1 2 3 4"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="1 2 3 4 5 6 1 2 3 4"
|
||||
|
||||
# On-screen keys theme
|
||||
# 0 = Ultimate Droid by Sean Stieber (green, with gamepad joystick)
|
||||
# 1 = Simple Theme by Beholder (white, with gamepad joystick)
|
||||
# 2 = Sun by Sirea (yellow, with round joystick)
|
||||
# 3 = Keen by Gerstrong (multicolor, with round joystick)
|
||||
TouchscreenKeysTheme=2
|
||||
|
||||
# Redefine gamepad keys to SDL keysyms, button order is:
|
||||
# A B X Y L1 R1 L2 R2 LThumb RThumb
|
||||
RedefinedKeysGamepad="1 2 3 4 5 6 1 2 3 4"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=3000
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout
|
||||
HiddenMenuOptions=''
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default
|
||||
# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout
|
||||
FirstStartMenuOptions=''
|
||||
|
||||
# Enable multi-ABI binary, with hardware FPU support - it will also work on old devices,
|
||||
# but .apk size is 2x bigger (y) / (n) / (x86) / (all)
|
||||
MultiABI=n
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=256
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=101
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="1.01"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade=""
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="sdl_image guichan"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=n
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-Wall -Wno-unused -DGUICHAN_BUILD -fexceptions'
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags=''
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild=''
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \\\\n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on (that's four backslashes, nice isn't it?)
|
||||
ReadmeText='^Readme text'
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=s
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/IAB_BANNER/IAB_LEADERBOARD/IAB_MRECT/IAB_WIDE_SKYSCRAPER/SMART_BANNER)
|
||||
AdmobBannerSize=
|
||||
|
||||
BIN
project/jni/application/guichan-xml/AndroidData/files.zip
Normal file
BIN
project/jni/application/guichan-xml/AndroidData/files.zip
Normal file
Binary file not shown.
23
project/jni/application/guichan-xml/gui.xml
Normal file
23
project/jni/application/guichan-xml/gui.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<container name="top" width="640" height="480">
|
||||
<label name="logo_text" caption="Simple example of using XmlGui" />
|
||||
<button x="5" y="20" name="exit" caption="Please click to exit" />
|
||||
<icon name="logo" x="250" y="160" image="darkbitslogo_by_haiko.bmp" />
|
||||
<dropdown name="dp" x="100" y="100">
|
||||
<li>Item 1</li>
|
||||
<li>Item 2</li>
|
||||
<li>Item 3</li>
|
||||
</dropdown>
|
||||
<listbox name="lb" x="200" y="100">
|
||||
<li>Item 1</li>
|
||||
<li>Item 2</li>
|
||||
<li>Item 3</li>
|
||||
</listbox>
|
||||
<textfield name="tf" text="simple text" x="5" y="300" />
|
||||
<scrollarea name="sc" x="300" y="5" width="100" height="100">
|
||||
<textbox name="tb" text="simple textbox
|
||||
ddjdjd" />
|
||||
</scrollarea>
|
||||
<window name="wnd" caption="Drag me!" x="100" y="200">
|
||||
<icon name="logo_in_wnd" x="0" y="0" image="darkbitslogo_by_haiko.bmp" />
|
||||
</window>
|
||||
</container>
|
||||
BIN
project/jni/application/guichan-xml/icon.png
Normal file
BIN
project/jni/application/guichan-xml/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
208
project/jni/application/guichan-xml/sdlguiexample.cpp
Normal file
208
project/jni/application/guichan-xml/sdlguiexample.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* SDL Hello World example for Guichan.
|
||||
*/
|
||||
|
||||
// Include all necessary headers.
|
||||
#include <iostream>
|
||||
#include <guichan.hpp>
|
||||
#include <guichan/sdl.hpp>
|
||||
#include <SDL/SDL.h>
|
||||
#include "xmlgui.h"
|
||||
/*
|
||||
* Common stuff we need
|
||||
*/
|
||||
bool running = true;
|
||||
|
||||
/*
|
||||
* SDL Stuff we need
|
||||
*/
|
||||
SDL_Surface* screen;
|
||||
SDL_Event event;
|
||||
|
||||
/*
|
||||
* Guichan SDL stuff we need
|
||||
*/
|
||||
gcn::SDLInput* input; // Input driver
|
||||
gcn::SDLGraphics* graphics; // Graphics driver
|
||||
gcn::SDLImageLoader* imageLoader; // For loading images
|
||||
|
||||
/*
|
||||
* Guichan stuff we need
|
||||
*/
|
||||
gcn::Gui* gui; // A Gui object - binds it all together
|
||||
gcn::Container* top; // A top container
|
||||
gcn::ImageFont* font; // A font
|
||||
|
||||
//XmlGui stuff
|
||||
XmlGui *xmlgui = new XmlGui();
|
||||
|
||||
/**
|
||||
* Initializes the Hello World
|
||||
*/
|
||||
void init()
|
||||
{
|
||||
/*
|
||||
* Here we initialize SDL as we would do with any SDL application.
|
||||
*/
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
|
||||
// We want unicode
|
||||
SDL_EnableUNICODE(1);
|
||||
// We want to enable key repeat
|
||||
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
|
||||
/*
|
||||
* Now it's time for Guichan SDL stuff
|
||||
*/
|
||||
imageLoader = new gcn::SDLImageLoader();
|
||||
// The ImageLoader in use is static and must be set to be
|
||||
// able to load images
|
||||
gcn::Image::setImageLoader(imageLoader);
|
||||
graphics = new gcn::SDLGraphics();
|
||||
// Set the target for the graphics object to be the screen.
|
||||
// In other words, we will draw to the screen.
|
||||
// Note, any surface will do, it doesn't have to be the screen.
|
||||
graphics->setTarget(screen);
|
||||
input = new gcn::SDLInput();
|
||||
|
||||
/*
|
||||
* Last but not least it's time to initialize and create the gui
|
||||
* with Guichan stuff.
|
||||
*/
|
||||
gui = new gcn::Gui();
|
||||
// Set gui to use the SDLGraphics object.
|
||||
gui->setGraphics(graphics);
|
||||
// Set gui to use the SDLInput object
|
||||
gui->setInput(input);
|
||||
// Set the top container
|
||||
gui->setTop(top);
|
||||
// Load the image font.
|
||||
font = new gcn::ImageFont("fixedfont.bmp", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
// The global font is static and must be set.
|
||||
gcn::Widget::setGlobalFont(font);
|
||||
|
||||
xmlgui = new XmlGui();
|
||||
xmlgui->parse("gui.xml");
|
||||
gui->setTop(xmlgui->getWidget("top"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Halts the application
|
||||
*/
|
||||
void halt()
|
||||
{
|
||||
/*
|
||||
* Destroy Guichan stuff
|
||||
*/
|
||||
delete xmlgui;
|
||||
delete font;
|
||||
delete top;
|
||||
delete gui;
|
||||
|
||||
/*
|
||||
* Destroy Guichan SDL stuff
|
||||
*/
|
||||
delete input;
|
||||
delete graphics;
|
||||
delete imageLoader;
|
||||
|
||||
/*
|
||||
* Destroy SDL stuff
|
||||
*/
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks input. On escape halt the application.
|
||||
*/
|
||||
void checkInput()
|
||||
{
|
||||
/*
|
||||
* Poll SDL events
|
||||
*/
|
||||
while(SDL_PollEvent(&event))
|
||||
{
|
||||
if (event.type == SDL_KEYDOWN)
|
||||
{
|
||||
if (event.key.keysym.sym == SDLK_ESCAPE)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_f)
|
||||
{
|
||||
if (event.key.keysym.mod & KMOD_CTRL)
|
||||
{
|
||||
// Works with X11 only
|
||||
SDL_WM_ToggleFullScreen(screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(event.type == SDL_QUIT)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we are done polling and using SDL events we pass
|
||||
* the leftovers to the SDLInput object to later be handled by
|
||||
* the Gui. (This example doesn't require us to do this 'cause a
|
||||
* label doesn't use input. But will do it anyway to show how to
|
||||
* set up an SDL application with Guichan.)
|
||||
*/
|
||||
input->pushInput(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the application
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
while(running)
|
||||
{
|
||||
// Poll input
|
||||
checkInput();
|
||||
// Let the gui perform it's logic (like handle input)
|
||||
gui->logic();
|
||||
// Draw the gui
|
||||
gui->draw();
|
||||
// Update the screen
|
||||
SDL_Flip(screen);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
init();
|
||||
run();
|
||||
halt();
|
||||
}
|
||||
/*
|
||||
* Catch all Guichan exceptions
|
||||
*/
|
||||
catch (gcn::Exception e)
|
||||
{
|
||||
std::cerr << e.getMessage() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Catch all Std exceptions
|
||||
*/
|
||||
catch (std::exception e)
|
||||
{
|
||||
std::cerr << "Std exception: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Catch all Unknown exceptions
|
||||
*/
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "Unknown exception" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
796
project/jni/application/guichan-xml/tinyxml.cpp
Normal file
796
project/jni/application/guichan-xml/tinyxml.cpp
Normal file
@@ -0,0 +1,796 @@
|
||||
/*
|
||||
Copyright (c) 2000 Lee Thomason (www.grinninglizard.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 "tinyxml.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
TiXmlNode::TiXmlNode( NodeType _type )
|
||||
{
|
||||
parent = 0;
|
||||
type = _type;
|
||||
firstChild = 0;
|
||||
lastChild = 0;
|
||||
prev = 0;
|
||||
next = 0;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode::~TiXmlNode()
|
||||
{
|
||||
TiXmlNode* node = firstChild;
|
||||
TiXmlNode* temp = 0;
|
||||
|
||||
while ( node )
|
||||
{
|
||||
temp = node;
|
||||
node = node->next;
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TiXmlNode::Clear()
|
||||
{
|
||||
TiXmlNode* node = firstChild;
|
||||
TiXmlNode* temp = 0;
|
||||
|
||||
while ( node )
|
||||
{
|
||||
temp = node;
|
||||
node = node->next;
|
||||
delete temp;
|
||||
}
|
||||
|
||||
firstChild = 0;
|
||||
lastChild = 0;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
|
||||
{
|
||||
node->parent = this;
|
||||
|
||||
node->prev = lastChild;
|
||||
node->next = 0;
|
||||
|
||||
if ( lastChild )
|
||||
lastChild->next = node;
|
||||
else
|
||||
firstChild = node; // it was an empty list.
|
||||
|
||||
lastChild = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
|
||||
{
|
||||
TiXmlNode* node = addThis.Clone();
|
||||
if ( !node )
|
||||
return 0;
|
||||
|
||||
return LinkEndChild( node );
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
|
||||
{
|
||||
if ( beforeThis->parent != this )
|
||||
return 0;
|
||||
|
||||
TiXmlNode* node = addThis.Clone();
|
||||
if ( !node )
|
||||
return 0;
|
||||
node->parent = this;
|
||||
|
||||
node->next = beforeThis;
|
||||
node->prev = beforeThis->prev;
|
||||
beforeThis->prev->next = node;
|
||||
beforeThis->prev = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
|
||||
{
|
||||
if ( afterThis->parent != this )
|
||||
return 0;
|
||||
|
||||
TiXmlNode* node = addThis.Clone();
|
||||
if ( !node )
|
||||
return 0;
|
||||
node->parent = this;
|
||||
|
||||
node->prev = afterThis;
|
||||
node->next = afterThis->next;
|
||||
afterThis->next->prev = node;
|
||||
afterThis->next = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
|
||||
{
|
||||
if ( replaceThis->parent != this )
|
||||
return 0;
|
||||
|
||||
TiXmlNode* node = withThis.Clone();
|
||||
if ( !node )
|
||||
return 0;
|
||||
|
||||
node->next = replaceThis->next;
|
||||
node->prev = replaceThis->prev;
|
||||
|
||||
if ( replaceThis->next )
|
||||
replaceThis->next->prev = node;
|
||||
else
|
||||
lastChild = node;
|
||||
|
||||
if ( replaceThis->prev )
|
||||
replaceThis->prev->next = node;
|
||||
else
|
||||
firstChild = node;
|
||||
|
||||
delete replaceThis;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
|
||||
{
|
||||
if ( removeThis->parent != this )
|
||||
{
|
||||
assert( 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( removeThis->next )
|
||||
removeThis->next->prev = removeThis->prev;
|
||||
else
|
||||
lastChild = removeThis->prev;
|
||||
|
||||
if ( removeThis->prev )
|
||||
removeThis->prev->next = removeThis->next;
|
||||
else
|
||||
firstChild = removeThis->next;
|
||||
|
||||
delete removeThis;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::FirstChild( const std::string& value ) const
|
||||
{
|
||||
TiXmlNode* node;
|
||||
for ( node = firstChild; node; node = node->next )
|
||||
{
|
||||
if ( node->Value() == value )
|
||||
return node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::LastChild( const std::string& value ) const
|
||||
{
|
||||
TiXmlNode* node;
|
||||
for ( node = lastChild; node; node = node->prev )
|
||||
{
|
||||
if ( node->Value() == value )
|
||||
return node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous )
|
||||
{
|
||||
if ( !previous )
|
||||
{
|
||||
return FirstChild();
|
||||
}
|
||||
else
|
||||
{
|
||||
//commented due Issue 1 (thanks copesetic)
|
||||
//assert( previous->parent == this );
|
||||
return previous->NextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::IterateChildren( const std::string& val, TiXmlNode* previous )
|
||||
{
|
||||
if ( !previous )
|
||||
{
|
||||
return FirstChild( val );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( previous->parent == this );
|
||||
return previous->NextSibling( val );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::NextSibling( const std::string& value ) const
|
||||
{
|
||||
TiXmlNode* node;
|
||||
for ( node = next; node; node = node->next )
|
||||
{
|
||||
if ( node->Value() == value )
|
||||
return node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::PreviousSibling( const std::string& value ) const
|
||||
{
|
||||
TiXmlNode* node;
|
||||
for ( node = prev; node; node = node->prev )
|
||||
{
|
||||
if ( node->Value() == value )
|
||||
return node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void TiXmlElement::RemoveAttribute( const std::string& name )
|
||||
{
|
||||
TiXmlAttribute* node = attributeSet.Find( name );
|
||||
if ( node )
|
||||
{
|
||||
attributeSet.Remove( node );
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TiXmlElement* TiXmlNode::FirstChildElement() const
|
||||
{
|
||||
TiXmlNode* node;
|
||||
|
||||
for ( node = FirstChild();
|
||||
node;
|
||||
node = node->NextSibling() )
|
||||
{
|
||||
if ( node->ToElement() )
|
||||
return node->ToElement();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TiXmlElement* TiXmlNode::FirstChildElement( const std::string& value ) const
|
||||
{
|
||||
TiXmlNode* node;
|
||||
|
||||
for ( node = FirstChild( value );
|
||||
node;
|
||||
node = node->NextSibling( value ) )
|
||||
{
|
||||
if ( node->ToElement() )
|
||||
return node->ToElement();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TiXmlElement* TiXmlNode::NextSiblingElement() const
|
||||
{
|
||||
TiXmlNode* node;
|
||||
|
||||
for ( node = NextSibling();
|
||||
node;
|
||||
node = node->NextSibling() )
|
||||
{
|
||||
if ( node->ToElement() )
|
||||
return node->ToElement();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TiXmlElement* TiXmlNode::NextSiblingElement( const std::string& value ) const
|
||||
{
|
||||
TiXmlNode* node;
|
||||
|
||||
for ( node = NextSibling( value );
|
||||
node;
|
||||
node = node->NextSibling( value ) )
|
||||
{
|
||||
if ( node->ToElement() )
|
||||
return node->ToElement();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TiXmlDocument* TiXmlNode::GetDocument() const
|
||||
{
|
||||
const TiXmlNode* node;
|
||||
|
||||
for( node = this; node; node = node->parent )
|
||||
{
|
||||
if ( node->ToDocument() )
|
||||
return node->ToDocument();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// TiXmlElement::TiXmlElement()
|
||||
// : TiXmlNode( TiXmlNode::ELEMENT )
|
||||
// {
|
||||
// }
|
||||
|
||||
TiXmlElement::TiXmlElement( const std::string& _value )
|
||||
: TiXmlNode( TiXmlNode::ELEMENT )
|
||||
{
|
||||
firstChild = lastChild = 0;
|
||||
value = _value;
|
||||
}
|
||||
|
||||
TiXmlElement::~TiXmlElement()
|
||||
{
|
||||
while( attributeSet.First() )
|
||||
{
|
||||
TiXmlAttribute* node = attributeSet.First();
|
||||
attributeSet.Remove( node );
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string* TiXmlElement::Attribute( const std::string& name ) const
|
||||
{
|
||||
TiXmlAttribute* node = attributeSet.Find( name );
|
||||
|
||||
if ( node )
|
||||
return &(node->Value() );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
|
||||
{
|
||||
const std::string* s = Attribute( name );
|
||||
if ( s )
|
||||
*i = atoi( s->c_str() );
|
||||
else
|
||||
*i = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void TiXmlElement::SetAttribute( const std::string& name, int val )
|
||||
{
|
||||
char buf[64];
|
||||
sprintf( buf, "%d", val );
|
||||
|
||||
std::string v = buf;
|
||||
|
||||
SetAttribute( name, v );
|
||||
}
|
||||
|
||||
|
||||
void TiXmlElement::SetAttribute( const std::string& name, const std::string& value )
|
||||
{
|
||||
TiXmlAttribute* node = attributeSet.Find( name );
|
||||
if ( node )
|
||||
{
|
||||
node->SetValue( value );
|
||||
return;
|
||||
}
|
||||
|
||||
TiXmlAttribute* attrib = new TiXmlAttribute( name, value );
|
||||
if ( attrib )
|
||||
{
|
||||
attributeSet.Add( attrib );
|
||||
}
|
||||
else
|
||||
{
|
||||
TiXmlDocument* document = GetDocument();
|
||||
if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TiXmlElement::Print( FILE* fp, int depth )
|
||||
{
|
||||
int i;
|
||||
for ( i=0; i<depth; i++ )
|
||||
fprintf( fp, " " );
|
||||
|
||||
fprintf( fp, "<%s", value.c_str() );
|
||||
|
||||
TiXmlAttribute* attrib;
|
||||
for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
|
||||
{
|
||||
fprintf( fp, " " );
|
||||
attrib->Print( fp, 0 );
|
||||
}
|
||||
// If this node has children, give it a closing tag. Else
|
||||
// make it an empty tag.
|
||||
TiXmlNode* node;
|
||||
if ( firstChild )
|
||||
{
|
||||
fprintf( fp, ">" );
|
||||
|
||||
for ( node = firstChild; node; node=node->NextSibling() )
|
||||
{
|
||||
if ( !node->ToText() )
|
||||
fprintf( fp, "\n" );
|
||||
node->Print( fp, depth+1 );
|
||||
}
|
||||
fprintf( fp, "\n" );
|
||||
for ( i=0; i<depth; i++ )
|
||||
fprintf( fp, " " );
|
||||
fprintf( fp, "</%s>", value.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( fp, " />" );
|
||||
}
|
||||
}
|
||||
|
||||
TiXmlNode* TiXmlElement::Clone() const
|
||||
{
|
||||
TiXmlElement* clone = new TiXmlElement( Value() );
|
||||
|
||||
if ( !clone )
|
||||
return 0;
|
||||
|
||||
CopyToClone( clone );
|
||||
|
||||
// Clone the attributes, then clone the children.
|
||||
TiXmlAttribute* attribute = 0;
|
||||
for( attribute = attributeSet.First();
|
||||
attribute;
|
||||
attribute = attribute->Next() )
|
||||
{
|
||||
clone->SetAttribute( attribute->Name(), attribute->Value() );
|
||||
}
|
||||
|
||||
TiXmlNode* node = 0;
|
||||
for ( node = firstChild; node; node = node->NextSibling() )
|
||||
{
|
||||
clone->LinkEndChild( node->Clone() );
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
|
||||
{
|
||||
error = false;
|
||||
// factory = new TiXmlFactory();
|
||||
}
|
||||
|
||||
|
||||
TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
|
||||
{
|
||||
// factory = new TiXmlFactory();
|
||||
value = documentName;
|
||||
error = false;
|
||||
}
|
||||
|
||||
// void TiXmlDocument::SetFactory( TiXmlFactory* f )
|
||||
// {
|
||||
// delete factory;
|
||||
// factory = f;
|
||||
// }
|
||||
|
||||
|
||||
bool TiXmlDocument::LoadFile()
|
||||
{
|
||||
return LoadFile( value );
|
||||
}
|
||||
|
||||
|
||||
bool TiXmlDocument::SaveFile()
|
||||
{
|
||||
return SaveFile( value );
|
||||
}
|
||||
|
||||
|
||||
bool TiXmlDocument::LoadFile( const std::string& filename )
|
||||
{
|
||||
// Delete the existing data:
|
||||
Clear();
|
||||
|
||||
// Load the new data:
|
||||
FILE* fp = fopen( filename.c_str(), "r" );
|
||||
if ( fp )
|
||||
{
|
||||
unsigned size;
|
||||
fseek( fp, 0, SEEK_END );
|
||||
size = ftell( fp );
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
|
||||
char* buf = new char[size+1];
|
||||
char* p = buf;
|
||||
while( fgets( p, size, fp ) )
|
||||
{
|
||||
p = strchr( p, 0 );
|
||||
}
|
||||
fclose( fp );
|
||||
|
||||
Parse( buf );
|
||||
delete [] buf;
|
||||
|
||||
if ( !Error() )
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError( TIXML_ERROR_OPENING_FILE );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool TiXmlDocument::SaveFile( const std::string& filename )
|
||||
{
|
||||
FILE* fp = fopen( filename.c_str(), "w" );
|
||||
if ( fp )
|
||||
{
|
||||
Print( fp, 0 );
|
||||
fclose( fp );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlDocument::Clone() const
|
||||
{
|
||||
TiXmlDocument* clone = new TiXmlDocument();
|
||||
if ( !clone )
|
||||
return 0;
|
||||
|
||||
CopyToClone( clone );
|
||||
clone->error = error;
|
||||
clone->errorDesc = errorDesc;
|
||||
|
||||
TiXmlNode* node = 0;
|
||||
for ( node = firstChild; node; node = node->NextSibling() )
|
||||
{
|
||||
clone->LinkEndChild( node->Clone() );
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
void TiXmlDocument::Print( FILE* fp, int )
|
||||
{
|
||||
TiXmlNode* node;
|
||||
for ( node=FirstChild(); node; node=node->NextSibling() )
|
||||
{
|
||||
node->Print( fp, 0 );
|
||||
fprintf( fp, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TiXmlAttribute* TiXmlAttribute::Next()
|
||||
{
|
||||
// We are using knowledge of the sentinel. The sentinel
|
||||
// have a value or name.
|
||||
if ( next->value.empty() && next->name.empty() )
|
||||
return 0;
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
TiXmlAttribute* TiXmlAttribute::Previous()
|
||||
{
|
||||
// We are using knowledge of the sentinel. The sentinel
|
||||
// have a value or name.
|
||||
if ( prev->value.empty() && prev->name.empty() )
|
||||
return 0;
|
||||
return prev;
|
||||
}
|
||||
|
||||
|
||||
void TiXmlAttribute::Print( FILE* fp, int )
|
||||
{
|
||||
if ( value.find( '\"' ) != std::string::npos )
|
||||
fprintf( fp, "%s='%s'", name.c_str(), value.c_str() );
|
||||
else
|
||||
fprintf( fp, "%s=\"%s\"", name.c_str(), value.c_str() );
|
||||
}
|
||||
|
||||
|
||||
void TiXmlComment::Print( FILE* fp, int depth )
|
||||
{
|
||||
for ( int i=0; i<depth; i++ )
|
||||
fprintf( fp, " " );
|
||||
fprintf( fp, "<!--%s-->", value.c_str() );
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlComment::Clone() const
|
||||
{
|
||||
TiXmlComment* clone = new TiXmlComment();
|
||||
|
||||
if ( !clone )
|
||||
return 0;
|
||||
|
||||
CopyToClone( clone );
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
void TiXmlText::Print( FILE* fp, int )
|
||||
{
|
||||
fprintf( fp, "%s", value.c_str() );
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlText::Clone() const
|
||||
{
|
||||
TiXmlText* clone = 0;
|
||||
clone = new TiXmlText();
|
||||
|
||||
if ( !clone )
|
||||
return 0;
|
||||
|
||||
CopyToClone( clone );
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
|
||||
const std::string& _encoding,
|
||||
const std::string& _standalone )
|
||||
: TiXmlNode( TiXmlNode::DECLARATION )
|
||||
{
|
||||
version = _version;
|
||||
encoding = _encoding;
|
||||
standalone = _standalone;
|
||||
}
|
||||
|
||||
|
||||
void TiXmlDeclaration::Print( FILE* fp, int )
|
||||
{
|
||||
std::string out = "<?xml ";
|
||||
|
||||
if ( !version.empty() )
|
||||
{
|
||||
out += "version=\"";
|
||||
out += version;
|
||||
out += "\" ";
|
||||
}
|
||||
if ( !encoding.empty() )
|
||||
{
|
||||
out += "encoding=\"";
|
||||
out += encoding;
|
||||
out += "\" ";
|
||||
}
|
||||
if ( !standalone.empty() )
|
||||
{
|
||||
out += "standalone=\"";
|
||||
out += standalone;
|
||||
out += "\" ";
|
||||
}
|
||||
out += "?>";
|
||||
|
||||
fprintf( fp, "%s", out.c_str() );
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlDeclaration::Clone() const
|
||||
{
|
||||
TiXmlDeclaration* clone = new TiXmlDeclaration();
|
||||
|
||||
if ( !clone )
|
||||
return 0;
|
||||
|
||||
CopyToClone( clone );
|
||||
clone->version = version;
|
||||
clone->encoding = encoding;
|
||||
clone->standalone = standalone;
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
void TiXmlUnknown::Print( FILE* fp, int depth )
|
||||
{
|
||||
for ( int i=0; i<depth; i++ )
|
||||
fprintf( fp, " " );
|
||||
fprintf( fp, "<%s>", value.c_str() );
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlUnknown::Clone() const
|
||||
{
|
||||
TiXmlUnknown* clone = new TiXmlUnknown();
|
||||
|
||||
if ( !clone )
|
||||
return 0;
|
||||
|
||||
CopyToClone( clone );
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
TiXmlAttributeSet::TiXmlAttributeSet()
|
||||
{
|
||||
sentinel.next = &sentinel;
|
||||
sentinel.prev = &sentinel;
|
||||
}
|
||||
|
||||
|
||||
TiXmlAttributeSet::~TiXmlAttributeSet()
|
||||
{
|
||||
assert( sentinel.next == &sentinel );
|
||||
assert( sentinel.prev == &sentinel );
|
||||
}
|
||||
|
||||
|
||||
void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
|
||||
{
|
||||
assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set.
|
||||
|
||||
addMe->next = &sentinel;
|
||||
addMe->prev = sentinel.prev;
|
||||
|
||||
sentinel.prev->next = addMe;
|
||||
sentinel.prev = addMe;
|
||||
}
|
||||
|
||||
void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
|
||||
{
|
||||
TiXmlAttribute* node;
|
||||
|
||||
for( node = sentinel.next; node != &sentinel; node = node->next )
|
||||
{
|
||||
if ( node == removeMe )
|
||||
{
|
||||
node->prev->next = node->next;
|
||||
node->next->prev = node->prev;
|
||||
node->next = 0;
|
||||
node->prev = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert( 0 ); // we tried to remove a non-linked attribute.
|
||||
}
|
||||
|
||||
|
||||
TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
|
||||
{
|
||||
TiXmlAttribute* node;
|
||||
|
||||
for( node = sentinel.next; node != &sentinel; node = node->next )
|
||||
{
|
||||
if ( node->Name() == name )
|
||||
return node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
613
project/jni/application/guichan-xml/tinyxml.h
Normal file
613
project/jni/application/guichan-xml/tinyxml.h
Normal file
@@ -0,0 +1,613 @@
|
||||
/*
|
||||
Copyright (c) 2000 Lee Thomason (www.grinninglizard.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 TINYXML_INCLUDED
|
||||
#define TINYXML_INCLUDED
|
||||
|
||||
#pragma warning( disable : 4530 )
|
||||
#pragma warning( disable : 4786 )
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
class TiXmlDocument;
|
||||
class TiXmlElement;
|
||||
class TiXmlComment;
|
||||
class TiXmlUnknown;
|
||||
class TiXmlAttribute;
|
||||
class TiXmlText;
|
||||
class TiXmlDeclaration;
|
||||
|
||||
|
||||
/** TiXmlBase is a base class for every class in TinyXml.
|
||||
It does little except to establist that TinyXml classes
|
||||
can be printed and provide some utility functions.
|
||||
|
||||
In XML, the document and elements can contain
|
||||
other elements and other types of nodes.
|
||||
|
||||
@verbatim
|
||||
A Document can contain: Element (container or leaf)
|
||||
Comment (leaf)
|
||||
Unknown (leaf)
|
||||
Declaration( leaf )
|
||||
|
||||
An Element can contain: Element (container or leaf)
|
||||
Text (leaf)
|
||||
Attributes (not on tree)
|
||||
Comment (leaf)
|
||||
Unknown (leaf)
|
||||
|
||||
A Decleration contains: Attributes (not on tree)
|
||||
@endverbatim
|
||||
*/
|
||||
class TiXmlBase
|
||||
{
|
||||
friend class TiXmlNode;
|
||||
friend class TiXmlElement;
|
||||
friend class TiXmlDocument;
|
||||
|
||||
public:
|
||||
TiXmlBase() {}
|
||||
virtual ~TiXmlBase() {}
|
||||
|
||||
/* All TinyXml classes can print themselves to a filestream.
|
||||
*/
|
||||
virtual void Print( FILE* fp, int depth ) = 0;
|
||||
|
||||
protected:
|
||||
/* General parsing helper method. Takes a pointer in,
|
||||
skips all the white space it finds, and returns a pointer
|
||||
to the first non-whitespace data.
|
||||
*/
|
||||
static const char* SkipWhiteSpace( const char* p );
|
||||
|
||||
/* Reads an XML name into the string provided. Returns
|
||||
a pointer just past the last character of the name,
|
||||
or 0 if the function has an error.
|
||||
*/
|
||||
static const char* ReadName( const char* p, std::string* name );
|
||||
|
||||
enum
|
||||
{
|
||||
TIXML_NO_ERROR = 0,
|
||||
TIXML_ERROR_OPENING_FILE,
|
||||
TIXML_ERROR_OUT_OF_MEMORY,
|
||||
TIXML_ERROR_PARSING_ELEMENT,
|
||||
TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
|
||||
TIXML_ERROR_READING_ELEMENT_VALUE,
|
||||
TIXML_ERROR_READING_ATTRIBUTES,
|
||||
TIXML_ERROR_PARSING_EMPTY,
|
||||
TIXML_ERROR_READING_END_TAG,
|
||||
TIXML_ERROR_PARSING_UNKNOWN,
|
||||
TIXML_ERROR_PARSING_COMMENT,
|
||||
TIXML_ERROR_PARSING_DECLARATION,
|
||||
|
||||
TIXML_ERROR_STRING_COUNT
|
||||
};
|
||||
static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
|
||||
};
|
||||
|
||||
|
||||
/** The parent class for everything in the Document Object Model.
|
||||
(Except for attributes, which are contained in elements.)
|
||||
Nodes have siblings, a parent, and children. A node can be
|
||||
in a document, or stand on its own. The type of a TyXmlNode
|
||||
can be queried, and it can be cast to its more defined type.
|
||||
*/
|
||||
class TiXmlNode : public TiXmlBase
|
||||
{
|
||||
public:
|
||||
/** The types of XML nodes supported by TinyXml. (All the
|
||||
unsupported types are picked up by UNKNOWN.)
|
||||
*/
|
||||
enum NodeType
|
||||
{
|
||||
DOCUMENT, ELEMENT, COMMENT, UNKNOWN, TEXT, DECLARATION, TYPECOUNT
|
||||
};
|
||||
|
||||
virtual ~TiXmlNode();
|
||||
|
||||
/** The meaning of 'value' changes for the specific type of
|
||||
TiXmlNode.
|
||||
@verbatim
|
||||
Document: filename of the xml file
|
||||
Element: name of the element
|
||||
Comment: the comment text
|
||||
Unknown: the tag contents
|
||||
Text: the text string
|
||||
@endverbatim
|
||||
|
||||
The subclasses will wrap this function.
|
||||
*/
|
||||
const std::string& Value() const { return value; }
|
||||
|
||||
/** Changes the value of the node. Defined as:
|
||||
@verbatim
|
||||
Document: filename of the xml file
|
||||
Element: name of the element
|
||||
Comment: the comment text
|
||||
Unknown: the tag contents
|
||||
Text: the text string
|
||||
@endverbatim
|
||||
*/
|
||||
void SetValue( const std::string& _value ) { value = _value; }
|
||||
|
||||
/// Delete all the children of this node. Does not affect 'this'.
|
||||
void Clear();
|
||||
|
||||
/// One step up the DOM.
|
||||
TiXmlNode* Parent() const { return parent; }
|
||||
|
||||
TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
|
||||
TiXmlNode* FirstChild( const std::string& value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
|
||||
|
||||
TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
|
||||
TiXmlNode* LastChild( const std::string& value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
|
||||
|
||||
/** An alternate way to walk the children of a node.
|
||||
One way to iterate over nodes is:
|
||||
@verbatim
|
||||
for( child = parent->FirstChild(); child; child = child->NextSibling() )
|
||||
@endverbatim
|
||||
|
||||
IterateChildren does the same thing with the syntax:
|
||||
@verbatim
|
||||
child = 0;
|
||||
while( child = parent->IterateChildren( child ) )
|
||||
@endverbatim
|
||||
|
||||
IterateChildren takes the previous child as input and finds
|
||||
the next one. If the previous child is null, it returns the
|
||||
first. IterateChildren will return null when done.
|
||||
*/
|
||||
TiXmlNode* IterateChildren( TiXmlNode* previous );
|
||||
|
||||
/// This flavor of IterateChildren searches for children with a particular 'value'
|
||||
TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous );
|
||||
|
||||
/** Add a new node related to this. Adds a child past the LastChild.
|
||||
Returns a pointer to the new object or NULL if an error occured.
|
||||
*/
|
||||
TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
|
||||
|
||||
/** Add a new node related to this. Adds a child before the specified child.
|
||||
Returns a pointer to the new object or NULL if an error occured.
|
||||
*/
|
||||
TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
|
||||
|
||||
/** Add a new node related to this. Adds a child after the specified child.
|
||||
Returns a pointer to the new object or NULL if an error occured.
|
||||
*/
|
||||
TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
|
||||
|
||||
/** Replace a child of this node.
|
||||
Returns a pointer to the new object or NULL if an error occured.
|
||||
*/
|
||||
TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
|
||||
|
||||
/// Delete a child of this node.
|
||||
bool RemoveChild( TiXmlNode* removeThis );
|
||||
|
||||
/// Navigate to a sibling node.
|
||||
TiXmlNode* PreviousSibling() const { return prev; }
|
||||
|
||||
/// Navigate to a sibling node.
|
||||
TiXmlNode* PreviousSibling( const std::string& ) const;
|
||||
|
||||
/// Navigate to a sibling node.
|
||||
TiXmlNode* NextSibling() const { return next; }
|
||||
|
||||
/// Navigate to a sibling node with the given 'value'.
|
||||
TiXmlNode* NextSibling( const std::string& ) const;
|
||||
|
||||
/** Convenience function to get through elements.
|
||||
Calls NextSibling and ToElement. Will skip all non-Element
|
||||
nodes. Returns 0 if there is not another element.
|
||||
*/
|
||||
TiXmlElement* NextSiblingElement() const;
|
||||
|
||||
/** Convenience function to get through elements.
|
||||
Calls NextSibling and ToElement. Will skip all non-Element
|
||||
nodes. Returns 0 if there is not another element.
|
||||
*/
|
||||
TiXmlElement* NextSiblingElement( const std::string& ) const;
|
||||
|
||||
/// Convenience function to get through elements.
|
||||
TiXmlElement* FirstChildElement() const;
|
||||
|
||||
/// Convenience function to get through elements.
|
||||
TiXmlElement* FirstChildElement( const std::string& value ) const;
|
||||
|
||||
/// Query the type (as an enumerated value, above) of this node.
|
||||
virtual int Type() { return type; }
|
||||
|
||||
/** Return a pointer to the Document this node lives in.
|
||||
Returns null if not in a document.
|
||||
*/
|
||||
TiXmlDocument* GetDocument() const;
|
||||
|
||||
TiXmlDocument* ToDocument() const { return ( type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
|
||||
TiXmlElement* ToElement() const { return ( type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
|
||||
TiXmlComment* ToComment() const { return ( type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
|
||||
TiXmlUnknown* ToUnknown() const { return ( type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
|
||||
TiXmlText* ToText() const { return ( type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
|
||||
TiXmlDeclaration* ToDeclaration() const { return ( type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
|
||||
|
||||
virtual TiXmlNode* Clone() const = 0;
|
||||
|
||||
protected:
|
||||
TiXmlNode( NodeType type );
|
||||
virtual const char* Parse( const char* ) = 0;
|
||||
|
||||
// The node is passed in by ownership. This object will delete it.
|
||||
TiXmlNode* LinkEndChild( TiXmlNode* addThis );
|
||||
|
||||
// Figure out what is at *p, and parse it. Return a node if
|
||||
// successful, and update p.
|
||||
TiXmlNode* IdentifyAndParse( const char** p );
|
||||
|
||||
void CopyToClone( TiXmlNode* target ) const { target->value = value; }
|
||||
|
||||
TiXmlNode* parent;
|
||||
NodeType type;
|
||||
|
||||
TiXmlNode* firstChild;
|
||||
TiXmlNode* lastChild;
|
||||
|
||||
std::string value;
|
||||
|
||||
TiXmlNode* prev;
|
||||
TiXmlNode* next;
|
||||
};
|
||||
|
||||
|
||||
/** An attribute is a name-value pair. Elements have an arbitrary
|
||||
number of attributes, each with a unique name.
|
||||
|
||||
@note The attributes are not TiXmlNodes, since they are not
|
||||
part of the tinyXML document object model. There are other
|
||||
suggested ways to look at this problem.
|
||||
|
||||
@note Attributes have a parent
|
||||
*/
|
||||
class TiXmlAttribute : public TiXmlBase
|
||||
{
|
||||
friend class TiXmlAttributeSet;
|
||||
|
||||
public:
|
||||
/// Construct an empty attribute.
|
||||
TiXmlAttribute() : prev( 0 ), next( 0 ) {}
|
||||
|
||||
/// Construct an attribute with a name and value.
|
||||
TiXmlAttribute( const std::string& _name, const std::string& _value ) : name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
|
||||
|
||||
const std::string& Name() const { return name; } ///< Return the name of this attribute.
|
||||
const std::string& Value() const { return value; } ///< Return the value of this attribute.
|
||||
|
||||
void SetName( const std::string& _name ) { name = _name; } ///< Set the name of this attribute.
|
||||
void SetValue( const std::string& _value ) { value = _value; } ///< Set the value.
|
||||
|
||||
/// Get the next sibling attribute in the DOM. Returns null at end.
|
||||
TiXmlAttribute* Next();
|
||||
/// Get the previous sibling attribute in the DOM. Returns null at beginning.
|
||||
TiXmlAttribute* Previous();
|
||||
|
||||
bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
|
||||
bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
|
||||
bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
|
||||
|
||||
/* [internal use]
|
||||
Attribtue parsing starts: first letter of the name
|
||||
returns: the next char after the value end quote
|
||||
*/
|
||||
const char* Parse( const char* );
|
||||
|
||||
// [internal use]
|
||||
virtual void Print( FILE* fp, int depth );
|
||||
|
||||
// [internal use]
|
||||
// Set the document pointer so the attribute can report errors.
|
||||
void SetDocument( TiXmlDocument* doc ) { document = doc; }
|
||||
|
||||
private:
|
||||
TiXmlDocument* document; // A pointer back to a document, for error reporting.
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
||||
TiXmlAttribute* prev;
|
||||
TiXmlAttribute* next;
|
||||
};
|
||||
|
||||
|
||||
/* A class used to manage a group of attributes.
|
||||
It is only used internally, both by the ELEMENT and the DECLARATION.
|
||||
|
||||
The set can be changed transparent to the Element and Declaration
|
||||
classes that use it, but NOT transparent to the Attribute
|
||||
which has to implement a next() and previous() method. Which makes
|
||||
it a bit problematic and prevents the use of STL.
|
||||
|
||||
This version is implemented with circular lists because:
|
||||
- I like circular lists
|
||||
- it demonstrates some independence from the (typical) doubly linked list.
|
||||
*/
|
||||
class TiXmlAttributeSet
|
||||
{
|
||||
public:
|
||||
TiXmlAttributeSet();
|
||||
~TiXmlAttributeSet();
|
||||
|
||||
void Add( TiXmlAttribute* attribute );
|
||||
void Remove( TiXmlAttribute* attribute );
|
||||
|
||||
TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
|
||||
TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
|
||||
|
||||
TiXmlAttribute* Find( const std::string& name ) const;
|
||||
|
||||
private:
|
||||
TiXmlAttribute sentinel;
|
||||
};
|
||||
|
||||
|
||||
/** The element is a container class. It has a value, the element name,
|
||||
and can contain other elements, text, comments, and unknowns.
|
||||
Elements also contain an arbitrary number of attributes.
|
||||
*/
|
||||
class TiXmlElement : public TiXmlNode
|
||||
{
|
||||
public:
|
||||
/// Construct an element.
|
||||
TiXmlElement( const std::string& value );
|
||||
|
||||
virtual ~TiXmlElement();
|
||||
|
||||
/** Given an attribute name, attribute returns the value
|
||||
for the attribute of that name, or null if none exists.
|
||||
*/
|
||||
const std::string* Attribute( const std::string& name ) const;
|
||||
|
||||
/** Given an attribute name, attribute returns the value
|
||||
for the attribute of that name, or null if none exists.
|
||||
*/
|
||||
const std::string* Attribute( const std::string& name, int* i ) const;
|
||||
|
||||
/** Sets an attribute of name to a given value. The attribute
|
||||
will be created if it does not exist, or changed if it does.
|
||||
*/
|
||||
void SetAttribute( const std::string& name,
|
||||
const std::string& value );
|
||||
|
||||
/** Sets an attribute of name to a given value. The attribute
|
||||
will be created if it does not exist, or changed if it does.
|
||||
*/
|
||||
void SetAttribute( const std::string& name,
|
||||
int value );
|
||||
|
||||
/** Deletes an attribute with the given name.
|
||||
*/
|
||||
void RemoveAttribute( const std::string& name );
|
||||
|
||||
TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } ///< Access the first attribute in this element.
|
||||
TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } ///< Access the last attribute in this element.
|
||||
|
||||
// [internal use] Creates a new Element and returs it.
|
||||
virtual TiXmlNode* Clone() const;
|
||||
// [internal use]
|
||||
virtual void Print( FILE* fp, int depth );
|
||||
|
||||
protected:
|
||||
/* [internal use]
|
||||
Attribtue parsing starts: next char past '<'
|
||||
returns: next char past '>'
|
||||
*/
|
||||
virtual const char* Parse( const char* );
|
||||
const char* ReadValue( const char* p );
|
||||
|
||||
private:
|
||||
TiXmlAttributeSet attributeSet;
|
||||
};
|
||||
|
||||
|
||||
/** An XML comment.
|
||||
*/
|
||||
class TiXmlComment : public TiXmlNode
|
||||
{
|
||||
public:
|
||||
/// Constructs an empty comment.
|
||||
TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
|
||||
virtual ~TiXmlComment() {}
|
||||
|
||||
// [internal use] Creates a new Element and returs it.
|
||||
virtual TiXmlNode* Clone() const;
|
||||
// [internal use]
|
||||
virtual void Print( FILE* fp, int depth );
|
||||
|
||||
protected:
|
||||
/* [internal use]
|
||||
Attribtue parsing starts: at the ! of the !--
|
||||
returns: next char past '>'
|
||||
*/
|
||||
virtual const char* Parse( const char* );
|
||||
};
|
||||
|
||||
|
||||
/** XML text. Contained in an element.
|
||||
*/
|
||||
class TiXmlText : public TiXmlNode
|
||||
{
|
||||
public:
|
||||
TiXmlText() : TiXmlNode( TiXmlNode::TEXT ) {}
|
||||
virtual ~TiXmlText() {}
|
||||
|
||||
|
||||
// [internal use] Creates a new Element and returns it.
|
||||
virtual TiXmlNode* Clone() const;
|
||||
// [internal use]
|
||||
virtual void Print( FILE* fp, int depth );
|
||||
// [internal use]
|
||||
bool Blank(); // returns true if all white space and new lines
|
||||
|
||||
/* [internal use]
|
||||
Attribtue parsing starts: First char of the text
|
||||
returns: next char past '>'
|
||||
*/
|
||||
virtual const char* Parse( const char* );
|
||||
};
|
||||
|
||||
|
||||
/** In correct XML the declaration is the first entry in the file.
|
||||
@verbatim
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
@endverbatim
|
||||
|
||||
TinyXml will happily read or write files without a declaration,
|
||||
however. There are 3 possible attributes to the declaration:
|
||||
version, encoding, and standalone.
|
||||
|
||||
Note: In this version of the code, the attributes are
|
||||
handled as special cases, not generic attributes, simply
|
||||
because there can only be at most 3 and they are always the same.
|
||||
*/
|
||||
class TiXmlDeclaration : public TiXmlNode
|
||||
{
|
||||
public:
|
||||
/// Construct an empty declaration.
|
||||
TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {}
|
||||
|
||||
/// Construct.
|
||||
TiXmlDeclaration( const std::string& version,
|
||||
const std::string& encoding,
|
||||
const std::string& standalone );
|
||||
|
||||
virtual ~TiXmlDeclaration() {}
|
||||
|
||||
/// Version. Will return empty if none was found.
|
||||
const std::string& Version() { return version; }
|
||||
/// Encoding. Will return empty if none was found.
|
||||
const std::string& Encoding() { return encoding; }
|
||||
/// Is this a standalone document?
|
||||
const std::string& Standalone() { return standalone; }
|
||||
|
||||
// [internal use] Creates a new Element and returs it.
|
||||
virtual TiXmlNode* Clone() const;
|
||||
// [internal use]
|
||||
virtual void Print( FILE* fp, int depth );
|
||||
|
||||
protected:
|
||||
// [internal use]
|
||||
// Attribtue parsing starts: next char past '<'
|
||||
// returns: next char past '>'
|
||||
|
||||
virtual const char* Parse( const char* );
|
||||
|
||||
private:
|
||||
std::string version;
|
||||
std::string encoding;
|
||||
std::string standalone;
|
||||
};
|
||||
|
||||
|
||||
/** Any tag that tinyXml doesn't recognize is save as an
|
||||
unknown. It is a tag of text, but should not be modified.
|
||||
It will be written back to the XML, unchanged, when the file
|
||||
is saved.
|
||||
*/
|
||||
class TiXmlUnknown : public TiXmlNode
|
||||
{
|
||||
public:
|
||||
TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
|
||||
virtual ~TiXmlUnknown() {}
|
||||
|
||||
// [internal use]
|
||||
virtual TiXmlNode* Clone() const;
|
||||
// [internal use]
|
||||
virtual void Print( FILE* fp, int depth );
|
||||
|
||||
protected:
|
||||
/* [internal use]
|
||||
Attribute parsing starts: First char of the text
|
||||
returns: next char past '>'
|
||||
*/
|
||||
virtual const char* Parse( const char* );
|
||||
};
|
||||
|
||||
|
||||
/** Always the top level node. A document binds together all the
|
||||
XML pieces. It can be saved, loaded, and printed to the screen.
|
||||
The 'value' of a document node is the xml file name.
|
||||
*/
|
||||
class TiXmlDocument : public TiXmlNode
|
||||
{
|
||||
public:
|
||||
/// Create an empty document, that has no name.
|
||||
TiXmlDocument();
|
||||
/// Create a document with a name. The name of the document is also the filename of the xml.
|
||||
TiXmlDocument( const std::string& documentName );
|
||||
|
||||
virtual ~TiXmlDocument() {}
|
||||
|
||||
/** Load a file using the current document value.
|
||||
Returns true if successful. Will delete any existing
|
||||
document data before loading.
|
||||
*/
|
||||
bool LoadFile();
|
||||
/// Save a file using the current document value. Returns true if successful.
|
||||
bool SaveFile();
|
||||
/// Load a file using the given filename. Returns true if successful.
|
||||
bool LoadFile( const std::string& filename );
|
||||
/// Save a file using the given filename. Returns true if successful.
|
||||
bool SaveFile( const std::string& filename );
|
||||
|
||||
/// Parse the given null terminated block of xml data.
|
||||
const char* Parse( const char* );
|
||||
|
||||
/// If, during parsing, a error occurs, Error will be set to true.
|
||||
bool Error() { return error; }
|
||||
/// Contains a textual (english) description of the error if one occurs.
|
||||
const std::string& ErrorDesc() { return errorDesc; }
|
||||
|
||||
/// Write the document to a file -- usually invoked by SaveFile.
|
||||
virtual void Print( FILE* fp, int depth = 0 );
|
||||
/// Dump the document to standard out.
|
||||
void Print() { Print( stdout, 0 ); }
|
||||
|
||||
// [internal use]
|
||||
virtual TiXmlNode* Clone() const;
|
||||
// [internal use]
|
||||
void SetError( int err ) { assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
|
||||
error = true;
|
||||
errorId = err;
|
||||
errorDesc = errorString[ errorId ]; }
|
||||
|
||||
private:
|
||||
bool error;
|
||||
int errorId;
|
||||
std::string errorDesc;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
24
project/jni/application/guichan-xml/tinyxmlerror.cpp
Normal file
24
project/jni/application/guichan-xml/tinyxmlerror.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "tinyxml.h"
|
||||
|
||||
// The goal of the seperate error file is to make the first
|
||||
// step towards localization. tinyxml (currently) only supports
|
||||
// latin-1, but at least the error messages could now be translated.
|
||||
//
|
||||
// It also cleans up the code a bit.
|
||||
|
||||
const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
|
||||
{
|
||||
"No error",
|
||||
"Failed to open file",
|
||||
"Memory allocation failed.",
|
||||
"Error parsing Element.",
|
||||
"Failed to read Element name",
|
||||
"Error reading Element value.",
|
||||
"Error reading Attributes.",
|
||||
"Error: empty tag.",
|
||||
"Error reading end tag.",
|
||||
"Error parsing Unknown.",
|
||||
"Error parsing Comment.",
|
||||
"Error parsing Declaration.",
|
||||
};
|
||||
|
||||
535
project/jni/application/guichan-xml/tinyxmlparser.cpp
Normal file
535
project/jni/application/guichan-xml/tinyxmlparser.cpp
Normal file
@@ -0,0 +1,535 @@
|
||||
/*
|
||||
Copyright (c) 2000 Lee Thomason (www.grinninglizard.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 "tinyxml.h"
|
||||
#include <ctype.h>
|
||||
|
||||
const char* TiXmlBase::SkipWhiteSpace( const char* p )
|
||||
{
|
||||
while ( p && *p &&
|
||||
( isspace( *p ) || *p == '\n' || *p == '\r' ) )
|
||||
p++;
|
||||
return p;
|
||||
}
|
||||
|
||||
const char* TiXmlBase::ReadName( const char* p, std::string* name )
|
||||
{
|
||||
*name = "";
|
||||
const char* start = p;
|
||||
|
||||
// Names start with letters or underscores.
|
||||
// After that, they can be letters, underscores, numbers,
|
||||
// hyphens, or colons. (Colons are valid ony for namespaces,
|
||||
// but tinyxml can't tell namespaces from names.)
|
||||
if ( p && ( isalpha( *p ) || *p == '_' ) )
|
||||
{
|
||||
p++;
|
||||
while( p && *p &&
|
||||
( isalnum( *p )
|
||||
|| *p == '_'
|
||||
|| *p == '-'
|
||||
|| *p == ':' ) )
|
||||
{
|
||||
p++;
|
||||
}
|
||||
name->append( start, p - start );
|
||||
return p;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char* TiXmlDocument::Parse( const char* start )
|
||||
{
|
||||
// Parse away, at the document level. Since a document
|
||||
// contains nothing but other tags, most of what happens
|
||||
// here is skipping white space.
|
||||
|
||||
const char* p = start;
|
||||
|
||||
p = SkipWhiteSpace( p );
|
||||
if ( !p || !*p )
|
||||
{
|
||||
error = true;
|
||||
errorDesc = "Document empty.";
|
||||
}
|
||||
|
||||
while ( p && *p )
|
||||
{
|
||||
if ( *p != '<' )
|
||||
{
|
||||
error = true;
|
||||
errorDesc = "The '<' symbol that starts a tag was not found.";
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
TiXmlNode* node = IdentifyAndParse( &p );
|
||||
if ( node )
|
||||
{
|
||||
LinkEndChild( node );
|
||||
}
|
||||
}
|
||||
p = SkipWhiteSpace( p );
|
||||
}
|
||||
return 0; // Return null is fine for a document: once it is read, the parsing is over.
|
||||
}
|
||||
|
||||
|
||||
TiXmlNode* TiXmlNode::IdentifyAndParse( const char** where )
|
||||
{
|
||||
const char* p = *where;
|
||||
TiXmlNode* returnNode = 0;
|
||||
assert( *p == '<' );
|
||||
TiXmlDocument* doc = GetDocument();
|
||||
|
||||
p = SkipWhiteSpace( p+1 );
|
||||
|
||||
// What is this thing?
|
||||
// - Elements start with a letter or underscore, but xml is reserved.
|
||||
// - Comments: <!--
|
||||
// - Everthing else is unknown to tinyxml.
|
||||
//
|
||||
if ( tolower( *(p+0) ) == '?'
|
||||
&& tolower( *(p+1) ) == 'x'
|
||||
&& tolower( *(p+2) ) == 'm'
|
||||
&& tolower( *(p+3) ) == 'l' )
|
||||
{
|
||||
#ifdef DEBUG_PARSER
|
||||
printf( "XML parsing Declaration\n" );
|
||||
#endif
|
||||
returnNode = new TiXmlDeclaration();
|
||||
}
|
||||
else if ( isalpha( *p ) || *p == '_' )
|
||||
{
|
||||
#ifdef DEBUG_PARSER
|
||||
printf( "XML parsing Element\n" );
|
||||
#endif
|
||||
returnNode = new TiXmlElement( "" );
|
||||
}
|
||||
else if ( *(p+0) == '!'
|
||||
&& *(p+1) == '-'
|
||||
&& *(p+2) == '-' )
|
||||
{
|
||||
#ifdef DEBUG_PARSER
|
||||
printf( "XML parsing Comment\n" );
|
||||
#endif
|
||||
returnNode = new TiXmlComment();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_PARSER
|
||||
printf( "XML parsing Comment\n" );
|
||||
#endif
|
||||
returnNode = new TiXmlUnknown();
|
||||
}
|
||||
|
||||
if ( returnNode )
|
||||
{
|
||||
// Set the parent, so it can report errors
|
||||
returnNode->parent = this;
|
||||
p = returnNode->Parse( p );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( doc )
|
||||
doc->SetError( TIXML_ERROR_OUT_OF_MEMORY );
|
||||
p = 0;
|
||||
}
|
||||
*where = p;
|
||||
return returnNode;
|
||||
}
|
||||
|
||||
|
||||
const char* TiXmlElement::Parse( const char* p )
|
||||
{
|
||||
TiXmlDocument* document = GetDocument();
|
||||
p = SkipWhiteSpace( p );
|
||||
if ( !p || !*p )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read the name.
|
||||
p = ReadName( p, &value );
|
||||
if ( !p )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME );
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string endTag = "</";
|
||||
endTag += value;
|
||||
endTag += ">";
|
||||
|
||||
// Check for and read attributes. Also look for an empty
|
||||
// tag or an end tag.
|
||||
while ( p && *p )
|
||||
{
|
||||
p = SkipWhiteSpace( p );
|
||||
if ( !p || !*p )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
|
||||
return 0;
|
||||
}
|
||||
if ( *p == '/' )
|
||||
{
|
||||
// Empty tag.
|
||||
if ( *(p+1) != '>' )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY );
|
||||
return 0;
|
||||
}
|
||||
return p+2;
|
||||
}
|
||||
else if ( *p == '>' )
|
||||
{
|
||||
// Done with attributes (if there were any.)
|
||||
// Read the value -- which can include other
|
||||
// elements -- read the end tag, and return.
|
||||
p = ReadValue( p+1 ); // Note this is an Element method, and will set the error if one happens.
|
||||
if ( !p )
|
||||
return 0;
|
||||
|
||||
// We should find the end tag now
|
||||
std::string buf( p, endTag.size() );
|
||||
if ( endTag == buf )
|
||||
{
|
||||
return p+endTag.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to read an element:
|
||||
TiXmlAttribute attrib;
|
||||
attrib.SetDocument( document );
|
||||
p = attrib.Parse( p );
|
||||
|
||||
if ( p )
|
||||
{
|
||||
SetAttribute( attrib.Name(), attrib.Value() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char* TiXmlElement::ReadValue( const char* p )
|
||||
{
|
||||
TiXmlDocument* document = GetDocument();
|
||||
|
||||
// Read in text and elements in any order.
|
||||
p = SkipWhiteSpace( p );
|
||||
while ( p && *p )
|
||||
{
|
||||
const char* start = p;
|
||||
while ( *p && *p != '<' )
|
||||
p++;
|
||||
|
||||
if ( !*p )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE );
|
||||
return 0;
|
||||
}
|
||||
if ( p != start )
|
||||
{
|
||||
// Take what we have, make a text element.
|
||||
TiXmlText* text = new TiXmlText();
|
||||
|
||||
if ( !text )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY );
|
||||
return 0;
|
||||
}
|
||||
text->Parse( start );
|
||||
if ( !text->Blank() )
|
||||
LinkEndChild( text );
|
||||
else
|
||||
delete text;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We hit a '<'
|
||||
// Have we hit a new element or an end tag?
|
||||
if ( *(p+1) == '/' )
|
||||
{
|
||||
return p; // end tag
|
||||
}
|
||||
else
|
||||
{
|
||||
// TiXmlElement* element = new TiXmlElement( "" );
|
||||
//
|
||||
// if ( element )
|
||||
// {
|
||||
// p = element->Parse( p+1 );
|
||||
// if ( p )
|
||||
// LinkEndChild( element );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if ( document ) document->SetError( ERROR_OUT_OF_MEMORY );
|
||||
// return 0;
|
||||
// }
|
||||
TiXmlNode* node = IdentifyAndParse( &p );
|
||||
if ( node )
|
||||
{
|
||||
LinkEndChild( node );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char* TiXmlUnknown::Parse( const char* p )
|
||||
{
|
||||
const char* end = strchr( p, '>' );
|
||||
if ( !end )
|
||||
{
|
||||
TiXmlDocument* document = GetDocument();
|
||||
if ( document )
|
||||
document->SetError( TIXML_ERROR_PARSING_UNKNOWN );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = std::string( p, end-p );
|
||||
// value.resize( end - p );
|
||||
return end + 1; // return just past the '>'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char* TiXmlComment::Parse( const char* p )
|
||||
{
|
||||
assert( *p == '!' && *(p+1) == '-' && *(p+2) == '-' );
|
||||
|
||||
// Find the end, copy the parts between to the value of
|
||||
// this object, and return.
|
||||
const char* start = p+3;
|
||||
const char* end = strstr( p, "-->" );
|
||||
if ( !end )
|
||||
{
|
||||
TiXmlDocument* document = GetDocument();
|
||||
if ( document )
|
||||
document->SetError( TIXML_ERROR_PARSING_COMMENT );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assemble the comment, removing the white space.
|
||||
bool whiteSpace = false;
|
||||
|
||||
const char* q;
|
||||
for( q=start; q<end; q++ )
|
||||
{
|
||||
if ( isspace( *q ) )
|
||||
{
|
||||
if ( !whiteSpace )
|
||||
{
|
||||
value += ' ';
|
||||
whiteSpace = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value += *q;
|
||||
whiteSpace = false;
|
||||
}
|
||||
}
|
||||
// value = std::string( start, end-start );
|
||||
return end + 3; // return just past the '>'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char* TiXmlAttribute::Parse( const char* p )
|
||||
{
|
||||
// Read the name, the '=' and the value.
|
||||
p = ReadName( p, &name );
|
||||
if ( !p )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
|
||||
return 0;
|
||||
}
|
||||
p = SkipWhiteSpace( p );
|
||||
if ( !p || *p != '=' )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = SkipWhiteSpace( p+1 );
|
||||
if ( !p || !*p )
|
||||
{
|
||||
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* end = 0;
|
||||
const char* start = p+1;
|
||||
const char* past = 0;
|
||||
|
||||
if ( *p == '\'' )
|
||||
{
|
||||
end = strchr( start, '\'' );
|
||||
past = end+1;
|
||||
}
|
||||
else if ( *p == '"' )
|
||||
{
|
||||
end = strchr( start, '"' );
|
||||
past = end+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// All attribute values should be in single or double quotes.
|
||||
// But this is such a common error that the parser will try
|
||||
// its best, even without them.
|
||||
start--;
|
||||
for ( end = start; *end; end++ )
|
||||
{
|
||||
if ( isspace( *end ) || *end == '/' || *end == '>' )
|
||||
break;
|
||||
}
|
||||
past = end;
|
||||
}
|
||||
value = std::string( start, end-start );
|
||||
return past;
|
||||
}
|
||||
|
||||
|
||||
const char* TiXmlText::Parse( const char* p )
|
||||
{
|
||||
value = "";
|
||||
bool whitespace = false;
|
||||
|
||||
// Remove leading white space:
|
||||
p = SkipWhiteSpace( p );
|
||||
while ( *p && *p != '<' )
|
||||
{
|
||||
if ( *p == '\r' || *p == '\n' )
|
||||
{
|
||||
whitespace = true;
|
||||
}
|
||||
else if ( isspace( *p ) )
|
||||
{
|
||||
whitespace = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we've found whitespace, add it before the
|
||||
// new character. Any whitespace just becomes a space.
|
||||
if ( whitespace )
|
||||
{
|
||||
value += ' ';
|
||||
whitespace = false;
|
||||
}
|
||||
value += *p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
// Keep white space before the '<'
|
||||
if ( whitespace )
|
||||
value += ' ';
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
const char* TiXmlDeclaration::Parse( const char* p )
|
||||
{
|
||||
// Find the beginning, find the end, and look for
|
||||
// the stuff in-between.
|
||||
const char* start = p+4;
|
||||
const char* end = strstr( start, "?>" );
|
||||
|
||||
// Be nice to the user:
|
||||
if ( !end )
|
||||
{
|
||||
end = strstr( start, ">" );
|
||||
end++;
|
||||
}
|
||||
else
|
||||
{
|
||||
end += 2;
|
||||
}
|
||||
|
||||
if ( !end )
|
||||
{
|
||||
TiXmlDocument* document = GetDocument();
|
||||
if ( document )
|
||||
document->SetError( TIXML_ERROR_PARSING_DECLARATION );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* p;
|
||||
|
||||
p = strstr( start, "version" );
|
||||
if ( p && p < end )
|
||||
{
|
||||
TiXmlAttribute attrib;
|
||||
attrib.Parse( p );
|
||||
version = attrib.Value();
|
||||
}
|
||||
|
||||
p = strstr( start, "encoding" );
|
||||
if ( p && p < end )
|
||||
{
|
||||
TiXmlAttribute attrib;
|
||||
attrib.Parse( p );
|
||||
encoding = attrib.Value();
|
||||
}
|
||||
|
||||
p = strstr( start, "standalone" );
|
||||
if ( p && p < end )
|
||||
{
|
||||
TiXmlAttribute attrib;
|
||||
attrib.Parse( p );
|
||||
standalone = attrib.Value();
|
||||
}
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
bool TiXmlText::Blank()
|
||||
{
|
||||
for ( unsigned i=0; i<value.size(); i++ )
|
||||
if ( !isspace( value[i] ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
865
project/jni/application/guichan-xml/xmlgui.cpp
Normal file
865
project/jni/application/guichan-xml/xmlgui.cpp
Normal file
@@ -0,0 +1,865 @@
|
||||
#include "xmlgui.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
XmlGui::XmlGui()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool XmlGui::parse(const std::string &filename)
|
||||
{
|
||||
TiXmlElement *element = NULL;
|
||||
TiXmlNode *node = NULL;
|
||||
|
||||
doc = new TiXmlDocument(filename.c_str());
|
||||
|
||||
bool loadOkay = doc->LoadFile();
|
||||
|
||||
if ( !loadOkay )
|
||||
{
|
||||
throw GCN_EXCEPTION("Error parsing xml file.");
|
||||
}
|
||||
node = doc->FirstChild();
|
||||
|
||||
if(node == NULL)
|
||||
{
|
||||
throw GCN_EXCEPTION("Xml document is null or has errors.");
|
||||
}
|
||||
|
||||
while(node!=NULL)
|
||||
{
|
||||
element = node->ToElement();
|
||||
parseWidgets(element,NULL);
|
||||
node = doc->IterateChildren(node);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void XmlGui::addToParent(gcn::Widget *widget,gcn::Widget *parent)
|
||||
{
|
||||
if(!parent) return;
|
||||
|
||||
gcn::Container* top = dynamic_cast<gcn::Container *>(parent);
|
||||
|
||||
if(top)
|
||||
{
|
||||
top->add(widget);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcn::Window* window = dynamic_cast<gcn::Window *>(parent);
|
||||
|
||||
if(window)
|
||||
// window->setContent(widget);
|
||||
window->add(widget);
|
||||
else
|
||||
{
|
||||
gcn::ScrollArea* scrollarea = dynamic_cast<gcn::ScrollArea *>(parent);
|
||||
scrollarea->setContent(widget);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void XmlGui::parseWidgets(TiXmlElement *element, gcn::Widget *parent)
|
||||
{
|
||||
if(!element) return;
|
||||
|
||||
std::string value = element->Value();
|
||||
|
||||
if(value == "container")
|
||||
parseContainer(element,parent);
|
||||
if(value == "label")
|
||||
parseLabel(element,parent);
|
||||
else if(value == "radiobutton")
|
||||
parseRadioButton(element,parent);
|
||||
else if(value == "button")
|
||||
parseButton(element,parent);
|
||||
else if(value == "checkbox")
|
||||
parseCheckBox(element,parent);
|
||||
else if(value == "icon")
|
||||
parseIcon(element,parent);
|
||||
else if(value == "textbox")
|
||||
parseTextBox(element,parent);
|
||||
else if(value == "textfield")
|
||||
parseTextField(element,parent);
|
||||
else if(value == "slider")
|
||||
parseSlider(element,parent);
|
||||
else if(value == "window")
|
||||
parseWindow(element,parent);
|
||||
else if(value == "scrollarea")
|
||||
parseScrollArea(element,parent);
|
||||
else if(value == "dropdown")
|
||||
parseDropdown(element,parent);
|
||||
else if(value == "listbox")
|
||||
parseListbox(element,parent);
|
||||
}
|
||||
|
||||
void XmlGui::parseDefaults(TiXmlElement *element, gcn::Widget *widget)
|
||||
{
|
||||
if(!element) return;
|
||||
|
||||
|
||||
if(element->Attribute("x"))
|
||||
{
|
||||
int x = atoi(element->Attribute("x")->c_str());
|
||||
widget->setX(x);
|
||||
}
|
||||
|
||||
|
||||
if(element->Attribute("y"))
|
||||
{
|
||||
int y = atoi(element->Attribute("y")->c_str());
|
||||
widget->setY(y);
|
||||
}
|
||||
|
||||
|
||||
if(element->Attribute("width"))
|
||||
{
|
||||
int w = atoi(element->Attribute("width")->c_str());
|
||||
widget->setWidth(w);
|
||||
}
|
||||
|
||||
if(element->Attribute("height"))
|
||||
{
|
||||
int h = atoi(element->Attribute("height")->c_str());
|
||||
widget->setHeight(h);
|
||||
}
|
||||
|
||||
if(element->Attribute("basecolor"))
|
||||
{
|
||||
int color;
|
||||
sscanf(element->Attribute("basecolor")->c_str(),"%x",&color);
|
||||
widget->setBaseColor(gcn::Color(color));
|
||||
}
|
||||
|
||||
if(element->Attribute("foregroundcolor"))
|
||||
{
|
||||
int color;
|
||||
sscanf(element->Attribute("foregroundcolor")->c_str(),"%x",&color);
|
||||
widget->setForegroundColor(gcn::Color(color));
|
||||
}
|
||||
|
||||
if(element->Attribute("backgroundcolor"))
|
||||
{
|
||||
int color;
|
||||
sscanf(element->Attribute("backgroundcolor")->c_str(),"%x",&color);
|
||||
widget->setBackgroundColor(gcn::Color(color));
|
||||
}
|
||||
|
||||
|
||||
if(element->Attribute("frame"))
|
||||
{
|
||||
int b = atoi(element->Attribute("framesize")->c_str());
|
||||
widget->setFrameSize(b);
|
||||
}
|
||||
|
||||
if(element->Attribute("font"))
|
||||
{
|
||||
if(fonts[*element->Attribute("font")])
|
||||
widget->setFont(fonts[*element->Attribute("visible")]);
|
||||
}
|
||||
|
||||
if(element->Attribute("visible"))
|
||||
widget->setVisible(checkBool(*element->Attribute("visible")));
|
||||
|
||||
if(element->Attribute("focusable"))
|
||||
widget->setFocusable(checkBool(*element->Attribute("focusable")));
|
||||
|
||||
if(element->Attribute("enabled"))
|
||||
widget->setEnabled(checkBool(*element->Attribute("enabled")));
|
||||
|
||||
if(element->Attribute("tabin"))
|
||||
widget->setTabInEnabled(checkBool(*element->Attribute("tabin")));
|
||||
|
||||
if(element->Attribute("tabout"))
|
||||
widget->setTabOutEnabled(checkBool(*element->Attribute("tabout")));
|
||||
|
||||
if(element->Attribute("eventId"))
|
||||
widget->setActionEventId(*element->Attribute("eventId"));
|
||||
|
||||
if(element->Attribute("actionListener"))
|
||||
widget->addActionListener(actions[*element->Attribute("actionListener")]);
|
||||
}
|
||||
|
||||
void XmlGui::parseContainer(TiXmlElement *element, gcn::Widget *parent)
|
||||
{
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("Container Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::Container *c = new gcn::Container();
|
||||
|
||||
|
||||
if(element->Attribute("opaque"))
|
||||
c->setOpaque(checkBool(*element->Attribute("opaque")));
|
||||
|
||||
|
||||
parseDefaults(element,c);
|
||||
|
||||
//parsing child elements
|
||||
TiXmlNode *child = element->FirstChild();
|
||||
|
||||
if(child)
|
||||
{
|
||||
while(child)
|
||||
{
|
||||
TiXmlElement *e = child->ToElement();
|
||||
|
||||
parseWidgets(e,c);
|
||||
|
||||
child = doc->IterateChildren(child);
|
||||
}
|
||||
}
|
||||
|
||||
addToParent(c,parent);
|
||||
widgets[name] = c;
|
||||
}
|
||||
|
||||
void XmlGui::parseLabel(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = *element->Attribute("name");
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("Label Widget must have a unique name");
|
||||
}
|
||||
|
||||
|
||||
gcn::Label *label = new gcn::Label;
|
||||
|
||||
|
||||
if(element->Attribute("caption"))
|
||||
{
|
||||
label->setCaption(*element->Attribute("caption"));
|
||||
}
|
||||
|
||||
label->adjustSize();
|
||||
|
||||
if(element->Attribute("align"))
|
||||
{
|
||||
if(*element->Attribute("align") == "center" || *element->Attribute("align") == "CENTER")
|
||||
{
|
||||
label->setAlignment(gcn::Graphics::CENTER);
|
||||
}else if(*element->Attribute("align") == "left" || *element->Attribute("align") == "LEFT")
|
||||
{
|
||||
label->setAlignment(gcn::Graphics::LEFT);
|
||||
}else
|
||||
{
|
||||
label->setAlignment(gcn::Graphics::RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
parseDefaults(element,label);
|
||||
|
||||
addToParent(label,parent);
|
||||
widgets[name] = label;
|
||||
}
|
||||
|
||||
void XmlGui::parseButton(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("Button Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::Button *button = new gcn::Button;
|
||||
|
||||
|
||||
if(element->Attribute("caption"))
|
||||
{
|
||||
button->setCaption(*element->Attribute("caption"));
|
||||
}
|
||||
|
||||
if(element->Attribute("align"))
|
||||
{
|
||||
if(*element->Attribute("align") == "center" || *element->Attribute("align") == "CENTER")
|
||||
{
|
||||
button->setAlignment(gcn::Graphics::CENTER);
|
||||
}else if(*element->Attribute("align") == "left" || *element->Attribute("align") == "LEFT")
|
||||
{
|
||||
button->setAlignment(gcn::Graphics::LEFT);
|
||||
}else
|
||||
{
|
||||
button->setAlignment(gcn::Graphics::RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
button->adjustSize();
|
||||
|
||||
parseDefaults(element,button);
|
||||
|
||||
// button->lostFocus(); //fix: this call must't exists
|
||||
//?????
|
||||
|
||||
addToParent(button,parent);
|
||||
|
||||
widgets[name] = button;
|
||||
}
|
||||
|
||||
void XmlGui::parseCheckBox(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("Checkbox Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::CheckBox *checkbox = new gcn::CheckBox;
|
||||
|
||||
|
||||
if(element->Attribute("caption"))
|
||||
{
|
||||
checkbox->setCaption(*element->Attribute("caption"));
|
||||
}
|
||||
|
||||
checkbox->adjustSize();
|
||||
|
||||
|
||||
if(element->Attribute("selected"))
|
||||
checkbox->setSelected(checkBool(*element->Attribute("selected")));
|
||||
|
||||
parseDefaults(element,checkbox);
|
||||
|
||||
|
||||
addToParent(checkbox,parent);
|
||||
|
||||
widgets[name] = checkbox;
|
||||
}
|
||||
|
||||
|
||||
void XmlGui::parseRadioButton(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("RadioButton Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::RadioButton *radio = new gcn::RadioButton;
|
||||
|
||||
if(element->Attribute("caption"))
|
||||
{
|
||||
radio->setCaption(*element->Attribute("caption"));
|
||||
}
|
||||
|
||||
radio->adjustSize();
|
||||
|
||||
|
||||
if(element->Attribute("selected"))
|
||||
radio->setSelected(checkBool(*element->Attribute("selected")));
|
||||
|
||||
if(element->Attribute("group"))
|
||||
radio->setGroup(*element->Attribute("group"));
|
||||
|
||||
parseDefaults(element,radio);
|
||||
|
||||
addToParent(radio,parent);
|
||||
|
||||
widgets[name] = radio;
|
||||
}
|
||||
|
||||
void XmlGui::parseIcon(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("Icon Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::Icon *icon;
|
||||
|
||||
gcn::Image *image;
|
||||
|
||||
if(element->Attribute("image"))
|
||||
{
|
||||
// image = new gcn::Image(*element->Attribute("image"));
|
||||
image = gcn::Image::load(*element->Attribute("image"));
|
||||
}
|
||||
|
||||
if(image)
|
||||
{
|
||||
icon = new gcn::Icon(image);
|
||||
}
|
||||
|
||||
parseDefaults(element,icon);
|
||||
|
||||
addToParent(icon,parent);
|
||||
widgets[name] = icon;
|
||||
}
|
||||
|
||||
|
||||
void XmlGui::parseTextBox(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("TextBox Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::TextBox *textbox = new gcn::TextBox;
|
||||
|
||||
if(element->Attribute("editable"))
|
||||
textbox->setEditable(checkBool(*element->Attribute("editable")));
|
||||
|
||||
if(element->Attribute("text"))
|
||||
{
|
||||
textbox->setText(*element->Attribute("text"));
|
||||
}
|
||||
|
||||
if(element->Attribute("opaque"))
|
||||
textbox->setOpaque(checkBool(*element->Attribute("opaque")));
|
||||
|
||||
parseDefaults(element,textbox);
|
||||
|
||||
addToParent(textbox,parent);
|
||||
|
||||
widgets[name] = textbox;
|
||||
}
|
||||
|
||||
void XmlGui::parseTextField(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("TextField Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::TextField *textfield = new gcn::TextField;
|
||||
|
||||
if(element->Attribute("text"))
|
||||
{
|
||||
textfield->setText(*element->Attribute("text"));
|
||||
}
|
||||
|
||||
parseDefaults(element,textfield);
|
||||
|
||||
addToParent(textfield,parent);
|
||||
|
||||
widgets[name] = textfield;
|
||||
}
|
||||
|
||||
void XmlGui::parseSlider(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("Slider Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::Slider *slider = new gcn::Slider;
|
||||
|
||||
if(element->Attribute("start"))
|
||||
{
|
||||
int start = atoi(element->Attribute("start")->c_str());
|
||||
|
||||
slider->setScaleStart(start);
|
||||
}
|
||||
|
||||
if(element->Attribute("end"))
|
||||
{
|
||||
int end = atoi(element->Attribute("end")->c_str());
|
||||
slider->setScaleEnd(end);
|
||||
}
|
||||
|
||||
if(element->Attribute("value"))
|
||||
{
|
||||
int value = atoi(element->Attribute("value")->c_str());
|
||||
slider->setValue(value);
|
||||
}
|
||||
|
||||
if(element->Attribute("markerLength"))
|
||||
{
|
||||
int l = atoi(element->Attribute("markerLength")->c_str());
|
||||
slider->setMarkerLength(l);
|
||||
}
|
||||
|
||||
if(element->Attribute("stepLength"))
|
||||
{
|
||||
int l = atoi(element->Attribute("stepLength")->c_str());
|
||||
slider->setStepLength(l);
|
||||
}
|
||||
|
||||
if(element->Attribute("orientation"))
|
||||
{
|
||||
if(*element->Attribute("orientation") == "HORIZONTAL" || *element->Attribute("orientation") == "horizontal")
|
||||
slider->setOrientation(gcn::Slider::HORIZONTAL);
|
||||
else slider->setOrientation(gcn::Slider::VERTICAL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
parseDefaults(element,slider);
|
||||
|
||||
addToParent(slider,parent);
|
||||
|
||||
widgets[name] = slider;
|
||||
}
|
||||
|
||||
void XmlGui::parseWindow(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = *element->Attribute("name");
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("Window Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::Window *window = new gcn::Window;
|
||||
|
||||
|
||||
if(element->Attribute("caption"))
|
||||
{
|
||||
window->setCaption(*element->Attribute("caption"));
|
||||
}
|
||||
|
||||
if(element->Attribute("tabbing"))
|
||||
{
|
||||
window->setPadding(checkBool(*element->Attribute("tabbing")));
|
||||
}
|
||||
|
||||
if(element->Attribute("movable"))
|
||||
{
|
||||
window->setMovable(checkBool(*element->Attribute("movable")));
|
||||
}
|
||||
|
||||
if(element->Attribute("titleBarHeight"))
|
||||
{
|
||||
int h = atoi(element->Attribute("titleBarHeight")->c_str());
|
||||
window->setTitleBarHeight(h);
|
||||
}
|
||||
|
||||
|
||||
if(element->Attribute("opaque"))
|
||||
window->setOpaque(checkBool(*element->Attribute("opaque")));
|
||||
|
||||
|
||||
parseDefaults(element,window);
|
||||
|
||||
//parsing child elements
|
||||
TiXmlNode *child = element->FirstChild();
|
||||
|
||||
if(child)
|
||||
{
|
||||
while(child)
|
||||
{
|
||||
TiXmlElement *e = child->ToElement();
|
||||
parseWidgets(e,window);
|
||||
child = doc->IterateChildren(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window->resizeToContent();
|
||||
|
||||
addToParent(window,parent);
|
||||
|
||||
widgets[name] = window;
|
||||
}
|
||||
|
||||
|
||||
void XmlGui::parseScrollArea(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("ScrollArea Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::ScrollArea *scroll = new gcn::ScrollArea;
|
||||
|
||||
|
||||
if(element->Attribute("hPolicy"))
|
||||
{
|
||||
if(*element->Attribute("hPolicy") == "ALWAYS" || *element->Attribute("hPolicy") == "always")
|
||||
scroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
|
||||
else if(*element->Attribute("hPolicy") == "NEVER" || *element->Attribute("hPolicy") == "never")
|
||||
scroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
|
||||
}
|
||||
|
||||
if(element->Attribute("vPolicy"))
|
||||
{
|
||||
if(*element->Attribute("vPolicy") == "ALWAYS" || *element->Attribute("vPolicy") == "always")
|
||||
scroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
|
||||
else if(*element->Attribute("vPolicy") == "NEVER" || *element->Attribute("vPolicy") == "never")
|
||||
scroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
|
||||
}
|
||||
|
||||
if(element->Attribute("vScrollAmount"))
|
||||
{
|
||||
int h;
|
||||
sscanf(element->Attribute("vScrollAmount")->c_str(),"%d",&h);
|
||||
scroll->setVerticalScrollAmount(h);
|
||||
}
|
||||
|
||||
if(element->Attribute("hScrollAmount"))
|
||||
{
|
||||
int h = atoi(element->Attribute("hScrollAmount")->c_str());
|
||||
scroll->setHorizontalScrollAmount(h);
|
||||
}
|
||||
|
||||
if(element->Attribute("scrollBarWidth"))
|
||||
{
|
||||
int w = atoi(element->Attribute("scrollbarWidth")->c_str());
|
||||
scroll->setScrollbarWidth(w);
|
||||
}
|
||||
|
||||
if(element->Attribute("content"))
|
||||
{
|
||||
gcn::Widget *content = getWidget(*element->Attribute("content"));
|
||||
if(content)
|
||||
{
|
||||
scroll->setContent(content);
|
||||
}
|
||||
}
|
||||
|
||||
parseDefaults(element,scroll);
|
||||
|
||||
if(!scroll->getContent())
|
||||
{
|
||||
|
||||
//parsing child elements
|
||||
TiXmlNode *child = element->FirstChild();
|
||||
|
||||
if(child)
|
||||
{
|
||||
while(child)
|
||||
{
|
||||
TiXmlElement *e = child->ToElement();
|
||||
|
||||
parseWidgets(e,scroll);
|
||||
|
||||
child = doc->IterateChildren(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addToParent(scroll,parent);
|
||||
|
||||
widgets[name] = scroll;
|
||||
}
|
||||
|
||||
void XmlGui::parseDropdown(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("DropDown Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::DropDown *dropdown = new gcn::DropDown;
|
||||
|
||||
|
||||
parseDefaults(element,dropdown);
|
||||
|
||||
XmlListModel *listmodel;
|
||||
//parsing child elements
|
||||
TiXmlNode *child = element->FirstChild();
|
||||
|
||||
if(child)
|
||||
{
|
||||
|
||||
listmodel = new XmlListModel;
|
||||
|
||||
while(child)
|
||||
{
|
||||
TiXmlElement *e = child->ToElement();
|
||||
if(e->Value() == "li")
|
||||
{
|
||||
listmodel->items.push_back(e->FirstChild()->Value());
|
||||
}
|
||||
child = doc->IterateChildren(child);
|
||||
}
|
||||
}
|
||||
|
||||
if(listmodel)
|
||||
dropdown->setListModel(listmodel);
|
||||
|
||||
if(element->Attribute("selected"))
|
||||
{
|
||||
int s = atoi(element->Attribute("selected")->c_str());
|
||||
dropdown->setSelected(s);
|
||||
}
|
||||
|
||||
addToParent(dropdown,parent);
|
||||
widgets[name] = dropdown;
|
||||
}
|
||||
|
||||
void XmlGui::parseListbox(TiXmlElement *element,gcn::Widget *parent)
|
||||
{
|
||||
if(!element)
|
||||
return;
|
||||
|
||||
|
||||
std::string name;
|
||||
if(element->Attribute("name"))
|
||||
{
|
||||
name = element->Attribute("name")->c_str();
|
||||
}else
|
||||
{
|
||||
throw GCN_EXCEPTION("ListBox Widget must have a unique name");
|
||||
}
|
||||
|
||||
gcn::ListBox *listbox = new gcn::ListBox;
|
||||
|
||||
|
||||
parseDefaults(element,listbox);
|
||||
|
||||
XmlListModel *listmodel;
|
||||
//parsing child elements
|
||||
TiXmlNode *child = element->FirstChild();
|
||||
|
||||
if(child)
|
||||
{
|
||||
|
||||
listmodel = new XmlListModel;
|
||||
|
||||
while(child)
|
||||
{
|
||||
TiXmlElement *e = child->ToElement();
|
||||
if(e->Value() == "li")
|
||||
{
|
||||
listmodel->items.push_back(e->FirstChild()->Value());
|
||||
}
|
||||
child = doc->IterateChildren(child);
|
||||
}
|
||||
}
|
||||
|
||||
if(listmodel)
|
||||
listbox->setListModel(listmodel);
|
||||
|
||||
if(element->Attribute("selected"))
|
||||
{
|
||||
int s = atoi(element->Attribute("selected")->c_str());
|
||||
listbox->setSelected(s);
|
||||
}
|
||||
|
||||
addToParent(listbox,parent);
|
||||
widgets[name] = listbox;
|
||||
}
|
||||
|
||||
|
||||
gcn::Widget *XmlGui::getWidget(const std::string &name)
|
||||
{
|
||||
|
||||
std::map<std::string,gcn::Widget*>::iterator it = widgets.find(name);
|
||||
if(it == widgets.end()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return widgets[name];
|
||||
}
|
||||
|
||||
bool XmlGui::checkBool(const std::string &value)
|
||||
{
|
||||
return (value == "1" || value == "true" || value == "True");
|
||||
}
|
||||
|
||||
void XmlGui::addActionListener(const std::string &name, gcn::ActionListener *al)
|
||||
{
|
||||
if(al)
|
||||
actions[name] = al;
|
||||
}
|
||||
|
||||
void XmlGui::addFont(const std::string &name, gcn::Font *font)
|
||||
{
|
||||
if(font)
|
||||
fonts[name] = font;
|
||||
}
|
||||
|
||||
|
||||
int XmlListModel::getNumberOfElements()
|
||||
{
|
||||
return items.size();
|
||||
}
|
||||
|
||||
std::string XmlListModel::getElementAt(int i)
|
||||
{
|
||||
return items[i];
|
||||
}
|
||||
|
||||
155
project/jni/application/guichan-xml/xmlgui.h
Normal file
155
project/jni/application/guichan-xml/xmlgui.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/* XmlGui - xml parsing class for guichan (http://guichan.sourceforge.net)
|
||||
* author - quard (quard8@gmail.com)
|
||||
* Changes:
|
||||
* v. 0.4 - fixed bug in Visual Studio .NET 2003, when compiler option /GR is not enabled;
|
||||
fixed widget allocation, when attribute "name" is't exists
|
||||
deleted all "return false" after GCN_EXCEPTION, because they not used ever
|
||||
* v. 0.3.5 - fixed stupid bug, when widgets not parsed if parent widget is NULL
|
||||
* v. 0.3 - added parsing method for widget,
|
||||
* now checking widget node is in one function
|
||||
* v. 0.2 - small bug fix
|
||||
* - added parsing widgets under 'container'
|
||||
* - changed sscanf to atoi
|
||||
* v. 0.1 - first public release
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XML_GUI_H
|
||||
#define XML_GUI_H
|
||||
|
||||
#include <guichan.hpp>
|
||||
#include "tinyxml.h"
|
||||
#include <map>
|
||||
|
||||
//!XmlGui class for loading gui widget from xml file
|
||||
class XmlGui
|
||||
{
|
||||
public:
|
||||
//!constructor
|
||||
XmlGui();
|
||||
//!parse xml file
|
||||
//@param filename the file name to parse
|
||||
//@return true if loaded ok
|
||||
bool parse(const std::string &filename);
|
||||
|
||||
//@param name th widget name
|
||||
//@return widget by name
|
||||
gcn::Widget *getWidget(const std::string &name);
|
||||
|
||||
//!parse default parameters for all widgets
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseDefaults(TiXmlElement *element, gcn::Widget *widget);
|
||||
|
||||
//!parse container widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseContainer(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse label widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseLabel(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse button widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseButton(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse checkbox widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseCheckBox(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse radiobutton widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseRadioButton(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse icon widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseIcon(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse textbox widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseTextBox(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse textfield widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseTextField(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse slider widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseSlider(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse window widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseWindow(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!parse scrollarea widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseScrollArea(TiXmlElement *element,gcn::Widget *parent);
|
||||
|
||||
//!parse dropdown widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseDropdown(TiXmlElement *element,gcn::Widget *parent);
|
||||
|
||||
//!parse listbox widget
|
||||
//@param element the xml element
|
||||
//@param widget the current widget
|
||||
void parseListbox(TiXmlElement *element,gcn::Widget *parent);
|
||||
|
||||
//!add actionlistener to array
|
||||
//@param name the actionlistener name
|
||||
//@param al the pointer to actionlistener class
|
||||
void addActionListener(const std::string &name,gcn::ActionListener *al);
|
||||
|
||||
//!add font
|
||||
//@param name the font name
|
||||
//@param al the pointer to font class
|
||||
void addFont(const std::string &name,gcn::Font *font);
|
||||
|
||||
|
||||
private:
|
||||
//!parse xml node
|
||||
//@param element - xml element
|
||||
//@param parent - the parent widget
|
||||
void parseWidgets(TiXmlElement *element, gcn::Widget *parent);
|
||||
|
||||
//!adding widget to parent
|
||||
//!parent widget can be Container,ScrollArea,Window. this function get class and set widget or add widget (for Container)
|
||||
//@param widget our widget
|
||||
//@param parent the parent widget
|
||||
void addToParent(gcn::Widget *widget, gcn::Widget *parent);
|
||||
|
||||
//!check string value for boolean value
|
||||
//@param value the string value
|
||||
//@return true if value are "1" or "true"
|
||||
bool checkBool(const std::string &value);
|
||||
|
||||
|
||||
std::map<std::string,gcn::Widget*> widgets;
|
||||
std::map<std::string,gcn::ActionListener*> actions;
|
||||
std::map<std::string,gcn::Font*> fonts;
|
||||
|
||||
//temporary xml document (need by some functions)
|
||||
TiXmlDocument *doc;
|
||||
};
|
||||
|
||||
class XmlListModel : public gcn::ListModel
|
||||
{
|
||||
public:
|
||||
virtual int getNumberOfElements();
|
||||
virtual std::string getElementAt(int i);
|
||||
std::vector<std::string> items;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user