*
This commit is contained in:
@@ -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>
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}*/
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "GUIFontManager.h"
|
||||
|
||||
namespace LifeGUI
|
||||
{
|
||||
GUIFont* GUIFontManager::GetFont(const String& font_name){
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}*/
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
Reference in New Issue
Block a user