improve text input
This commit is contained in:
@@ -570,6 +570,14 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="icon.ico" />
|
<Image Include="icon.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Xsd Include="extra\layout.xsd">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</Xsd>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
@@ -739,4 +739,9 @@
|
|||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</Image>
|
</Image>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Xsd Include="extra\layout.xsd">
|
||||||
|
<Filter>extras</Filter>
|
||||||
|
</Xsd>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<root>
|
<root
|
||||||
|
xmlns="http://panopainter.com/layout.xsd"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
>
|
||||||
|
|
||||||
<!--brush icon-->
|
<!--brush icon-->
|
||||||
<layout id="tpl-brush-icon">
|
<layout id="tpl-brush-icon">
|
||||||
@@ -60,15 +63,15 @@
|
|||||||
<node grow="1">
|
<node grow="1">
|
||||||
<node dir="row" height="30" align="center" grow="1">
|
<node dir="row" height="30" align="center" grow="1">
|
||||||
<text text="Author" margin="0 5 0 0"/>
|
<text text="Author" margin="0 5 0 0"/>
|
||||||
<text-input align="center" pad="5" grow="1" height="30" color=".3"/>
|
<text-input pad="5" grow="1" height="30" color=".3"/>
|
||||||
</node>
|
</node>
|
||||||
<node dir="row" height="30" align="center" grow="1">
|
<node dir="row" height="30" align="center" grow="1">
|
||||||
<text text="URL" margin="0 5 0 0"/>
|
<text text="URL" margin="0 5 0 0"/>
|
||||||
<text-input align="center" pad="5" grow="1" height="30" color=".3"/>
|
<text-input pad="5" grow="1" height="30" color=".3"/>
|
||||||
</node>
|
</node>
|
||||||
<node dir="row" height="30" align="center" grow="1">
|
<node dir="row" height="80" align="center" grow="1">
|
||||||
<text text="Description" margin="0 5 0 0"/>
|
<text text="Description" margin="0 5 0 0"/>
|
||||||
<text-input align="center" pad="5" grow="1" height="30" color=".3"/>
|
<text-input text-vertical-align="top" pad="5" grow="1" min-height="80" color=".3" multiline="1"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</border>
|
</border>
|
||||||
@@ -2009,5 +2012,6 @@ Here's a list of what's available in this release.
|
|||||||
</border>
|
</border>
|
||||||
-->
|
-->
|
||||||
<!--<ref id="dialog-brush-upload"/>-->
|
<!--<ref id="dialog-brush-upload"/>-->
|
||||||
</layout>
|
|
||||||
|
</layout>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
352
extra/layout.xsd
Normal file
352
extra/layout.xsd
Normal file
@@ -0,0 +1,352 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xs:schema id="layout"
|
||||||
|
targetNamespace="http://panopainter.com/layout.xsd"
|
||||||
|
elementFormDefault="qualified"
|
||||||
|
xmlns="http://panopainter.com/layout.xsd"
|
||||||
|
xmlns:mstns="http://panopainter.com/layout.xsd"
|
||||||
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
>
|
||||||
|
<xs:element name="root">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element maxOccurs="unbounded" ref="layout"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="layout">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:choice minOccurs="0">
|
||||||
|
<xs:element ref="border"/>
|
||||||
|
<xs:element ref="button-custom"/>
|
||||||
|
<xs:element ref="popup-menu"/>
|
||||||
|
</xs:choice>
|
||||||
|
<xs:element minOccurs="0" ref="canvas"/>
|
||||||
|
<xs:element minOccurs="0" ref="node"/>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="popup-menu">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element ref="border"/>
|
||||||
|
<xs:element ref="button-custom"/>
|
||||||
|
</xs:choice>
|
||||||
|
<xs:attribute name="border-color" use="required" type="xs:decimal"/>
|
||||||
|
<xs:attribute name="color" use="required"/>
|
||||||
|
<xs:attribute name="dir" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="position" use="required"/>
|
||||||
|
<xs:attribute name="positioning" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="thickness" use="required" type="xs:integer"/>
|
||||||
|
<xs:attribute name="width" use="required" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="canvas">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="grow" use="required" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" use="required"/>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="positioning" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="width" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="border">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:choice minOccurs="0">
|
||||||
|
<xs:element ref="checkbox"/>
|
||||||
|
<xs:element ref="image"/>
|
||||||
|
<xs:element ref="image-texture"/>
|
||||||
|
<xs:element ref="color-quad"/>
|
||||||
|
</xs:choice>
|
||||||
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element ref="border"/>
|
||||||
|
<xs:element ref="button"/>
|
||||||
|
<xs:element ref="button-custom"/>
|
||||||
|
<xs:element ref="combobox"/>
|
||||||
|
<xs:element ref="node"/>
|
||||||
|
<xs:element ref="scroll"/>
|
||||||
|
<xs:element ref="slider-h"/>
|
||||||
|
<xs:element ref="text"/>
|
||||||
|
<xs:element ref="text-input"/>
|
||||||
|
<xs:element ref="colorwheel"/>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="align" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="border-color" type="xs:decimal"/>
|
||||||
|
<xs:attribute name="color"/>
|
||||||
|
<xs:attribute name="dir" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="flood-events" type="xs:integer"/>
|
||||||
|
<xs:attribute name="grow" type="xs:decimal"/>
|
||||||
|
<xs:attribute name="height"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="justify" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="max-width" type="xs:integer"/>
|
||||||
|
<xs:attribute name="min-height" type="xs:integer"/>
|
||||||
|
<xs:attribute name="min-width" type="xs:integer"/>
|
||||||
|
<xs:attribute name="mouse-capture" type="xs:boolean"/>
|
||||||
|
<xs:attribute name="pad"/>
|
||||||
|
<xs:attribute name="position"/>
|
||||||
|
<xs:attribute name="positioning" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="rtl" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="shrink" type="xs:integer"/>
|
||||||
|
<xs:attribute name="thickness" type="xs:integer"/>
|
||||||
|
<xs:attribute name="width"/>
|
||||||
|
<xs:attribute name="wrap" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="color-quad">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="color" use="required"/>
|
||||||
|
<xs:attribute name="grow" use="required" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" use="required"/>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="colorwheel">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="aspect-ratio" use="required" type="xs:integer"/>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="width" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="button-custom">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:choice minOccurs="0">
|
||||||
|
<xs:element ref="checkbox"/>
|
||||||
|
<xs:element ref="icon"/>
|
||||||
|
</xs:choice>
|
||||||
|
<xs:element minOccurs="0" ref="image"/>
|
||||||
|
<xs:element minOccurs="0" ref="border"/>
|
||||||
|
<xs:element minOccurs="0" ref="stroke-preview"/>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" ref="text"/>
|
||||||
|
<xs:element minOccurs="0" ref="combobox"/>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="align" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="border-color"/>
|
||||||
|
<xs:attribute name="color"/>
|
||||||
|
<xs:attribute name="dir" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="grow" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="justify" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="os"/>
|
||||||
|
<xs:attribute name="pad"/>
|
||||||
|
<xs:attribute name="shrink" type="xs:integer"/>
|
||||||
|
<xs:attribute name="thickness" type="xs:integer"/>
|
||||||
|
<xs:attribute name="width"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="icon">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="icon" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="width" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="stroke-preview">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="grow" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" use="required"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="width" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="node">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element ref="border"/>
|
||||||
|
<xs:element ref="button-custom"/>
|
||||||
|
<xs:element ref="checkbox"/>
|
||||||
|
<xs:element ref="image"/>
|
||||||
|
<xs:element ref="image-texture"/>
|
||||||
|
<xs:element ref="node"/>
|
||||||
|
<xs:element ref="scroll"/>
|
||||||
|
<xs:element ref="slider-h"/>
|
||||||
|
<xs:element ref="text"/>
|
||||||
|
<xs:element ref="panel-quick"/>
|
||||||
|
</xs:choice>
|
||||||
|
<xs:choice>
|
||||||
|
<xs:element ref="combobox"/>
|
||||||
|
<xs:element ref="text-input"/>
|
||||||
|
<xs:element ref="slider-hue"/>
|
||||||
|
<xs:element ref="slider-v"/>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" ref="button"/>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="align" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="color"/>
|
||||||
|
<xs:attribute name="dir" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="flood-events" type="xs:integer"/>
|
||||||
|
<xs:attribute name="grow" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="justify" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="max-height" type="xs:integer"/>
|
||||||
|
<xs:attribute name="min-height" type="xs:integer"/>
|
||||||
|
<xs:attribute name="min-width" type="xs:integer"/>
|
||||||
|
<xs:attribute name="os"/>
|
||||||
|
<xs:attribute name="pad"/>
|
||||||
|
<xs:attribute name="rtl" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="shrink" type="xs:integer"/>
|
||||||
|
<xs:attribute name="width"/>
|
||||||
|
<xs:attribute name="wrap" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="panel-quick">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="slider-hue">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="slider-v">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="height" use="required" type="xs:integer"/>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="shrink" use="required" type="xs:integer"/>
|
||||||
|
<xs:attribute name="width" use="required" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="image">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="align" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="autosize" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="justify" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="mips" type="xs:boolean"/>
|
||||||
|
<xs:attribute name="path"/>
|
||||||
|
<xs:attribute name="width" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="checkbox">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="height" type="xs:integer"/>
|
||||||
|
<xs:attribute name="icon"/>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="width" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="image-texture">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:choice minOccurs="0">
|
||||||
|
<xs:element ref="border"/>
|
||||||
|
<xs:element ref="text"/>
|
||||||
|
</xs:choice>
|
||||||
|
<xs:attribute name="aspect-ratio" type="xs:integer"/>
|
||||||
|
<xs:attribute name="grow" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" use="required"/>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="pad" type="xs:integer"/>
|
||||||
|
<xs:attribute name="width" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="text">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="align" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="color"/>
|
||||||
|
<xs:attribute name="font-size" type="xs:integer"/>
|
||||||
|
<xs:attribute name="grow" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" type="xs:integer"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="justify" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="os"/>
|
||||||
|
<xs:attribute name="pad" type="xs:integer"/>
|
||||||
|
<xs:attribute name="text"/>
|
||||||
|
<xs:attribute name="text-wrap-width" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="button">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="color"/>
|
||||||
|
<xs:attribute name="grow" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" use="required"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="os"/>
|
||||||
|
<xs:attribute name="pad" type="xs:integer"/>
|
||||||
|
<xs:attribute name="text" use="required"/>
|
||||||
|
<xs:attribute name="width" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="scroll">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element minOccurs="0" ref="ref"/>
|
||||||
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element ref="border"/>
|
||||||
|
<xs:element ref="image"/>
|
||||||
|
<xs:element ref="node"/>
|
||||||
|
</xs:choice>
|
||||||
|
<xs:choice>
|
||||||
|
<xs:element ref="button"/>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" ref="text"/>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="color" use="required"/>
|
||||||
|
<xs:attribute name="dir" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="flood-events" type="xs:integer"/>
|
||||||
|
<xs:attribute name="grow" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="justify" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="min-width" type="xs:integer"/>
|
||||||
|
<xs:attribute name="mouse-capture" type="xs:boolean"/>
|
||||||
|
<xs:attribute name="pad"/>
|
||||||
|
<xs:attribute name="rtl" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="scroll-color" type="xs:decimal"/>
|
||||||
|
<xs:attribute name="shrink" type="xs:integer"/>
|
||||||
|
<xs:attribute name="wrap" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="ref">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="text-input">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="align" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="color" use="required" type="xs:decimal"/>
|
||||||
|
<xs:attribute name="grow" use="required" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" type="xs:integer"/>
|
||||||
|
<xs:attribute name="id" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="min-height" type="xs:integer"/>
|
||||||
|
<xs:attribute name="multiline" type="xs:integer"/>
|
||||||
|
<xs:attribute name="pad" use="required" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="combobox">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="combo-list" use="required"/>
|
||||||
|
<xs:attribute name="default" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" use="required" type="xs:integer"/>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="text" type="xs:NMTOKEN"/>
|
||||||
|
<xs:attribute name="width" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="slider-h">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="grow" type="xs:integer"/>
|
||||||
|
<xs:attribute name="height" type="xs:integer"/>
|
||||||
|
<xs:attribute name="id" use="required" type="xs:NCName"/>
|
||||||
|
<xs:attribute name="margin"/>
|
||||||
|
<xs:attribute name="value" type="xs:decimal"/>
|
||||||
|
<xs:attribute name="width" type="xs:integer"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -113,7 +113,7 @@ void App::dialog_newdoc()
|
|||||||
|
|
||||||
dialog->btn_ok->on_click = [this, dialog](Node*)
|
dialog->btn_ok->on_click = [this, dialog](Node*)
|
||||||
{
|
{
|
||||||
std::string name = dialog->input->m_string;
|
std::string name = dialog->input->m_text;
|
||||||
std::string path = work_path + "/" + name + ".ppi";
|
std::string path = work_path + "/" + name + ".ppi";
|
||||||
|
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
@@ -381,7 +381,7 @@ void App::dialog_save()
|
|||||||
|
|
||||||
dialog->btn_ok->on_click = [this, dialog](Node*)
|
dialog->btn_ok->on_click = [this, dialog](Node*)
|
||||||
{
|
{
|
||||||
std::string name = dialog->input->m_string;
|
std::string name = dialog->input->m_text;
|
||||||
std::string path = work_path + "/" + name + ".ppi";
|
std::string path = work_path + "/" + name + ".ppi";
|
||||||
|
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
|
|||||||
36
src/font.cpp
36
src/font.cpp
@@ -83,7 +83,7 @@ std::vector<TextMesh::Token> TextMesh::tokenize(const std::string& s, const Font
|
|||||||
bool is_delim = std::find(delims.begin(), delims.end(), c) != delims.end();
|
bool is_delim = std::find(delims.begin(), delims.end(), c) != delims.end();
|
||||||
wrap |= is_delim; // set wrap to notify a delimiter has been reached
|
wrap |= is_delim; // set wrap to notify a delimiter has been reached
|
||||||
// when a new non-delim char is detected, start a new token
|
// when a new non-delim char is detected, start a new token
|
||||||
if (wrap && !is_delim)
|
if (wrap && !is_delim && !tmp.empty())
|
||||||
{
|
{
|
||||||
parts.push_back(tmp);
|
parts.push_back(tmp);
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
@@ -130,40 +130,61 @@ bool TextMesh::create()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextMesh::update(kFont id, const char* text)
|
void TextMesh::update(kFont id, const std::string& text)
|
||||||
{
|
{
|
||||||
font_id = id;
|
font_id = id;
|
||||||
auto& f = FontManager::get(id);
|
auto& f = FontManager::get(id);
|
||||||
|
float spacing = f.bounds.w - f.bounds.y;
|
||||||
|
float avg_width = f.bounds.z - f.bounds.x;
|
||||||
|
cur_box = glm::vec4(0, 0, 5, spacing);
|
||||||
|
|
||||||
|
glm::vec2 bbmin(FLT_MAX);
|
||||||
|
glm::vec2 bbmax(-FLT_MAX);
|
||||||
|
if (text.empty())
|
||||||
|
{
|
||||||
|
bbmin = { 0, -spacing * 0.5f };
|
||||||
|
bbmax = { 1, +spacing * 0.5f };
|
||||||
|
}
|
||||||
|
|
||||||
if (f.chars.size())
|
if (f.chars.size())
|
||||||
{
|
{
|
||||||
float x = 0;
|
float x = 0;
|
||||||
float y = 0;
|
float y = 0;
|
||||||
std::vector<glm::vec4> v;
|
std::vector<glm::vec4> v;
|
||||||
std::vector<GLushort> idx;
|
std::vector<GLushort> idx;
|
||||||
glm::vec2 bbmin(FLT_MAX);
|
|
||||||
glm::vec2 bbmax(-FLT_MAX);
|
|
||||||
|
|
||||||
std::vector<Token> parts = max_width > 0 ?
|
std::vector<Token> parts = max_width > 0 ?
|
||||||
tokenize(text, f) :
|
tokenize(text, f) :
|
||||||
std::vector<Token>{ Token(text, 0.f) };
|
std::vector<Token>{ Token(text, 0.f) };
|
||||||
|
|
||||||
|
if (parts.empty())
|
||||||
|
{
|
||||||
|
bbmin = { 0, -spacing * 0.5f };
|
||||||
|
bbmax = { 1, +spacing * 0.5f };
|
||||||
|
}
|
||||||
|
|
||||||
for (auto p : parts)
|
for (auto p : parts)
|
||||||
{
|
{
|
||||||
if (max_width > 0 && x + p.w > max_width * f.scale)
|
if (max_width > 0 && (x + p.w) * f.scale > max_width)
|
||||||
{
|
{
|
||||||
x = 0;
|
x = 0;
|
||||||
y += f.size * f.scale;
|
y += spacing;
|
||||||
}
|
}
|
||||||
for (char c : p.s)
|
for (char c : p.s)
|
||||||
{
|
{
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
x = 0;
|
x = 0;
|
||||||
y += f.size * f.scale;
|
y += spacing;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
stbtt_aligned_quad q;
|
stbtt_aligned_quad q;
|
||||||
stbtt_GetBakedQuad((stbtt_bakedchar*)f.chars.data(), f.w, f.h, c - f.start_char, &x, &y, &q, true);
|
stbtt_GetBakedQuad((stbtt_bakedchar*)f.chars.data(), f.w, f.h, c - f.start_char, &x, &y, &q, true);
|
||||||
|
if (max_width > 0 && x * f.scale > max_width /*font scale factor*/)
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y += spacing;
|
||||||
|
}
|
||||||
auto n = (int)v.size();
|
auto n = (int)v.size();
|
||||||
v.emplace_back(q.x0 / f.scale, q.y1 / f.scale, q.s0, q.t1);
|
v.emplace_back(q.x0 / f.scale, q.y1 / f.scale, q.s0, q.t1);
|
||||||
v.emplace_back(q.x0 / f.scale, q.y0 / f.scale, q.s0, q.t0);
|
v.emplace_back(q.x0 / f.scale, q.y0 / f.scale, q.s0, q.t0);
|
||||||
@@ -177,6 +198,7 @@ void TextMesh::update(kFont id, const char* text)
|
|||||||
idx.push_back(n + 3);
|
idx.push_back(n + 3);
|
||||||
bbmin = glm::min(bbmin, { q.x0 / f.scale, q.y0 / f.scale });
|
bbmin = glm::min(bbmin, { q.x0 / f.scale, q.y0 / f.scale });
|
||||||
bbmax = glm::max(bbmax, { q.x1 / f.scale, q.y1 / f.scale });
|
bbmax = glm::max(bbmax, { q.x1 / f.scale, q.y1 / f.scale });
|
||||||
|
cur_box = glm::vec4(x, y, 5, spacing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto& vi : v)
|
for (auto& vi : v)
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ public:
|
|||||||
GLuint font_buffers[2] = {0, 0};
|
GLuint font_buffers[2] = {0, 0};
|
||||||
kFont font_id;
|
kFont font_id;
|
||||||
glm::vec2 bb = { 0, 0 };
|
glm::vec2 bb = { 0, 0 };
|
||||||
|
glm::vec4 cur_box;
|
||||||
bool create();
|
bool create();
|
||||||
void update(kFont id, const char* text);
|
void update(kFont id, const std::string& text);
|
||||||
void draw();
|
void draw();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1036,7 +1036,7 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj, float
|
|||||||
m_mvp = proj * pos * scale * pivot * prescale;
|
m_mvp = proj * pos * scale * pivot * prescale;
|
||||||
m_proj = proj;
|
m_proj = proj;
|
||||||
|
|
||||||
if (m_size != old_size || m_zoom != zoom)
|
if (!glm::any(glm::isnan(m_size)) && m_size != old_size || m_zoom != zoom)
|
||||||
{
|
{
|
||||||
m_zoom = zoom;
|
m_zoom = zoom;
|
||||||
handle_resize(old_size, m_size, zoom);
|
handle_resize(old_size, m_size, zoom);
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ enum class kAttribute : uint16_t
|
|||||||
AutoSize = const_hash("autosize"),
|
AutoSize = const_hash("autosize"),
|
||||||
MouseCapture = const_hash("mouse-capture"),
|
MouseCapture = const_hash("mouse-capture"),
|
||||||
ScrollColor = const_hash("scroll-color"),
|
ScrollColor = const_hash("scroll-color"),
|
||||||
|
Multiline = const_hash("multiline"),
|
||||||
|
TextAlign = const_hash("text-align"),
|
||||||
|
TextVerticalAlign = const_hash("text-vertical-align"),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kWidget : uint16_t
|
enum class kWidget : uint16_t
|
||||||
|
|||||||
@@ -43,5 +43,5 @@ void NodeDialogLayerRename::loaded()
|
|||||||
|
|
||||||
std::string NodeDialogLayerRename::get_name()
|
std::string NodeDialogLayerRename::get_name()
|
||||||
{
|
{
|
||||||
return input ? input->m_string : "";
|
return input ? input->m_text : "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ void NodeInputBox::init()
|
|||||||
btn_ok = m_template->find<NodeButton>("btn-ok");
|
btn_ok = m_template->find<NodeButton>("btn-ok");
|
||||||
btn_ok->on_click = [&](Node*) {
|
btn_ok->on_click = [&](Node*) {
|
||||||
if (on_submit)
|
if (on_submit)
|
||||||
on_submit(this, m_field_text->m_text->m_text);
|
on_submit(this, m_field_text->m_text);
|
||||||
};
|
};
|
||||||
btn_cancel = m_template->find<NodeButton>("btn-cancel");
|
btn_cancel = m_template->find<NodeButton>("btn-cancel");
|
||||||
btn_cancel->on_click = [&](Node*) { destroy(); };
|
btn_cancel->on_click = [&](Node*) { destroy(); };
|
||||||
@@ -39,7 +39,7 @@ kEventResult NodeInputBox::handle_event(Event* e)
|
|||||||
break;
|
break;
|
||||||
case kEventType::KeyUp:
|
case kEventType::KeyUp:
|
||||||
if (ke->m_key == kKey::KeyEnter && on_submit)
|
if (ke->m_key == kKey::KeyEnter && on_submit)
|
||||||
on_submit(this, m_field_text->m_text->m_text);
|
on_submit(this, m_field_text->m_text);
|
||||||
break;
|
break;
|
||||||
case kEventType::KeyChar:
|
case kEventType::KeyChar:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ void NodeText::clone_copy(Node* dest) const
|
|||||||
NodeText* n = static_cast<NodeText*>(dest);
|
NodeText* n = static_cast<NodeText*>(dest);
|
||||||
n->m_text_mesh.max_width = m_text_mesh.max_width;
|
n->m_text_mesh.max_width = m_text_mesh.max_width;
|
||||||
n->m_text_mesh.create();
|
n->m_text_mesh.create();
|
||||||
n->m_text_mesh.update(font_id, m_text.c_str());
|
n->m_text_mesh.update(font_id, m_text);
|
||||||
n->m_text = m_text;
|
n->m_text = m_text;
|
||||||
n->m_font = m_font;
|
n->m_font = m_font;
|
||||||
n->m_color = m_color;
|
n->m_color = m_color;
|
||||||
@@ -31,7 +31,7 @@ void NodeText::create()
|
|||||||
sprintf(font, "%s-%d", m_font.c_str(), m_font_size);
|
sprintf(font, "%s-%d", m_font.c_str(), m_font_size);
|
||||||
font_id = (kFont)const_hash(font);
|
font_id = (kFont)const_hash(font);
|
||||||
m_text_mesh.create();
|
m_text_mesh.create();
|
||||||
m_text_mesh.update(font_id, m_text.c_str());
|
m_text_mesh.update(font_id, m_text);
|
||||||
SetSize(m_text_mesh.bb);
|
SetSize(m_text_mesh.bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ void NodeText::set_font(kFont fontID)
|
|||||||
{
|
{
|
||||||
font_id = fontID;
|
font_id = fontID;
|
||||||
m_text_mesh.create();
|
m_text_mesh.create();
|
||||||
m_text_mesh.update(font_id, m_text.c_str());
|
m_text_mesh.update(font_id, m_text);
|
||||||
SetSize(m_text_mesh.bb);
|
SetSize(m_text_mesh.bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,5 +116,6 @@ void NodeText::draw()
|
|||||||
|
|
||||||
void NodeText::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom)
|
void NodeText::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom)
|
||||||
{
|
{
|
||||||
m_text_mesh.update(font_id, m_text.c_str());
|
if (old_size != new_size)
|
||||||
|
m_text_mesh.update(font_id, m_text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,53 +14,39 @@ void NodeTextInput::on_tick(float dt)
|
|||||||
timer += dt;
|
timer += dt;
|
||||||
|
|
||||||
bool focus = root()->current_key_capture.get() == this;
|
bool focus = root()->current_key_capture.get() == this;
|
||||||
if (m_cursor && !focus)
|
if (!focus)
|
||||||
m_cursor->m_display = false;
|
m_cursor_visible = false;
|
||||||
m_thinkness = focus;
|
m_thinkness = focus;
|
||||||
|
|
||||||
if (timer > 1.0)
|
if (timer > 1.0)
|
||||||
{
|
{
|
||||||
timer = 0;
|
timer = 0;
|
||||||
if (focus && m_cursor)
|
if (focus)
|
||||||
{
|
{
|
||||||
m_cursor->m_display = !m_cursor->m_display;
|
m_cursor_visible = !m_cursor_visible;
|
||||||
app_redraw();
|
app_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeTextInput::clone_finalize(Node* dest) const
|
void NodeTextInput::clone_copy(Node* dest) const
|
||||||
{
|
{
|
||||||
NodeBorder::clone_copy(dest);
|
NodeBorder::clone_copy(dest);
|
||||||
NodeTextInput* n = static_cast<NodeTextInput*>(dest);
|
NodeTextInput* n = static_cast<NodeTextInput*>(dest);
|
||||||
if (n->m_children.size())
|
|
||||||
{
|
|
||||||
n->m_text = (NodeText*)n->m_children[0].get();
|
|
||||||
n->m_cursor = (NodeBorder*)n->m_children[1].get();
|
|
||||||
}
|
|
||||||
n->m_string = m_string;
|
|
||||||
|
|
||||||
}
|
n->m_multiline = m_multiline;
|
||||||
|
|
||||||
void NodeTextInput::init()
|
n->m_text_mesh.max_width = m_text_mesh.max_width;
|
||||||
{
|
n->m_text_mesh.create();
|
||||||
init_controls();
|
n->m_text_mesh.update(font_id, m_text);
|
||||||
}
|
n->m_text = m_text;
|
||||||
|
n->m_font = m_font;
|
||||||
void NodeTextInput::init_controls()
|
n->m_color = m_color;
|
||||||
{
|
n->m_font_size = m_font_size;
|
||||||
m_text = new NodeText;
|
n->font_id = font_id;
|
||||||
add_child(m_text);
|
n->m_off = m_off;
|
||||||
m_text->m_font = "arial";
|
n->m_text_align_v = m_text_align_v;
|
||||||
m_text->m_font_size = 11;
|
n->m_text_align_h = m_text_align_h;
|
||||||
m_text->m_text = "TextInput";
|
|
||||||
m_text->create();
|
|
||||||
m_string = "TextInput";
|
|
||||||
YGNodeStyleSetFlexDirection(y_node, YGFlexDirectionRow);
|
|
||||||
m_cursor = add_child<NodeBorder>();
|
|
||||||
m_cursor->SetWidth(4);
|
|
||||||
m_cursor->SetHeightP(100);
|
|
||||||
m_cursor->SetMargin(0, 0, 0, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kEventResult NodeTextInput::handle_event(Event* e)
|
kEventResult NodeTextInput::handle_event(Event* e)
|
||||||
@@ -74,15 +60,14 @@ kEventResult NodeTextInput::handle_event(Event* e)
|
|||||||
case kEventType::MouseUpL:
|
case kEventType::MouseUpL:
|
||||||
key_capture();
|
key_capture();
|
||||||
timer = 0;
|
timer = 0;
|
||||||
if (m_cursor)
|
m_cursor_visible = true;
|
||||||
m_cursor->m_display = true;
|
|
||||||
break;
|
break;
|
||||||
case kEventType::KeyDown:
|
case kEventType::KeyDown:
|
||||||
//switch (ke->m_key)
|
//switch (ke->m_key)
|
||||||
//{
|
//{
|
||||||
//case VK_BACK:
|
//case VK_BACK:
|
||||||
// m_string.erase(m_string.end() - 1);
|
// m_string.erase(m_string.end() - 1);
|
||||||
// m_text->set_text(m_string.c_str());
|
// m_text->set_text(m_string);
|
||||||
// break;
|
// break;
|
||||||
//default:
|
//default:
|
||||||
// break;
|
// break;
|
||||||
@@ -93,38 +78,42 @@ kEventResult NodeTextInput::handle_event(Event* e)
|
|||||||
on_return(this);
|
on_return(this);
|
||||||
if (ke->m_key == kKey::KeyBackspace)
|
if (ke->m_key == kKey::KeyBackspace)
|
||||||
{
|
{
|
||||||
if (!m_string.empty())
|
if (!m_text.empty())
|
||||||
{
|
{
|
||||||
m_string.erase(m_string.end() - 1);
|
m_text.erase(m_text.end() - 1);
|
||||||
m_text->set_text(m_string.c_str());
|
set_text(m_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kEventType::KeyChar:
|
case kEventType::KeyChar:
|
||||||
if (m_cursor)
|
|
||||||
{
|
|
||||||
timer = 0;
|
timer = 0;
|
||||||
m_cursor->m_display = true;
|
m_cursor_visible = true;
|
||||||
}
|
|
||||||
if (ke->m_char == '\b' // backspace
|
if (ke->m_char == '\b' // backspace
|
||||||
|| ke->m_char == 0x7f // DEL
|
|| ke->m_char == 0x7f // DEL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!m_string.empty())
|
if (!m_text.empty())
|
||||||
{
|
{
|
||||||
m_string.erase(m_string.end() - 1);
|
m_text.erase(m_text.end() - 1);
|
||||||
m_text->set_text(m_string.c_str());
|
set_text(m_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ke->m_char == '\n' || ke->m_char == '\r') // enter/return
|
else if (ke->m_char == '\n' || ke->m_char == '\r') // enter/return
|
||||||
{
|
{
|
||||||
if (on_return)
|
if (m_multiline)
|
||||||
|
{
|
||||||
|
m_text += '\n';
|
||||||
|
set_text(m_text);
|
||||||
|
}
|
||||||
|
else if (on_return)
|
||||||
|
{
|
||||||
on_return(this);
|
on_return(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (ke->m_char >= 32 && ke->m_char < (32 + 96))
|
else if (ke->m_char >= 32 && ke->m_char < (32 + 96))
|
||||||
{
|
{
|
||||||
m_string += (char)ke->m_char;
|
m_text += (char)ke->m_char;
|
||||||
m_text->set_text(m_string.c_str());
|
set_text(m_text);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -136,9 +125,117 @@ kEventResult NodeTextInput::handle_event(Event* e)
|
|||||||
|
|
||||||
void NodeTextInput::set_text(const std::string& s)
|
void NodeTextInput::set_text(const std::string& s)
|
||||||
{
|
{
|
||||||
if (m_text)
|
m_text = s;
|
||||||
m_text->set_text(s.c_str());
|
m_text_mesh.update(font_id, s);
|
||||||
m_string = s;
|
update_layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTextInput::set_text_format(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
static char buffer[4096];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
m_text = buffer;
|
||||||
|
m_text_mesh.update(font_id, buffer);
|
||||||
|
update_layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTextInput::update_layout()
|
||||||
|
{
|
||||||
|
auto pad = GetPadding();
|
||||||
|
float h = GetHeight() - (pad[1] + pad[3]);
|
||||||
|
float w = GetWidth() - (pad[0] + pad[2]);
|
||||||
|
|
||||||
|
if (m_text_align_v == TextAlign::Begin)
|
||||||
|
m_off.y = pad[0];
|
||||||
|
else if (m_text_align_v == TextAlign::Center)
|
||||||
|
m_off.y = (h - m_text_mesh.bb.y) * 0.5f + pad[0];
|
||||||
|
else
|
||||||
|
m_off.y = (h - m_text_mesh.bb.y) + pad[0];
|
||||||
|
|
||||||
|
if (m_text_align_h == TextAlign::Begin)
|
||||||
|
m_off.x = pad[3];
|
||||||
|
else if (m_text_align_v == TextAlign::Center)
|
||||||
|
m_off.x = (w - m_text_mesh.bb.x) * 0.5f + pad[3];
|
||||||
|
else
|
||||||
|
m_off.x = (w - m_text_mesh.bb.x) + pad[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTextInput::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom)
|
||||||
|
{
|
||||||
|
auto pad = GetPadding();
|
||||||
|
m_text_mesh.max_width = m_multiline ? new_size.x - (pad[1] + pad[3]) : 0;
|
||||||
|
update_layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTextInput::create()
|
||||||
|
{
|
||||||
|
NodeBorder::create();
|
||||||
|
if (!m_font.empty())
|
||||||
|
{
|
||||||
|
char font[64];
|
||||||
|
sprintf(font, "%s-%d", m_font.c_str(), m_font_size);
|
||||||
|
font_id = (kFont)const_hash(font);
|
||||||
|
m_text_mesh.create();
|
||||||
|
m_text_mesh.update(font_id, m_text);
|
||||||
|
update_layout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTextInput::draw()
|
||||||
|
{
|
||||||
|
NodeBorder::draw();
|
||||||
|
|
||||||
|
glm::mat4 pos = glm::translate(glm::vec3(glm::floor(m_pos + m_off), 0));
|
||||||
|
ShaderManager::use(kShader::Font);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, m_proj * pos);
|
||||||
|
ShaderManager::u_vec4(kShaderUniform::Col, m_color);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
m_text_mesh.draw();
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
if (m_cursor_visible)
|
||||||
|
{
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glm::mat4 cur_pos = glm::translate(glm::vec3(m_pos + m_off + xy(m_text_mesh.cur_box), 0));
|
||||||
|
glm::mat4 cur_scale = glm::scale(glm::vec3(zw(m_text_mesh.cur_box), 1));
|
||||||
|
glm::mat4 cur_pivot = glm::translate(glm::vec3(0.5, 0.5, 0));
|
||||||
|
ShaderManager::use(kShader::Color);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, m_proj * cur_pos * cur_scale * cur_pivot);
|
||||||
|
ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 });
|
||||||
|
m_plane.draw_fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTextInput::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||||
|
{
|
||||||
|
switch (ka)
|
||||||
|
{
|
||||||
|
case kAttribute::Multiline:
|
||||||
|
m_multiline = attr->BoolValue();
|
||||||
|
break;
|
||||||
|
case kAttribute::TextAlign:
|
||||||
|
if (strcmp(attr->Value(), "left") == 0)
|
||||||
|
m_text_align_h = TextAlign::Begin;
|
||||||
|
else if (strcmp(attr->Value(), "center") == 0)
|
||||||
|
m_text_align_h = TextAlign::Center;
|
||||||
|
else if (strcmp(attr->Value(), "right") == 0)
|
||||||
|
m_text_align_h = TextAlign::End;
|
||||||
|
break;
|
||||||
|
case kAttribute::TextVerticalAlign:
|
||||||
|
if (strcmp(attr->Value(), "top") == 0)
|
||||||
|
m_text_align_v = TextAlign::Begin;
|
||||||
|
else if (strcmp(attr->Value(), "center") == 0)
|
||||||
|
m_text_align_v = TextAlign::Center;
|
||||||
|
else if (strcmp(attr->Value(), "bottom") == 0)
|
||||||
|
m_text_align_v = TextAlign::End;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NodeBorder::parse_attributes(ka, attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeTextInput::destroy()
|
void NodeTextInput::destroy()
|
||||||
|
|||||||
@@ -1,22 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "node_border.h"
|
#include "node_border.h"
|
||||||
#include "node_text.h"
|
#include "node_text.h"
|
||||||
|
#include "shape.h"
|
||||||
|
|
||||||
class NodeTextInput : public NodeBorder
|
class NodeTextInput : public NodeBorder
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
float timer = 0;
|
float timer = 0;
|
||||||
NodeText* m_text;
|
public:
|
||||||
NodeBorder* m_cursor;
|
enum class TextAlign
|
||||||
NodeBorder* m_border;
|
{
|
||||||
std::string m_string;
|
Begin,
|
||||||
|
Center,
|
||||||
|
End,
|
||||||
|
};
|
||||||
|
|
||||||
|
TextMesh m_text_mesh;
|
||||||
|
std::string m_text;
|
||||||
|
std::string m_font = "arial";
|
||||||
|
glm::vec4 m_color{ 1, 1, 1, 1 };
|
||||||
|
int m_font_size = 11;
|
||||||
|
kFont font_id;
|
||||||
|
bool m_multiline = false;
|
||||||
|
bool m_cursor_visible = false;
|
||||||
|
glm::vec2 m_off;
|
||||||
|
TextAlign m_text_align_v = TextAlign::Center;
|
||||||
|
TextAlign m_text_align_h = TextAlign::Begin;
|
||||||
|
|
||||||
std::function<void(NodeTextInput*target)> on_return;
|
std::function<void(NodeTextInput*target)> on_return;
|
||||||
|
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
virtual void clone_finalize(Node* dest) const override;
|
virtual void clone_copy(Node* dest) const override;
|
||||||
virtual void init() override;
|
|
||||||
virtual void on_tick(float dt) override;
|
virtual void on_tick(float dt) override;
|
||||||
virtual kEventResult handle_event(Event* e) override;
|
virtual kEventResult handle_event(Event* e) override;
|
||||||
virtual void destroy() override;
|
virtual void destroy() override;
|
||||||
void init_controls();
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
||||||
|
virtual void draw() override;
|
||||||
|
virtual void create() override;
|
||||||
|
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom) override;
|
||||||
|
|
||||||
void set_text(const std::string& s);
|
void set_text(const std::string& s);
|
||||||
|
void set_text_format(const char* fmt, ...);
|
||||||
|
void update_layout();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user