This commit is contained in:
2025-05-13 02:46:21 +03:00
parent 143e16692e
commit 86914b7fcc
610 changed files with 92343 additions and 2 deletions
+251
View File
@@ -0,0 +1,251 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\GUIButton.cpp" />
<ClCompile Include="src\GUICheckBox.cpp" />
<ClCompile Include="src\GUIComboBox.cpp" />
<ClCompile Include="src\GUIFileBrowser.cpp" />
<ClCompile Include="src\GUIFileBrowserDialog.cpp" />
<ClCompile Include="src\GUIFont.cpp" />
<ClCompile Include="src\GUIFontManager.cpp" />
<ClCompile Include="src\GUIForm.cpp" />
<ClCompile Include="src\GUIList.cpp" />
<ClCompile Include="src\GUIManager.cpp" />
<ClCompile Include="src\GUIMenu.cpp" />
<ClCompile Include="src\GUIMenuItem.cpp" />
<ClCompile Include="src\GUIOverlay.cpp" />
<ClCompile Include="src\GUIOverlayManager.cpp" />
<ClCompile Include="src\GUIPicture.cpp" />
<ClCompile Include="src\GUIPlane.cpp" />
<ClCompile Include="src\GUIProgress.cpp" />
<ClCompile Include="src\GUIPropertyGrid.cpp" />
<ClCompile Include="src\GUIRadioButton.cpp" />
<ClCompile Include="src\GUIRenderWindow.cpp" />
<ClCompile Include="src\GUIScroll.cpp" />
<ClCompile Include="src\GUIScrollablePlane.cpp" />
<ClCompile Include="src\GUISlider.cpp" />
<ClCompile Include="src\GUISplitPanel.cpp" />
<ClCompile Include="src\GUITab.cpp" />
<ClCompile Include="src\GUIText.cpp" />
<ClCompile Include="src\GUITextInput.cpp" />
<ClCompile Include="src\GUIToolStrip.cpp" />
<ClCompile Include="src\GUIToolStripButton.cpp" />
<ClCompile Include="src\GUIToolStripImage.cpp" />
<ClCompile Include="src\GUIToolStripItem.cpp" />
<ClCompile Include="src\GUIToolStripMenu.cpp" />
<ClCompile Include="src\GUITreeNode.cpp" />
<ClCompile Include="src\GUITreeView.cpp" />
<ClCompile Include="src\GUIWindow.cpp" />
<ClCompile Include="src\IGUIRenderer.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\GUIBorder.h" />
<ClInclude Include="src\GUIButton.h" />
<ClInclude Include="src\GUICheckBox.h" />
<ClInclude Include="src\GUIComboBox.h" />
<ClInclude Include="src\GUIFileBrowser.h" />
<ClInclude Include="src\GUIFileBrowserDialog.h" />
<ClInclude Include="src\GUIFont.h" />
<ClInclude Include="src\GUIFontGlyph.h" />
<ClInclude Include="src\GUIFontManager.h" />
<ClInclude Include="src\GUIForm.h" />
<ClInclude Include="src\GUIList.h" />
<ClInclude Include="src\GUIManager.h" />
<ClInclude Include="src\GUIMenu.h" />
<ClInclude Include="src\GUIMenuItem.h" />
<ClInclude Include="src\GUIMenuTextItem.h" />
<ClInclude Include="src\GUIMessaging.h" />
<ClInclude Include="src\GUIOverlay.h" />
<ClInclude Include="src\GUIOverlayManager.h" />
<ClInclude Include="src\GUIPicture.h" />
<ClInclude Include="src\GUIPlane.h" />
<ClInclude Include="src\GUIProgress.h" />
<ClInclude Include="src\GUIPropertyGrid.h" />
<ClInclude Include="src\GUIRadioButton.h" />
<ClInclude Include="src\GUIRenderWindow.h" />
<ClInclude Include="src\GUIScroll.h" />
<ClInclude Include="src\GUIScrollablePlane.h" />
<ClInclude Include="src\GUISlider.h" />
<ClInclude Include="src\GUISplitPanel.h" />
<ClInclude Include="src\GUITab.h" />
<ClInclude Include="src\GUITabPage.h" />
<ClInclude Include="src\GUIText.h" />
<ClInclude Include="src\GUITextInput.h" />
<ClInclude Include="src\GUIToolStrip.h" />
<ClInclude Include="src\GUIToolStripButton.h" />
<ClInclude Include="src\GUIToolStripImage.h" />
<ClInclude Include="src\GUIToolStripItem.h" />
<ClInclude Include="src\GUIToolStripMenu.h" />
<ClInclude Include="src\GUITreeNode.h" />
<ClInclude Include="src\GUITreeView.h" />
<ClInclude Include="src\GUIVertex.h" />
<ClInclude Include="src\GUIWidgetSkin.h" />
<ClInclude Include="src\GUIWindow.h" />
<ClInclude Include="src\IGUICursor.h" />
<ClInclude Include="src\IGUIDataManager.h" />
<ClInclude Include="src\IGUIRenderer.h" />
<ClInclude Include="src\IImage.h" />
<ClInclude Include="src\PropertyItemFile.h" />
<ClInclude Include="src\PropertyItemFloat.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3F1B6A31-4B40-4A4D-A213-35AAE300BA1C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LifeGUI</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>$(ProjectName)_d</TargetName>
<OutDir>$(SolutionDir)$(ProjectName)\lib\</OutDir>
<IntDir>$(SolutionDir)$(ProjectName)\tmp\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>$(ProjectName)_d</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(ProjectName)\lib\</OutDir>
<IntDir>$(SolutionDir)$(ProjectName)\tmp\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)LifeCore\;$(REPO_DIR)\freetype-2.4.3\include</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalDependencies>freetype243_D.lib;</AdditionalDependencies>
<AdditionalLibraryDirectories>$(REPO_DIR)\freetype-2.4.3\objs\win32\vc2008</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)LifeCore\include;$(ProjectDir)include;$(REPO_DIR)\freetype-2.4.3\include</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalDependencies>freetype243_D.lib;</AdditionalDependencies>
<AdditionalLibraryDirectories>$(REPO_DIR)\freetype-2.4.3\objs\win32\vc2008</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)LifeCore\;$(REPO_DIR)\freetype-2.4.3\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalLibraryDirectories>$(REPO_DIR)\freetype-2.4.3\objs\win32\vc2008</AdditionalLibraryDirectories>
<AdditionalDependencies>freetype243.lib;</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+50
View File
@@ -0,0 +1,50 @@
#ifndef GUIBorder_h__
#define GUIBorder_h__
#include <Types.h>
namespace LifeGUI
{
struct GUIBorder
{
int32 Top, Bottom, Left, Right;
GUIBorder()
{
Top = Bottom = Left = Right = 0;
}
GUIBorder(int32 size)
{
Top = Bottom = Left = Right = size;
}
GUIBorder(int32 h_size, int32 v_size)
{
Top = Bottom = v_size;
Left = Right = h_size;
}
GUIBorder(int32 top, int32 bottom, int32 left, int32 right)
{
Top = top;
Bottom = bottom;
Left = left;
Right = right;
}
void SetSize(int size)
{
Top = Bottom = Left = Right = size;
}
void SetSize(int h_size, int v_size)
{
Top = Bottom = v_size;
Left = Right = h_size;
}
void SetSize(int32 top, int32 bottom, int32 left, int32 right)
{
Top = top;
Bottom = bottom;
Left = left;
Right = right;
}
};
}
#endif // GUIBorder_h__
+152
View File
@@ -0,0 +1,152 @@
#include "GUIManager.h"
#include "GUIButton.h"
namespace LifeGUI
{
GUIButton::GUIButton()
:pressed(false), checkable(false)
{
SetStyle(STR("Button"));
// skin = GUIManager::me()->skinDefault[STR("Button")];
caption = new GUIText();
caption->SetPosition(LifeMath::Vec2i(0,0));
caption->SetWidth(this->width);
caption->SetHAlign(HA_CENTER);
caption->SetVAlign(VA_CENTER);
caption->SetHeight(this->height);
caption->SetForeColor(LifeMath::float4(0.0f,0.0f,0.0f,1.0f));
caption->SetBackColor(LifeMath::float4(0.0f,0.0f,0.0f,0.0f));
this->SetBorderColor(LifeMath::float4(0.45f,0.45f,0.45f,1.0f));
caption->SetText(STR("Unnamed button"));
caption->mouseEnabled = false;
this->AddChild(caption);
}
void GUIButton::OnMouseEnter()
{
if(!checkable)
{
this->state = "Hover";
Invalidate();
}
GUIWindow::OnMouseEnter();
}
void GUIButton::Reset()
{
pressed = false;
state = STR("Normal");
Invalidate();
}
void GUIButton::OnMousePress(int x, int y, int key)
{
if(checkable)
{
pressed = !pressed;
if(pressed)
{
state = STR("Hover");
Invalidate();
}
else
{
state = STR("Normal");
Invalidate();
}
}
GUIWindow::OnMousePress(x, y, key);
}
void GUIButton::OnMouseRelease(int x, int y, int key)
{
GUIWindow::OnMouseRelease(x, y, key);
}
void GUIButton::OnMouseLeave()
{
if(!checkable)
{
this->state = "Normal";
Invalidate();
}
GUIWindow::OnMouseLeave();
}
void GUIButton::SetForeColor(LifeMath::float4 color)
{
GUIPlane::SetForeColor(color);
caption->SetForeColor(color);
}
String GUIButton::GetCaption()
{
return caption->GetText();
}
void GUIButton::SetSkin(GUIWidgetSkin* _skin)
{
skin = _skin;
}
void GUIButton::SetCaption(const String& text)
{
caption->SetText(text);
}
void GUIButton::SetWidth(int val)
{
width = val;
caption->SetWidth(val);
Invalidate();
}
void GUIButton::SetHeight(int val)
{
height = val;
caption->SetHeight(val);
Invalidate();
}
GUIButton::~GUIButton()
{
}
void GUIButton::ReleaseFocus()
{
Event_LostFocus.Invoke(this,0);
}
void GUIButton::Update(float dt)
{
/*if(InRect(GUIManager::me()->GetActiveOverlay()->cursorPos, this->GetPositionAbs(), this->width, this->height))
{
if(!mouseCaptured && enabled)
{
mouseCaptured = true;
Event_MouseEnter.Invoke(this,0);
}
if(!PickChild(GUIManager::me()->GetActiveOverlay()->cursorPos))
{
GUIManager::me()->GetActiveOverlay()->SelectFocus(this);
Event_GotFocus.Invoke(this,0);
}
}
else
{
if(mouseCaptured)
{
mouseCaptured = false;
Event_MouseLeave.Invoke(this,0);
}
}*/
// UpdateChilds(dt);
}
/*void GUIButton::Render()
{
if(invalid)
GenGeom();
GUIManager::me()->GetRenderer()->SetPSTexture(skin->texture.ptr(), 0);
GUIManager::me()->GetRenderer()->SetVSConstantBuffer(cb, 0);
GUIManager::me()->GetRenderer()->SetVertexBuffer(vb);
if(borderEnabled)
GUIManager::me()->GetRenderer()->Draw(6*9, 0);
else
GUIManager::me()->GetRenderer()->Draw(6, 0);
RenderChilds();
}*/
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef GUIButton_h__
#define GUIButton_h__
#include "GUIPlane.h"
#include "GUIText.h"
namespace LifeGUI
{
class GUIButton : public GUIPlane
{
private:
GUIText* caption;
bool checkable;
public:
void SetCheckable(bool state) {checkable = state;}
bool GetCheckable(){return checkable; }
bool pressed;
void OnMouseEnter();
void OnMouseLeave();
GUIButton();
virtual ~GUIButton();
void SetWidth(int val);
void SetHeight(int val);
void Update(float dt);
void KeyPress(int key, int modifier);
void SetSkin(GUIWidgetSkin* _skin);
void ReleaseFocus();
void SetCaption(const String& text);
void SetForeColor(LifeMath::float4 color);
String GetCaption();
void Reset();
void OnMousePress(int x, int y, int key);
void OnMouseRelease(int x, int y, int key);
};
}
#endif // GUIButton_h__
+110
View File
@@ -0,0 +1,110 @@
#include "GUICheckBox.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUICheckBox::GUICheckBox()
:_checked(false)
{
box = new GUIPlane();
box->SetStyle(STR("Check"));
box->SetWidth(19);
box->SetHeight(19);
this->AddChild(box);
text = new GUIText();
text->SetText(STR("CheckBox"));
text->SetPosition(LifeMath::Vec2i(box->GetWidth(), 0));
text->SetAutoSize(true);
this->AddChild(text);
text->SetVAlign(VA_CENTER);
box->SetBorderEnabled(false);
text->SetBorderEnabled(false);
box->Event_MouseClick += NewDelegate(this, &GUICheckBox::OnBoxClick);
UpdateLayout();
}
GUICheckBox::~GUICheckBox()
{
if(box)
delete box;
if(text)
delete text;
}
void GUICheckBox::UpdateLayout()
{
int h1, h2;
//
//
h1 = box->GetHeight();
h2 = text->GetHeight();
int text_offset = 5;
if(h1 == h2)
{
this->SetHeight(h1);
box->SetPosition(LifeMath::Vec2i(0,0));
text->SetPosition(LifeMath::Vec2i(box->GetWidth() + text_offset, 0));
}
else if(h1 > h2)
{
this->SetHeight(h1);
box->SetPosition(LifeMath::Vec2i(0,0));
text->SetPosition(LifeMath::Vec2i(box->GetWidth() + text_offset, (h1 - h2) / 2));
}
else
{
this->SetHeight(h2);
box->SetPosition(LifeMath::Vec2i(0,(h2 - h1) / 2));
text->SetPosition(LifeMath::Vec2i(box->GetWidth() + text_offset, 0));
}
this->SetWidth(box->GetWidth() + text->GetWidth() + text_offset);
}
void GUICheckBox::OnBoxClick(GUIWindow* wnd, int v)
{
InternalSetChecked(!_checked);
}
void GUICheckBox::InternalSetChecked(bool state)
{
if(_checked != state)
{
_checked = state;
if(_checked)
{
//box->skin_name = STR("Check:Checked:Back");
box->state = "Pressed";
}
else
{
box->state = "Normal";
//box->skin_name = STR("Check:Unchecked:Back");
}
box->Invalidate();
Event_CheckChanged.Invoke(this);
}
}
bool GUICheckBox::IsChecked()
{
return _checked;
}
void GUICheckBox::SetChecked(bool state)
{
InternalSetChecked(state);
}
void GUICheckBox::SetText(const String& _text)
{
text->SetText(_text);
}
const String& GUICheckBox::GetText()
{
return text->GetText();
}
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef GUICheckBox_h__
#define GUICheckBox_h__
#include "GUIText.h"
#include "GUIPlane.h"
namespace LifeGUI
{
class GUICheckBox : public GUIWindow
{
public:
EVENT1(CheckEvent, GUICheckBox*);
CheckEvent Event_CheckChanged;
GUICheckBox();
~GUICheckBox();
bool IsChecked();
void SetChecked(bool state);
void SetText(const String& _text);
const String& GetText();
private:
void InternalSetChecked(bool state);
void OnBoxClick(GUIWindow* wnd, int v);
bool _checked;
void UpdateLayout();
GUIPlane* box;
GUIText* text;
};
}
#endif // GUICheckBox_h__
+114
View File
@@ -0,0 +1,114 @@
#include "GUIComboBox.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUIComboBox::GUIComboBox()
:list_hidden(true), hide_on_focus_lost(true)
{
this->SetHeight(20);
this->SetWidth(300);
this->SetText(STR("640x480"));
this->SetForeColor(LifeMath::float4(0.74f,0.74f,0.74f,1));
this->SetBackColor(LifeMath::float4(1,1,1,1));
this->SetBorderColor(LifeMath::float4(0.15f,0.15f,0.15f,1.0f));
// this->AddChild(text);
this->SetStyle(STR("Combo"));
arrowButton = new GUIPlane();
this->AddChild(arrowButton);
arrowButton->SetStyle(STR("Combo_arrow"));
arrowButton->SetBorderEnabled(false);
arrowButton->SetBackColor(LifeMath::float4(1,1,1,1));
//arrowButton->Hide();
list = new GUIList();
list->SetWidth(270);
list->SetHeight(100);
list->Hide();
//this->AddChild(list);
list->AddItem(STR("640x480"), 0);
list->AddItem(STR("800x600"), 0);
list->AddItem(STR("1024x768"), 0);
list->AddItem(STR("1280x1024"), 0);
list->AddItem(STR("1600x900"), 0);
list->AddItem(STR("1600x900"), 0);
list->AddItem(STR("100500"), 0);
arrowButton->Event_MouseDown += NewDelegate(this, &GUIComboBox::onArrowClick);
list->Event_LostFocus += NewDelegate(this, &GUIComboBox::OnListLostFocus);
list->Event_ItemSelected += NewDelegate(this, &GUIComboBox::onItemSelected);
UpdateLayout();
}
void GUIComboBox::UpdateLayout()
{
LifeMath::Rect2i r = this->GetClientRectangle();
arrowButton->SetWidth(14);
arrowButton->SetHeight(r.height);
arrowButton->SetPosition(LifeMath::Vec2i(r.width - r.height, 0));
}
void GUIComboBox::onArrowClick(GUIWindow* sender, int args)
{
if(list_hidden)
{
if(hide_on_focus_lost)
ShowList();
else
hide_on_focus_lost = true;
}
else
{
HideList();
}
}
/*void GUIComboBox::ReleaseFocus()
{
list->Hide();
Event_LostFocus.Invoke(this, 0);
}*/
void GUIComboBox::OnListLostFocus(GUIWindow* wnd, int p)
{
HideList();
if(arrowButton->GetClientRectangleAbs().InRect(FindOverlay()->cursorPos))
hide_on_focus_lost = false;
}
void GUIComboBox::ShowList()
{
if(list_hidden)
{
list_hidden = false;
LifeMath::Vec2i pos = this->GetPositionAbs();
pos.Y+= this->GetHeight();
list->SetPosition(pos);
list->Show();
FindOverlay()->AddChild(list);
FindOverlay()->SetFocusWindow(list);
}
}
void GUIComboBox::HideList()
{
if(!list_hidden)
{
list_hidden = true;
list->Hide();
FindOverlay()->RemoveChild(list->hwnd);
/* if(FindOverlay()->IsFocusWindow(list))
{
FindOverlay()->SetFocusWindow(NULL);
}**/
}
}
GUIComboBox::~GUIComboBox()
{
}
void GUIComboBox::onItemSelected(GUIWindow* sender, const String& text, void* data)
{
this->SetText(text);
FindOverlay()->SetFocusWindow(NULL);
}
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef GUIComboBox_h__
#define GUIComboBox_h__
#include "GUIWindow.h"
#include "GUITextInput.h"
#include "GUIButton.h"
#include "GUIPlane.h"
#include "GUIList.h"
namespace LifeGUI
{
class GUIComboBox : public GUITextInput
{
public:
GUIComboBox();
~GUIComboBox();
private:
bool hide_on_focus_lost;
bool list_hidden;
void UpdateLayout();
GUIPlane* arrowButton;
GUIList* list;
void OnListLostFocus(GUIWindow* wnd, int p);
void ShowList();
void HideList();
void onItemSelected(GUIWindow* sender, const String& text, void* data);
void onArrowClick(GUIWindow* sender, int args);
};
}
#endif // GUIComboBox_h__
+142
View File
@@ -0,0 +1,142 @@
#include "GUIFileBrowser.h"
namespace LifeGUI
{
GUIFileBrowser::GUIFileBrowser()
{
currentDir = STR("root");
this->Event_Resize += NewDelegate(this, &GUIFileBrowser::OnResize);
backButton = new GUIButton();
backButton->SetCaption(STR("..."));
backButton->SetBackColor(LifeMath::float4(1,0,0,1));
this->AddChild(backButton);
backButton->Event_MouseClick += NewDelegate(this, &GUIFileBrowser::OnNavigateBack);
}
GUIFileBrowser::~GUIFileBrowser()
{
}
void GUIFileBrowser::OnNavigateBack(GUIWindow* wnd, int i)
{
LifeCore::IFolder* folder;
if(fileSystem->GetFolder(currentDir, &folder) == SC_OK)
{
/*if(fileSystem->GetFolder(folder->getPath(), &folder) == SC_OK)
{
ScanFolder(folder);
}*/
LifeCore::IFolder* parent = folder->getParent();
if(parent)
{
SetDirectory(parent->getPath());
//ScanFolder(parent);
}
else
{
SetDirectory(folder->getPath());
//ScanFolder(folder);
}
}
}
void GUIFileBrowser::SetFileSystem(LifeCore::IFileSystem* fs)
{
fileSystem = fs;
LifeCore::IFolder* folder;
if(fileSystem->GetFolder(currentDir, &folder) == SC_OK)
{
ScanFolder(folder);
}
}
void GUIFileBrowser::OnFolderExpand(GUIWindow* wnd, int i)
{
printf("Folder expand begin!\n");
int id = (int)wnd->UserData;
LifeCore::IFolder* f;
if(fileSystem->GetFolder(currentDir, &f) == SC_OK)
{
LifeCore::IFolder* sf = f->GetFolder(id);
SetDirectory(sf->getPath());
}
printf("Folder expand end!\n");
}
void GUIFileBrowser::ScanFolder(LifeCore::IFolder* folder)
{
for(FileCollectionItr it = filesToDelete.begin(); it != filesToDelete.end(); ++it)
{
delete (*it);
}
filesToDelete.clear();
//
for(FileCollectionItr it = files.begin(); it != files.end(); ++it)
{
this->RemoveChild((*it)->hwnd);
filesToDelete.push_back((*it));
//delete (*it);
}
files.clear();
for(int i = 0; i < folder->folderCount; i++)
{
LifeCore::IFolder* f = folder->GetFolder(i);
GUIButton* b = new GUIButton();
this->AddChild(b);
files.push_back(b);
b->UserData = (void*)i;
b->Event_MouseClick += NewDelegate(this, &GUIFileBrowser::OnFolderExpand);
b->SetCaption(f->Name);
}
for(int i = 0; i < folder->fileCount; i++)
{
LifeCore::IFile* f = folder->GetFile(i);
GUIButton* b = new GUIButton();
this->AddChild(b);
files.push_back(b);
b->UserData = (void*)i;
b->SetBackColor(LifeMath::float4(0,1,0,1));
b->Event_MouseClick += NewDelegate(this, &GUIFileBrowser::OnSelectFile);
//b->Event_MouseClick += NewDelegate(this, &GUIFileBrowser::OnFolderExpand);
b->SetCaption(f->FileName);
}
Format();
}
void GUIFileBrowser::OnResize(GUIWindow* wnd)
{
Format();
}
void GUIFileBrowser::Format()
{
int lineHeight = 19;
int cnt = files.size();
backButton->SetPosition(LifeMath::Vec2i(0,0));
backButton->SetWidth(25);
backButton->SetHeight(lineHeight);
for(int i = 0; i < cnt; i++)
{
GUIButton* b = files[i];
b->SetHeight(lineHeight);
b->SetPosition(LifeMath::Vec2i(0, (i + 1) * lineHeight));
b->SetWidth(this->GetClientRectangle().width);
}
}
void GUIFileBrowser::SetDirectory(const String& path)
{
currentDir = path;
LifeCore::IFolder* folder;
if(fileSystem->GetFolder(currentDir, &folder) == SC_OK)
{
ScanFolder(folder);
}
}
const String& GUIFileBrowser::GetSelectedFile()
{
return selectedFile;
}
void GUIFileBrowser::OnSelectFile(GUIWindow* wnd, int i)
{
selectedFile = currentDir + STR("/") + ((GUIButton*)wnd)->GetCaption();
Event_SelectedFile.Invoke(this);
}
}
+38
View File
@@ -0,0 +1,38 @@
#ifndef GUIFileBrowser_h__
#define GUIFileBrowser_h__
#include "GUIScrollablePlane.h"
#include "GUIButton.h"
#include <vfs/IFileSystem.h>
#include <vector>
namespace LifeGUI
{
class GUIFileBrowser : public GUIScrollablePlane
{
public:
EVENT1(FileBrowserEvent, GUIFileBrowser*);
FileBrowserEvent Event_SelectedFile;
GUIFileBrowser();
~GUIFileBrowser();
void SetFileSystem(LifeCore::IFileSystem* fs);
void SetDirectory(const String& path);
const String& GetSelectedFile();
private:
void OnSelectFile(GUIWindow* wnd, int i);
void OnNavigateBack(GUIWindow* wnd, int i);
void OnFolderExpand(GUIWindow* wnd, int i);
void Format();
void OnResize(GUIWindow* wnd);
void ScanFolder(LifeCore::IFolder* folder);
LifeCore::IFileSystem* fileSystem;
String currentDir;
String selectedFile;
typedef std::vector<GUIButton*> FileCollection;
typedef std::vector<GUIButton*>::iterator FileCollectionItr;
GUIButton* backButton;
FileCollection files;
FileCollection filesToDelete;
};
}
#endif // GUIFileBrowser_h__
+34
View File
@@ -0,0 +1,34 @@
#include "GUIFileBrowserDialog.h"
namespace LifeGUI
{
GUIFileBrowserDialog::GUIFileBrowserDialog()
{
browser = new GUIFileBrowser();
this->AddChild(browser);
browser->SetPosition(LifeMath::Vec2i(5, 5));
browser->SetBackColor(LifeMath::float4(0,1,0,1));
browser->SetWidth(200);
browser->SetHeight(150);
browser->Event_SelectedFile += NewDelegate(this, &GUIFileBrowserDialog::OnSelectFile);
}
GUIFileBrowserDialog::~GUIFileBrowserDialog()
{
}
const String& GUIFileBrowserDialog::GetSelectedFile()
{
return browser->GetSelectedFile();
}
void GUIFileBrowserDialog::OnSelectFile(GUIFileBrowser* browser)
{
this->Event_SelectedFile.Invoke(this);
}
void GUIFileBrowserDialog::SetFileSystem(LifeCore::IFileSystem* fs)
{
browser->SetFileSystem(fs);
}
void GUIFileBrowserDialog::SetDirectory(const String& path)
{
browser->SetDirectory(path);
}
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef GUIFileBrowserDialog_h__
#define GUIFileBrowserDialog_h__
#include "GUIForm.h"
#include "GUIFileBrowser.h"
namespace LifeGUI
{
class GUIFileBrowserDialog : public GUIForm
{
public:
EVENT1(FileBrowserDialogEvent, GUIFileBrowserDialog*);
FileBrowserDialogEvent Event_SelectedFile;
GUIFileBrowserDialog();
~GUIFileBrowserDialog();
void SetFileSystem(LifeCore::IFileSystem* fs);
void SetDirectory(const String& path);
const String& GetSelectedFile();
private:
GUIFileBrowser* browser;
void OnSelectFile(GUIFileBrowser* browser);
};
}
#endif // GUIFileBrowserDialog_h__
+137
View File
@@ -0,0 +1,137 @@
#include "GUIFont.h"
#include "GUIManager.h"
#include <ft2build.h>
#include <IDataRectangle.h>
#include FT_FREETYPE_H
namespace LifeGUI
{
int GUIFont::MeasureString(const std::wstring& text)
{
int size = text.size();
const wchar_t* str = text.c_str();
int stringSize = 0;
if(size == 0)
return 0;
else if(size == 1)
{
return GetGlyph(str[0])->Width;
}
for(int i = 0; i < size; i++)
{
if(str[i] == 0x0020)
{
stringSize += spaceSize;
}
else
{
GUIFontGlyph* glyph = GetGlyph(str[i]);
stringSize += glyph->hor_advance;
}
}
return stringSize;
}
GUIFont::GUIFont(LifeCore::Range<unsigned long>* charRange, int rangeCount){
FT_Library ftLib;
FT_Face ftFontFace;
FT_Init_FreeType(&ftLib);
LifeCore::IFile* font;
GUIManager::me()->GetDataManager()->getFileSystem()->GetFile(AS_STRING("root/Data/Fonts/arial.ttf"), &font);
if(!font){
printf("Font not found!");
return;
}
LifeCore::IDataStreamPtr stm = font->OpenRead();
printf("Font size: %i\n", stm->Length());
FT_Byte* data = new FT_Byte[stm->Length()];
stm->Read(data,stm->Length());
//create font face
FT_New_Memory_Face(ftLib, data,stm->Length(),0, &ftFontFace);
//font size (hardcoded yet : ( )
int size = 10;
FT_Set_Char_Size(ftFontFace, size << 6, size << 6, 96, 96);
//size of "space" character. I dunno where to get it, so i hardcoded it in my way ))
spaceSize = size / 4 * 3;
stm.release();
//text string height
stringHeight = (ftFontFace->size->metrics.height >> 6);
//hardcoded size of target font map. Baaaaad.....
int texW = 600, texH = 600;
font_tex = GUIManager::me()->GetDataManager()->createImage(texW, texH);
LifeCore::IDataRectangle* texData = font_tex->Map(0,0,1);
texData->data.Clear(0xff);
int xOffset = 0, yOffset = 0, curRowMaxHeight = 0;
//render symbol ranges to texture
for(int rc = 0; rc <rangeCount; rc++)//for each range
{
//render each character to texture
for(ULONG i = charRange[rc].RangeStart; i <= charRange[rc].RangeEnd; i++)
{
FT_UInt index = FT_Get_Char_Index(ftFontFace, i);
FT_Load_Glyph(ftFontFace,index,0);
FT_Render_Glyph(ftFontFace->glyph, FT_RENDER_MODE_NORMAL);
FT_Bitmap bm = ftFontFace->glyph->bitmap;
if((xOffset + bm.width + 1) >= texW)
{
yOffset += stringHeight;
curRowMaxHeight = 0;
xOffset = 0;
}
GUIFontGlyph* glyph = new GUIFontGlyph();
glyph->Character = i;
glyph->X = xOffset + ftFontFace->glyph->bitmap_left;
glyph->Y = yOffset + (stringHeight - ftFontFace->glyph->bitmap_top);
glyph->Width = bm.width;
glyph->Height = bm.rows;
glyph->U = (float)glyph->X / (float)texW;
glyph->V = (float)glyph->Y / (float)texH;
glyph->TexW = (float)glyph->Width / (float)texW;
glyph->TexH = (float)glyph->Height / (float)texH;
glyph->Width = ftFontFace->glyph->metrics.width >> 6;
glyph->topOffset = ((ftFontFace->size->metrics.ascender) >> 6) - ((ftFontFace->glyph->metrics.horiBearingY) >> 6);
glyph->leftOffset = (ftFontFace->glyph->metrics.horiBearingX >> 6);
glyph->hor_advance = (ftFontFace->glyph->advance.x >> 6);\
glyphs[static_cast<wchar_t>(i)] = glyph;
for(int ty = 0; ty < bm.rows; ty++) for(int tx = 0; tx < bm.width; tx++){
int bigX = tx + xOffset + ftFontFace->glyph->bitmap_left;
int bigY = ty + yOffset + (stringHeight - ftFontFace->glyph->bitmap_top);
texData->data.Seek((bigY*(texData->pitch/4)+bigX)* font_tex->GetPixelSize());
unsigned char tc = bm.buffer[(ty * bm.pitch + tx)];
unsigned int color = 0x00ffffff | (tc << 24);
texData->data.Write(&color, 4);
}
xOffset+= (ftFontFace->glyph->advance.x >> 6) + 1;
}
}
FT_Done_Face(ftFontFace);
FT_Done_FreeType(ftLib);
font_tex->Unmap(0);
delete[] data;
}
GUIFont::~GUIFont()
{
}
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef GUIFONT_h__
#define GUIFONT_h__
//#include "Globals.h"
#include "Range.h"
#include "GUIFontGlyph.h"
#include "IImage.h"
#include <map>
#include "LString.h"
#include <vfs/IFileSystem.h>
namespace LifeGUI
{
class GUIFont
{
public:
int stringHeight;
IImage* font_tex;
int trololo;
GUIFontGlyph* GetGlyph(wchar_t name)
{
GUIFontGlyph* g = glyphs[name];
if(g)
return g;
std::map<wchar_t, GUIFontGlyph*>::iterator it = glyphs.begin();
return it->second;
}
GUIFont(LifeCore::Range<unsigned long>* charRange, int rangeCount);
~GUIFont();
int spaceSize;
int MeasureString(const std::wstring& text);
private:
std::map<wchar_t, GUIFontGlyph*> glyphs;
};
}
#endif
+20
View File
@@ -0,0 +1,20 @@
#ifndef GUIFONTGLYPH_H__
#define GUIFONTGLYPH_H__
namespace LifeGUI
{
class GUIFontGlyph
{
public:
GUIFontGlyph(){}
~GUIFontGlyph(){}
int Width, Height, X, Y;
float U, V, TexW, TexH;
int topOffset;
int leftOffset;
unsigned long Character;
int hor_advance;
};
}
#endif
+8
View File
@@ -0,0 +1,8 @@
#include "GUIFontManager.h"
namespace LifeGUI
{
GUIFont* GUIFontManager::GetFont(const String& font_name){
return nullptr;
}
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef GUIFontManager_h__
#define GUIFontManager_h__
#include <array>
#include <vector>
#include <LString.h>
#include "GUIFont.h"
namespace LifeGUI
{
class GUIFontManager{
public:
GUIFontManager();
GUIFont* GetFont(const String& font_name);
private:
typedef std::vector<GUIFont*> FontCollection;
typedef std::vector<GUIFont*>::iterator FontCollectionIt;
FontCollection fonts;
};
}
#endif // GUIFontManager_h__
+85
View File
@@ -0,0 +1,85 @@
#include "GUIForm.h"
#include "GUIOverlay.h"
namespace LifeGUI
{
GUIForm::GUIForm()
:drag(false)
{
pText = new GUIText();
pText->SetText(STR("Unnamed window"));
this->AddChild(pText);
pText->NonClientControl = true;
Border.SetSize(5);
Border.Top = 24;
pText->SetPosition(LifeMath::Vec2i(0, -Border.Top));
pText->SetHeight(Border.Top);
pText->SetVAlign(VA_CENTER);
pText->SetWidth(this->GetWidth());
pText->skip_mouse = true;
this->Event_Resize += NewDelegate(this, &GUIForm::OnResize);
//pText->SetAutoSize(true);
}
GUIForm::~GUIForm()
{
}
void GUIForm::OnResize(GUIWindow* wnd)
{
pText->SetWidth(this->GetWidth());
}
void GUIForm::SetText(const String& text)
{
pText->SetText(text);
}
void GUIForm::OnNCMousePress(int x, int y, int key)
{
LifeMath::Rect2i r = this->GetRectangleAbs();
r.height = Border.Top;
if(r.InRect(x, y))//click on window header
{
drag = true;
dragOffset = LifeMath::Vec2i(x, y) - this->GetPositionAbs();
FindOverlay()->GrabMouse(this);
}
else
{
drag = false;
}
GUIWindow::OnNCMousePress(x, y, key);
}
void GUIForm::OnNCMouseRelease(int x, int y, int key)
{
if(drag)
FindOverlay()->ReleaseMouse();
drag = false;
GUIWindow::OnNCMouseRelease(x, y, key);
}
void GUIForm::OnMouseRelease(int x, int y, int key)
{
if(drag)
FindOverlay()->ReleaseMouse();
drag = false;
GUIWindow::OnMouseRelease(x, y, key);
}
void GUIForm::OnNCMouseMove(int abs_x, int abs_y, int rel_x, int rel_y)
{
GUIWindow::OnNCMouseMove(abs_x, abs_y, rel_x, rel_y);
}
void GUIForm::OnMouseMove(int abs_x, int abs_y, int rel_x, int rel_y)
{
if(drag)
{
LifeMath::Vec2i pos = LifeMath::Vec2i(abs_x, abs_y) - dragOffset;
if(this->GetParent())
{
pos = this->GetParent()->CursorToLocal(pos);
}
this->SetPosition(pos);
}
GUIWindow::OnNCMouseMove(abs_x, abs_y, rel_x, rel_y);
}
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef GUIForm_h__
#define GUIForm_h__
#include "GUIPlane.h"
#include "GUIText.h"
#include "GUIButton.h"
namespace LifeGUI
{
class GUIForm : public GUIPlane
{
public:
GUIForm();
~GUIForm();
void SetText(const String& text);
private:
LifeMath::Vec2i dragOffset;
bool drag;
GUIText* pText;
GUIButton* pButtonClose;
void OnResize(GUIWindow* wnd);
void OnNCMousePress(int x, int y, int key);
void OnNCMouseRelease(int x, int y, int key);
void OnNCMouseMove(int abs_x, int abs_y, int rel_x, int rel_y);
void OnMouseMove(int abs_x, int abs_y, int rel_x, int rel_y);
void OnMouseRelease(int x, int y, int key);
};
}
#endif // GUIForm_h__
+85
View File
@@ -0,0 +1,85 @@
#include "GUIList.h"
namespace LifeGUI
{
GUIList::GUIList()
:max_visible_items(4), AutoHeight(true)
{
NeedKeyFocus = true;
WindowStyle = GWS_POPUP;
this->SetBorderColor(LifeMath::float4(0.0f,0.0f,0.0f,1.0f));
this->Event_Resize += NewDelegate(this, &GUIList::OnResizeList);
}
GUIList::~GUIList()
{
}
void GUIList::OnResizeList(GUIWindow* e)
{
int cnt = items.size();
int w = this->GetClientRectangle().width;
for(int i = 0; i < cnt; i++)
{
items[i]->SetWidth(w);
}
}
void GUIList::itemMouseEnter(GUIWindow* e, int a)
{
GUIButton* b = (GUIButton*)e;
e->SetBackColor(LifeMath::float4(1,1,1,1));
e->SetForeColor(LifeMath::float4(0.05f,0.05f,0.05f,1));
//e->state = STR("Hover");
//e->Invalidate();
}
void GUIList::itemMouseLeave(GUIWindow* e, int a)
{
GUIButton* b = (GUIButton*)e;
e->SetBackColor(LifeMath::float4(1,1,1,1));
e->SetForeColor(LifeMath::float4(1,1,1,1));
//e->state = STR("Normal");
//e->Invalidate();
}
void GUIList::SetBackColor(const LifeMath::float4& color)
{
GUIScrollablePlane::SetBackColor(color);
}
void GUIList::SelectItem(GUIWindow* e, int a)
{
String text = ((GUIButton*)e)->GetCaption();
this->Event_ItemSelected.Invoke(this, text, e->UserData);
}
void GUIList::ReleaseFocus()
{
Event_LostFocus.Invoke(this, 0);
}
void GUIList::AddItem(const String& text, void* data)
{
GUIButton* b = new GUIButton();
b->SetWidth(this->GetClientRectangle().width);
b->SetHeight(18);
b->SetCaption(text);
b->SetBorderEnabled(false);
b->SetBackColor(LifeMath::float4(1,1,1,1));
b->SetForeColor(LifeMath::float4(1,1,1,1));
b->SetStyle(STR("Combo_list"));
b->UserData = data;
this->AddChild(b);
int c = items.size();
b->SetPosition(LifeMath::Vec2i(0, c * 18));
b->Event_MouseDown += NewDelegate(this, &GUIList::SelectItem);
b->Event_MouseEnter += NewDelegate(this, &GUIList::itemMouseEnter);
b->Event_MouseLeave += NewDelegate(this, &GUIList::itemMouseLeave);
items.push_back(b);
if(AutoHeight)
{
if(items.size() <= max_visible_items)
this->SetHeight(items.size() * 18 + 2);
else
{
this->SetHeight(max_visible_items * 18 + 2);
}
}
}
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef GUIList_h__
#define GUIList_h__
#include "GUIWindow.h"
#include "GUIPlane.h"
#include "GUIScrollablePlane.h"
#include "GUIButton.h"
namespace LifeGUI
{
class GUIList : public GUIScrollablePlane
{
public:
bool AutoHeight;
EVENT3(ListEvent, GUIWindow*, const String&, void*);
ListEvent Event_ItemSelected;
GUIList();
~GUIList();
void SetBackColor(const LifeMath::float4& color);
void ReleaseFocus();
void AddItem(const String& text, void* data);
private:
void OnResizeList(GUIWindow* e);
size_t max_visible_items;
typedef std::vector<GUIButton*> ItemList;
ItemList items;
void SelectItem(GUIWindow* e, int a);
void itemMouseEnter(GUIWindow* e, int a);
void itemMouseLeave(GUIWindow* e, int a);
};
}
#endif // GUIList_h__
+440
View File
@@ -0,0 +1,440 @@
#include "GUIManager.h"
namespace LifeGUI
{
IGUIRenderer* GUIManager::GetRenderer()
{
return guiRenderer;
}
IGUIDataManager* GUIManager::GetDataManager(){
return guiDataManager;
}
void GUIManager::Init(IGUIRenderer* renderer, IGUIDataManager* data_manager)
{
guiRenderer = renderer;
guiDataManager = data_manager;
IImage* main_skin;
main_skin = guiDataManager->getImage(STR("design_black_orange3.dds"));
//DIFF = main_skin;
DIFF = guiDataManager->getImage(AS_STRING("White.bmp"));
cursorTex = guiDataManager->getImage(AS_STRING("mouse.png"));
LifeCore::IFile* sf;
guiDataManager->getFileSystem()->GetFile(String(STR("root/Data/GUI/Default.mmf")), &sf);
LifeCore::IDataStreamPtr stm = sf->OpenRead();
char buf[2];
buf[1] = '\0';
int str_num = 0;
String str;
int tw, th;
String prev_skin;
GUIWidgetSkin* skin_tmp;
std::vector<String> coll;
while(stm->Read(&buf[0], 1))
{
if(buf[0] == '\n')
{
if(str != STR(""))
{
String tmp;
//parse main skin texture info
if(str_num == 0)
{
size_t pos2;
size_t pos = str.find_first_of(STR(":"));
tmp = str.substr(0, pos);
tw = StrToInt(tmp);
pos++;
pos2 = pos;
pos = str.find_first_of(STR(":"), pos2);
tmp = str.substr(pos2, pos);
th = StrToInt(tmp);
pos++;
pos2 = pos;
//pos = str.find_first_of(STR(":"), pos2);
tmp = str.substr(pos2, str.size());
//main_skin = guiRenderer->GetImage(tmp);
}
else
{//
coll.clear();
SplitString(str, &coll, ':');
//new skin!
if(prev_skin != coll[0])
{
prev_skin = coll[0];
if(coll[0] != STR("Cursor"))
skin_tmp = new GUIWidgetSkin(main_skin);
else
skin_tmp = new GUIWidgetSkin(cursorTex);
skinDefault[coll[0]] = skin_tmp;
}
int i1,i2,i3,i4;
i1 = StrToInt(coll[3]);
i2 = StrToInt(coll[4]);
i3 = StrToInt(coll[5]);
i4 = StrToInt(coll[6]);
//if(!skin_tmp->GetState(coll[1]))
//{
skin_tmp->AddState(coll[1]);
//}
skin_tmp->states[coll[1]]->AddElement(coll[2], LifeMath::Vec4i(i1, i2, i3, i4));
}
}
str_num++;
str= STR("");
}
else
{
str = str + String(&buf[0]);
}
}
//create default skin
GUIWidgetSkin* skin = new GUIWidgetSkin(guiDataManager->getImage(STR("Button.bmp")));
/* GUISkinState* normal = skin->AddState("Normal");
//border defines
normal->AddElement("BorderLeft", LifeMath::Vec4i(5,6,7,9));
normal->AddElement("BorderRight", LifeMath::Vec4i(12,6,14,9));
normal->AddElement("BorderTop", LifeMath::Vec4i(8,3,11,5));
normal->AddElement("BorderBottom", LifeMath::Vec4i(8,10,11,12));
normal->AddElement("CornerTopLeft", LifeMath::Vec4i(5,3,7,5));
normal->AddElement("CornerTopRight", LifeMath::Vec4i(12,3,14,5));
normal->AddElement("CornerBottomLeft", LifeMath::Vec4i(5,10,7,12));
normal->AddElement("CornerBottomRight", LifeMath::Vec4i(12,10,14,12));
normal->AddElement("Background", LifeMath::Vec4i(30,32,35,57));
skinDefault[STR("Button")] = skin;*/
LifeCore::Range<unsigned long> r[] =
{
LifeCore::Range<unsigned long>(0x0410, 0x044f),//russian characters
LifeCore::Range<unsigned long>(0x0041, 0x007A),//latin characters
LifeCore::Range<unsigned long>(0x0019, 0x002f), //space
LifeCore::Range<unsigned long>(0x0030, 0x0040) //space
};
font = new GUIFont(r, 4);
}
int GUIManager::GetNewID()
{
return lastID++;
}
GUIOverlay* GUIManager::GetActiveOverlay()
{
return curOverlay;
}
/*bool GUIManager::KeyDown( LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str )
{
if(curOverlay)
curOverlay->OnKeyDown(key, text, str);
return true;
//return curOverlay->KeyDown(key, text);
}
bool GUIManager::KeyUp( LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str )
{
return true;
}
bool GUIManager::MouseMove( int absX, int relX, int absY, int relY)
{
if(curOverlay)
{
curOverlay->OnMouseMove(absX, absY, relX, relY);
}
return true;
}
bool GUIManager::MousePressed( LifeCore::KeyCodes::Key button)
{
if(curOverlay)
{
curOverlay->OnMousePress(curOverlay->cursorPos.X, curOverlay->cursorPos.Y, button);
}
return false;
}
bool GUIManager::MouseReleased( LifeCore::KeyCodes::Key button)
{
if(curOverlay)
{
curOverlay->OnMouseRelease(curOverlay->cursorPos.X, curOverlay->cursorPos.Y, button);
}
return false;
}*/
int GUIManager::GetWidth()
{
return scrW;
}
int GUIManager::GetHeight()
{
return scrH;
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, LifeMath::float2 tile)
{
LifeMath::float4 color(1.0f, 1.0f, 1.0f, 1.0f);
return GUIManager::GenQuad(layer, scissor, position, width, height, pBuffer, 0.0f, 0.0f, 1.0f, 1.0f,color,color,color,color, tile);
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, const LifeMath::float4& col, LifeMath::float2 tile)
{
return GUIManager::GenQuad(layer, scissor, position, width, height, pBuffer, 0.0f, 0.0f, 1.0f, 1.0f,col,col,col,col, tile);
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, const LifeMath::float4& col, float texOffX, float texOffY, float texWX, float texWY, LifeMath::float2 tile)
{
return GUIManager::GenQuad(layer, scissor, position, width, height, pBuffer, texOffX, texOffY, texWX, texWY,col,col,col,col,tile);
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, float texOffX, float texOffY, float texWX, float texWY, LifeMath::float2 tile)
{
LifeMath::float4 color(1.0f, 1.0f, 1.0f, 1.0f);
return GUIManager::GenQuad(layer, scissor, position, width, height, pBuffer, texOffX, texOffY, texWX, texWY,color,color,color,color, tile);
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, float texOffX, float texOffY, float texWX, float texWY, const LifeMath::float4& color0, const LifeMath::float4& color1, const LifeMath::float4& color2, const LifeMath::float4& color3, const LifeMath::float2& tile)
{
//if quad is outside of scissor
if(position.X > scissor.GetMaxX()) return 0;
if(position.Y > scissor.GetMaxY()) return 0;
if((position.X + width) < scissor.x) return 0;
if((position.Y + height) < scissor.y) return 0;
//cut left side
if(scissor.x > position.X)
{
int offset = scissor.x - position.X;
float pc = float(offset) / (float)width;
position.X += offset;
width -= offset;
float to = texWX * pc;
texOffX += to;
texWX -= to;
}
//cut right side
if(scissor.GetMaxX() < (position.X + width))
{
int offset = (position.X + width) - scissor.GetMaxX();
float pc = float(offset) / (float)width;
width -= offset;
float to = texWX * pc;
texWX -= to;
}
//cut top side
if(scissor.y > position.Y)
{
int offset = scissor.y - position.Y;
float pc = float(offset) / (float)height;
position.Y += offset;
height -= offset;
float to = texWY * pc;
texOffY += to;
texWY -= to;
}
//cut bottom side
if(scissor.GetMaxY() < (position.Y + height))
{
int offset = (position.Y + height) - (scissor.GetMaxY());
float pc = float(offset) / (float)height;
height -= offset;
float to = texWY * pc;
texWY -= to;
}
//width -=1;
//height -=1;
pBuffer[0] = GUIVertex(LifeMath::float3(static_cast<float>(position.X), static_cast<float>(position.Y), (float)layer), color0, LifeMath::float4(0, 0, tile.X, tile.Y), LifeMath::float4(texOffX, texOffY, texWX, texWY)); //0
pBuffer[1] = GUIVertex(LifeMath::float3(static_cast<float>(position.X + width), static_cast<float>(position.Y), (float)layer), color1, LifeMath::float4(tile.X, 0, tile.X, tile.Y), LifeMath::float4(texOffX, texOffY, texWX, texWY)); //1
pBuffer[2] = GUIVertex(LifeMath::float3(static_cast<float>(position.X + width),static_cast<float>( position.Y + height), (float)layer), color2, LifeMath::float4(tile.X, tile.Y, tile.X, tile.Y), LifeMath::float4(texOffX, texOffY, texWX, texWY)); //2
pBuffer[3] = GUIVertex(LifeMath::float3(static_cast<float>(position.X), static_cast<float>(position.Y), (float)layer), color0, LifeMath::float4(0, 0, tile.X, tile.Y), LifeMath::float4(texOffX, texOffY, texWX, texWY)); //1
pBuffer[4] = GUIVertex(LifeMath::float3(static_cast<float>(position.X + width), static_cast<float>(position.Y + height), (float)layer), color2, LifeMath::float4(tile.X, tile.Y, tile.X, tile.Y), LifeMath::float4(texOffX, texOffY, texWX, texWY)); //2
pBuffer[5] = GUIVertex(LifeMath::float3(static_cast<float>(position.X), static_cast<float>(position.Y + height), (float)layer), color3, LifeMath::float4(0, tile.Y, tile.X, tile.Y), LifeMath::float4(texOffX, texOffY, texWX, texWY)); //3
return 6;
}
int GUIManager::GenFrame(int layer, const LifeMath::Rect2i& scissor, int width, int height, LifeGUI::GUIBorder* border, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer)
{
return GenFrame(layer, scissor, 0, 0, width, height, border, color, pBuffer);
}
int GUIManager::GenFrame(int layer, const LifeMath::Rect2i& scissor, int x, int y,int width, int height, LifeGUI::GUIBorder* border, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer)
{
//1 2 3
//
//4 5
//
//6 7 8
LifeMath::Vec2i pos(x, y);
int offset = 0;
//top left corner
offset += GenQuad(layer, scissor, LifeMath::Vec2i(0,0) + pos, border->Left, border->Top, pBuffer + offset, color, 0.0f, 0.0f,0.0f,0.0f);
//top center
offset += GenQuad(layer, scissor, LifeMath::Vec2i(border->Left,0) + pos, width - (border->Left + border->Right), border->Top, pBuffer + offset, color, 0.0f, 0.0f,0.0f,0.0f);
//top right corner
offset += GenQuad(layer, scissor, LifeMath::Vec2i(width - border->Right, 0) + pos, border->Right, border->Top, pBuffer + offset, color, 0.0f, 0.0f,0.0f,0.0f);
//left center
offset += GenQuad(layer, scissor, LifeMath::Vec2i(0, border->Top) + pos, border->Left, height - (border->Top + border->Bottom), pBuffer + offset, color, 0.0f, 0.0f,0.0f,0.0f);
//right center
offset += GenQuad(layer, scissor, LifeMath::Vec2i(width - border->Right, border->Top) + pos, border->Right, height - (border->Top + border->Bottom), pBuffer + offset, color, 0.0f, 0.0f,0.0f,0.0f);
//bottom left corner
offset += GenQuad(layer, scissor, LifeMath::Vec2i(0,height - border->Bottom ) + pos, border->Left, border->Bottom, pBuffer + offset, color, 0.0f, 0.0f,0.0f,0.0f);
//bottom center
offset += GenQuad(layer, scissor, LifeMath::Vec2i(border->Left,height - border->Bottom) + pos, width - (border->Left + border->Right), border->Bottom, pBuffer + offset, color, 0.0f, 0.0f,0.0f,0.0f);
//bottom right corner
offset += GenQuad(layer, scissor, LifeMath::Vec2i(width - border->Right, height - border->Bottom) + pos, border->Right, border->Bottom, pBuffer + offset, color, 0.0f, 0.0f,0.0f,0.0f);
return offset;
}
int GUIManager::GenFrame(int layer, const LifeMath::Rect2i& scissor, int width, int height, int borderSize, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer, LifeGUI::GUIWidgetSkin* skin)
{
return GenFrame(layer, scissor, 0, 0, width, height, borderSize, color, pBuffer, skin);
}
int GUIManager::GenFrame(int layer, const LifeMath::Rect2i& scissor, int x, int y, int width, int height, int borderSize, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer, LifeGUI::GUIWidgetSkin* skin)
{
//1 2 3
//
//4 5
//
//6 7 8
GUISkinState* normalState = skin->GetState("Normal");
LifeMath::float4 bl = normalState->GetElement("BorderLeft")->Mapping;
LifeMath::float4 br = normalState->GetElement("BorderRight")->Mapping;
LifeMath::float4 bt = normalState->GetElement("BorderTop")->Mapping;
LifeMath::float4 bb = normalState->GetElement("BorderBottom")->Mapping;
LifeMath::float4 ctl = normalState->GetElement("CornerTopLeft")->Mapping;
LifeMath::float4 ctr = normalState->GetElement("CornerTopRight")->Mapping;
LifeMath::float4 cbl = normalState->GetElement("CornerBottomLeft")->Mapping;
LifeMath::float4 cbr = normalState->GetElement("CornerBottomRight")->Mapping;
LifeMath::Vec2i pos(x, y);
int offset = 0;
offset += GenQuad(layer, scissor, LifeMath::Vec2i(0,0) + pos, borderSize, borderSize, pBuffer + offset, color, ctl.X, ctl.Y, ctl.Z, ctl.W);
offset += GenQuad(layer, scissor, LifeMath::Vec2i(borderSize,0) + pos, width - borderSize * 2, borderSize, pBuffer + offset, color, bt.X, bt.Y, bt.Z, bt.W);
offset += GenQuad(layer, scissor, LifeMath::Vec2i(width - borderSize, 0) + pos, borderSize, borderSize, pBuffer + offset, color, ctr.X, ctr.Y, ctr.Z, ctr.W);
offset += GenQuad(layer, scissor, LifeMath::Vec2i(0, borderSize) + pos, borderSize, height - borderSize * 2, pBuffer + offset, color, bl.X, bl.Y, bl.Z, bl.W);
offset += GenQuad(layer, scissor, LifeMath::Vec2i(width - borderSize, borderSize) + pos, borderSize, height - borderSize * 2, pBuffer + offset, color, br.X, br.Y, br.Z, br.W);
offset += GenQuad(layer, scissor, LifeMath::Vec2i(0,height - borderSize) + pos, borderSize, borderSize, pBuffer + offset, color, cbl.X, cbl.Y, cbl.Z, cbl.W);
offset += GenQuad(layer, scissor, LifeMath::Vec2i(borderSize,height - borderSize) + pos, width - borderSize * 2, borderSize, pBuffer + offset, color, bb.X, bb.Y, bb.Z, bb.W);
offset += GenQuad(layer, scissor, LifeMath::Vec2i(width - borderSize, height - borderSize) + pos, borderSize, borderSize, pBuffer + offset, color, cbr.X, cbr.Y, cbr.Z, cbr.W);
return offset;
}
/*int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, LifeMath::float2 tile){
return 0;
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, const LifeMath::float4& col, LifeMath::float2 tile){
return 0;
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, const LifeMath::float4& col, float texOffX, float texOffY, float texWX, float texWY, LifeMath::float2 tile){
return 0;
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, float texOffX, float texOffY, float texWX, float texWY, LifeMath::float2 tile){
return 0;
}
int GUIManager::GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, float texOffX, float texOffY, float texWX, float texWY, const LifeMath::float4& color0, const LifeMath::float4& color1, const LifeMath::float4& color2, const LifeMath::float4& color3, const LifeMath::float2& tile){
return 0;
}
int GUIManager::GenFrame(int layer, const LifeMath::Rect2i& scissor, int width, int height, LifeGUI::GUIBorder* border, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer){
return 0;
}
int GUIManager::GenFrame(int layer, const LifeMath::Rect2i& scissor, int x, int y,int width, int height, LifeGUI::GUIBorder* border, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer){
return 0;
}
int GUIManager::GenFrame(int layer, const LifeMath::Rect2i& scissor, int width, int height, int borderSize, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer, LifeGUI::GUIWidgetSkin* skin){
return 0;
}
int GUIManager::GenFrame(int layer, const LifeMath::Rect2i& scissor, int x, int y, int width, int height, int borderSize, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer, LifeGUI::GUIWidgetSkin* skin){
return 0;
}*/
void GUIManager::Update(float dt)
{
if(curOverlay)
curOverlay->Update(dt);
}
void GUIManager::Render()
{
guiRenderer->Reset();
if(curOverlay)
curOverlay->Render();
guiRenderer->Render();
}
void GUIManager::AddOverlay(const String& name)
{
GUIOverlay* ovrl = new GUIOverlay(name);
ovrl->SetPosition(LifeMath::Vec2i(0,0));
ovrl->SetWidth(this->GetWidth());
ovrl->SetHeight(this->GetHeight());
if(!overlays.size())
curOverlay = ovrl;
overlays.push_back(ovrl);
}
LifeGUI::GUIOverlay* GUIManager::GetOverlay(const String& name)
{
for(OverlayList::iterator it = overlays.begin(); it != overlays.end(); ++it)
{
if( (*it)->name == name)
return *it;
}
return 0;
}
void GUIManager::SelectOverlay(const String& name)
{
for(OverlayList::iterator it = overlays.begin(); it != overlays.end(); ++it)
{
if( (*it)->name == name)
{
curOverlay = *it;
return;
}
}
}
}
+67
View File
@@ -0,0 +1,67 @@
#ifndef GUIMANAGER_H__
#define GUIMANAGER_H__
#include "Singleton.h"
#include "GUIOverlay.h"
#include "GUIWindow.h"
#include "GUIFont.h"
#include "GUIVertex.h"
#include <vector>
#include "Types.h"
#include "GUIWidgetSkin.h"
#include "IInputSystem.h"
#include "GUIMessaging.h"
#include <Singleton.h>
#include "IGUIRenderer.h"
#include "IGUIDataManager.h"
namespace LifeGUI
{
class GUIManager : public Singleton<GUIManager>
{
friend class Singleton<GUIManager>;
private:
int lastID;
LifeMath::Vec2i cursorPos;
int scrW;
int scrH;
typedef std::vector<GUIOverlay*> OverlayList;
OverlayList overlays;
GUIOverlay* curOverlay;
IGUIRenderer* guiRenderer;
IGUIDataManager* guiDataManager;
GUIManager()
:curOverlay(0), lastID(0), guiRenderer(nullptr), guiDataManager(nullptr)
{
}
public:
IGUIRenderer* GetRenderer();
IGUIDataManager* GetDataManager();
void Init(IGUIRenderer* renderer, IGUIDataManager* data_manager);
int GetNewID();
GUIOverlay* GetActiveOverlay();
std::map<String, GUIWidgetSkin*> skinDefault;
IImage* DIFF;
IImage* cursorTex;
GUIFont* font;
int GetWidth();
int GetHeight();
int GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, LifeMath::float2 tile = LifeMath::float2(1,1));
int GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, const LifeMath::float4& col, LifeMath::float2 tile = LifeMath::float2(1,1));
int GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, const LifeMath::float4& col, float texOffX, float texOffY, float texWX, float texWY, LifeMath::float2 tile = LifeMath::float2(1,1));
int GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, float texOffX, float texOffY, float texWX, float texWY, LifeMath::float2 tile = LifeMath::float2(1,1));
int GenQuad(int layer, const LifeMath::Rect2i& scissor, LifeMath::Vec2i position, int width, int height, LifeGUI::GUIVertex* pBuffer, float texOffX, float texOffY, float texWX, float texWY, const LifeMath::float4& color0, const LifeMath::float4& color1, const LifeMath::float4& color2, const LifeMath::float4& color3, const LifeMath::float2& tile);
int GenFrame(int layer, const LifeMath::Rect2i& scissor, int width, int height, LifeGUI::GUIBorder* border, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer);
int GenFrame(int layer, const LifeMath::Rect2i& scissor, int x, int y,int width, int height, LifeGUI::GUIBorder* border, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer);
int GenFrame(int layer, const LifeMath::Rect2i& scissor, int width, int height, int borderSize, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer, LifeGUI::GUIWidgetSkin* skin);
int GenFrame(int layer, const LifeMath::Rect2i& scissor, int x, int y, int width, int height, int borderSize, const LifeMath::float4& color, LifeGUI::GUIVertex* pBuffer, LifeGUI::GUIWidgetSkin* skin);
void Update(float dt);
void Render();
void AddOverlay(const String& name);
LifeGUI::GUIOverlay* GetOverlay(const String& name);
void SelectOverlay(const String& name);
};
}
#endif
+237
View File
@@ -0,0 +1,237 @@
#include "GUIMenu.h"
#include "GUIButton.h"
#include "GUIOverlay.h"
namespace LifeGUI
{
GUIMenu::GUIMenu(bool allowFocus)
:expand_id(-1), parentMenu(0)
{
//NeedKeyFocus = allowFocus;
NeedKeyFocus = true;
this->SetWidth(150);
this->SetHeight(10);
this->Event_LostFocus += NewDelegate(this, &GUIMenu::OnLostFocus);
//this->Event_Resize += NewDelegate(this, &GUIMenu::OnResize);
}
GUIMenu::~GUIMenu()
{
}
void GUIMenu::RemoveItems()
{
for(ItemCollectionItr it = Items.begin(); it != Items.end(); ++it)
{
delete (*it);
}
Items.clear();
RebuildControls();
UpdateLayout();
}
bool GUIMenu::IsChildMenu(GUIWindow* m)
{
if(expand_id < 0)
{
return false;
}
else
{
GUIMenu* menu = Items[expand_id]->GetSubmenu();
if(m == menu)
return true;
else
return menu->IsChildMenu(m);
}
}
GUIMenu* GUIMenu::FindRootMenu()
{
if(parentMenu)
{
return parentMenu->FindRootMenu();
}
else
{
return this;
}
}
void GUIMenu::SetParentMenu(GUIMenu* p)
{
parentMenu = p;
}
void GUIMenu::OnLostFocus(GUIWindow* wnd, int arg)
{
GUIWindow* newFocus = FindOverlay()->GetFocusWindow();
//if focus gained not by the child menu - auto hide!
if(!IsChildMenu(newFocus))
{
OnCollapse();
}
}
void GUIMenu::OnSelectElement(GUIWindow* wnd, int arg)
{
FindOverlay()->SetFocusWindow(0);
GUIButton* b = (GUIButton*)wnd;
GUIMenuItem* itm = (GUIMenuItem*)b->UserData;
itm->Event_Select.Invoke(itm);
printf("Selected menu item! Text: %s\n", b->GetCaption().c_str());
FindRootMenu()->Event_SelectItem.Invoke(this, 0);
printf("OMFG Set up item index!!!\n");
FindRootMenu()->OnCollapse();
}
void GUIMenu::OnCollapse()
{
CollapseSubmenu();
if(parent)
parent->RemoveChild(this->ID);
Event_Collapse.Invoke(this);
}
GUIMenuItem* GUIMenu::AddItem(const String& text, bool hasSubmenu)
{
GUIMenuItem* itm = new GUIMenuItem(text, hasSubmenu);
Items.push_back(itm);
if(itm->HasSubmenu())
itm->GetSubmenu()->SetParentMenu(this);
RebuildControls();
UpdateLayout();
return itm;
}
void GUIMenu::OnResize(GUIWindow* wnd)
{
UpdateLayout();
}
void GUIMenu::UpdateLayout()
{
LifeMath::Rect2i r = this->GetClientRectangle();
int offset = 0;
int item_h = 20;
for(WindowListIter it = internal_windows.begin(); it != internal_windows.end(); ++it)
{
GUIWindow* itm = (*it);
//itm->SetWidth(r.width);
//itm->SetHeight(item_h);
itm->SetPosition(LifeMath::Vec2i(0, offset * item_h));
offset++;
}
int h = offset*item_h;
if(IsBorderEnabled())
h+=1*2;
this->SetHeight(h);
}
void GUIMenu::CollapseSubmenu()
{
if(expand_id >=0)
{
Items[expand_id]->GetSubmenu()->CollapseSubmenu();
FindOverlay()->RemoveChild(Items[expand_id]->GetSubmenu()->ID);
expand_id = -1;
}
}
void GUIMenu::OnHoverElement(GUIWindow* wnd, int arg)
{
GUIMenuItem* itm = reinterpret_cast<GUIMenuItem*>(wnd->UserData);
if(expand_id >= 0)
{
if(GetItemID(itm) != expand_id)
{
CollapseSubmenu();
}
}
}
void GUIMenu::OnExpandMenu(GUIWindow* wnd, int arg)
{
GUIMenuItem* itm = reinterpret_cast<GUIMenuItem*>(wnd->UserData);
if(expand_id >=0) //already expanded
{
int itm_id = GetItemID(itm);
if(expand_id == itm_id)
{
CollapseSubmenu();
return;
}
else
CollapseSubmenu();
}
GUIButton* b = reinterpret_cast<GUIButton*>(wnd);
FindOverlay()->AddChild(itm->GetSubmenu());
expand_id = GetItemID(itm);
itm->GetSubmenu()->Show();
LifeMath::Vec2i pos = b->GetRectangleAbs().GetMax();
pos.Y -= b->GetHeight();
itm->GetSubmenu()->SetPosition(pos);
}
size_t GUIMenu::GetItemID(GUIMenuItem* itm)
{
for(int i = 0; i < Items.size(); i++)
{
if(Items[i] == itm)
return i;
}
return -1;
}
void GUIMenu::RebuildControls()
{
int itm_cnt = Items.size();
LifeMath::Rect2i r = this->GetClientRectangle();
for(WindowListIter it = internal_windows.begin(); it != internal_windows.end(); ++it)
{
this->RemoveChild((*it)->ID);
delete (*it);
}
for(WindowListIter it = internal_arrows.begin(); it != internal_arrows.end(); ++it)
{
delete (*it);
}
internal_windows.clear();
internal_arrows.clear();
int item_h = 20;
for(ItemCollectionItr it = Items.begin(); it != Items.end(); it++)
{
GUIButton* b = new GUIButton();
b->UserData = (*it);
b->SetCaption((*it)->GetText());
internal_windows.push_back(b);
this->AddChild(b);
b->SetWidth(r.width);
b->SetHeight(item_h);
b->SetBorderEnabled(false);
b->Event_MouseEnter += NewDelegate(this, &GUIMenu::OnHoverElement);
b->SetStyle(STR("Combo_list"));
if(!(*it)->HasSubmenu())
b->Event_MouseDown += NewDelegate(this, &GUIMenu::OnSelectElement);
//
if((*it)->HasSubmenu())
{
b->Event_MouseDown += NewDelegate(this, &GUIMenu::OnExpandMenu);
//add arrow
GUIPlane* arrow = new GUIPlane();
arrow->SetWidth(14);
arrow->SetHeight(14);
arrow->state = STR("Normal");
arrow->SetStyle(STR("Menu_arrow"));
arrow->skip_mouse = true;
arrow->SetBorderEnabled(false);
b->AddChild(arrow);
internal_arrows.push_back(arrow);
arrow->SetPosition(LifeMath::Vec2i(b->GetClientRectangle().width - 14, (b->GetClientRectangle().height - 14) / 2));
}
}
}
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef GUIMenu_h__
#define GUIMenu_h__
#include "GUIPlane.h"
#include "GUIButton.h"
#include "GUIMenuItem.h"
#include <vector>
namespace LifeGUI
{
class GUIMenu : public GUIPlane
{
public:
EVENT1(MenuEvent, GUIMenu*);
EVENT2(MenuItemEvent, GUIMenu*, int);
MenuEvent Event_Collapse;
MenuItemEvent Event_SelectItem;
GUIMenu(bool allowFocus);
~GUIMenu();
void RemoveItems();
GUIMenuItem* AddItem(const String& text, bool hasSubmenu);
private:
void OnCollapse();
GUIMenu* parentMenu;
bool IsChildMenu(GUIWindow* m);
void SetParentMenu(GUIMenu* p);
GUIMenu* FindRootMenu();
void OnLostFocus(GUIWindow* wnd, int arg);
void CollapseSubmenu();
int expand_id;
size_t GetItemID(GUIMenuItem* itm);
void OnExpandMenu(GUIWindow* wnd, int arg);
void OnHoverElement(GUIWindow* wnd, int arg);
void OnSelectElement(GUIWindow* wnd, int arg);
void OnResize(GUIWindow* wnd);
void RebuildControls();
typedef std::vector<GUIMenuItem*> ItemCollection;
typedef std::vector<GUIMenuItem*>::iterator ItemCollectionItr;
ItemCollection Items;
void UpdateLayout();
WindowList internal_windows;
WindowList internal_arrows;
};
}
#endif // GUIMenu_h__
+26
View File
@@ -0,0 +1,26 @@
#include "GUIMenuItem.h"
#include "GUIMenu.h"
namespace LifeGUI
{
GUIMenuItem::GUIMenuItem(const String& _text, bool hasSubmenu)
:SubMenu(0)
{
text = _text;
if(hasSubmenu)
{
SubMenu = new GUIMenu(false);
}
}
GUIMenuItem::~GUIMenuItem()
{
}
bool GUIMenuItem::HasSubmenu()
{
return SubMenu != 0;
}
GUIMenu* GUIMenuItem::GetSubmenu()
{
return SubMenu;
}
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef GUIMenuItem_h__
#define GUIMenuItem_h__
#include "GUIWindow.h"
#include <vector>
namespace LifeGUI
{
class GUIMenu;
class GUIMenuItem
{
public:
EVENT1(MenuItemEvent, GUIMenuItem*);
MenuItemEvent Event_Select;
GUIMenuItem(const String& _text, bool hasSubmenu);
~GUIMenuItem();
bool HasSubmenu();
GUIMenu* GetSubmenu();
const String& GetText(){return text;}
protected:
GUIMenu* SubMenu;
String text;
GUIWindow* control;
};
}
#endif // GUIMenuItem_h__
+16
View File
@@ -0,0 +1,16 @@
#ifndef GUIMenuTextItem_h__
#define GUIMenuTextItem_h__
#include "GUIMenuItem.h"
namespace LifeGUI
{
class GUIMenuTextItem : public GUIMenuItem
{
public:
GUIMenuTextItem();
~GUIMenuTextItem();
bool IsDropDown();
};
}
#endif // GUIMenuTextItem_h__
+59
View File
@@ -0,0 +1,59 @@
#ifndef GUIMessaging_h__
#define GUIMessaging_h__
#include <string>
#include "IInputSystem.h"
namespace LifeGUI
{
class GUIManager;
class GUIOverlay;
enum GUIMessageType
{
GM_MOUSE = 0,
GM_KEYBOARD = 1,
GM_JOYSTICK = 2,
};
enum GUIMessageParam
{
MP_KEY_DOWN = 0,
MP_KEY_UP = 1,
MP_MOUSE_MOVE = 2
};
class IMessageArgs
{
public:
virtual ~IMessageArgs()
{
}
};
class IMouseArgs : public IMessageArgs
{
public:
~IMouseArgs()
{
}
int ShiftRelX;
int ShiftRelY;
int CursorX;
int CursorY;
GUIManager* manager;
GUIOverlay* overlay;
int Mousekey;
};
class IKeyboardArgs : public IMessageArgs
{
public:
~IKeyboardArgs()
{
}
LifeCore::KeyCodes::Key keycode;
uint32 text;
std::string str;
GUIManager* manager;
GUIOverlay* overlay;
};
}
#endif // GUIMessaging_h__
+330
View File
@@ -0,0 +1,330 @@
#include "GUIOverlay.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUIOverlay::GUIOverlay(const String& _name)
:drawBackground(false), cursorPos(0,0),
hideCursor(false), focus(0), focusWindow(0), grabbed_wnd(0), grabbed_mouse(false), drag_mode(false), drag_info(0),
drag_src(0), drag_target(0), drop_valid(false), wnd_hover(0), wnd_hover_client(true)
{
cursorAbsolute = true;
cursor_relative.Set(0, 0);
name = _name;
GUIManager* manager = GUIManager::me();
this->SetPosition(LifeMath::Vec2i(0, 0));
this->SetWidth(manager->GetWidth());
this->SetHeight(manager->GetHeight());
manager->GetRenderer()->SetScreenSize(GetWidth(), GetHeight());
cursorGeom = new GUIPlane();
cursorGeom->SetBorderEnabled(false);
cursorGeom->SetWidth(32);
cursorGeom->SetHeight(32);
//load cursors
GUIWidgetSkin* cursor_skin = manager->skinDefault[STR("Cursor")];
int cnt = cursor_skin->states.size();
for(std::map<String, GUISkinState*>::iterator it = cursor_skin->states.begin(); it != cursor_skin->states.end(); ++it)
{
IGUICursor* cur = new IGUICursor();
cur->skin = cursor_skin;
cur->name = it->first;
LifeMath::Vec4i v = it->second->GetElement(STR("Background"))->Coord;
int w = v.Z - v.X + 1;
int h = v.W - v.Y + 1;
cur->size.X = w;
cur->size.Y = h;
Cursors[cur->name] = cur;
}
Cursors[STR("Size_h")]->offset = LifeMath::Vec2i(4, 11);
Cursors[STR("Size_v")]->offset = LifeMath::Vec2i(11, 4);
Cursors[STR("Text")]->offset = LifeMath::Vec2i(5, 10);
Cursors[STR("Size_d1")]->offset = LifeMath::Vec2i(8, 8);
Cursors[STR("Size_d2")]->offset = LifeMath::Vec2i(8, 8);
SetCursor("Arrow");
}
void GUIOverlay::SetCursorMode(bool absolute){
cursorAbsolute = absolute;
}
void GUIOverlay::GrabMouse(GUIWindow* wnd)
{
grabbed_mouse = true;
grabbed_wnd = wnd;
}
void GUIOverlay::BeginDrag(GUIWindow* source, DragInfo* info)
{
drag_mode = true;
drag_src = source;
drag_info = info;
drag_target = 0;
drop_valid = false;
}
//release mouse after grabbing it
void GUIOverlay::ReleaseMouse()
{
grabbed_mouse = false;
grabbed_wnd = 0;
}
void GUIOverlay::OnMousePress(int x, int y, LifeCore::KeyCodes::Key key)
{
GUIWindow* wnd;
if(grabbed_mouse)
{
wnd = grabbed_wnd;
wnd_hover_client = true;
}
else
wnd = GetWindowAtPoint(cursorPos.X, cursorPos.Y);
GUIWindow* new_focus = wnd;
//find first window, which wants to accept keyboard focus
while(new_focus != 0 && !new_focus->NeedKeyFocus)
new_focus = new_focus->GetParent();
//set new focus window
SetFocusWindow(new_focus);
if(wnd && (wnd != this))
{
if(wnd_hover_client)
wnd->OnMousePress(cursorPos.X, cursorPos.Y, key);
else
wnd->OnNCMousePress(cursorPos.X, cursorPos.Y, key);
}
}
LifeMath::Vec2i GUIOverlay::GetCursorCoord(){
return cursorPos;
}
void GUIOverlay::OnMouseRelease(int x, int y, LifeCore::KeyCodes::Key key)
{
if(drag_mode)
{
if(drop_valid)
{
drag_target->AcceptDrop(drag_info);
drag_src->FinishDrag();
}
}
else
{
GUIWindow* wnd;
if(grabbed_mouse)
{
wnd = grabbed_wnd;
wnd_hover_client = true;
}
else
wnd = GetWindowAtPoint(cursorPos.X, cursorPos.Y);
if(wnd && (wnd != this))
{
if(wnd_hover_client)
wnd->OnMouseRelease(cursorPos.X, cursorPos.Y, key);
else
wnd->OnNCMouseRelease(cursorPos.X, cursorPos.Y, key);
}
}
drag_mode = false;
}
LifeMath::Vec2i GUIOverlay::GetCursorRelative(){
return cursor_relative;
}
void GUIOverlay::OnMouseMove(int abs_x, int abs_y, int rel_x, int rel_y)
{
if(cursorAbsolute){
cursorPos.X = abs_x;
cursorPos.Y = abs_y;
}else{
cursorPos.X += rel_x;
cursorPos.Y += rel_y;
}
cursor_relative.Set(rel_x, rel_y);
if(!drag_mode)
{
if(grabbed_mouse)
{
wnd_hover = grabbed_wnd;
wnd_hover_client = true;
}
else
{
GUIWindow* wnd = GetWindowAtPoint(cursorPos.X, cursorPos.Y);
bool clientZone = wnd != 0 ? wnd->GetClientRectangleAbs().InRect(cursorPos) : true;
//if changed window
if(wnd != wnd_hover)
{
//if there was hovered window, send it "mouse leave" message
if(wnd_hover)
{
if(wnd_hover_client)
wnd_hover->OnMouseLeave();
else
wnd_hover->OnNCMouseLeave();
}
//send "mouse enter" to newly hovered window
if(wnd)
{
wnd_hover_client = clientZone;
if(wnd_hover_client)
wnd->OnMouseEnter();
else
wnd->OnNCMouseEnter();
}
//change cursor
if((wnd != 0) && cursorGeom->state != wnd->cursor)
SetCursor(wnd->cursor);
}
else if(clientZone != wnd_hover_client) //changed only zone type
{
if(wnd)
{
if(clientZone)//if entered to client zone
{
wnd->OnNCMouseLeave();
wnd->OnMouseEnter();
}
else
{
wnd->OnMouseLeave();
wnd->OnNCMouseEnter();
}
wnd_hover_client = clientZone;
}
}
wnd_hover = wnd;
}
if(wnd_hover && (wnd_hover != this))
{
if(wnd_hover_client)
wnd_hover->OnMouseMove(cursorPos.X, cursorPos.Y, rel_x, rel_y);
else
wnd_hover->OnNCMouseMove(cursorPos.X, cursorPos.Y, rel_x, rel_y);
}
}
else //DragDrop
{
GUIWindow* target = GetWindowAtPoint(cursorPos.X, cursorPos.Y);
//mouse under different target
if(target != 0 && target != drag_target && target != drag_src)
{
drag_target = target;
if(target->IsAllowDrop() && target->DragEnter(drag_info))
{
drop_valid = true;
}
else
{
drop_valid = false;
}
}
}
}
void GUIOverlay::OnKeyDown(LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str){
if(focusWindow){
focusWindow->OnKeyDown(key, text, str);
}
}
void GUIOverlay::OnKeyUp(LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str){
if(focusWindow){
focusWindow->OnKeyUp(key, text, str);
}
}
GUIOverlay::~GUIOverlay()
{
}
GUIOverlay* GUIOverlay::FindOverlay()
{
return this;
}
void GUIOverlay::SetBackColor(const LifeMath::float4& color)
{
BackColor = color;
}
void GUIOverlay::Update(float dt)
{
// UpdateChilds(dt);
}
void GUIOverlay::SetCursor(const String& name)
{
IGUICursor* cur = Cursors[name];
cursorGeom->state = cur->name;
cursorGeom->SetStyle(STR("Cursor"));
cursorGeom->SetWidth(cur->size.X);
cursorGeom->SetHeight(cur->size.Y);
cursor = cur;
}
/*bool GUIOverlay::MouseMove( int absX, int relX, int absY, int relY)
{
cursorPos += LifeMath::Vec2i(relX, relY);
if(cursorPos.X < 0)
cursorPos.X = 0;
if(cursorPos.Y < 0)
cursorPos.Y = 0;
if(cursorPos.X > (this->width - 5))
cursorPos.X = (this->width - 5);
if(cursorPos.Y > (this->height - 5))
cursorPos.Y = (this->height - 5);
LifeMath::float4 pos;
pos.Z = this->cursorPos.X;
pos.W = this->cursorPos .Y;
pos.X = GUIManager::me()->GetWidth();
pos.Y = GUIManager::me()->GetHeight();
cbVs->Update(&pos, sizeof(LifeMath::float4));
return true;
}*/
/*LifeMath::Rect2i GUIOverlay::GetClientRectangle()
{
return LifeMath::Rect2i(0, 0, this->GetWidth(), this->GetHeight());
}
LifeMath::Rect2i GUIOverlay::GetClientRectangleAbs()
{
return LifeMath::Rect2i(0,0, this->GetWidth(), this->GetHeight());
}*/
void GUIOverlay::Render()
{
this->UpdateScissor();
GUIManager::me()->GetRenderer()->SetScissor(this->GetScissor());
if(drawBackground)
{
GUIManager::me()->GetRenderer()->SetTexture(GUIManager::me()->DIFF, 0, false);
GUIVertex cursor_vertex[6];
GUIManager::me()->GenQuad(0, this->GetScissor(), LifeMath::Vec2i(0,0), GetWidth(), GetHeight(), &cursor_vertex[0]);
GUIManager::me()->GetRenderer()->Write(&cursor_vertex[0], 6);
}
RenderChilds();
GUIManager::me()->GetRenderer()->SetScissor(this->GetScissor());
if(!hideCursor)
{
GUIManager::me()->GetRenderer()->SetTexture(GUIManager::me()->cursorTex, 0, false);
cursorGeom->SetPosition(cursorPos - cursor->offset);
cursorGeom->SetScissor(this->GetScissor());
cursorGeom->Render();
}
}
}
+71
View File
@@ -0,0 +1,71 @@
#ifndef GUIOverlay_h__
#define GUIOverlay_h__
#include "GUIWindow.h"
#include "IInputSystem.h"
#include "delegate/Delegate.h"
#include "IGUICursor.h"
#include "GUIPlane.h"
#include <map>
namespace LifeGUI
{
class GUIOverlay : public GUIWindow{
public:
EVENT1(GUIEvent, GUIWindow*);
LifeMath::Vec2i cursorPos;
GUIEvent FocusChanged;
bool drawBackground;
GUIWindow* focus;
GUIOverlay(const String& _name);
~GUIOverlay();
GUIOverlay* FindOverlay();
void SetCursorMode(bool absolute);
void SetCursor(const String& name);
void GrabMouse(GUIWindow* wnd);
void ReleaseMouse();
void BeginDrag(GUIWindow* source, DragInfo* info);
GUIWindow* GetFocusWindow(){
return focusWindow;
}
void SetFocusWindow(GUIWindow* wnd){
GUIWindow* tmp = focusWindow;
focusWindow = wnd;
if(tmp != NULL && tmp != wnd)
tmp->ReleaseFocus();
}
bool IsFocusWindow(GUIWindow* wnd){
return focusWindow == wnd;
}
GUIWindow* focusWindow;
void Update(float dt);
//void KeyPress(int key, int modifier);
void Render();
void SetBackColor(const LifeMath::float4& color);
void OnMousePress(int x, int y, LifeCore::KeyCodes::Key key);
void OnMouseRelease(int x, int y, LifeCore::KeyCodes::Key key);
void OnMouseMove(int abs_x, int abs_y, int rel_x, int rel_y);
void OnKeyDown(LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str);
void OnKeyUp(LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str);
LifeMath::Vec2i GetCursorCoord();
LifeMath::Vec2i GetCursorRelative();
private:
bool cursorAbsolute;
LifeMath::Vec2i cursor_relative;
bool wnd_hover_client;
GUIPlane* cursorGeom;
GUIWindow* wnd_hover;
bool hideCursor;
bool grabbed_mouse;
GUIWindow* grabbed_wnd;
DragInfo* drag_info;
GUIWindow* drag_src;
GUIWindow* drag_target;
bool drop_valid;
bool drag_mode;
IGUICursor* cursor;
std::map<String, IGUICursor*> Cursors;
};
}
#endif // GUIOverlay_h__
+77
View File
@@ -0,0 +1,77 @@
#include "GUIOverlayManager.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUIOverlayManager::GUIOverlayManager() :selected_ovrl(nullptr),
scr_width(100), scr_height(100), cur_y(0), cur_x(0)
{
}
bool GUIOverlayManager::KeyDown( LifeCore::KeyCodes::Key key, unsigned int text, const String& str ){
selected_ovrl->OnKeyDown(key, text, str);
return true;
}
bool GUIOverlayManager::KeyUp( LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str ){
selected_ovrl->OnKeyUp(key, text, str);
return true;
}
bool GUIOverlayManager::MouseMove( int absX, int relX, int absY, int relY){
cur_x = absX;
cur_y = absY;
selected_ovrl->OnMouseMove(absX,absY, relX,relY);
return true;
}
bool GUIOverlayManager::MousePressed( LifeCore::KeyCodes::Key button){
selected_ovrl->OnMousePress(cur_x, cur_y, button);
return true;
}
bool GUIOverlayManager::MouseReleased( LifeCore::KeyCodes::Key button){
selected_ovrl->OnMouseRelease(cur_x, cur_y, button);
return true;
}
GUIOverlay* GUIOverlayManager::GetOverlay(){
return selected_ovrl;
}
GUIOverlay* GUIOverlayManager::GetOverlay(const String& name, bool create){
GUIOverlay* ovrl = FindOverlay(name);
if(ovrl == nullptr && create){
ovrl = new GUIOverlay(name);
overlays[name] = ovrl;
}
return ovrl;
}
void GUIOverlayManager::SetSize(uint32 width, uint32 height){
scr_width = width;
scr_height = height;
if(selected_ovrl != nullptr){
selected_ovrl->SetWidth(scr_width);
selected_ovrl->SetHeight(scr_height);
}
}
bool GUIOverlayManager::SwitchOverlay(const String& name){
selected_ovrl = FindOverlay(name);
if(selected_ovrl != nullptr){
selected_ovrl->SetWidth(scr_width);
selected_ovrl->SetHeight(scr_height);
}
return true;
}
GUIOverlay* GUIOverlayManager::FindOverlay(const String& name){
OverlayCollectionIt it = overlays.find(name);
if(it != overlays.end())
return it->second;
else
return nullptr;
}
void GUIOverlayManager::Render(){
if(selected_ovrl!=nullptr){
LifeGUI::GUIManager::me()->GetRenderer()->SetScreenSize(scr_width, scr_height);
selected_ovrl->Render();
LifeGUI::GUIManager::me()->GetRenderer()->Render();
LifeGUI::GUIManager::me()->GetRenderer()->Reset();
}
}
}
+38
View File
@@ -0,0 +1,38 @@
#ifndef GUIOverlayManager_h__
#define GUIOverlayManager_h__
#include <LString.h>
#include <IInputSystem.h>
#include <map>
#include "GUIOverlay.h"
#include <Types.h>
namespace LifeGUI
{
class GUIOverlayManager
{
public:
GUIOverlayManager();
bool KeyDown( LifeCore::KeyCodes::Key key, unsigned int text, const String& str );
bool KeyUp( LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str );
bool MouseMove( int absX, int relX, int absY, int relY);
bool MousePressed( LifeCore::KeyCodes::Key button);
bool MouseReleased( LifeCore::KeyCodes::Key button);
GUIOverlay* GetOverlay();
GUIOverlay* GetOverlay(const String& name, bool create = false);
void SetSize(uint32 width, uint32 height);
bool SwitchOverlay(const String& name);
void Render();
private:
GUIOverlay* selected_ovrl;
typedef std::map<String, GUIOverlay*> OverlayCollection;
typedef std::map<String, GUIOverlay*>::iterator OverlayCollectionIt;
OverlayCollection overlays;
GUIOverlay* FindOverlay(const String& name);
uint32 scr_width;
uint32 scr_height;
uint32 cur_x, cur_y;
};
}
#endif // GUIOverlayManager_h__
+135
View File
@@ -0,0 +1,135 @@
#include "GUIPicture.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUIPicture::GUIPicture()
:mode(SM_STRETCH), pic(0)
{
this->SetBackColor(LifeMath::float4(0.7f, 0.7f, 0.7f, 1.0f));
pictureHolder = new GUIPlane();
pictureHolder->skip_mouse = true;
this->AddChild(pictureHolder);
//pictureHolder->SetDock(DOCK_FILL);
pictureHolder->SetBorderEnabled(false);
this->Event_Resize += NewDelegate(this, &GUIPicture::UpdateLayout);
}
GUIPicture::~GUIPicture()
{
}
void GUIPicture::SetSizeMode(int _mode)
{
mode = _mode;
UpdateLayout(this);
}
void GUIPicture::UpdateLayout(GUIWindow* wnd)
{
LifeMath::Rect2i r = this->GetClientRectangle();
if(pic)
{
pictureHolder->Show();
switch(mode)
{
case SM_STRETCH:
{
pictureHolder->SetPosition(r.GetMin());
pictureHolder->SetWidth(r.width);
pictureHolder->SetHeight(r.height);
}
break;
case SM_CENTER:
{
int pw = pic->GetWidth();
int ph = pic->GetHeight();
if(pictureHolder->IsBorderEnabled())
{
pw += 2;
ph += 2;
}
int offsetX = (-(pw - r.width)) / 2;
int offsetY = (-(ph - r.height)) / 2;
pictureHolder->SetPosition(LifeMath::Vec2i(offsetX, offsetY));
pictureHolder->SetWidth(pw);
pictureHolder->SetHeight(ph);
}
break;
case SM_ZOOM:
{
int pw = pic->GetWidth();
int ph = pic->GetHeight();
if(pictureHolder->IsBorderEnabled())
{
pw += 2;
ph += 2;
}
int dw = abs(r.width - pw);
int dh = abs(r.height - ph);
float aspect = float(pw) / float(ph);
if(dh < dw) //vertical on borders
{
pictureHolder->SetHeight(r.height);
pictureHolder->SetWidth(int(float(r.height) * aspect));
pictureHolder->SetPosition(LifeMath::Vec2i(dw/2, 0));
}
else
{
pictureHolder->SetWidth(r.width);
pictureHolder->SetHeight(int(float(r.width) / aspect));
pictureHolder->SetPosition(LifeMath::Vec2i(0, dh / 2));
}
}
break;
case SM_FILL:
{
int pw = pic->GetWidth();
int ph = pic->GetHeight();
if(pictureHolder->IsBorderEnabled())
{
pw += 2;
ph += 2;
}
int dw = abs(r.width - pw);
int dh = abs(r.height - ph);
float aspect = float(pw) / float(ph);
if(dh < dw) //vertical on borders
{
pictureHolder->SetWidth(r.width);
pictureHolder->SetHeight(int(float(r.width) / aspect));
pictureHolder->SetPosition(LifeMath::Vec2i(0, dh / 2));
}
else
{
pictureHolder->SetHeight(r.height);
pictureHolder->SetWidth(int(float(r.height) * aspect));
pictureHolder->SetPosition(LifeMath::Vec2i(dw / 2, 0));
}
}
break;
}
}
else
{
pictureHolder->Hide();
}
}
void GUIPicture::SetPicture(IImage* picture)
{
pic = picture;
pictureHolder->SetBackPicture(picture);
pictureHolder->SetBackColor(LifeMath::float4(1,1,1,1));
UpdateLayout(this);
}
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef GUIPicture_h__
#define GUIPicture_h__
#include "GUIPlane.h"
namespace LifeGUI
{
enum SIZE_MODE
{
SM_FILL,
SM_CENTER,
SM_STRETCH,
SM_ZOOM
};
class GUIPicture : public GUIWindow
{
public:
GUIPicture();
~GUIPicture();
IImage* GetPicture(){return pic;}
void SetPicture(IImage* picture);
void SetSizeMode(int _mode);
private:
int mode;
GUIPlane* pictureHolder;
void UpdateLayout(GUIWindow* wnd);
IImage* pic;
};
}
#endif // GUIPicture_h__
+181
View File
@@ -0,0 +1,181 @@
#include "GUIPlane.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUIPlane::GUIPlane()
:border_color(0.9f, 0.9f, 0.9f, 1.0f), vertex_count(0), invalid(false)
{
back_tex = GUIManager::me()->DIFF;
geom = new GUIVertex[6 + 8 * 6]; //background + border
this->SetBackColor(LifeMath::float4(1.0f, 1.0f, 1.0f, 1.0f));
GenGeom();
}
GUIPlane::~GUIPlane()
{
}
void GUIPlane::Invalidate()
{
GUIWindow::Invalidate();
invalid = true;
}
void GUIPlane::GenGeom()
{
vertex_count = 0;
if(this->GetScissor().GetSquare() != 0)
{
if(skin)
{
SetBackPicture(skin->texture);
}
if(borderEnabled)
{
if(skin)
{
GUISkinElement* e = skin->GetState(state)->GetElement(STR("Background"));
LifeMath::float4 m = e->Mapping;
if(AutoTiling)
{
LifeMath::Rect2i r = this->GetClientRectangle();
BackgroundTiling.X = float(r.width) / float(e->Coord.Z - e->Coord.X + 1);
BackgroundTiling.Y = float(r.height) / float(e->Coord.W - e->Coord.Y + 1);
}
vertex_count += GUIManager::me()->GenQuad(0, this->GetScissor(), LifeMath::Vec2i(Border.Left, Border.Top) + positionAbs, this->width - (Border.Left + Border.Right),this->height - (Border.Top + Border.Bottom), geom, BackColor,m.X,
m.Y, m.Z, m.W, BackgroundTiling);
vertex_count += GUIManager::me()->GenFrame(0, this->GetScissor(), this->positionAbs.X, this->positionAbs.Y, this->width, this->height, &Border, border_color, geom + vertex_count);
}
else
{
if(back_tex)
vertex_count += GUIManager::me()->GenQuad(0, this->GetScissor(), LifeMath::Vec2i(Border.Left, Border.Top) + positionAbs,this->width - (Border.Left + Border.Right),this->height - (Border.Top + Border.Bottom),geom, BackColor,0,0,1,1,BackgroundTiling);
else
vertex_count += GUIManager::me()->GenQuad(0, this->GetScissor(), LifeMath::Vec2i(Border.Left, Border.Top) + positionAbs,this->width - (Border.Left + Border.Right),this->height - (Border.Top + Border.Bottom),geom, BackColor,0,0,0,0,BackgroundTiling);
vertex_count += GUIManager::me()->GenFrame(0, this->GetScissor(), this->positionAbs.X, this->positionAbs.Y, this->width, this->height, &Border, border_color, geom + vertex_count);
}
}
else
{
if(skin)
{
GUISkinElement* e = skin->GetState(state)->GetElement(STR("Background"));
LifeMath::float4 m = e->Mapping;
if(AutoTiling)
{
LifeMath::Rect2i r = this->GetClientRectangle();
BackgroundTiling.X = float(r.width) / float(e->Coord.Z - e->Coord.X + 1);
BackgroundTiling.Y = float(r.height) / float(e->Coord.W - e->Coord.Y + 1);
}
vertex_count = GUIManager::me()->GenQuad(0, this->GetScissor(), positionAbs,this->width,this->height,geom, BackColor, m.X,
m.Y, m.Z, m.W, BackgroundTiling);
}
else
{
if(back_tex)
vertex_count = GUIManager::me()->GenQuad(0, this->GetScissor(), positionAbs,this->width,this->height,geom, BackColor,0,0,1,1,BackgroundTiling);
else
vertex_count = GUIManager::me()->GenQuad(0, this->GetScissor(), positionAbs,this->width,this->height,geom, BackColor,0,0,0,0, BackgroundTiling);
}
}
}
invalid = false;
}
void GUIPlane::SetBackPicture(IImage* pic)
{
if(pic == 0)
back_tex = GUIManager::me()->DIFF;
else
back_tex = pic;
Invalidate();
}
void GUIPlane::Update(float dt)
{
}
void GUIPlane::RenderSelf()
{
//printf("Scissor X=%i, Y=%i\n", scissor.x, scissor.y);
//GUIManager::me()->GetRenderer()->SetScissor(scissor);
if(invalid)
GenGeom();
if(this->GetScissor().GetSquare() > 0)
{
GUIManager::me()->GetRenderer()->SetTexture(back_tex, 0, false);
GUIManager::me()->GetRenderer()->Write(geom, vertex_count);
}
}
void GUIPlane::ReleaseFocus()
{
Event_LostFocus.Invoke(this, 0);
}
void GUIPlane::SetBackColor(const LifeMath::float4& color)
{
GUIWindow::SetBackColor(color);
Invalidate();
}
void GUIPlane::SetBorderColor(const LifeMath::float4& color)
{
border_color = color;
Invalidate();
}
bool GUIPlane::ProcessMessage(GUIMessageType mt, GUIMessageParam mp, IMessageArgs* args)
{
/* if(BroadcastMessage(mt, mp, args))
return true;
if(mt == GM_MOUSE && mouseEnabled)
{
IMouseArgs* mArgs = static_cast<IMouseArgs*>(args);
LifeMath::Vec2i cursor = mArgs->overlay->cursorPos;
//if cursor is in client area
if(GetClientRectangleAbs().InRect(cursor))
{
if(mp == MP_MOUSE_MOVE)
{
//PickChild()
}
else if(mp == MP_KEY_DOWN)
{
}
}
}*/
return false;
}
LifeMath::Rect2i GUIPlane::GetClientRectangle()
{
LifeMath::Vec2i pos = this->GetPosition();
if(borderEnabled)
{
return LifeMath::Rect2i(Border.Left, Border.Top, width - (Border.Left + Border.Right), height - (Border.Top + Border.Bottom));
}
else
{
return LifeMath::Rect2i(0, 0, width, height);
}
}
LifeMath::Rect2i GUIPlane::GetClientRectangleAbs()
{
LifeMath::Vec2i pos = this->GetPositionAbs();
if(borderEnabled)
{
return LifeMath::Rect2i(pos.X + Border.Left, pos.Y + Border.Top, width - (Border.Left + Border.Right), height - (Border.Top + Border.Bottom));
}
else
{
return LifeMath::Rect2i(pos.X, pos.Y, width, height);
}
}
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef GUIPlane_h__
#define GUIPlane_h__
#include "GUIWindow.h"
#include <LString.h>
namespace LifeGUI
{
class GUIPlane : public GUIWindow
{
public:
GUIPlane();
~GUIPlane();
void Update(float dt);
void RenderSelf();
void SetBackColor(const LifeMath::float4& color);
void SetBorderColor(const LifeMath::float4& color);
void ReleaseFocus();
bool ProcessMessage(GUIMessageType mt, GUIMessageParam mp, IMessageArgs* args);
void SetBackPicture(IImage* pic);
LifeMath::Rect2i GetClientRectangle();
LifeMath::Rect2i GetClientRectangleAbs();
void Invalidate();
private:
bool invalid;
void GenGeom();
LifeMath::float4 border_color;
GUIVertex* geom;
int vertex_count;
IImage* back_tex;
};
}
#endif // GUIPlane_h__
+65
View File
@@ -0,0 +1,65 @@
#include "GUIProgress.h"
namespace LifeGUI
{
GUIProgress::GUIProgress()
:mValue(0.0f)
{
this->SetWidth(300);
this->SetHeight(15);
this->SetBorderEnabled(false);
this->SetStyle(STR("Progress"));
value_bar = new GUIPlane();
value_bar->AutoTiling = true;
this->AddChild(value_bar);
value_bar->SetBorderEnabled(false);
value_bar->SetStyle(STR("Progress_line"));
UpdateLayout();
this->Event_Resize += NewDelegate(this, &GUIProgress::OnResize);
}
GUIProgress::~GUIProgress()
{
}
void GUIProgress::SetValue(float val)
{
mValue = val;
if(mValue < 0.0f)
mValue = 0.0f;
if(mValue > 1.0f)
mValue = 1.0f;
UpdateLayout();
}
float GUIProgress::GetValue()
{
return mValue;
}
void GUIProgress::OnResize(GUIWindow* wnd)
{
UpdateLayout();
}
void GUIProgress::UpdateLayout()
{
if(this->GetHeight() != 15)
this->SetHeight(15);
if(value_bar->GetHeight() != 12)
value_bar->SetHeight(12);
LifeMath::Rect2i r = this->GetClientRectangle();
LifeMath::Vec2i pos;
int offset_hor = 2;
int max_path = r.width - 2*offset_hor;
pos.Y = (r.height - value_bar->GetHeight()) / 2;
pos.X = offset_hor;
value_bar->SetPosition(pos);
int length = int(float(max_path) * mValue);
value_bar->SetWidth(length);
}
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef GUIProgress_h__
#define GUIProgress_h__
#include "GUIPlane.h"
namespace LifeGUI
{
class GUIProgress : public GUIPlane
{
public:
GUIProgress();
~GUIProgress();
void SetValue(float val);
float GetValue();
private:
void OnResize(GUIWindow* wnd);
void UpdateLayout();
GUIPlane* value_bar;
float mValue;
};
}
#endif // GUIProgress_h__
+150
View File
@@ -0,0 +1,150 @@
#include "GUIPropertyGrid.h"
#include "GUIText.h"
#include "GUITextInput.h"
namespace LifeGUI
{
GUIPropertyGrid::GUIPropertyGrid()
:target(nullptr)
{
this->SetWidth(100);
this->SetHeight(100);
}
GUIPropertyGrid::~GUIPropertyGrid()
{
}
void GUIPropertyGrid::AddEditor(GUIPropertyEditor* editor)
{
Editors.push_back(editor);
}
GUIPropertyEditor* GUIPropertyGrid::GetEditor(const String& name)
{
for(int i = 0; i < Editors.size(); i++)
{
if(Editors[i]->GetName() == name)
return Editors[i];
}
return 0;
}
LifeCore::IPropertyHolder* GUIPropertyGrid::GetTarget()
{
return target;
}
void GUIPropertyGrid::SetTarget(LifeCore::IPropertyHolder* obj)
{
target = obj;
for(PropertyLineCollectionItr it = Properties.begin(); it != Properties.end(); ++it)
{
//TODO Fix child removal! Failed when not found!
this->RemoveChild((*it)->editor->hwnd);
this->RemoveChild((*it)->header->hwnd);
(*it)->property->Event_ValueChanged.Remove((*it)->ValueChangedDelegate);
//TODO detach property line from event
delete *it;
}
Properties.clear();
if(target != nullptr)
{
PropertyCollection* props = target->GetProperties();
for(int i = 0; i < props->size(); i++)
{
LifeCore::IProperty* p = (*props)[i];
String name = STR("Unnamed property!");
p->GetAttribute(STR("DisplayName"), name);
GUITextInput* text = new GUITextInput();
text->SetText(name);
text->Border = GUIBorder(1);
text->SetForeColor(LifeMath::float4(0,0,0,1));
text->SetBackColor(LifeMath::float4(0,1,0,1));
text->SetBorderEnabled(true);
PropertyGridLine* line = new PropertyGridLine();
line->header = text;
line->property = p;
GUITextInput* input = new GUITextInput();
input->SetText(p->ToString());
input->Event_MouseClick += NewDelegate(this,&GUIPropertyGrid::OnValueMouseDown);
input->SetBorderColor(LifeMath::float4(0,0,0,1));
line->ValueChangedDelegate = NewDelegate(line, &PropertyGridLine::OnValueChanged);
p->Event_ValueChanged += line->ValueChangedDelegate;
line->editor = input;
input->SetBackColor(LifeMath::float4(1,0,0,1));
Properties.push_back(line);
input->UserData = line;
this->AddChild(text);
this->AddChild(input);
String propEditor;
line->propEditor = 0;
if(p->GetAttribute(STR("ValueEditor"), propEditor) == SC_OK)
{
GUIPropertyEditor* edt = GetEditor(propEditor);
line->propEditor = edt;
}
else
{
input->Event_EnterPressed += NewDelegate(this, &GUIPropertyGrid::OnAcceptValue);
}
}
Format();
}
}
void GUIPropertyGrid::OnValueMouseDown(GUIWindow* wnd, int param)
{
PropertyGridLine* line = (PropertyGridLine*)wnd->UserData;
if(line->propEditor)
{
line->propEditor->BeginEdit(line);
}
}
void GUIPropertyGrid::OnAcceptValue(GUITextInput* input)
{
PropertyGridLine* line = (PropertyGridLine*)input->UserData;
line->property->FromString(input->GetText());
}
void GUIPropertyGrid::Format()
{
int lineHeight = 24;
int id = 0;
for(PropertyLineCollectionItr it = Properties.begin(); it != Properties.end(); ++it)
{
GUIWindow* wndProp = (*it)->header;
wndProp->SetPosition(LifeMath::Vec2i(0, lineHeight * id));
wndProp->SetHeight(lineHeight);
wndProp->SetWidth(this->GetClientRectangle().width / 2);
GUIWindow* wndEdit = (*it)->editor;
wndEdit->SetPosition(LifeMath::Vec2i(this->GetClientRectangle().width / 2, lineHeight * id));
wndEdit->SetHeight(lineHeight);
wndEdit->SetWidth(this->GetClientRectangle().width / 2);
id++;
}
}
void GUIPropertyGrid::SetWidth(int val)
{
GUIPlane::SetWidth(val);
Format();
}
void GUIPropertyGrid::SetHeight(int val)
{
GUIPlane::SetHeight(val);
Format();
}
}
+134
View File
@@ -0,0 +1,134 @@
#ifndef GUIPropertyGrid_h__
#define GUIPropertyGrid_h__
#include "GUIText.h"
#include "GUIPlane.h"
#include "GUITextInput.h"
#include "IPropertyHolder.h"
#include "GUIFileBrowserDialog.h"
#include "GUIOverlay.h"
#include <delegate/Delegate.h>
namespace LifeGUI
{
struct PropertyGridLine;
class GUIPropertyEditor
{
public:
EVENT1(PropertyEditorEvent, PropertyGridLine*);
PropertyEditorEvent Event_FinishEdit;
virtual String GetName() = 0;
virtual void BeginEdit(PropertyGridLine* line) = 0;
private:
void OnFinishEdit(PropertyGridLine* line)
{
Event_FinishEdit.Invoke(line);
}
};
struct PropertyGridLine
{
GUITextInput* header;
GUIWindow* editor;
LifeCore::IProperty* property;
GUIPropertyEditor* propEditor;
CDelegate* ValueChangedDelegate;
PropertyGridLine()
{
propEditor = 0;
property = 0;
editor = 0;
header = 0;
ValueChangedDelegate = 0;
}
void OnValueChanged()
{
if(!propEditor || propEditor->GetName() == STR("FilePath"))
{
if(editor)
((GUITextInput*)editor)->SetText(property->ToString());
}
}
};
class GUIPropertyGrid : public GUIPlane
{
public:
GUIPropertyGrid();
~GUIPropertyGrid();
void SetTarget(LifeCore::IPropertyHolder* obj);
LifeCore::IPropertyHolder* GetTarget();
void SetWidth(int val);
void SetHeight(int val);
void AddEditor(GUIPropertyEditor* editor);
GUIPropertyEditor* GetEditor(const String& name);
void OnValueMouseDown(GUIWindow* wnd, int param);
private:
LifeCore::IPropertyHolder* target;
typedef std::vector<PropertyGridLine*> PropertyLineCollection;
typedef std::vector<PropertyGridLine*>::iterator PropertyLineCollectionItr;
typedef std::vector<GUIPropertyEditor*> PropertyEditorCollection;
typedef std::vector<GUIPropertyEditor*>::iterator PropertyEditorCollectionItr;
PropertyLineCollection Properties;
PropertyEditorCollection Editors;
void Format();
void OnAcceptValue(GUITextInput* input);
};
class GUIFilePathPropertyEditor: public GUIPropertyEditor
{
public:
GUIFilePathPropertyEditor(GUIPropertyGrid* _parent)
{
parent = _parent;
fd = 0;
}
String GetName()
{
return STR("FilePath");
}
void BeginEdit(PropertyGridLine* line)
{
prop = line;
printf("Before delete\n");
if(fd)
delete fd;
printf("After delete\n");
fd = new GUIFileBrowserDialog();
//fd->SetFileSystem( );
fd->SetWidth(300);
fd->SetHeight(280);
parent->FindOverlay()->AddChild(fd);
fd->Event_SelectedFile += NewDelegate(this, &GUIFilePathPropertyEditor::OnFileSelected);
}
private:
void OnFileSelected(GUIFileBrowserDialog* dlg)
{
printf("Begin OnFileSelected\n");
if((int)prop->property == 0xfdfdfdfd ||
(int)prop->property == 0xfeeefeee)
{
printf("EPIC FAIL!");
}
prop->property->FromString(dlg->GetSelectedFile());
printf("Begin RemoveChild\n");
parent->FindOverlay()->RemoveChild(fd->hwnd);
printf("End RemoveChild\n");
printf("End OnFileSelected\n");
}
PropertyGridLine* prop;
GUIFileBrowserDialog* fd;
GUIPropertyGrid* parent;
};
}
#endif // GUIPropertyGrid_h__
+111
View File
@@ -0,0 +1,111 @@
#include "GUIRadioButton.h"
namespace LifeGUI
{
GUIRadioButton::GUIRadioButton()
:_checked(false)
{
box = new GUIPlane();
//box->skin_name = STR("Radio:Unchecked:Back");
box->SetStyle(STR("Radio"));
box->SetWidth(19);
box->SetHeight(19);
this->AddChild(box);
text = new GUIText();
text->SetText(STR("RadioButton"));
text->SetPosition(LifeMath::Vec2i(box->GetWidth(), 0));
text->SetAutoSize(true);
text->SetVAlign(VA_CENTER);
this->AddChild(text);
box->SetBorderEnabled(false);
text->SetBorderEnabled(false);
box->Event_MouseClick += NewDelegate(this, &GUIRadioButton::OnBoxClick);
UpdateLayout();
}
GUIRadioButton::~GUIRadioButton()
{
if(box)
delete box;
if(text)
delete text;
}
void GUIRadioButton::UpdateLayout()
{
int h1, h2;
//
//
h1 = box->GetHeight();
h2 = text->GetHeight();
int text_offset = 5;
if(h1 == h2)
{
this->SetHeight(h1);
box->SetPosition(LifeMath::Vec2i(0,0));
text->SetPosition(LifeMath::Vec2i(box->GetWidth() + text_offset, 0));
}
else if(h1 > h2)
{
this->SetHeight(h1);
box->SetPosition(LifeMath::Vec2i(0,0));
text->SetPosition(LifeMath::Vec2i(box->GetWidth() + text_offset, (h1 - h2) / 2));
}
else
{
this->SetHeight(h2);
box->SetPosition(LifeMath::Vec2i(0,(h2 - h1) / 2));
text->SetPosition(LifeMath::Vec2i(box->GetWidth() + text_offset, 0));
}
this->SetWidth(box->GetWidth() + text->GetWidth() + text_offset);
}
void GUIRadioButton::OnBoxClick(GUIWindow* wnd, int v)
{
InternalSetChecked(!_checked);
}
void GUIRadioButton::InternalSetChecked(bool state)
{
if(_checked != state)
{
_checked = state;
if(_checked)
{
box->state = "Pressed";
//box->skin_name = STR("Radio:Checked:Back");
}
else
{
box->state = "Normal";
box->skin_name = STR("Radio:Unchecked:Back");
}
box->Invalidate();
Event_CheckChanged.Invoke(this);
}
}
bool GUIRadioButton::IsChecked()
{
return _checked;
}
void GUIRadioButton::SetChecked(bool state)
{
InternalSetChecked(state);
}
void GUIRadioButton::SetText(const String& _text)
{
text->SetText(_text);
}
const String& GUIRadioButton::GetText()
{
return text->GetText();
}
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef GUIRadioButton_h__
#define GUIRadioButton_h__
#include "GUIPlane.h"
#include "GUIText.h"
namespace LifeGUI
{
class GUIRadioButton : public GUIWindow
{
public:
EVENT1(CheckEvent, GUIRadioButton*);
CheckEvent Event_CheckChanged;
GUIRadioButton();
~GUIRadioButton();
bool IsChecked();
void SetChecked(bool state);
void SetText(const String& _text);
const String& GetText();
private:
void InternalSetChecked(bool state);
void OnBoxClick(GUIWindow* wnd, int v);
bool _checked;
void UpdateLayout();
GUIPlane* box;
GUIText* text;
};
}
#endif // GUIRadioButton_h__
+82
View File
@@ -0,0 +1,82 @@
#include "GUIRenderWindow.h"
#include <GUIOverlay.h>
namespace LifeGUI
{
GUIRenderWindow::GUIRenderWindow(){
picture = new GUIPicture();
picture->Event_Resize += NewDelegate(this, &LifeGUI::GUIRenderWindow::OnPictureResize);
picture->NeedKeyFocus = true;
input_provider = new GUIInputProvider();
input_provider->SetWindow(picture);
}
void GUIRenderWindow::OnPictureResize(LifeGUI::GUIWindow* sender){
Event_Resize.Invoke(this);
}
GUIPicture* GUIRenderWindow::GetGUIWindow(){
return picture;
}
void GUIRenderWindow::Update(){
}
void GUIRenderWindow::SetCaption(const String& caption){
}
int GUIRenderWindow::GetWindowHandle(){
return -1;
}
int GUIRenderWindow::GetWidth(){
return picture->GetWidth();
}
int GUIRenderWindow::GetHeight(){
return picture->GetHeight();
}
void GUIRenderWindow::SetSize(int w, int h){
}
const String& GUIRenderWindow::GetCaption(){
return "GUIRenderWindow";
}
bool GUIRenderWindow::IsFullScreen(){
return false;
}
void GUIRenderWindow::SetFullScreen(bool state){
}
bool GUIRenderWindow::SwitchMode(bool fullscreen){
return false;
}
void GUIRenderWindow::SetFullscreenMode(LifeCore::DisplayMode mode){
}
void GUIRenderWindow::OnActivate(){
}
void GUIRenderWindow::OnDeactivate(){
}
void GUIRenderWindow::OnResize(){
}
bool GUIRenderWindow::IsActive(){
return true;
}
bool GUIRenderWindow::IsModeSwitching(){
return false;
}
void GUIRenderWindow::SetCursorVisible(bool state){
}
bool GUIRenderWindow::IsCursorVisible(){
return true;
}
void GUIRenderWindow::CenterWindow(){
}
LifeCore::IInputSystem* GUIRenderWindow::GetInputSystem(){
return input_provider;
}
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef GUIRenderWindow_h__
#define GUIRenderWindow_h__
#include "GUIPicture.h"
#include "IRenderWindow.h"
#include <IInputSystem.h>
#include <vector>
#include "GUIInputProvider.h"
namespace LifeGUI
{
class GUIRenderWindow : public LifeCore::IRenderWindow
{
public:
GUIRenderWindow();
GUIPicture* GetGUIWindow();
void Update();
void SetCaption(const String& caption);
int GetWindowHandle();
int GetWidth();
int GetHeight();
void SetSize(int w, int h);
const String& GetCaption();
bool IsFullScreen();
void SetFullScreen(bool state);
bool SwitchMode(bool fullscreen);
void SetFullscreenMode(LifeCore::DisplayMode mode);
void OnActivate();
void OnDeactivate();
void OnResize();
bool IsActive();
bool IsModeSwitching();
void SetCursorVisible(bool state);
bool IsCursorVisible();
void CenterWindow();
LifeCore::IInputSystem* GetInputSystem();
private:
void OnPictureResize(LifeGUI::GUIWindow* sender);
GUIPicture* picture;
GUIInputProvider* input_provider;
};
}
#endif // GUIRenderWindow_h__
+310
View File
@@ -0,0 +1,310 @@
#include "GUIScroll.h"
#include "GUIManager.h"
#include "GUIButton.h"
namespace LifeGUI
{
GUIScroll::GUIScroll(bool _vertical)
:vertical(_vertical), sliding(false), content_ratio(1.0f), sc_size(10), scroll_range(100), scroll_value(0),
sc_min_size(10), thickness(14)
{
b1 = new GUIPlane();
b2 = new GUIPlane();
scroller = new GUIButton();
scroller->SetCaption(STR(""));
this->AddChild(b1);
this->AddChild(b2);
this->AddChild(scroller);
scroller->Event_MouseDown += NewDelegate(this, &GUIScroll::BeginSliding);
scroller->Event_MouseUp += NewDelegate(this, &GUIScroll::EndSliding);
scroller->Event_MouseMove += NewDelegate(this, &GUIScroll::DoSliding);
b1->Event_MouseDown += NewDelegate(this, &GUIScroll::OnMinClick);
b2->Event_MouseDown += NewDelegate(this, &GUIScroll::OnMaxClick);
scroller->SetBorderColor(LifeMath::float4(0.3f, 0.3f, 0.3f, 1.0f));
scroller->SetBorderEnabled(false);
scroller->SetPosition(LifeMath::Vec2i(0,0));
this->SetBackColor(LifeMath::float4(1,1,1,1));
this->SetBorderEnabled(false);
b1->SetBorderEnabled(false);
b2->SetBorderEnabled(false);
if(vertical)
{
scroller->SetStyle(STR("VScroll_slider"));
this->SetStyle(STR("VScroll"));
b1->SetStyle(STR("VScroll_up"));
b2->SetStyle(STR("VScroll_down"));
}
else
{
scroller->SetStyle(STR("HScroll_slider"));
this->SetStyle(STR("HScroll"));
b1->SetStyle(STR("HScroll_left"));
b2->SetStyle(STR("HScroll_right"));
}
this->Event_Resize += NewDelegate(this, &GUIScroll::UpdateLayout);
if(vertical)
{
this->SetWidth(thickness);
this->SetHeight(200);
}
else
{
this->SetWidth(200);
this->SetHeight(thickness);
}
}
void GUIScroll::SetScrollRange(int range)
{
scroll_range = range;
if(scroll_value > range)
scroll_value = range;
UpdateLayout(this);
}
void GUIScroll::OnMinClick(GUIWindow* w, int p)
{
if(vertical)
{
LifeMath::Vec2i pos = scroller->GetPosition();
pos.Y -=1;
scroller->SetPosition(pos);
ComputeValue();
UpdateLayout(this);
Event_Scroll.Invoke(this, GetValue());
}
else
{
LifeMath::Vec2i pos = scroller->GetPosition();
pos.X -=1;
scroller->SetPosition(pos);
ComputeValue();
UpdateLayout(this);
Event_Scroll.Invoke(this, GetValue());
}
}
void GUIScroll::OnMaxClick(GUIWindow* w, int p)
{
}
GUIScroll::~GUIScroll()
{
}
void GUIScroll::BeginSliding(GUIWindow* w, int p)
{
this->FindOverlay()->GrabMouse(w);
LifeMath::Vec2i pos = FindOverlay()->cursorPos;
scroller_click = scroller->CursorToLocal(pos);
sliding = true;
}
void GUIScroll::EndSliding(GUIWindow* w, int p)
{
this->FindOverlay()->ReleaseMouse();
sliding = false;
}
void GUIScroll::DoSliding(GUIWindow* w, int p)
{
if(sliding)
{
LifeMath::Vec2i pos = FindOverlay()->cursorPos;
pos = this->CursorToClient(pos) - scroller_click;
if(vertical)
{
if(pos.Y < button_size)
pos.Y = button_size;
if(pos.Y > (button_size + sc_max_path)) pos.Y = (button_size + sc_max_path);
LifeMath::Vec2i cp = scroller->GetPosition();
if(cp.Y != pos.Y)
{
cp.Y = pos.Y;
sc_offset = cp.Y;
scroller->SetPosition(cp);
ComputeValue();
//invoke event
Event_Scroll.Invoke(this, GetValue());
}
}
else
{
if(pos.X < button_size) pos.X = button_size;
if(pos.X > (button_size + sc_max_path)) pos.X = (button_size + sc_max_path);
LifeMath::Vec2i cp = scroller->GetPosition();
if(cp.X != pos.X)
{
cp.X = pos.X;
sc_offset = cp.X;
scroller->SetPosition(cp);
ComputeValue();
//invoke event
Event_Scroll.Invoke(this, GetValue());
}
}
}
}
void GUIScroll::ComputeValue()
{
int val;
if(vertical)
{
val = scroller->GetPosition().Y;
}
else
val = scroller->GetPosition().X;
val-= button_size;
if(scroll_range > sc_max_path)
{
float scale = float(scroll_range) / float(sc_max_path);
scroll_value = int(floorf(float(val) * scale + 0.5f));
}
else
{
scroll_value = val;
}
}
int GUIScroll::GetValue()
{
return scroll_value;
}
void GUIScroll::UpdateLayout(GUIWindow* w)
{
LifeMath::Rect2i rect_container = GetClientRectangle();
if(vertical)
{
button_size = rect_container.width;
//scrollable distance between buttons
inner_size = rect_container.height - (button_size * 2);
}
else
{
button_size = rect_container.height;
//scrollable distance between buttons
inner_size = rect_container.width - (button_size * 2);
}
//compute scroller vertical size
sc_size = inner_size - scroll_range;
//fix up scroller size (if it is smaller than minimal allowed size)
if(sc_size < sc_min_size) sc_size = sc_min_size;
sc_max_path = inner_size - sc_size;
sc_offset = int((float(scroll_value) / float(scroll_range)) * float(sc_max_path));
b1->SetWidth(button_size);
b1->SetHeight(button_size);
b2->SetWidth(button_size);
b2->SetHeight(button_size);
b1->SetPosition(LifeMath::Vec2i(0, 0));
if(vertical)
{
b2->SetPosition(LifeMath::Vec2i(0, inner_size + button_size));
scroller->SetPosition(LifeMath::Vec2i(0, sc_offset + button_size));
scroller->SetWidth(button_size);
scroller->SetHeight(sc_size);
}
else
{
b2->SetPosition(LifeMath::Vec2i(inner_size + button_size, 0));
scroller->SetPosition(LifeMath::Vec2i(sc_offset + button_size, 0));
scroller->SetWidth(sc_size);
scroller->SetHeight(button_size);
}
/*LifeMath::Rect2i r = GetClientRectangle();
int max_size;
if(vertical)
{
max_size = r.height - b1->GetHeight() - b2->GetHeight();
sc_size = int((float)max_size / content_ratio);
if(sc_size < 10) sc_size = 10;
scroller->SetHeight(sc_size);
}
else
{
max_size = r.width - b1->GetWidth() - b2->GetWidth();
sc_size = int((float)max_size / content_ratio);
if(sc_size < 10) sc_size = 10;
scroller->SetWidth(sc_size);
}
if(vertical)
{
b1->SetWidth(GetClientRectangle().width - 1);
b2->SetWidth(GetClientRectangle().width - 1);
b1->SetHeight(GetClientRectangle().width - 1);
b2->SetHeight(GetClientRectangle().width - 1);
scroller->SetWidth(GetClientRectangle().width);
scroller->SetHeight(sc_size);
//fix slider size
int max_track_size = this->GetClientRectangle().height - b1->GetHeight() - b2->GetHeight();
int new_slider_size = max_track_size - scroll_range;
if(new_slider_size < sc_min_size) new_slider_size = sc_min_size;
scroller->SetHeight(new_slider_size);
//fix up scroller pos
if((new_slider_size + scroller->GetPosition().Y) > max_track_size)
{
sc_offset = max_track_size - new_slider_size;
scroller->SetPosition(LifeMath::Vec2i(0, max_track_size - new_slider_size));
// Event_Scroll.Invoke(this, GetValue());
}
sc_max_path = this->GetClientRectangle().height - b1->GetHeight() - b2->GetHeight() - scroller->GetHeight();
sc_offset = b1->GetHeight();
min_c = sc_offset;
max_c = sc_max_path + sc_offset;
if(scroller->GetPosition().Y < sc_offset)
{
scroller->SetPosition(LifeMath::Vec2i(0,sc_offset));
// Event_Scroll.Invoke(this, GetValue());
}
b1->SetPosition(LifeMath::Vec2i(0, 0));
b2->SetPosition(LifeMath::Vec2i(0, GetClientRectangle().height - b2->GetHeight()));
}
else
{
b1->SetWidth(GetClientRectangle().height - 1);
b2->SetWidth(GetClientRectangle().height - 1);
b1->SetHeight(GetClientRectangle().height - 1);
b2->SetHeight(GetClientRectangle().height - 1);
scroller->SetWidth(sc_size);
scroller->SetHeight(GetClientRectangle().height);
//fix slider size
int max_track_size = this->GetClientRectangle().width - b1->GetWidth() - b2->GetWidth();
int new_slider_size = max_track_size - scroll_range;
if(new_slider_size < sc_min_size) new_slider_size = sc_min_size;
scroller->SetWidth(new_slider_size);
//fix up scroller pos
if((new_slider_size + scroller->GetPosition().X) > max_track_size)
{
sc_offset = max_track_size - new_slider_size;
scroller->SetPosition(LifeMath::Vec2i(max_track_size - new_slider_size, 0));
//Event_Scroll.Invoke(this, GetValue());
}
sc_max_path = this->GetClientRectangle().width - b1->GetWidth() - b2->GetWidth() - scroller->GetWidth();
sc_offset = b1->GetWidth();
min_c = sc_offset;
max_c = sc_max_path + sc_offset;
if(scroller->GetPosition().X < sc_offset)
{
scroller->SetPosition(LifeMath::Vec2i(sc_offset, 0));
}
b1->SetPosition(LifeMath::Vec2i(0, 0));
b2->SetPosition(LifeMath::Vec2i(GetClientRectangle().width - b2->GetWidth(), 0));
}*/
}
}
+55
View File
@@ -0,0 +1,55 @@
#ifndef GUIScroll_h__
#define GUIScroll_h__
#include "GUIPlane.h"
#include "GUIButton.h"
#include <delegate/Delegate.h>
namespace LifeGUI
{
class GUIScroll : public GUIPlane
{
public:
EVENT2(ScrollEvent, GUIScroll*, int);
ScrollEvent Event_Scroll;
GUIScroll(bool _vertical);
~GUIScroll();
void SetScrollRange(int range);
int GetValue();
int GetThickness()
{
return thickness;
}
private:
size_t ValToOffset(size_t val);
size_t OffsetToVal(size_t offset);
int thickness;
bool vertical;
void ComputeValue();
void UpdateLayout(GUIWindow* w);
void BeginSliding(GUIWindow* w, int p);
void EndSliding(GUIWindow* w, int p);
void DoSliding(GUIWindow* w, int p);
void OnMinClick(GUIWindow* w, int p);
void OnMaxClick(GUIWindow* w, int p);
GUIPlane* b1;
GUIPlane* b2;
GUIButton* scroller;
int sc_max_path;
int sc_pos;
int sc_offset;
int inner_size;
int button_size;
int sc_size;
int sc_min_size;
bool sliding;
int min_c, max_c;
LifeMath::Vec2i scroller_click;
float content_ratio;
int scroll_range;
int scroll_value;
};
}
#endif // GUIScroll_h__
+206
View File
@@ -0,0 +1,206 @@
#include "GUIScrollablePlane.h"
namespace LifeGUI
{
GUIScrollablePlane::GUIScrollablePlane()
:hscroll_enable(true),vscroll_enable(true), invalid(false)
{
hscroll = new GUIScroll(false);
vscroll = new GUIScroll(true);
container = new GUIPlane();
corner = new GUIPlane();
corner->SetWidth(vscroll->GetWidth());
corner->SetHeight(vscroll->GetWidth());
corner->SetBackColor(LifeMath::float4(1.0f, 1.0f, 1.0f, 1.0f));
container->SetBackColor(LifeMath::float4(1.0f, 0.0f, 0.0f, 0.0f));
corner->SetStyle(STR("ScrollablePlane"));
this->SetStyle(STR("ScrollablePlane"));
this->SetBorderEnabled(true);
this->SetBorderColor(LifeMath::float4(0.0f, 0.0f, 0.0f, 1.0f));
corner->SetBorderEnabled(false);
GUIWindow::AddChild(hscroll);
GUIWindow::AddChild(vscroll);
GUIWindow::AddChild(container);
GUIWindow::AddChild(corner);
vscroll->Event_Scroll += NewDelegate(this, &GUIScrollablePlane::OnScrollVertical);
hscroll->Event_Scroll += NewDelegate(this, &GUIScrollablePlane::OnScrollHorisontal);
this->Event_Resize += NewDelegate(this, &GUIScrollablePlane::UpdateLayout);
container->SetBorderEnabled(false);
this->Border.SetSize(1);
UpdateLayout(this);
}
int GUIScrollablePlane::RemoveChild(int hwnd)
{
return container->RemoveChild(hwnd);
}
void GUIScrollablePlane::OnScrollVertical(GUIScroll* wnd, int param)
{
//Invalidate();
UpdateLayout(wnd);
}
void GUIScrollablePlane::OnScrollHorisontal(GUIScroll* wnd, int param)
{
//Invalidate();
UpdateLayout(wnd);
}
void GUIScrollablePlane::RenderSelf()
{
LifeMath::Rect2i r = container->GetContentRectangle();
if(r!= content_rect || invalid)
{
content_rect = r;
UpdateLayout(this);
}
GUIPlane::RenderSelf();
}
GUIScrollablePlane::~GUIScrollablePlane()
{
}
void GUIScrollablePlane::AddChild(GUIWindow* val)
{
container->AddChild(val);
}
LifeMath::Rect2i GUIScrollablePlane::GetClientRectangle()
{
LifeMath::Vec2i pos = this->GetPosition();
LifeMath::Rect2i rect;
if(borderEnabled)
{
rect = LifeMath::Rect2i(Border.Left, Border.Top, width - (Border.Left + Border.Right), height - (Border.Top + Border.Bottom));
}
else
{
rect = LifeMath::Rect2i(0, 0, width, height);
}
/* if(vscroll_enable)
rect.width -= vscroll->GetWidth();
if(hscroll_enable)
rect.height -= vscroll->GetHeight();*/
return rect;
}
LifeMath::Rect2i GUIScrollablePlane::GetClientRectangleAbs()
{
LifeMath::Vec2i pos = this->GetPositionAbs();
LifeMath::Rect2i rect;
if(borderEnabled)
{
rect = LifeMath::Rect2i(pos.X + Border.Left, pos.Y + Border.Top, width - (Border.Left + Border.Right), height - (Border.Top + Border.Bottom));
}
else
{
rect = LifeMath::Rect2i(pos.X, pos.Y, width, height);
}
/*if(vscroll_enable)
rect.width -= vscroll->GetWidth();
if(hscroll_enable)
rect.height -= vscroll->GetHeight();*/
return rect;
}
void GUIScrollablePlane::UpdateLayout(GUIWindow* wnd)
{
LifeMath::Rect2i r = this->GetClientRectangle();
LifeMath::Rect2i rc = container->GetContentRectangle();
hscroll_enable = rc.GetMaxX() > r.width;
vscroll_enable = rc.GetMaxY() > r.height;
int w = r.width;
int h = r.height;
if(vscroll_enable)
w -= vscroll->GetWidth();
if(hscroll_enable)
h -= vscroll->GetWidth();
if(rc.GetMaxX() > r.width)
{
//hscroll->SetContentRatio(float(rc.GetMaxX()) / float(r.width));
hscroll->SetScrollRange(rc.GetMaxX() - w);
hscroll_enable = true;
hscroll->Show();
}
else
{
hscroll_enable = false;
hscroll->Hide();
}
if(rc.GetMaxY() > r.height)
{
//hscroll->SetContentRatio(float(rc.GetMaxY()) / float(r.height));
vscroll->SetScrollRange(rc.GetMaxY() - h);
vscroll_enable = true;
vscroll->Show();
}
else
{
vscroll_enable = false;
vscroll->Hide();
}
if(vscroll_enable && hscroll_enable)
{
corner->Show();
corner->SetPosition(LifeMath::Vec2i(r.width - vscroll->GetWidth(), r.height - vscroll->GetWidth()));
}
else
{
corner->Hide();
}
container_size.X = w;
container_size.Y = h;
if(hscroll_enable)
{
hscroll->SetWidth(w);
hscroll->SetHeight(hscroll->GetThickness());
hscroll->SetPosition(LifeMath::Vec2i(0, r.height - hscroll->GetHeight()));
}
if(vscroll_enable)
{
vscroll->SetHeight(h);
// vscroll->SetWidth(13);
vscroll->SetPosition(LifeMath::Vec2i(r.width - vscroll->GetWidth(), 0));
}
LifeMath::Vec2i new_pos;
LifeMath::Vec2i new_size(w, h);
if(vscroll_enable)
{
new_pos.Y = -vscroll->GetValue();
//container->SetPosition(pos);
new_size.Y = container_size.Y + vscroll->GetValue();
//container->SetHeight();
}
if(hscroll_enable)
{
//LifeMath::Vec2i pos = container->GetPosition();
new_pos.X = -hscroll->GetValue();
//container->SetPosition(pos);
new_size.X = container_size.X + hscroll->GetValue();
//container->SetWidth(container_size.X - container->GetPosition().X);
}
container->SetWidth(new_size.X);
container->SetHeight(new_size.Y);
//container->SetPosition(LifeMath::Vec2i(0, -200));
container->SetPosition(new_pos);
}
}
+50
View File
@@ -0,0 +1,50 @@
#ifndef GUIScrollablePlane_h__
#define GUIScrollablePlane_h__
#include "GUIPlane.h"
#include "GUIScroll.h"
namespace LifeGUI
{
class GUIScrollablePlane : public GUIPlane
{
private:
bool hscroll_enable;
bool vscroll_enable;
GUIScroll* hscroll;
GUIScroll* vscroll;
GUIPlane* container;
GUIPlane* corner;
void UpdateLayout(GUIWindow* wnd);
void OnScrollVertical(GUIScroll* wnd, int param);
void OnScrollHorisontal(GUIScroll* wnd, int param);
bool invalid;
LifeMath::Vec2i container_size;
protected:
void RenderSelf();
public:
void Invalidate()
{
GUIPlane::Invalidate();
invalid = true;
}
GUIScrollablePlane();
~GUIScrollablePlane();
void AddChild(GUIWindow* val);
int RemoveChild(int hwnd);
LifeMath::Rect2i content_rect;
LifeMath::Rect2i GetClientRectangle();
LifeMath::Rect2i GetClientRectangleAbs();
GUIScroll* GetHScroll()
{
return hscroll;
}
GUIScroll* GetVScroll()
{
return vscroll;
}
};
}
#endif // GUIScrollablePlane_h__
+223
View File
@@ -0,0 +1,223 @@
#include "GUISlider.h"
#include "GUIOverlay.h"
namespace LifeGUI
{
GUISlider::GUISlider(bool isVertical)
:vertical(isVertical), slider_size(18), value_min(0.0f), value_max(1.0f), value_now(0.5f),
sliding(false)
{
if(vertical)
{
this->SetWidth(50);
this->SetHeight(300);
}
else
{
this->SetWidth(300);
this->SetHeight(50);
}
track_left = new GUIPlane();
track_right = new GUIPlane();
slider = new GUIPlane();
this->AddChild(track_left);
this->AddChild(track_right);
this->AddChild(slider);
track_right->SetBorderEnabled(false);
track_left->SetBorderEnabled(false);
slider->SetBorderEnabled(false);
if(!vertical)
{
track_left->SetStyle(STR("HSlider_left"));
track_right->SetStyle(STR("HSlider_right"));
slider->SetStyle(STR("HSlider_slider"));
}
else
{
track_left->SetStyle(STR("VSlider_left"));
track_right->SetStyle(STR("VSlider_right"));
slider->SetStyle(STR("VSlider_slider"));
}
slider->Event_MouseDown += NewDelegate(this, &GUISlider::OnBeginSlide);
slider->Event_MouseUp += NewDelegate(this, &GUISlider::OnEndSlide);
slider->Event_MouseMove += NewDelegate(this, &GUISlider::OnDoSlide);
track_left->Event_MouseDown += NewDelegate(this, &GUISlider::OnDoClick);
track_right->Event_MouseDown += NewDelegate(this, &GUISlider::OnDoClick);
this->skip_mouse = true;
this->mouseEnabled = true;
UpdateLayout(this);
this->Event_Resize += NewDelegate(this, &GUISlider::UpdateLayout);
}
void GUISlider::OnBeginSlide(GUIWindow* w, int p)
{
sliding = true;
LifeMath::Rect2i r = slider->GetClientRectangleAbs();
slide_offset = (r.GetMin() + (r.GetMax() - r.GetMin()) / 2) - FindOverlay()->cursorPos;
FindOverlay()->GrabMouse(w);
}
void GUISlider::OnEndSlide(GUIWindow* w, int p)
{
sliding = false;
FindOverlay()->ReleaseMouse();
}
void GUISlider::OnDoClick(GUIWindow* w, int p)
{
SetValue(PointToValue(FindOverlay()->cursorPos));
Event_MouseDown.Invoke(this, 0);
}
float GUISlider::PointToValue(const LifeMath::Vec2i& point)
{
if(!vertical)
{
LifeMath::Rect2i r = this->GetClientRectangleAbs();
int minX = r.x + slider_size.X / 2;
int maxX = r.x + r.width - slider_size.X / 2;
int cursor_pos = point.X + slide_offset.X;
if(cursor_pos < minX) cursor_pos = minX;
if(cursor_pos > maxX) cursor_pos = maxX;
float a = float(cursor_pos - minX) / float(maxX - minX);
return value_min * (1 - a) + value_max * a;
}
else
{
LifeMath::Rect2i r = this->GetClientRectangleAbs();
int minY = r.y + slider_size.Y / 2;
int maxY = r.y + r.height - slider_size.Y / 2;
int cursor_pos = point.Y + slide_offset.Y;
if(cursor_pos < minY) cursor_pos = minY;
if(cursor_pos > maxY) cursor_pos = maxY;
float a = float(cursor_pos - minY) / float(maxY - minY);
return value_min * (1 - a) + value_max * a;
}
}
void GUISlider::OnDoSlide(GUIWindow* w, int p)
{
if(sliding)
{
SetValue(PointToValue(FindOverlay()->cursorPos));
}
}
GUISlider::~GUISlider()
{
}
void GUISlider::UpdateLayout(GUIWindow* w)
{
slider->SetWidth(slider_size.X);
slider->SetHeight(slider_size.Y);
int track_size = 6;
if(!vertical)//horizontal
{
int width = this->GetWidth() - slider_size.X;
float a = (value_now - value_min) / (value_max - value_min);
int offset = int(float(width) * a);
LifeMath::Vec2i pos;
pos.Y = (this->GetHeight() - track_size) / 2;
pos.X = slider_size.X / 2;
track_left->SetPosition(pos);
track_left->SetWidth(offset);
track_left->SetHeight(track_size);
pos.X += offset;
track_right->SetPosition(pos);
track_right->SetWidth(width - offset);
track_right->SetHeight(track_size);
pos.Y += track_size / 2;
pos -= (slider_size / 2);
slider->SetPosition(pos);
}
else
{
int height = this->GetHeight() - slider_size.Y;
float a = (value_now - value_min) / (value_max - value_min);
int offset = int(float(height) * a);
LifeMath::Vec2i pos;
pos.X = (this->GetWidth() - track_size) / 2;
pos.Y = slider_size.Y / 2;
track_left->SetPosition(pos);
track_left->SetHeight(offset);
track_left->SetWidth(track_size);
pos.Y += offset;
track_right->SetPosition(pos);
track_right->SetHeight(height - offset);
track_right->SetWidth(track_size);
pos.X += track_size / 2;
pos -= (slider_size / 2);
slider->SetPosition(pos);
}
}
void GUISlider::SetStartValue(float val)
{
if(val > value_max)
val = value_max;
value_min = val;
if(value_now < value_min)
SetValue(value_min);
}
void GUISlider::SetEndValue(float val)
{
if(val < value_min)
val = value_min;
value_max = val;
if(value_now > value_max)
SetValue(value_max);
}
void GUISlider::SetValue(float val)
{
if(value_now == val) return;
value_now = val;
if(value_now > value_max)
value_now = value_max;
if(value_now < value_min)
value_now = value_min;
UpdateLayout(this);
Event_ValueChanged.Invoke(this, value_now);
}
float GUISlider::GetValue()
{
return value_now;
}
void GUISlider::OnBeginSliding(GUIWindow* w, int p)
{
}
void GUISlider::OnEndSliding(GUIWindow* w, int p)
{
}
void GUISlider::OnDoSliding(GUIWindow* w, int p)
{
}
void GUISlider::OnTapRight(GUIWindow* w, int p)
{
}
void GUISlider::OnTapLeft(GUIWindow* w, int p)
{
}
}
+48
View File
@@ -0,0 +1,48 @@
#ifndef GUISlider_h__
#define GUISlider_h__
#include "GUIPlane.h"
namespace LifeGUI
{
class GUISlider : public GUIWindow
{
public:
EVENT2(SliderEvent, GUISlider*, float);
SliderEvent Event_ValueChanged;
GUISlider(bool isVertical);
~GUISlider();
void SetStartValue(float val);
void SetEndValue(float val);
void SetValue(float val);
float GetValue();
protected:
void OnBeginSliding(GUIWindow* w, int p);
void OnEndSliding(GUIWindow* w, int p);
void OnDoSliding(GUIWindow* w, int p);
void OnTapRight(GUIWindow* w, int p);
void OnTapLeft(GUIWindow* w, int p);
void OnBeginSlide(GUIWindow* w, int p);
void OnEndSlide(GUIWindow* w, int p);
void OnDoSlide(GUIWindow* w, int p);
void OnDoClick(GUIWindow* w, int p);
private:
float PointToValue(const LifeMath::Vec2i& point);
LifeMath::Vec2i slide_offset;
LifeMath::Vec2i slider_size;
void UpdateLayout(GUIWindow* w);
bool vertical;
bool sliding;
GUIPlane* track_left;
GUIPlane* track_right;
GUIPlane* slider;
float value_min;
float value_max;
float value_now;
};
}
#endif // GUISlider_h__
+244
View File
@@ -0,0 +1,244 @@
#include "GUISplitPanel.h"
#include "GUIManager.h"
#include "GUIPlane.h"
namespace LifeGUI
{
GUISplitPanel::GUISplitPanel()
:splitter_vertical(true), splitter_size(7), splitter_pos(100),
minPanelSize(30), size_mode(false), update_realtime(false)
{
width = 200;
height = 200;
plane1 = new GUIPlane();
plane2 = new GUIPlane();
plane_split = new GUIPlane();
plane1->SetBorderColor(LifeMath::float4(0,0,0,1));
plane2->SetBorderColor(LifeMath::float4(0,0,0,1));
plane_split->SetBorderColor(LifeMath::float4(0,0,0,1));
plane_split->SetBackColor(LifeMath::float4(0.4f,0.4f,0.4f,1));
// plane_split->mouseEnabled = false;
plane_split->cursor = STR("Size_v");
plane_split->Event_MouseDown += NewDelegate(this, &GUISplitPanel::OnBeginSlide);
plane_split->Event_MouseUp += NewDelegate(this, &GUISplitPanel::OnEndSlide);
plane_split->Event_MouseMove += NewDelegate(this, &GUISplitPanel::OnDoSlide);
AddChild(plane1);
AddChild(plane2);
AddChild(plane_split);
UpdatePanels();
}
GUISplitPanel::~GUISplitPanel()
{
}
void GUISplitPanel::SetSplitterPosition(size_t pos)
{
splitter_pos = pos;
UpdatePanels();
}
void GUISplitPanel::SetBorderEnabled(bool state)
{
plane1->SetBorderEnabled(state);
plane2->SetBorderEnabled(state);
this->Invalidate();
}
void GUISplitPanel::UpdatePanels()
{
if(splitter_vertical)
{
if(splitter_pos < minPanelSize)
splitter_pos = minPanelSize;
if((this->GetWidth() - splitter_pos - splitter_size) < minPanelSize)
splitter_pos = this->GetWidth() - minPanelSize - splitter_size;
plane1->SetPosition(LifeMath::Vec2i(0,0));
plane1->SetWidth(splitter_pos);
plane1->SetHeight(this->GetHeight());
plane2->SetPosition(LifeMath::Vec2i(splitter_pos + splitter_size, 0));
plane2->SetWidth(this->GetWidth() - splitter_pos - splitter_size);
plane2->SetHeight(this->GetHeight());
plane_split->SetPosition(LifeMath::Vec2i(splitter_pos, 0));
plane_split->SetWidth(splitter_size);
plane_split->SetHeight(this->GetHeight());
}
else
{
if(splitter_pos < minPanelSize)
splitter_pos = minPanelSize;
if((this->GetHeight() - splitter_pos - splitter_size) < minPanelSize)
splitter_pos = this->GetHeight() - minPanelSize - splitter_size;
plane1->SetPosition(LifeMath::Vec2i(0,0));
plane1->SetWidth(this->GetWidth());
plane1->SetHeight(splitter_pos);
plane2->SetPosition(LifeMath::Vec2i(0, splitter_pos + splitter_size));
plane2->SetWidth(this->GetWidth());
plane2->SetHeight(this->GetHeight() - splitter_pos - splitter_size);
plane_split->SetPosition(LifeMath::Vec2i(0, splitter_pos));
plane_split->SetWidth(this->GetWidth());
plane_split->SetHeight(splitter_size);
}
}
GUIWindow* GUISplitPanel::GetContainer1()
{
return plane1;
}
GUIWindow* GUISplitPanel::GetContainer2()
{
return plane2;
}
void GUISplitPanel::SetWidth(int val)
{
width = val;
UpdatePanels();
}
void GUISplitPanel::SetHeight(int val)
{
height = val;
UpdatePanels();
}
void GUISplitPanel::Update(float dt)
{
}
void GUISplitPanel::SetBackColor(const LifeMath::float4& color)
{
}
void GUISplitPanel::SetSplitterHorisontal(bool state)
{
splitter_vertical = !state;
if(splitter_vertical)
plane_split->cursor = STR("Size_v");
else
plane_split->cursor = STR("Size_h");
UpdatePanels();
}
void GUISplitPanel::SetRealtimeResize(bool state)
{
update_realtime = state;
}
void GUISplitPanel::OnBeginSlide(GUIWindow* wnd, int p)
{
//transform cursor coordinate to local space
FindOverlay()->GrabMouse(wnd);
size_mode = true;
//a little bit different code for vertical and horizontal splitters
if(splitter_vertical)
click_offset = FindOverlay()->cursorPos.X - plane_split->GetPositionAbs().X;
else
click_offset = FindOverlay()->cursorPos.Y - plane_split->GetPositionAbs().Y;
}
void GUISplitPanel::OnEndSlide(GUIWindow* wnd, int p)
{
FindOverlay()->ReleaseMouse();
size_mode = false;
UpdatePanels();
}
void GUISplitPanel::OnDoSlide(GUIWindow* wnd, int p)
{
LifeMath::Vec2i pos = CursorToLocal(FindOverlay()->cursorPos);
if(size_mode)
{
if(splitter_vertical)
{
splitter_pos = pos.X - click_offset;
}
else
{
splitter_pos = pos.Y - click_offset;
}
if(update_realtime)
UpdatePanels();
}
}
bool GUISplitPanel::ProcessMessage(GUIMessageType mt, GUIMessageParam mp, IMessageArgs* args)
{
/*if(mt == GM_MOUSE)
{
if(mp == MP_KEY_DOWN)
{
IMouseArgs* a = static_cast<IMouseArgs*>(args);
//transform cursor coordinate to local space
LifeMath::Vec2i pos = CursorToLocal(LifeMath::Vec2i(a->CursorX, a->CursorY));
//a little bit different code for vertical and horizontal splitters
if(splitter_vertical)
{
//test if click happened inside splitter
if(pos.X >= splitter_pos && pos.X < (splitter_pos + splitter_size))
{
if(pos.Y >=0 && pos.Y < this->GetHeight())
{
size_mode = true;
click_offset = pos.X - splitter_pos;
return true;
}
}
}
else
{
//test if click happened inside splitter
if(pos.Y >= splitter_pos && pos.Y < (splitter_pos + splitter_size))
{
if(pos.X >=0 && pos.X < this->GetWidth())
{
size_mode = true;
click_offset = pos.Y - splitter_pos;
return true;
}
}
}
return BroadcastMessage(mt, mp, args);
}
else if(mp == MP_KEY_UP)
{
if(size_mode)
{
size_mode = false;
UpdatePanels();
}
else
return BroadcastMessage(mt, mp, args);
}
else if(mp == MP_MOUSE_MOVE)
{
IMouseArgs* a = static_cast<IMouseArgs*>(args);
//transform cursor coordinate to local space
LifeMath::Vec2i pos = CursorToLocal(LifeMath::Vec2i(a->CursorX, a->CursorY));
if(size_mode)
{
if(splitter_vertical)
{
splitter_pos = pos.X - click_offset;
}
else
{
splitter_pos = pos.Y - click_offset;
}
if(update_realtime)
UpdatePanels();
return true;
}
else
return BroadcastMessage(mt, mp, args);
}
}*/
return false;
}
}
+48
View File
@@ -0,0 +1,48 @@
#ifndef GUISplitPanel_h__
#define GUISplitPanel_h__
#include "GUIWindow.h"
namespace LifeGUI
{
class GUIPlane;
class GUISplitPanel : public GUIWindow
{
public:
GUISplitPanel();
~GUISplitPanel();
void SetWidth(int val);
void SetHeight(int val);
void Update(float dt);
void SetBackColor(const LifeMath::float4& color);
void SetSplitterHorisontal(bool state);
void SetRealtimeResize(bool state);
void SetSplitterPosition(size_t pos);
GUIWindow* GetContainer1();
GUIWindow* GetContainer2();
bool ProcessMessage(GUIMessageType mt, GUIMessageParam mp, IMessageArgs* args);
void OnBeginSlide(GUIWindow* wnd, int p);
void OnEndSlide(GUIWindow* wnd, int p);
void OnDoSlide(GUIWindow* wnd, int p);
void SetBorderEnabled(bool state);
private:
LifeMath::Vec2i splitter_click;
void UpdatePanels();
int splitter_size;
bool splitter_vertical;
int splitter_pos;
int minPanelSize;
GUIPlane* plane1;
GUIPlane* plane2;
GUIPlane* plane_split;
bool size_mode;
int click_offset;
bool update_realtime;
};
}
#endif // GUISplitPanel_h__
+100
View File
@@ -0,0 +1,100 @@
#include "GUITab.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUITab::GUITab()
:Align(ALIGN_TOP), activeTab(0), invalid(true)
{
}
GUITab::~GUITab()
{
}
void GUITab::TabClick(GUIWindow* sender, int arg)
{
if(activeTab != sender)
activeTab->Reset();
size_t count = pages.size();
GUITabPage* p = reinterpret_cast<GUITabPage*>(sender->UserData);
//sender->state = STR("Pressed");
//sender->Invalidate();
activeTab = reinterpret_cast<GUIButton*>(sender);
p->Show();
p->Invalidate();
for(size_t i = 0; i < count; i++)
{
GUITabPage* tp = pages[i];
if(tp != p)
{
tp->Hide();
}
}
}
void GUITab::RenderSelf()
{
if(invalid)
{
switch(Align)
{
case ALIGN_TOP:
{
size_t tab_count = tabs.size();
int tabs_offset_left = 10;
//setup TAB buttons and pages
for(size_t i = 0; i < tab_count; i++)
{
GUIButton* b = tabs[i];
b->SetWidth(60);
b->SetHeight(25);
b->SetPosition(LifeMath::Vec2i(tabs_offset_left + i * 60, 0));
GUITabPage* p = pages[i];
p->SetHeight(this->GetHeight() - 25);
p->SetWidth(this->GetWidth());
p->SetPosition(LifeMath::Vec2i(0, 25));
}
}
break;
}
invalid = false;
}
}
void GUITab::AddTab(const String& name)
{
GUITabPage* page = new GUITabPage();
this->AddChild(page);
pages.push_back(page);
if(pages.size() > 1)
page->Hide();
page->AutoTiling = true;
page->SetStyle(STR("Tab_page"));
page->SetBackColor(LifeMath::float4(1,1,1,1));
//page->SetBorderColor(LifeMath::float4(0,0,0,1));
page->SetBorderEnabled(true);
page->Invalidate();
//TODO add search of same name in existing tabs and do something o_O
GUIButton* tab = new GUIButton();
tab->SetStyle(STR("Tab_button"));
tab->SetCheckable(true);
if(activeTab == 0)
{
activeTab = tab;
tab->state = STR("Hover");
}
tab->Event_MouseDown += NewDelegate(this, &GUITab::TabClick);
tab->UserData = page;
tab->SetBorderEnabled(false);
tab->SetForeColor(LifeMath::float4(1,1,1,1));
this->AddChild(tab);
tab->SetCaption(name);
tabs.push_back(tab);
Invalidate();
}
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef GUITab_h__
#define GUITab_h__
#include "GUIWindow.h"
#include "GUITabPage.h"
#include "GUIButton.h"
#include <vector>
namespace LifeGUI
{
class GUITab : public GUIWindow
{
public:
GUITab();
~GUITab();
void AddTab(const String& name);
void RenderSelf();
ALIGN_TYPE Align;
GUITabPage* GetPage()
{
return reinterpret_cast<GUITabPage*>(activeTab->UserData);
}
void Invalidate()
{
GUIWindow::Invalidate();
invalid = true;
}
private:
bool invalid;
GUIButton* activeTab;
void TabClick(GUIWindow* sender, int arg);
typedef std::vector<GUITabPage*> PageCollection;
typedef std::vector<GUIButton*> ButtonCollection;
ButtonCollection tabs;
PageCollection pages;
};
}
#endif // GUITab_h__
+16
View File
@@ -0,0 +1,16 @@
#ifndef GUITabPage_h__
#define GUITabPage_h__
#include "GUIScrollablePlane.h"
namespace LifeGUI
{
class GUITabPage : public GUIScrollablePlane
{
public:
GUITabPage(){}
~GUITabPage(){}
};
}
#endif // GUITabPage_h__
+311
View File
@@ -0,0 +1,311 @@
#include "GUIText.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUIText::GUIText()
:invalid(false), charCount(0), AutoSize(false), WrapWords(false), halign(HA_LEFT), valign(VA_TOP), quadCount(1), bufSize(128)
{
vert = new GUIVertex[128*6];
this->SetBorderEnabled(false);
this->SetForeColor(LifeMath::float4(0,0,0,1));
this->SetBackColor(LifeMath::float4(1,0,0,0));
this->SetWidth(100);
this->SetHeight(20);
this->Invalidate();
}
void GUIText::SetBackColor(const LifeMath::float4& color)
{
GUIPlane::SetBackColor(color);
Invalidate();
SetText(text);
}
void GUIText::SetHAlign(HALIGN align)
{
if(halign != align)
{
halign = align;
SetText(text);
}
}
bool GUIText::ProcessMessage(GUIMessageType mt, GUIMessageParam mp, IMessageArgs* args)
{
return false;
}
void GUIText::SetVAlign(VALIGN align)
{
if(valign != align)
{
valign = align;
SetText(text);
}
}
void GUIText::SetText(const String& _text)
{
LifeMath::Rect2i s = this->GetScissor();
vertex_count = 0;
text = _text;
std::wstring source;
MBSTWCS(text, source);
WStringVector srcLines;
WStringVector dstLines;
//split string to lines
SplitStringW(source, &srcLines);
int lineCount = srcLines.size();
int maxWidth = 0;
for(int i = 0; i < lineCount; i++)
{
int strSize = GUIManager::me()->font->MeasureString(srcLines[i]);
if(strSize > maxWidth)
maxWidth = strSize;
if(!AutoSize)
{
if(strSize <= this->width)
{
dstLines.push_back(srcLines[i]);
}
else //not autosize and string is too long
{
if(WrapWords)
{
WStringVector words;
SplitStringW(srcLines[i], &words, L' ');
int wordCount = words.size();
//now we need to split too long words
std::wstring newLine(L"");
std::wstring oldLine(L"");
for(int j = 0; j < wordCount; j++)
{
newLine = oldLine + words[j] + std::wstring(L" ");
if(GUIManager::me()->font->MeasureString(newLine) > this->width)
{
dstLines.push_back(oldLine);
oldLine = words[j];
newLine = std::wstring(L"");
}
else if(j == (wordCount - 1))
{
dstLines.push_back(newLine);
}
else
oldLine = newLine;
}
}
else
{
WStringVector lines;
SplitLongString(srcLines[i], &lines, this->width);
int cnt = lines.size();
for(int k = 0; k < cnt; k++)
{
dstLines.push_back(lines[k]);
}
}
}
}
else
{
dstLines.push_back(srcLines[i]);
}
}
int charCnt = source.size() + 1 + 5;
if(bufSize < charCnt)
{
bufSize = charCnt;
delete[]vert;
vert = new GUIVertex[bufSize * 6];
}
//genGeom(false);
//generate quads
int newLineCount = dstLines.size();
//delete[] vert;
//vert = new GUIVertex[(source.size()+10) * 6];
int xOff = 0;
int yOff = 0;
int counter = 0;
int vShift = 0;
if(valign == VA_TOP)
vShift = 0;
else if(valign == VA_BOTTOM)
{
int textHeight = dstLines.size() * GUIManager::me()->font->stringHeight;
vShift = this->height - textHeight;
}
else //center
{
int textHeight = dstLines.size() * GUIManager::me()->font->stringHeight;
vShift = (this->height - textHeight)/2;
}
for(int i = 0; i < newLineCount; i++)
{
yOff = i * GUIManager::me()->font->stringHeight + vShift;
if(halign == HA_LEFT)
xOff = 0;
else if(halign == HA_RIGHT)
{
int stringWidth = GUIManager::me()->font->MeasureString(dstLines[i]);
xOff = this->width - stringWidth;
}
else //center
{
int stringWidth = GUIManager::me()->font->MeasureString(dstLines[i]);
xOff = (this->width - stringWidth) / 2;
}
int charCount = dstLines[i].size();
const wchar_t* ptr = dstLines[i].c_str();
for(int j = 0; j < charCount; j++)
{
if(ptr[j] != 0x0020)
{
GUIFontGlyph* g = GUIManager::me()->font->GetGlyph(ptr[j]);
vertex_count += GUIManager::me()->GenQuad(1, s, LifeMath::Vec2i(xOff + g->leftOffset, yOff + g->topOffset) + GetPositionAbs(),g->Width, g->Height, (vert + vertex_count),g->U, g->V, g->TexW, g->TexH,ForeColor,ForeColor,ForeColor,ForeColor, LifeMath::float2(1,1));
xOff+=g->hor_advance;
counter++;
}
else
{
xOff+=GUIManager::me()->font->spaceSize;
}
}
}
quadCount = counter + 1;
//update geom buffer
/* LifeCore::IDataStream* stm = vb->Map(0, LF_Discard);
stm->Write(vert, sizeof(GUIVertex) * 6 * quadCount);
vb->Unmap();*/
if(AutoSize)
{
this->height = dstLines.size() * GUIManager::me()->font->stringHeight;
int max_size = 0;
for(int i = 0; i < dstLines.size(); i++)
{
int line_size = GUIManager::me()->font->MeasureString(dstLines[i]);
if(max_size < line_size)
max_size = line_size;
}
this->width = max_size;
}
Event_TextChanged.Invoke(this, 0);
}
void GUIText::GenGeom(bool updateVb)
{
this->SetText(text);
invalid = false;
}
void GUIText::SplitLongString(const std::wstring& text, WStringVector* container, int maxLength)
{
GUIFont* fnt = GUIManager::me()->font;
int stringSize = text.size();
const wchar_t* str = text.c_str();
int oldSize = 0;
int newSize = 0;
int oldPos = 0;
//wchar_t tmp[2];
std::wstring wtmp;
for(int i = 0; i < stringSize; i++)
{
GUIFontGlyph* glyph = fnt->GetGlyph(str[i]);
newSize = oldSize + glyph->Width;
if(newSize > maxLength)
{
newSize = 0;
oldSize = 0;
std::wstring ws = text.substr(oldPos, i - oldPos);
oldPos = i;
(*container).push_back(ws);
}
else if(i == (stringSize - 1))
{
if(i-oldPos)
{
std::wstring ws = text.substr(oldPos, i - oldPos);
(*container).push_back(ws);
}
return;
}
else
oldSize = newSize;
}
}
GUIText::~GUIText()
{
}
void GUIText::Update(float dt)
{
}
void GUIText::KeyPress(int key, int modifier)
{
}
void GUIText::SetWidth(int val)
{
width = val;
SetText(text);
//Invalidate();
}
void GUIText::SetForeColor(LifeMath::float4 color)
{
GUIPlane::SetForeColor(color);
SetText(text);
Invalidate();
}
void GUIText::SetHeight(int val)
{
height = val;
//SetText(text);
//Invalidate();
}
const String& GUIText::GetText()
{
return text;
}
void GUIText::RenderSelf()
{
GUIPlane::RenderSelf();
IGUIRenderer* renderer = GUIManager::me()->GetRenderer();
if(invalid)
GenGeom(true);
if(this->GetScissor().GetSquare() != 0)
{
renderer->SetTexture(0, GUIManager::me()->font->font_tex, false);
renderer->Write(vert, vertex_count);
}
}
}
+72
View File
@@ -0,0 +1,72 @@
#ifndef GUIText_h__
#define GUIText_h__
#include "GUIWindow.h"
#include "GUIPlane.h"
namespace LifeGUI
{
enum HALIGN
{
HA_LEFT = 0,
HA_CENTER = 1,
HA_RIGHT = 2
};
enum VALIGN
{
VA_TOP = 0,
VA_CENTER = 1,
VA_BOTTOM = 2
};
class GUIText : public GUIPlane
{
private:
GUIVertex* vert;
int charCount;
String text;
bool AutoSize;
bool invalidGeom;
bool WrapWords;
int quadCount;
void SplitLongString(const std::wstring& text, WStringVector* container, int maxLength);
void GenGeom(bool updateVb);
int halign;
int valign;
int bufSize;
int vertex_count;
bool invalid;
public:
EVENT2(TextEvent, GUIWindow*, uint32);
TextEvent Event_TextChanged;
void SetForeColor(LifeMath::float4 color);
void SetBackColor(const LifeMath::float4& color);
void SetHAlign(HALIGN align);
void SetVAlign(VALIGN align);
void Invalidate()
{
GUIPlane::Invalidate();
invalid = true;
}
void SetAutoSize(bool condition)
{
AutoSize = condition;
}
bool GetAutoSize()
{
return AutoSize;
}
GUIText();
~GUIText();
void Update(float dt);
void KeyPress(int key, int modifier);
void RenderSelf();
void SetWidth(int val);
void SetHeight(int val);
void SetText(const String& _text);
const String& GetText();
bool ProcessMessage(GUIMessageType mt, GUIMessageParam mp, IMessageArgs* args);
};
}
#endif // GUIText_h__
+153
View File
@@ -0,0 +1,153 @@
#include "GUITextInput.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUITextInput::GUITextInput()
{
NeedKeyFocus = true;
this->SetWidth(150);
this->SetHeight(20);
caption = new GUIText();
caption->SetWidth(this->GetWidth());
caption->SetHeight(this->GetHeight());
caption->SetText(STR("omfg"));
caption->SetVAlign(VA_CENTER);
caption->SetHAlign(HA_LEFT);
caption->SetPosition(LifeMath::Vec2i(0,0));
caption->SetBackColor(LifeMath::float4(0,0,0,0));
caption->SetForeColor(LifeMath::float4(0,0,0,1));
caption->SetBorderEnabled(false);
this->SetBackColor(LifeMath::float4(0.9f,0.9f,0.9f,0.5f));
this->AddChild(caption);
this->cursor = STR("Text");
this->SetBorderColor(LifeMath::float4(0,0,0,1));
this->SetBorderEnabled(true);
this->Border = GUIBorder(1);
caption->mouseEnabled = false;
this->Event_MouseDown += NewDelegate(this, &GUITextInput::OnMouseDown);
}
void GUITextInput::RenderSelf()
{
if(invalid)
{
LifeMath::Rect2i r = this->GetClientRectangle();
caption->SetWidth(r.width);
caption->SetHeight(r.height);
}
GUIPlane::RenderSelf();
}
void GUITextInput::SetForeColor(LifeMath::float4 color)
{
caption->SetForeColor(color);
}
void GUITextInput::OnKeyDown(LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str)
{
switch(key)
{
case LifeCore::KeyCodes::Key_BACK:
{
String s = caption->GetText();
if(s.size() > 0)
{
s = s.substr(0, s.size()-1);
caption->SetText(s);
}
}
break;
case LifeCore::KeyCodes::Key_TAB:
{
}
break;
case LifeCore::KeyCodes::Key_RETURN:
{
Event_EnterPressed.Invoke(this);
}
break;
default:
{
if(text != 0 && str != std::string(""))
caption->SetText(caption->GetText() + str);
}
break;
}
}
void GUITextInput::OnMouseDown(GUIWindow* wnd, int p)
{
FindOverlay()->SetFocusWindow(wnd);
}
GUITextInput::~GUITextInput()
{
}
String GUITextInput::GetText()
{
return caption->GetText();
}
void GUITextInput::SetText(const String& _text)
{
caption->SetText(_text);
}
/*
bool GUITextInput::ProcessMessage(GUIMessageType mt, GUIMessageParam mp, IMessageArgs* args)
{
//mouse message
if(mt == GM_MOUSE && mouseEnabled)
{
//get mouse args
IMouseArgs* mArgs = static_cast<IMouseArgs*>(args);
LifeMath::Vec2i cursor = mArgs->overlay->cursorPos;
bool grabMouse = GetRectangleAbs().InRect(cursor);
if(mp == MP_KEY_DOWN)
{
if(grabMouse)
{
FindOverlay()->focusWindow = this;
return true;
}
else
{
if(FindOverlay()->focusWindow == this)
{
FindOverlay()->focusWindow = 0;
}
}
}
}
else if(mt == GM_KEYBOARD && FindOverlay()->focusWindow == this)
{
IKeyboardArgs* kArgs = static_cast<IKeyboardArgs*>(args);
if(mp == MP_KEY_DOWN && kArgs->keycode != KEY_LSHIFT && kArgs->keycode != KEY_BACK)
{
String str = text->GetText();
#ifdef _UNICODE
str += String((wchar_t)kArgs->text);
#else
String dst;
WCSTMBS(reinterpret_cast<wchar_t*>(&kArgs->text), dst);
str += dst;
//str+=kArgs->str;
#endif
text->SetText(str);
return true;
}
else if(mp == MP_KEY_DOWN && kArgs->keycode == KEY_BACK)
{
String str = text->GetText();
int l = str.size();
if(l <= 1)
text->SetText(STR(""));
else
text->SetText(str.substr(0, l-1));
return true;
}
}
return false;
}*/
}
+34
View File
@@ -0,0 +1,34 @@
#ifndef GUITextInput_h__
#define GUITextInput_h__
#include "GUIPlane.h"
#include "GUIText.h"
namespace LifeGUI
{
class GUITextInput : public GUIPlane
{
public:
EVENT1(TextInputEvent, GUITextInput*);
TextInputEvent Event_EnterPressed;
GUITextInput();
~GUITextInput();
void SetText(const String& text);
String GetText();
void SetForeColor(LifeMath::float4 color);
void RenderSelf();
void GUITextInput::OnKeyDown(LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str);
void Invalidate()
{
GUIPlane::Invalidate();
invalid = true;
}
private:
bool invalid;
void OnMouseDown(GUIWindow* wnd, int p);
GUIText* caption;
};
}
#endif // GUITextInput_h__
+63
View File
@@ -0,0 +1,63 @@
#include "GUIToolStrip.h"
namespace LifeGUI
{
GUIToolStrip::GUIToolStrip()
:isVertical(false)
{
this->Event_Resize += NewDelegate(this, &GUIToolStrip::UpdateLayout);
this->SetBackColor(LifeMath::float4(0.737f, 0.7803f, 0.847f, 1.0f));
this->SetBorderColor(LifeMath::float4(0.78823f, 0.82353f, 0.8824f, 1.0f));
this->SetBorderEnabled(true);
}
GUIToolStrip::~GUIToolStrip()
{
}
void GUIToolStrip::AddItem(GUIToolStripItem* itm)
{
Items.push_back(itm);
AddChild(itm->GetInternalWindow());
UpdateLayout(this);
}
void GUIToolStrip::SetIsVertical(bool state)
{
if(isVertical != state)
{
isVertical = state;
UpdateLayout(this);
}
}
void GUIToolStrip::UpdateLayout(GUIWindow* wnd)
{
if(isVertical)
{
}
else
{
int s_h = 24;
int i_h = 22;
if (this->GetHeight() != s_h)
this->SetHeight(s_h);
int spacing = 3;
//arrange all childs
int itm_count = Items.size();
int itm_w = 35;
int itm_h = 22;
int off_y = (s_h - itm_h) / 2;
for(int i = 0; i < itm_count; i++)
{
GUIToolStripItem* itm = Items[i];
GUIWindow* wnd = itm->GetInternalWindow();
wnd->SetPosition(LifeMath::Vec2i((itm_w + spacing) * i + spacing, off_y));
wnd->SetWidth(itm_w);
wnd->SetHeight(itm_h);
}
}
}
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef GUIToolStrip_h__
#define GUIToolStrip_h__
#include "GUIButton.h"
#include "GUIToolStripItem.h"
#include <vector>
namespace LifeGUI
{
class GUIToolStrip : public GUIPlane
{
public:
GUIToolStrip();
~GUIToolStrip();
void AddItem(GUIToolStripItem* itm);
void SetIsVertical(bool state);
private:
void UpdateLayout(GUIWindow* wnd);
protected:
typedef std::vector<GUIToolStripItem*> ItemCollection;
typedef std::vector<GUIToolStripItem*>::iterator ItemCollectionIter;
ItemCollection Items;
bool isVertical;
};
}
#endif // GUIToolStrip_h__
+20
View File
@@ -0,0 +1,20 @@
#include "GUIToolStripButton.h"
#include "GUIButton.h"
namespace LifeGUI
{
GUIToolStripButton::GUIToolStripButton()
{
pWindow = new GUIButton();
GUIButton* b = (GUIButton*)pWindow;
b->SetBorderEnabled(false);
b->SetCaption(STR("Tool"));
}
GUIToolStripButton::~GUIToolStripButton()
{
}
GUIButton* GUIToolStripButton::AsButton()
{
return static_cast<GUIButton*>(pWindow);
}
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef GUIToolStripButton_h__
#define GUIToolStripButton_h__
#include "GUIToolStripItem.h"
#include "GUIButton.h"
namespace LifeGUI
{
class GUIToolStripButton : public GUIToolStripItem
{
public:
GUIButton* AsButton();
GUIToolStripButton();
~GUIToolStripButton();
};
}
#endif // GUIToolStripButton_h__
+15
View File
@@ -0,0 +1,15 @@
#include "GUIToolStripImage.h"
#include "GUIPicture.h"
namespace LifeGUI
{
GUIToolStripImage::GUIToolStripImage()
{
pWindow = new GUIPicture();
GUIPicture* b = (GUIPicture*)pWindow;
b->SetSizeMode(SM_CENTER);
}
GUIToolStripImage::~GUIToolStripImage()
{
}
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef GUIToolStripImage_h__
#define GUIToolStripImage_h__
#include "GUIToolStripItem.h"
namespace LifeGUI
{
class GUIToolStripImage : public GUIToolStripItem
{
public:
GUIToolStripImage();
~GUIToolStripImage();
};
}
#endif // GUIToolStripImage_h__
View File
+17
View File
@@ -0,0 +1,17 @@
#ifndef GUIToolStripItem_h__
#define GUIToolStripItem_h__
#include "GUIWindow.h"
namespace LifeGUI
{
class GUIToolStripItem
{
public:
GUIWindow* GetInternalWindow() { return pWindow; };
protected:
GUIWindow* pWindow;
};
}
#endif // GUIToolStripItem_h__
+60
View File
@@ -0,0 +1,60 @@
#include "GUIToolStripMenu.h"
#include "GUIButton.h"
#include "GUIOverlay.h"
namespace LifeGUI
{
GUIToolStripMenu::GUIToolStripMenu()
:menu_visible(false), show_on_click(true)
{
pWindow = new GUIButton();
GUIButton* b = (GUIButton*)pWindow;
b->SetBorderEnabled(false);
b->SetCaption(STR("Tool"));
b->Event_MouseDown += NewDelegate(this, &GUIToolStripMenu::OnButtonPress);
menu = new GUIMenu(true);
menu->Event_Collapse += NewDelegate(this, &GUIToolStripMenu::OnMenuHide);
menu->Event_SelectItem += NewDelegate(this, &GUIToolStripMenu::OnMenuItemSelect);
}
void GUIToolStripMenu::SetCaption(const String& text)
{
GUIButton* b = (GUIButton*)pWindow;
b->SetCaption(text);
}
void GUIToolStripMenu::OnMenuItemSelect(GUIMenu* wnd, int p)
{
show_on_click = true;
}
GUIToolStripMenu::~GUIToolStripMenu()
{
}
void GUIToolStripMenu::OnButtonPress(GUIWindow* wnd, int p)
{
if(menu_visible)
{
pWindow->FindOverlay()->ReleaseFocus();
menu_visible = false;
}
else
{
if(show_on_click)
{
pWindow->FindOverlay()->AddChild(menu);
pWindow->FindOverlay()->SetFocusWindow(menu);
LifeMath::Vec2i newPos = pWindow->GetRectangleAbs().GetMax();
newPos.X-= pWindow->GetWidth();
menu->SetPosition(newPos);
menu_visible = true;
}
show_on_click = true;
}
}
void GUIToolStripMenu::OnMenuHide(GUIMenu* wnd)
{
menu_visible = false;
if(pWindow->GetClientRectangleAbs().InRect(pWindow->FindOverlay()->cursorPos))
show_on_click = false;
}
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef GUIToolStripMenu_h__
#define GUIToolStripMenu_h__
#include "GUIToolStripItem.h"
#include "GUIMenu.h"
namespace LifeGUI
{
class GUIToolStripMenu : public GUIToolStripItem
{
public:
GUIToolStripMenu();
~GUIToolStripMenu();
GUIMenu* GetMenu(){return menu;}
void SetCaption(const String& text);
private:
bool show_on_click;
bool menu_visible;
GUIMenu* menu;
void OnButtonPress(GUIWindow* wnd, int p);
void OnMenuItemSelect(GUIMenu* wnd, int p);
void OnMenuHide(GUIMenu* wnd);
};
}
#endif // GUIToolStripMenu_h__
+19
View File
@@ -0,0 +1,19 @@
#include "GUITreeNode.h"
#include "GUITreeView.h"
namespace LifeGUI
{
void GUITreeNode::SetOwner(GUITreeView* _owner)
{
owner = _owner;
}
void GUITreeNode::OnArrowClick(GUIWindow* sender, int args)
{
if(IsCollapsed())
{
Expand();
}
else
Collapse();
}
}
+82
View File
@@ -0,0 +1,82 @@
#ifndef GUITreeNode_h__
#define GUITreeNode_h__
#include "LString.h"
#include <vector>
#include "GUIPlane.h"
#include "GUIText.h"
namespace LifeGUI
{
class GUITreeView;
class GUITreeNode
{
public:
bool need_update;
GUITreeView* owner;
void SetOwner(GUITreeView* _owner);
GUITreeNode()
:collapsed(true), need_update(true)
{
groupButton = new GUIPlane();
text = new GUIText();
text->SetText(STR("Tree node"));
groupButton->Hide();
groupButton->SetStyle(STR("Tree_button"));
groupButton->Event_MouseDown += NewDelegate(this, &GUITreeNode::OnArrowClick);
}
void AddChildNode(GUITreeNode* node)
{
children.push_back(node);
}
String Name;
size_t ChildrenCount()
{
return children.size();
}
GUITreeNode& operator[](size_t index)
{
return *children[index];
}
void Collapse()
{
collapsed = true;
groupButton->state = "Normal";
need_update = true;
groupButton->Invalidate();
}
GUITreeNode* GetChild(size_t id)
{
return children[id];
}
void Expand()
{
collapsed = false;
groupButton->state = "Pressed";
need_update = true;
groupButton->Invalidate();
}
bool IsCollapsed()
{
return collapsed;
}
GUIPlane* GetGroupButton()
{
return groupButton;
}
GUIText* GetLabel()
{
return text;
}
private:
void OnArrowClick(GUIWindow* sender, int args);
typedef std::vector<GUITreeNode*> NodeCollection;
typedef std::vector<GUITreeNode*>::iterator NodeCollectionIter;
GUIPlane* groupButton;
GUIText* text;
bool collapsed;
NodeCollection children;
};
}
#endif // GUITreeNode_h__
+127
View File
@@ -0,0 +1,127 @@
#include "GUITreeView.h"
#include "GUIManager.h"
namespace LifeGUI
{
GUITreeView::GUITreeView()
{
}
GUITreeView::~GUITreeView()
{
}
void GUITreeView::RenderSelf()
{
for(NodeCollectionIter it = nodes.begin(); it != nodes.end(); ++it)
{
GUITreeNode* node = (*it);
if(NeedUpdate(node))
{
Invalidate();
//UpdateLayout();
break;
}
}
if(invalid)
UpdateLayout();
GUIScrollablePlane::RenderSelf();
}
void GUITreeView::AddNode(GUITreeNode* node)
{
nodes.push_back(node);
node->SetOwner(this);
// this->AddChild(node->GetLabel());
// this->AddChild(node->GetGroupButton());
Invalidate();
}
void GUITreeView::UpdateLayout()
{
//childs.clear();
//clear child nodes
for(std::vector<GUIWindow*>::iterator it = internal_childs.begin(); it != internal_childs.end(); ++it)
{
GUIWindow* wnd = *it;
this->RemoveChild(wnd->hwnd);
}
internal_childs.clear();
last_node = 0;
for(NodeCollectionIter it = nodes.begin(); it != nodes.end(); ++it)
{
GUITreeNode* node = (*it);
ExposeNode(node, 0);
}
Invalidate();
}
bool GUITreeView::NeedUpdate(GUITreeNode* node)
{
if(node->need_update)
return true;
else
{
size_t cnt = node->ChildrenCount();
if(cnt && !node->IsCollapsed())
for(size_t i = 0; i < cnt; i++)
{
if(NeedUpdate(node->GetChild(i)))
return true;
}
}
return false;
}
void GUITreeView::ExposeNode(GUITreeNode* node, int depth)
{
int x_main_off = 25;
int y_main_off = 25;
int node_height = 15;
int left_offset = 20;
node->need_update = false;
if(node->ChildrenCount() > 0)
{
int y_off = node_height * last_node + x_main_off;
int x_off = left_offset * depth + y_main_off;
GUIText* label = node->GetLabel();
label->SetPosition(LifeMath::Vec2i(x_off, y_off));
this->AddChild(label);
internal_childs.push_back(label);
GUIPlane* button = node->GetGroupButton();
button->SetWidth(14);
button->SetHeight(14);
button->SetBorderEnabled(false);
// button->SetBorderColor(LifeMath::float4(0,0,0,1));
button->SetPosition(LifeMath::Vec2i(x_off - 18, y_off + 4));
this->AddChild(button);
internal_childs.push_back(button);
button->Show();
last_node++;
if(!node->IsCollapsed())
{
size_t node_cnt = node->ChildrenCount();
for(size_t i = 0; i < node_cnt; i++)
{
GUITreeNode* n = node->GetChild(i);
ExposeNode( n, depth + 1);
}
}
}
else
{
int y_off = node_height * last_node + x_main_off;
int x_off = left_offset * depth + y_main_off;
GUIText* label = node->GetLabel();
label->SetPosition(LifeMath::Vec2i(x_off, y_off));
this->AddChild(label);
internal_childs.push_back(label);
last_node++;
}
}
}
+42
View File
@@ -0,0 +1,42 @@
#ifndef GUITreeView_h__
#define GUITreeView_h__
#include "GUIScrollablePlane.h"
#include "GUITreeNode.h"
#include "GUIButton.h"
#include "GUIText.h"
namespace LifeGUI
{
struct GroupButton
{
GUIButton* b;
bool grouped;
};
class GUITreeView : public GUIScrollablePlane
{
public:
GUITreeView();
~GUITreeView();
void AddNode(GUITreeNode* node);
void Invalidate()
{
GUIScrollablePlane::Invalidate();
invalid = true;
}
protected:
void RenderSelf();
private:
bool invalid;
bool NeedUpdate(GUITreeNode* node);
WindowList internal_childs;
typedef std::vector<GUITreeNode*> NodeCollection;
typedef std::vector<GUITreeNode*>::iterator NodeCollectionIter;
size_t last_node;
void UpdateLayout();
void ExposeNode(GUITreeNode* node, int depth);
NodeCollection nodes;
};
}
#endif // GUITreeView_h__
+64
View File
@@ -0,0 +1,64 @@
#ifndef GUIVertex_h__
#define GUIVertex_h__
#include <math/Vector2D.h>
#include <math/Vector3D.h>
#include <math/Vector4D.h>
#include <intrin.h>
namespace LifeGUI
{
struct RectangleInfo
{
LifeMath::float4 v1;
LifeMath::float4 v2;
};
struct GUIVertex
{
LifeMath::float3 Position;
LifeMath::float4 Color;
LifeMath::float4 Texcoord;
LifeMath::float4 TileInfo;
GUIVertex()
:Position(0,0,0), Color(0,0,0,0), Texcoord(0,0, 1, 1)
{
}
GUIVertex(LifeMath::float3 pos, LifeMath::float4 col, LifeMath::float4 tc, LifeMath::float4 tc_tile)
{
Position = pos;
Color = col;
Texcoord = tc;
TileInfo = tc_tile;
}
const GUIVertex operator *(float val) const
{
GUIVertex result;
result.Color = this->Color * val;
result.Position = this->Position * val;
result.Texcoord = this->Texcoord * val;
return result;
}
const GUIVertex operator +(const GUIVertex& val) const
{
GUIVertex result;
result.Color = this->Color + val.Color;
result.Position = this->Position + val.Position;
result.Texcoord = this->Texcoord + val.Texcoord;
return result;
}
const GUIVertex& operator *=(float val)
{
this->Color *= val;
this->Position *= val;
this->Texcoord *= val;
return *this;
}
};
}
#endif // GUIVertex_h__
+96
View File
@@ -0,0 +1,96 @@
#ifndef GUIWidgetSkin_h__
#define GUIWidgetSkin_h__
#include "LString.h"
#include <map>
#include "math/LifeMath.h"
#include "Types.h"
namespace LifeGUI
{
class GUISkinElement;
class GUISkinState;
class GUIWidgetSkin;
class GUISkinElement
{
public:
LifeMath::Vec4i Coord;
LifeMath::float4 Mapping;
GUISkinElement(const LifeMath::Vec4i& pixCoords, const LifeMath::float4& texCoords)
{
Coord = pixCoords;
Mapping = texCoords;
}
};
class GUISkinState
{
private:
std::map<String, GUISkinElement*> elements;
LifeMath::Vec2i texSize;
LifeMath::float4 ComputeTC(const LifeMath::Vec4i& coord)
{
float x, y, z, w;
LifeMath::Vec4i pixCoord = coord + LifeMath::Vec4i(0,0,1,1);
x = (float)pixCoord.X / (float)texSize.X;
y = (float)pixCoord.Y / (float)texSize.Y;
z = (float)pixCoord.Z / (float)texSize.X;
w = (float)pixCoord.W / (float)texSize.Y;
return LifeMath::float4(x, y, z-x, w-y);
}
public:
GUISkinState(const LifeMath::Vec2i& texDim)
{
texSize = texDim;
}
~GUISkinState()
{
}
void AddElement(const String& name, const LifeMath::Vec4i& data)
{
GUISkinElement* element = new GUISkinElement(data, ComputeTC(data));
elements[name] = element;
}
GUISkinElement* GetElement(const String& name)
{
return elements[name];
}
};
class GUIWidgetSkin
{
public:
IImage* texture;
std::map<String, GUISkinState*> states;
GUIWidgetSkin(IImage* skinTex)
{
texture = skinTex;
}
GUISkinState* AddState(const String& name)
{
GUISkinState* state = new GUISkinState(LifeMath::Vec2i(texture->GetWidth(), texture->GetHeight()));
states[name] = state;
return state;
}
GUISkinState* GetState(const String& name)
{
if(states.find(name) == states.end())
{
if(states.find(STR("Normal")) != states.end())
{
return states[STR("Normal")];
}
else
{
return 0;
}
}
else
return states[name];
}
};
}
#endif // GUIWidgetSkin_h__
+91
View File
@@ -0,0 +1,91 @@
#include "GUIWindow.h"
#include "GUIManager.h"
namespace LifeGUI
{
static int wndCounter = 0;
GUIWindow::GUIWindow()
:parent(0), position(0, 0), width(100), height(100), positionAbs(0, 0), BackColor(1.0f, 1.0f, 1.0f, 1.0f), visible(true),
borderEnabled(true), mouseCaptured(false), enabled(true), mouseEnabled(true), mouseButtons(0),
dock(DOCK_NONE), mouse_keys(0), allowDrag(false), allowDrop(false), skin(0), state("Normal"), skip_mouse(false),
WindowStyle(GWS_OVERLAPPED), NeedKeyFocus(false),BackgroundTiling(1,1),AutoTiling(false),
cursor("Arrow"), NonClientControl(false), Border(1), nc_mouse_keys(0)
{
ID = GUIManager::me()->GetNewID();
hwnd = wndCounter++;
}
void GUIWindow::SetStyle(const String& name)
{
skin = GUIManager::me()->skinDefault[name];
this->Invalidate();
}
GUIWindow* GUIWindow::PickWindow(const LifeMath::Vec2i& pos)
{
if(!childs.size())
{
if(GetRectangleAbs().InRect(pos))
return this;
else
return 0;
}
else
{
return 0;
}
}
GUIWindow* GUIWindow::PickChild(int x, int y)
{
if(childs.size())
{
for(WindowList::reverse_iterator it = childs.rbegin(); it!= childs.rend(); ++it)
{
GUIWindow* wnd = *it;
if(wnd->skip_mouse)
wnd = wnd->PickChild(x, y);
if(wnd !=0 && wnd->GetRectangleAbs().InRect(x, y) && wnd->IsEnabled() && wnd->mouseEnabled && wnd->IsVisible())
return (*it);
}
}
return 0;
}
GUIOverlay* GUIWindow::FindOverlay()
{
if(parent)
return parent->FindOverlay();
else
return 0;
}
void GUIWindow::SetPosition(const LifeMath::Vec2i& _position)
{
if(position != _position)
Invalidate();
position = _position;
if(parent)
{
LifeMath::Rect2i r = parent->GetClientRectangleAbs();
LifeMath::Vec2i new_abs = position + LifeMath::Vec2i(r.x, r.y);
if(positionAbs != new_abs)
Invalidate();
positionAbs = new_abs;
}
else
positionAbs = position;
/*LifeMath::float4 pos;
pos.Z = static_cast<float>(this->positionAbs.X);
pos.W = static_cast<float>(this->positionAbs.Y);
pos.X = static_cast<float>(GUIManager::me()->GetWidth());
pos.Y = static_cast<float>(GUIManager::me()->GetHeight());*/
//cb->Update(&pos, sizeof(LifeMath::float4));
//Invalidate();
UpdateChildTransform();
}
}
+607
View File
@@ -0,0 +1,607 @@
#ifndef GUIWindow_h__
#define GUIWindow_h__
#include <vector>
#include "math/LifeMath.h"
#include "LString.h"
#include "GUIVertex.h"
#include "IImage.h"
#include "GUIWidgetSkin.h"
#include "GUIMessaging.h"
#include <delegate/Delegate.h>
#include "math/Rectangle.h"
#include "GUIBorder.h"
namespace LifeGUI
{
enum DOCK_TYPE
{
DOCK_NONE = 0,
DOCK_LEFT,
DOCK_RIGHT,
DOCK_TOP,
DOCK_BOTTOM,
DOCK_FILL
};
enum ALIGN_TYPE
{
ALIGN_LEFT = 0,
ALIGN_RIGHT,
ALIGN_TOP,
ALIGN_BOTTOM
};
enum GUI_WINDOW_STYLE
{
GWS_OVERLAPPED = 0,
GWS_POPUP = 1
};
struct DragInfo
{
String Name;
void* data;
};
class GUIManager;
class GUIWindow
{
public:
bool AbortFocusChange;
LifeMath::float2 BackgroundTiling;
bool AutoTiling;
bool NeedKeyFocus;
bool NonClientControl;
String cursor;
GUIBorder Border;
GUIWindow* GetParent()
{
return parent;
}
bool IsParent(GUIWindow* wnd)
{
if(!parent)
return false;
if(parent == wnd)
return true;
return parent->IsParent(wnd);
}
int WindowStyle;
virtual void SetBackColor(const LifeMath::float4& color)
{
Invalidate();
BackColor = color;
}
virtual void SetStyle(const String& name);
bool skip_mouse;
String state;
void* UserData;
EVENT2(MouseEvent, GUIWindow*, int);
EVENT2(KeyboardEvent, GUIWindow*, int);
EVENT1(WindowEvent, GUIWindow*);
String skin_name;
WindowEvent Event_Resize;
WindowEvent Event_Move;
//WindowEvent Event_Drop;
MouseEvent Event_NCMouseEnter;
MouseEvent Event_NCMouseLeave;
MouseEvent Event_NCMouseDown;
MouseEvent Event_NCMouseMove;
MouseEvent Event_NCMouseUp;
MouseEvent Event_NCMouseClick;
MouseEvent Event_MouseEnter;
MouseEvent Event_MouseLeave;
MouseEvent Event_MouseDown;
MouseEvent Event_MouseMove;
MouseEvent Event_MouseUp;
MouseEvent Event_MouseClick;
MouseEvent Event_GotFocus;
MouseEvent Event_LostFocus;
KeyboardEvent Event_KeyDown;
KeyboardEvent Event_KeyUp;
int mouse_keys;
int nc_mouse_keys;
GUIWindow* PickWindow(const LifeMath::Vec2i& pos);
GUIWindow* PickChild(int x, int y);
GUIWindow* PickChild(const LifeMath::Vec2i& pos)
{
PickChild(pos.X, pos.Y);
}
virtual void Invalidate()
{
UpdateChildDock();
}
bool mouseEnabled;
int ID;
LifeMath::float4 BackColor;
LifeMath::float4 ForeColor;
String name;
int hwnd;
GUIWindow();
virtual ~GUIWindow()
{
}
virtual void SetForeColor(LifeMath::float4 color)
{
ForeColor = color;
Invalidate();
}
virtual void OnMousePress(int x, int y, int key)
{
SetFlag(mouse_keys, 1 << key);
Event_MouseDown.Invoke(this, key);
}
virtual void OnMouseRelease(int x, int y, int key)
{
Event_MouseUp.Invoke(this, key);
if(GetFlag(mouse_keys, 1 << key)){
RemoveFlag(mouse_keys, 1 << key);
Event_MouseClick.Invoke(this, key);
}
}
virtual void OnMouseMove(int abs_x, int abs_y, int rel_x, int rel_y)
{
Event_MouseMove.Invoke(this, 0);
}
virtual void OnMouseEnter()
{
Event_MouseEnter.Invoke(this, 0);
}
virtual void OnMouseLeave()
{
Event_MouseLeave.Invoke(this, 0);
}
virtual void OnNCMousePress(int x, int y, int key)
{
SetFlag(nc_mouse_keys, 1 << key);
Event_NCMouseDown.Invoke(this, key);
}
virtual void OnNCMouseRelease(int x, int y, int key)
{
Event_NCMouseUp.Invoke(this, key);
if(GetFlag(nc_mouse_keys, 1 << key))
{
RemoveFlag(nc_mouse_keys, 1 << key);
Event_NCMouseClick.Invoke(this, key);
}
}
virtual void OnNCMouseMove(int abs_x, int abs_y, int rel_x, int rel_y)
{
Event_NCMouseMove.Invoke(this, 0);
}
virtual void OnNCMouseEnter()
{
Event_NCMouseEnter.Invoke(this, 0);
}
virtual void OnNCMouseLeave()
{
Event_NCMouseLeave.Invoke(this, 0);
}
virtual void OnKeyDown(LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str)
{
Event_KeyDown.Invoke(this, key);
}
virtual void OnKeyUp(LifeCore::KeyCodes::Key key, unsigned int text, const std::string& str)
{
Event_KeyUp.Invoke(this, key);
}
GUIWindow* GetWindowAtPoint(int x, int y)
{
if(GetRectangleAbs().InRect(x, y) && mouseEnabled && IsVisible())
{
GUIWindow* child = PickChild(x, y);
if(child)
{
return child->GetWindowAtPoint(x, y);
}
else
{
if(!this->skip_mouse)
return this;
}
}
return 0;
}
virtual GUIOverlay* FindOverlay();
LifeMath::Vec2i GetPosition()
{
return position;
}
LifeMath::Vec2i GetPositionAbs()
{
return positionAbs;
}
int GetWidth() const
{
return width;
}
LifeMath::Vec2i CursorToLocal(const LifeMath::Vec2i& world_coord)
{
return world_coord - positionAbs;
}
LifeMath::Vec2i CursorToClient(const LifeMath::Vec2i& world_coord)
{
LifeMath::Rect2i r = GetClientRectangleAbs();
return world_coord - LifeMath::Vec2i(r.x, r.y);
}
LifeMath::Vec2i CursorToWorld(const LifeMath::Vec2i& local_coord)
{
return local_coord + positionAbs;
}
int GetHeight() const
{
return height;
}
void SetDock(DOCK_TYPE t)
{
if(dock != t)
{
dock = t;
if(parent != 0)
{
parent->Invalidate();
}
}
}
DOCK_TYPE GetDock()
{
return dock;
}
bool IsVisible()
{
return visible;
}
void Show()
{
visible = true;
}
void Hide()
{
visible = false;
}
bool IsEnabled()
{
return enabled;
}
bool IsBorderEnabled()
{
return borderEnabled;
}
virtual void SetBorderEnabled(bool state)
{
borderEnabled = state;
Invalidate();
}
virtual void RenderSelf()
{
}
virtual void ReleaseFocus()
{
}
virtual void SetPosition(const LifeMath::Vec2i& _position);
virtual void AddChild(GUIWindow* val)
{
childs.push_back(val);
val->SetParent(this);
Invalidate();
}
virtual int RemoveChild(int hwnd)
{
for(WindowList::iterator it = childs.begin(); it != childs.end(); ++it)
{
if((*it)->hwnd == hwnd)
{
childs.erase(it);
return 1;
}
}
return 0;
}
LifeMath::Rect2i GetContentRectangle()
{
LifeMath::Rect2i r;
if(!childs.size())
return r;
r = childs[0]->GetRectangle();
for(WindowList::iterator it = childs.begin(); it != childs.end(); ++it)
{
r.Merge((*it)->GetRectangle());
}
return r;
}
virtual void SetParent(GUIWindow* val)
{
parent = val;
SetPosition(position);
UpdateScissor();
Invalidate();
}
virtual void SetWidth(int val)
{
if(width != val)
{
width = val;
Invalidate();
Event_Resize.Invoke(this);
}
}
virtual void SetHeight(int val)
{
if(height != val)
{
height = val;
Invalidate();
Event_Resize.Invoke(this);
}
}
// TODO trololo every day
virtual void Render()
{
RenderSelf();
RenderChilds();
}
virtual LifeMath::Rect2i GetClientRectangle()
{
return LifeMath::Rect2i(0, 0, this->GetWidth(), this->GetHeight());
}
virtual LifeMath::Rect2i GetClientRectangleAbs()
{
LifeMath::Vec2i pos = this->GetPositionAbs();
return LifeMath::Rect2i(pos.X, pos.Y, this->GetWidth(), this->GetHeight());
}
virtual LifeMath::Rect2i GetRectangle()
{
LifeMath::Vec2i rel = GetPosition();
return LifeMath::Rect2i(rel.X, rel.Y,this->GetWidth(), this->GetHeight());
}
virtual LifeMath::Rect2i GetRectangleAbs()
{
LifeMath::Vec2i abs = GetPositionAbs();
return LifeMath::Rect2i(abs.X,abs.Y,this->GetWidth(), this->GetHeight());
}
bool IsAllowDrag()
{
return allowDrag;
}
bool IsAllowDrop()
{
return allowDrop;
}
virtual void FinishDrag()
{
}
virtual bool DragEnter(DragInfo* info)
{
return false;
}
virtual void AcceptDrop(DragInfo* info)
{
}
void SetScissor(const LifeMath::Rect2i& _scissor)
{
scissor = _scissor;
scissor_local = _scissor;
scissor_client = _scissor;
}
protected:
bool allowDrop;
bool allowDrag;
int mouseButtons;
bool enabled;
bool visible;
bool mouseCaptured;
GUIWidgetSkin* skin;
bool borderEnabled;
//int borderSize;
int width;
int height;
GUIWindow* parent;
typedef std::vector<GUIWindow*> WindowList;
typedef std::vector<GUIWindow*>::iterator WindowListIter;
WindowList childs;
LifeMath::Vec2i position;
LifeMath::Vec2i positionAbs;
GUIVertex* vert;
DOCK_TYPE dock;
LifeMath::Rect2i scissor;
LifeMath::Rect2i scissor_local;
LifeMath::Rect2i scissor_client;
const LifeMath::Rect2i& GetScissor()
{
return scissor;
}
const LifeMath::Rect2i& GetScissorClient()
{
return scissor_client;
}
void UpdateScissor()
{
LifeMath::Rect2i sc;
sc = GetRectangleAbs();
if(parent)
{
if(NonClientControl)
sc.Crop(parent->GetScissor());
else
sc.Crop(parent->GetScissorClient());
}
LifeMath::Rect2i sc_t = sc;
LifeMath::Vec2i pos = CursorToLocal(LifeMath::Vec2i(sc_t.x, sc_t.y));
sc_t.x = pos.X;
sc_t.y = pos.Y;
if(scissor != sc || sc_t != scissor_local)
//if(sc_t != scissor_local)
{
scissor = sc;
scissor_local = sc_t;
sc = GetClientRectangleAbs();
if(parent)
sc.Crop(parent->GetScissorClient());
scissor_client = sc;
Invalidate();
}
/* else if (sc_t != scissor_local)
{
scissor_local = sc_t;
Invalidate();
}*/
for(WindowList::iterator it = childs.begin(); it!= childs.end(); ++it)
{
if((*it)->IsVisible())
(*it)->UpdateScissor();
}
}
void UpdateChildDock()
{
LifeMath::Rect2i available_area = this->GetClientRectangle();
for(WindowList::iterator it = childs.begin(); it!= childs.end(); ++it)
{
GUIWindow* child = (*it);
if(child->IsVisible())
{
DOCK_TYPE d = child->GetDock();
LifeMath::Rect2i r = this->GetClientRectangle();
switch(d)
{
case DOCK_LEFT:
{
if(available_area.GetSquare() > 0)
{
child->SetPosition(LifeMath::Vec2i(available_area.x, available_area.y));
child->SetHeight(available_area.height);
available_area.width -= child->GetWidth();
available_area.x += child->GetWidth();
}
else
{
child->SetPosition(LifeMath::Vec2i(0, 0));
child->SetHeight(r.height);
}
}
break;
case DOCK_RIGHT:
{
if(available_area.GetSquare() > 0)
{
child->SetPosition(LifeMath::Vec2i(available_area.width - child->GetWidth() + available_area.x, 0));
child->SetHeight(available_area.height);
available_area.width -= child->GetWidth();
}
else
{
child->SetPosition(LifeMath::Vec2i(r.width - child->GetWidth(), 0));
child->SetHeight(r.height);
}
}
break;
case DOCK_TOP:
{
if(available_area.GetSquare() > 0)
{
child->SetPosition(LifeMath::Vec2i(available_area.x, available_area.y));
child->SetWidth(available_area.width);
available_area.height -= child->GetHeight();
available_area.y += child->GetHeight();
}
else
{
child->SetPosition(LifeMath::Vec2i(0, 0));
child->SetWidth(r.width);
}
}
break;
case DOCK_BOTTOM:
{
if(available_area.GetSquare() > 0)
{
child->SetPosition(LifeMath::Vec2i(available_area.x, available_area.height - child->GetHeight() + available_area.y));
child->SetWidth(available_area.width);
available_area.height -= child->GetHeight();
}
else
{
child->SetPosition(LifeMath::Vec2i(0, r.height - child->GetHeight()));
child->SetWidth(r.width);
}
}
break;
case DOCK_FILL:
{
if(available_area.GetSquare() > 0)
{
child->SetPosition(LifeMath::Vec2i(available_area.x, available_area.y));
child->SetWidth(available_area.width);
child->SetHeight(available_area.height);
available_area.width = 0;
available_area.height = 0;
}
else
{
child->SetPosition(LifeMath::Vec2i(0, 0));
child->SetWidth(r.width);
child->SetHeight(r.height);
}
}
break;
}
//fix up available area rectangle
if(available_area.width < 0)
available_area.width = 0;
if(available_area.height < 0)
available_area.height = 0;
}
}
}
void RenderChilds()
{
for(WindowList::iterator it = childs.begin(); it!= childs.end(); ++it)
{
if((*it)->IsVisible())
(*it)->Render();
}
}
void UpdateChildTransform()
{
for(WindowList::iterator it = childs.begin(); it!= childs.end(); ++it)
{
GUIWindow* w = (*it);
if(w->IsVisible())
w->SetPosition(w->GetPosition());
}
}
/*void UpdateChilds(float dt)
{
for(WindowList::iterator it = childs.begin(); it!= childs.end(); ++it)
{
if((*it)->IsVisible())
(*it)->Update( dt);
}
}*/
};
}
#endif // GUIWindow_h__
+19
View File
@@ -0,0 +1,19 @@
#ifndef IGUICursor_h__
#define IGUICursor_h__
#include "IImage.h"
#include "GUIWidgetSkin.h"
namespace LifeGUI
{
class IGUICursor
{
public:
IImage* tex;
GUIWidgetSkin* skin;
String name;
LifeMath::Vec2i offset;
LifeMath::Vec2i size;
};
}
#endif // IGUICursor_h__
+20
View File
@@ -0,0 +1,20 @@
#ifndef IGUIDataManager_h__
#define IGUIDataManager_h__
#include <vfs/IFileSystem.h>
#include <LString.h>
#include "IImage.h"
namespace LifeGUI
{
class IGUIDataManager
{
public:
virtual LifeCore::IFileSystem* getFileSystem() = 0;
virtual LifeGUI::IImage* getImage(const String& name) = 0;
virtual LifeGUI::IImage* createImage(uint32 width, uint32 height) = 0;
virtual const String getGuiRootDir() = 0;
};
}
#endif // IGUIDataManager_h__
+46
View File
@@ -0,0 +1,46 @@
#include "IGUIRenderer.h"
#include "GUIManager.h"
#include <assert.h>
namespace LifeGUI
{
IGUIRenderer::IGUIRenderer()
:batch_id(0)
{
buffer = new LifeCore::IMemoryStream(sizeof(GUIVertex) * MAX_GUI_VERTEX_COUNT);
buffer->Seek(0);
}
void IGUIRenderer::Reset()
{
buffer->Seek(0);
batch_id = 0;
memset(&batch[0], 0, MAX_DIP_COUNT * sizeof(GUIBatch));
}
void IGUIRenderer::SetTexture(IImage* tex, IImage* font, bool line_geom)
{
//start new batch if _any_ condition is changed
if((tex != 0 && batch[batch_id].tex != 0 && (batch[batch_id].tex->GetID() != tex->GetID())) ||
(tex != 0 && batch[batch_id].tex == 0) || (tex == 0 && batch[batch_id].tex != 0))
batch_id++;
else if( font != 0 && batch[batch_id].font != 0 && (batch[batch_id].font->GetID() != font->GetID()))
batch_id++;
else if (batch[batch_id].lines != line_geom)
batch_id++;
assert(batch_id < MAX_DIP_COUNT && "GUI batch count overflow!");
if(font != 0) batch[batch_id].font = font;
if(tex != 0) batch[batch_id].tex = tex;
batch[batch_id].lines = line_geom;
}
void IGUIRenderer::Write(const GUIVertex& data)
{
buffer->Write(&data, sizeof(GUIVertex));
batch[batch_id].vertex_count++;
}
void IGUIRenderer::Write(const GUIVertex* data, size_t count)
{
buffer->Write(data, sizeof(GUIVertex) * count);
batch[batch_id].vertex_count += count;
}
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef IGUIRenderer_h__
#define IGUIRenderer_h__
#include "IImage.h"
#include "GUIVertex.h"
#include <LString.h>
#include <IMemoryStream.h>
#define MAX_DIP_COUNT 128
#define MAX_GUI_VERTEX_COUNT (6 * 4096)
namespace LifeGUI
{
struct GUIBatch
{
IImage* tex;
IImage* font;
bool lines;
int tex_id;
size_t vertex_count;
GUIBatch()
:tex(nullptr), font(nullptr), vertex_count(0)
{
lines = false;
tex_id = 0;
}
};
class IGUIRenderer
{
public:
IGUIRenderer();
void Reset();
void SetTexture(IImage* tex, IImage* font, bool line_geom);
void Write(const GUIVertex& data);
void Write(const GUIVertex* data, size_t count);
virtual void SetScissor(const LifeMath::Rect2i& rect) = 0;
virtual void Render() = 0;
virtual void SetScreenSize(int w, int h) = 0;
protected:
LifeCore::IMemoryStream* buffer;
LifeGUI::GUIBatch batch[MAX_DIP_COUNT];
size_t batch_id;
};
}
#endif // IGUIRenderer_h__
+28
View File
@@ -0,0 +1,28 @@
#ifndef IImage_h__
#define IImage_h__
#include <Types.h>
#include <math\Rectangle.h>
#include <IDataRectangle.h>
namespace LifeGUI
{
class IImage
{
public:
virtual size_t GetID() = 0;
virtual uint32 GetWidth() = 0;
virtual uint32 GetHeight() = 0;
virtual uint32 GetPixelSize() = 0;
virtual void SetPixel(uint32 x, uint32 y, const void* data) = 0;
virtual void GetPixel(uint32 x, uint32 y, void* data) = 0;
virtual void SetData(const void* data, uint32 size) = 0;
virtual void SetData(const void* data, const LifeMath::Rect2i& area) = 0;
virtual void GetData(void* data, uint32 size) = 0;
virtual void GetData(void* data, const LifeMath::Rect2i& area) = 0;
virtual LifeCore::IDataRectangle* Map(uint32 level, bool read, bool write) = 0;
virtual void Unmap(uint32 level) = 0;
};
}
#endif // IImage_h__
+43
View File
@@ -0,0 +1,43 @@
#ifndef PropertyItemFile_h__
#define PropertyItemFile_h__
#include "IPropertyItem.h"
#include "GUIFileBrowserDialog.h"
#include "GUIManager.h"
namespace LifeGUI
{
class PropertyItemFile : public LifeCore::IPropertyItem
{
public:
PropertyItemFile(IFileSystem* fs, LifeCore::Property<String>* _prop)
{
dialog = new GUIFileBrowserDialog();
dialog->SetFileSystem(fs);
dialog->Hide();
prop = _prop;
}
PropertyEditMode GetEditMode()
{
return EM_CUSTOM;
}
void OnBeginEdit()
{
GUIManager::me()->GetActiveOverlay()->AddChild(dialog);
dialog->Show();
}
void OnEndEdit(const String& data)
{
dialog->Hide();
GUIManager::me()->GetActiveOverlay()->RemoveChild(dialog->hwnd);
}
String ToString()
{
return (*prop)();
}
private:
GUIFileBrowserDialog* dialog;
LifeCore::Property<String>* prop;
};
}
#endif // PropertyItemFile_h__
+32
View File
@@ -0,0 +1,32 @@
#ifndef PropertyItemFloat_h__
#define PropertyItemFloat_h__
#include "IPropertyItem.h"
namespace LifeGUI
{
class PropertyItemFloat : public LifeCore::IPropertyItem
{
public:
PropertyItemFloat( LifeCore::Property<float>* _prop)
{
prop = _prop;
}
PropertyEditMode GetEditMode()
{
return EM_INPLACE;
}
void OnEndEdit(const String& data)
{
*prop = (float)atof(data.c_str());
}
String ToString()
{
char buffer[64];
sprintf(buffer, "%f", (*prop)());
return String(buffer);
}
private:
LifeCore::Property<float>* prop;
};
}
#endif // PropertyItemFloat_h__