Simple2D 1.11 now available
A new major release of Simple2D is now available (the download link can be found at the bottom of the page).
Version 1.11 introduces 49 improvements and bug fixes with an emphasis on user interface coding. Improvements have been made to scene objects, user interface objects and object groups, experimental support for skinning has been added, as well as support for XInput-compatible gamepads.
- Windows 7 Service Pack 1 with Platform Update for Windows 7
- Windows Server 2008 R2 Service Pack 1 with Platform Update for Windows 7
- Windows 8
The installer will download and install Platform Update for Windows 7 for you if you don’t have it already.
Migrating your libraries from Simple2D 1.06 or later
Simply run the new installer. Your Simple2D installation will be upgraded automatically to the latest version.
Migrating your libraries from Simple2D 1.05 or earlier
- Uninstall Simple2D from Add/Remove Programs in Control Panel
- Run the new installer
Migrating your applications from Simple2D 1.10
Applications must now link to xinput9_1_0.lib as well as the previously used DirectX libraries.
There is one breaking change in this version: Simple2D::GetFocusObject() now returns a pointer instead of a reference.
Migration your applications from Simple2D 1.07 or earlier
Please see the section entitled Code Migration from Simple2D 1.07 and earlier in the Simple2D 1.10 Release Notes.
Improvements and bug fixes
- When creating a standard Windows or full-screen application using a class derived from Simple2D, include Simple2D.h as normal. New feature: If you want to define your own main() or WinMain(), eg. for a console application or custom Windows application, include Simple2DLib.h instead (the new example GamepadTextDemo shows this)
- Bug fix: Calling Simple2D::Line() without a brush argument (to use the current brush) failed to call Prepare() on the brush (to set gradient properties etc.)
- Bug fix: Calling SetPoints(), SetPointsWH(), SetPointsUsingAlignmentType() or SetPointsUsingAlignmentTypeWH() on a brush before the brush resource is created caused an application crash (the brush resource is now created if needed when these functions are called)
- You can now unbind an animation from an object with SceneObject::Unbind(bindingName) (this allows the previously bound variable to be set freely once again)
- The BindAlpha2 binding type was added
User interface objects:
- Breaking change: Simple2D::GetFocusObject() now returns a pointer instead of a reference (in case there is no focus object, nullptr is returned)
- ButtonTemplate can now be initialized with the parameterized constructor ButtonTemplate(std::string text, boost::function<void (Button &)> onClick = NULL)
- The UserInterfaceItemGroup template class functions AddItemRow() and AddItemColumn() can now accept a vector of InterfaceItems as well as an array (the size argument can be omitted when using a vector)
- The TextBoxTemplate and TextBoxGroupTemplate structs have been added for use with UserInterfaceItemGroup (both can be initialized with parameterized constructors)
- A group of text boxes can be referred to as a TextBoxGroup (a concrete specialization of UserInterfaceItemGroup)
- TextBox now has an IsPassword public property which you can set to control whether the display of the text is replaced with asterisks (“*”)
- TextBoxes can now have captions. Configure the caption with TextBox::SetCaption(string text, TextFormat format, GenericBrush *brush, TextBoxCaptionPosition position, int gap). The position parameter should be TBCP_Above or TBCP_Left depending on where the caption should be displayed, and gap is the number of pixels gap between the text box and the caption text.
- Typedefs ButtonList and TextBoxList have been added to represent storing ButtonTemplates and TextBoxTemplates in vectors
- Tabbable items are now supported. InterfaceObjects in an ObjectGroup with focus can be tabbed through with Tab and Shift+Tab. To implement a tabbable object group, implement ITabbedObjectGroup. To implement a tabbable item, implement ITabbedItem. Currently, only TextBox is tabbable of the built-in interface element types. To find the next item in a tabbed object group, call ITabbedItem *ITabbedObjectGroup::FindTabbedItem(). To find the previous item, specify the optional bool parameter as false. The built-in group ObjectGroup now implements ITabbedObjectGroup by default, so no changes are needed to your code to support tabbable text boxes. Non-tabbable items in a group (objects which do not implement ITabbedItem) will be ignored and can be freely mixed in a group with tabbable items.
- Skinned dialog boxes are now available via the new Dialog class. A title bar, information/error label, arbitrary number of text boxes and buttons can be added to the dialog, and the visual layout configured via a separate class. See the SkinnedDialogDemo example for usage information.
- Objects can now remove themselves from their owner scene or group by calling SceneObject::SetDone() (this can also be used by application code as an alternative to Scene::Remove())
- The new functions ObjectManager::AddBehind(&|*), ObjectManager::AddBehindRef(&|*) and ObjectManager::AddDrawingBehind(func) allow you to add objects to the back of a Scene or ObjectGroup (rendered behind all the existing objects)
- The parent owner of each object is now stored; set and cleared automatically via SceneObject::SetOwner(ObjectManager &|*) when an object is added to or removed from a scene or group and can be fetched with ObjectManager *SceneObject::GetOwner(). NOTE: SetOwner() should not be called directly by your own applications.
- Adding a UserInterfaceItemGroup to a Scene or ObjectGroup now returns a vector of unmanaged raw pointers to the objects created so that you can reference them in your application (the pointers are still managed by the Scene or ObjectGroup so you can just discard them when they are no longer needed)
- You can now get the objects in a Scene or ObjectGroup with boost::ptr_list<SceneObject> *ObjectManager::GetObjects().
- Bug fix: potential memory leak when removing objects added to a Scene or ObjectGroup via a UserInterfaceItemGroup (SetDeleteBehaviour() was not called on the child objects)
- Bug fix: Mouse events were not dispatched to user interface objects in an ObjectGroup (or derived class thereof)
- Bug fix: The mouse co-ordinate checking against objects in an ObjectGroup was not mapped relative to the position of the ObjectGroup on the screen
- Bug fix: Mouse events were dispatched to user interface objects in an ObjectGroup even if the ObjectGroup was switched off (not visible)
- Bug fix: Potential crash if the object with focus is removed from the scene or the scene or group owning the object is deleted (object was not de-focussed first)
- The new Gamepad class (Gamepad.h, included by Simple2DLib.h) provides access to Xbox 360 controllers connected via USB from your applications using XInput
- The Gamepad constructor allows you to specify X and Y deadzones for both sticks, in percent (0-1). The default is 5% in X and 2% in Y, based on controller testing.
- bool CheckConnection() re-tests all controller connections returns true if a controller is connected, false otherwise
- bool GetPort() returns the port (1-4) of the connected controller (0 if not connected) (uses data from previous call to CheckConnection())
- bool Refresh() calls CheckConnection() and if a controller is connected, retrieves its state and makes it available in via a number of methods and public fields. Call Gamepad::Refresh() every frame in your UpdateObjects() function, it will automatically deal with controller connects and disconnects. If Refresh() returns true, a controller is connected and its state is now available; if Refresh() returns false, don’t do any gamepad input processing this frame
- XINPUT_GAMEPAD *GetState() fetches the XINPUT_GAMEPAD object from when the controller state was last retrieved by Refresh(). Only use this if you need a feature which isn’t supported by the Gamepad class.
- bool IsPressed(WORD) returns true if the specified button is currently pressed down (using the data from the last call to Refresh()), eg. IsPressed(XINPUT_GAMEPAD_A) or IsPressed(XINPUT_GAMEPAD_LEFT_SHOULDER)
- void SetDeadzone(float, float) allows you to set the X and Y thumb stick deadzones in percent
- Public fields: leftStickX, leftStickY, rightStickX and rightStickY give the off-center movement of each stick from -1 to 1 (-1 is fully left or up, 1 is fully right or down). A value of 0 indicates the stick is in the specified deadzone; all possible positions outside the deadzone are scaled from 0-1. leftTrigger and rightTrigger return the percentage depressed each trigger is, from 0-1. No deadzone is configurable.
- Public fields: the Buttons field is a std::map of XInput button codes and official button name strings for use in your own applications
- You can configure gamepad support to send keyboard events to your application’s Windows message pump (which will forward them to your OnKeyDown and OnKeyUp functions, the active scene etc.) to minimize the number of changes you need to make to allow existing applications to use the gamepad. Use EnableKeyEvents() and DisableKeyEvents() to toggle this on and off (it is off by default; turning it on will cause key events to be sent to the application’s main window). Use SetWindow(HWND) to send keyboard event messages to the specified window. See the new GamepadWinMsgDemo demo for examples.
- You can map gamepad buttons to keyboard keys to make integration with existing applications easier. Use AddKeyMapping(WORD, int) with an XINPUT_GAMEPAD_* enum value and a virtual key code to add a mapping, and RemoveKeyMapping(int) or RemoveKeyMappingByButton(WORD) to remove it. Mapped buttons will have the corresponding virtual key code sent in Windows key event messages, unmapped buttons will have their XINPUT_GAMEPAD_* enum value sent. See the new GamepadMappingDemo demo for examples.
- You can map the analog sticks and triggers to keyboard keys if their movement amount exceeds a specified threshold. Use AddAnalogKeyMapping(AnalogButtons, float, int) with an analog item enum value, threshold from 0-1 (but must be greater than 0), and a virtual key code to add a mapping, and RemoveAnalogKeyMapping(AnalogButtons) to remove it. Mapped items will have the corresponding virtual key code sent in Windows key event messages; movement of unmapped items will not generate any messages. The values for the AnalogButtons enum are LeftStickLeft, LeftStickRight, LeftStickUp, LeftStickDown, RightStickLeft, RightStickRight, RightStickUp, RightStickDown, LeftTrigger and RightTrigger. See the new GamepadMappingDemo demo for examples.
- If you try to map a button or analog item that has already been mapped, the new mapping will replace the old one. To remove all mappings for digital and analog items, call ClearMappings().
- You can set the repeat interval for buttons or analog movements on the controller in milliseconds. Use SetRepeatIntervalMsAll(int) to set all buttons and analog movements to a fixed repeat interval. Use SetRepeatIntervalMs(WORD, int) (with an XInput enum value) and SetAnalogRepeatIntervalMs(AnalogButtons) to set repeat rates for individual buttons and analog actions. Use a value of 0 to indicate that the button push or movement should not send repeated messages.
- EXPERIMENTAL: The ability to create and consume skins and objects which use them has been added (ISkin<>, specializations, Skin, SkinnedObjectGroup, Dialog). See the SkinnedDialogDemo example for information on how to implement and use skins.
- The _SCL_SECURE_NO_WARNINGS flag is now set in the Simple2D library header
- Bug fix: Simple2DLib.h in Simple2D 1.10 would not compile on Visual Studio 2010 (syntax error due to use of C++11 for (each) construct)
- Bug fix: Simple2D could not be re-compiled by end users because the release libraries were compiled with /GL (Whole Program Optimization). This has been removed
Changes to example applications:
- AsyncHTTPDemo – now attempts to get the Content-Length of the file to download and show how many bytes there are in total
- AsyncHTTPDemo – the notification bar now includes a progress bar when the Content-Length header is present
- AsyncHTTPDemo – now allocates its download buffer memory on the heap instead of the stack; the buffer size is increased from 256K to 64MB and a chunk size has been introduced as the maximum amount to download per iteration of the while loop (64K)
New example applications:
- GamepadTextDemo – shows how to retrieve movement and button information from a connected Xbox 360 controller
- GamepadWinMsgDemo – shows how to configure the gamepad library to send button presses/releases to your OnKeyDown and OnKeyUp functions
- GamepadMappingDemo – shows how to configure the gamepad library to map buttons and analog movements on the game controller to keyboard keys
- SkinnedDialogDemo – shows how to used a skinned dialog box and define custom skins
Known issues in Simple2D 1.11
- Simple2D::TextWidth() returns an incorrect result if the text contains a newline.
- ResolutionX and ResolutionY are not correctly set in the main application constructor
- Gamepad support does not currently support vibration
Download link (always download the latest version)
Please be aware that Simple2D is very much a work in progress, and that changes from version to version can break older code, although I try to maintain backwards compatibility as much as possible. The code is currently undergoing significant re-factoring with each new version.
I hope you find Simple2D useful!
For setup and installation instructions, follow the Simple2D Installation Tutorial.