Merge pull request #71 from nem0/gui
additional GUI features and redirected error stream of script compiler
This commit is contained in:
commit
0486cd4f8e
15 changed files with 320 additions and 22 deletions
|
@ -97,6 +97,7 @@
|
|||
<ClInclude Include="..\..\src\gui\controls\text_box.h" />
|
||||
<ClInclude Include="..\..\src\gui\decorators\box_decorator.h" />
|
||||
<ClInclude Include="..\..\src\gui\decorators\check_box_decorator.h" />
|
||||
<ClInclude Include="..\..\src\gui\decorators\cursor_decorator.h" />
|
||||
<ClInclude Include="..\..\src\gui\decorators\dockable_decorator.h" />
|
||||
<ClInclude Include="..\..\src\gui\decorators\scrollbar_decorator.h" />
|
||||
<ClInclude Include="..\..\src\gui\decorators\text_decorator.h" />
|
||||
|
@ -121,6 +122,7 @@
|
|||
<ClCompile Include="..\..\src\gui\controls\text_box.cpp" />
|
||||
<ClCompile Include="..\..\src\gui\decorators\box_decorator.cpp" />
|
||||
<ClCompile Include="..\..\src\gui\decorators\check_box_decorator.cpp" />
|
||||
<ClCompile Include="..\..\src\gui\decorators\cursor_decorator.cpp" />
|
||||
<ClCompile Include="..\..\src\gui\decorators\dockable_decorator.cpp" />
|
||||
<ClCompile Include="..\..\src\gui\decorators\scrollbar_decorator.cpp" />
|
||||
<ClCompile Include="..\..\src\gui\decorators\text_decorator.cpp" />
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
<ClInclude Include="..\..\src\gui\decorators\dockable_decorator.h">
|
||||
<Filter>decorators</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\gui\decorators\cursor_decorator.h">
|
||||
<Filter>decorators</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\gui\gui.cpp" />
|
||||
|
@ -98,6 +101,9 @@
|
|||
<ClCompile Include="..\..\src\gui\decorators\dockable_decorator.cpp">
|
||||
<Filter>decorators</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\gui\decorators\cursor_decorator.cpp">
|
||||
<Filter>decorators</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="decorators">
|
||||
|
|
|
@ -167,6 +167,15 @@ class base_string
|
|||
return ret;
|
||||
}
|
||||
|
||||
void erase(size_t pos)
|
||||
{
|
||||
if(pos >= 0 && pos < m_size)
|
||||
{
|
||||
base_string<T>::strcpy(m_cstr + pos, m_cstr + pos + 1);
|
||||
--m_size;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static const int npos = 0xffFFffFF;
|
||||
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
#include "editor/server_message_types.h"
|
||||
#include "editor_native/main_frame.h"
|
||||
#include "gui/controls/scrollable.h"
|
||||
#include "gui/gui.h"
|
||||
|
||||
|
||||
LogUI::LogUI(MainFrame& main_frame)
|
||||
: Dockable(main_frame.getGui(), NULL)
|
||||
, m_main_frame(main_frame)
|
||||
{
|
||||
m_scrollable = NULL;
|
||||
main_frame.getDockable().dock(*this, Dockable::BOTTOM);
|
||||
main_frame.getEditorClient()->getEventManager().addListener(Lux::ServerMessageType::LOG_MESSAGE).bind<LogUI, &LogUI::onLogMessage>(this);
|
||||
Lux::UI::Block* handle = LUX_NEW(Lux::UI::Block)(getGui(), this, "_box");
|
||||
|
@ -30,7 +32,31 @@ void LogUI::onLogMessage(Lux::Event& evt)
|
|||
cell->setArea(0, 0, 0, y, 0.3f, 0, 0, y + 20);
|
||||
|
||||
cell = LUX_NEW(Lux::UI::Block)(getGui(), container, "_text");
|
||||
float w, h;
|
||||
getGui().getRenderer().measureText(log_evt.message.c_str(), &w, &h, getGlobalWidth() * 0.7f);
|
||||
cell->setBlockText(log_evt.message.c_str());
|
||||
cell->setArea(0.3f, 0, 0, y, 1, 0, 0, y + 20);
|
||||
cell->setArea(0.3f, 0, 0, y, 1, 0, 0, y + h + 5);
|
||||
layout();
|
||||
}
|
||||
|
||||
|
||||
void LogUI::layout()
|
||||
{
|
||||
Dockable::layout();
|
||||
if(m_scrollable)
|
||||
{
|
||||
Lux::UI::Block* container = m_scrollable->getContainer();
|
||||
float w, h;
|
||||
float y = 0;
|
||||
for(int i = 1; i < container->getChildCount(); i += 2)
|
||||
{
|
||||
getGui().getRenderer().measureText(container->getChild(i)->getBlockText().c_str(), &w, &h, getGlobalWidth() * 0.7f);
|
||||
|
||||
container->getChild(i-1)->getLocalArea().top = y;
|
||||
container->getChild(i)->getLocalArea().top = y;
|
||||
|
||||
y += h + 5;
|
||||
}
|
||||
Dockable::layout();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ class LogUI : public Lux::UI::Dockable
|
|||
{
|
||||
public:
|
||||
LogUI(MainFrame& main_frame);
|
||||
virtual void layout() LUX_OVERRIDE;
|
||||
|
||||
private:
|
||||
void onLogMessage(Lux::Event& evt);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "graphics/renderer.h"
|
||||
#include "gui/block.h"
|
||||
#include "gui/decorators/box_decorator.h"
|
||||
#include "gui/decorators/cursor_decorator.h"
|
||||
#include "gui/decorators/check_box_decorator.h"
|
||||
#include "gui/decorators/dockable_decorator.h"
|
||||
#include "gui/decorators/text_decorator.h"
|
||||
|
@ -30,6 +31,7 @@ void initGui(Lux::EditorClient& client, Lux::EditorServer& server)
|
|||
renderer->create();
|
||||
renderer->loadFont("gui/font.tga", server.getEngine().getFileSystem());
|
||||
renderer->setWindowHeight(600);
|
||||
Lux::UI::CursorDecorator* cursor_decorator = LUX_NEW(Lux::UI::CursorDecorator)("_cursor");
|
||||
Lux::UI::CheckBoxDecorator* check_box_decorator = LUX_NEW(Lux::UI::CheckBoxDecorator)("_check_box");
|
||||
Lux::UI::TextDecorator* text_decorator = LUX_NEW(Lux::UI::TextDecorator)("_text");
|
||||
Lux::UI::TextDecorator* text_centered_decorator = LUX_NEW(Lux::UI::TextDecorator)("_text_centered");
|
||||
|
@ -39,6 +41,7 @@ void initGui(Lux::EditorClient& client, Lux::EditorServer& server)
|
|||
Lux::UI::ScrollbarDecorator* scrollbar_decorator = LUX_NEW(Lux::UI::ScrollbarDecorator)("_scrollbar");
|
||||
server.getEngine().loadPlugin("gui.dll");
|
||||
Lux::UI::Gui* gui = (Lux::UI::Gui*)server.getEngine().getPluginManager().getPlugin("gui");
|
||||
gui->addDecorator(*cursor_decorator);
|
||||
gui->addDecorator(*text_decorator);
|
||||
gui->addDecorator(*text_centered_decorator);
|
||||
gui->addDecorator(*box_decorator);
|
||||
|
@ -46,6 +49,7 @@ void initGui(Lux::EditorClient& client, Lux::EditorServer& server)
|
|||
gui->addDecorator(*scrollbar_decorator);
|
||||
gui->addDecorator(*check_box_decorator);
|
||||
gui->setRenderer(*renderer);
|
||||
cursor_decorator->create(*gui, "gui/skin.atl");
|
||||
check_box_decorator->create(*gui, "gui/skin.atl");
|
||||
scrollbar_decorator->create(*gui, "gui/skin.atl");
|
||||
box_decorator->create(*gui, "gui/skin.atl");
|
||||
|
|
|
@ -38,8 +38,9 @@ void ScriptCompiler::compile(const char path[])
|
|||
|
||||
CreatePipe(&read_pipe, &write_pipe, &saAttr, 0);
|
||||
SetHandleInformation(read_pipe, HANDLE_FLAG_INHERIT, 0);
|
||||
si.hStdInput = read_pipe;
|
||||
//si.hStdInput = read_pipe;
|
||||
si.hStdOutput = write_pipe;
|
||||
si.hStdError = write_pipe;
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
sprintf(cmd_line, "/C scripts\\compile.bat %s", path);
|
||||
if ( CreateProcess("C:\\windows\\system32\\cmd.exe", // Application name
|
||||
|
@ -53,7 +54,7 @@ void ScriptCompiler::compile(const char path[])
|
|||
&si,
|
||||
&pi) == TRUE)
|
||||
{
|
||||
Process* p = LUX_NEW(Process)();
|
||||
Process* p = new Process();
|
||||
p->m_handle = pi.hProcess;
|
||||
p->m_path = path;
|
||||
p->m_pipe = read_pipe;
|
||||
|
@ -78,7 +79,7 @@ void ScriptCompiler::checkFinished()
|
|||
Process* p = m_processes[i];
|
||||
m_processes.eraseFast(i);
|
||||
m_delegates.invoke(p->m_path.c_str(), code);
|
||||
char buf[512];
|
||||
char buf[513];
|
||||
DWORD read;
|
||||
if(code != 0)
|
||||
{
|
||||
|
@ -95,7 +96,7 @@ void ScriptCompiler::checkFinished()
|
|||
}
|
||||
CloseHandle(p->m_pipe);
|
||||
CloseHandle(p->m_write_pipe);
|
||||
LUX_DELETE(p);
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "gui/controls/text_box.h"
|
||||
#include "core/crc32.h"
|
||||
#include "core/iserializer.h"
|
||||
#include "gui/gui.h"
|
||||
|
||||
|
||||
namespace Lux
|
||||
|
@ -17,29 +18,77 @@ TextBox::TextBox(const char* text, Gui& gui, Block* parent)
|
|||
label_ui->setBlockText(text);
|
||||
label_ui->setArea(0, 3, 0, 0, 1, 0, 1, 0);
|
||||
label_ui->onEvent("key_down").bind<TextBox, &TextBox::keyDown>(this);
|
||||
label_ui->onEvent("focus").bind<TextBox, &TextBox::focused>(this);
|
||||
label_ui->onEvent("blur").bind<TextBox, &TextBox::blurred>(this);
|
||||
label_ui->setIsClipping(true);
|
||||
m_cursor_pos = 0;
|
||||
m_cursor = LUX_NEW(Block)(gui, label_ui, "_cursor");
|
||||
m_cursor->hide();
|
||||
}
|
||||
|
||||
|
||||
void TextBox::setCursorArea()
|
||||
{
|
||||
Block::Area area = getGui().getRenderer().getCharArea(getChild(0)->getBlockText().c_str(), m_cursor_pos, getGlobalWidth());
|
||||
m_cursor->setArea(area);
|
||||
layout();
|
||||
}
|
||||
|
||||
|
||||
void TextBox::blurred(Block& block, void* user_data)
|
||||
{
|
||||
m_cursor->hide();
|
||||
}
|
||||
|
||||
|
||||
void TextBox::focused(Block& block, void* user_data)
|
||||
{
|
||||
m_cursor_pos = getChild(0)->getBlockText().length();
|
||||
m_cursor->show();
|
||||
setCursorArea();
|
||||
}
|
||||
|
||||
static const int32_t KEY_RIGHT = 79 + (1 << 30);
|
||||
static const int32_t KEY_LEFT = 80 + (1 << 30);
|
||||
static const int32_t KEY_UP = 81 + (1 << 30);
|
||||
static const int32_t KEY_DOWN = 82 + (1 << 30);
|
||||
static const int32_t KEY_BACKSPACE = '\b';
|
||||
static const int32_t KEY_DELETE = '\177';
|
||||
|
||||
void TextBox::keyDown(Block& block, void* user_data)
|
||||
{
|
||||
Lux::string s = block.getBlockText();
|
||||
char c[2];
|
||||
switch((int32_t)user_data)
|
||||
{
|
||||
case KEY_RIGHT:
|
||||
m_cursor_pos = m_cursor_pos > s.length() - 1 ? s.length() : m_cursor_pos + 1;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
m_cursor_pos = m_cursor_pos < 1 ? 0 : m_cursor_pos - 1;
|
||||
break;
|
||||
case KEY_UP:
|
||||
case KEY_DOWN:
|
||||
break;
|
||||
case '\r':
|
||||
block.emitEvent("text_accepted");
|
||||
break;
|
||||
case '\b':
|
||||
s = s.substr(0, s.length() - 1);
|
||||
case KEY_BACKSPACE:
|
||||
s.erase(m_cursor_pos - 1);
|
||||
if(m_cursor_pos > 0)
|
||||
{
|
||||
--m_cursor_pos;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
c[0] = (char)user_data;
|
||||
c[1] = '\0';
|
||||
s += c;
|
||||
++m_cursor_pos;
|
||||
break;
|
||||
}
|
||||
block.setBlockText(s.c_str());
|
||||
setCursorArea();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,13 @@ namespace UI
|
|||
|
||||
private:
|
||||
void keyDown(Block& block, void* user_data);
|
||||
void focused(Block& block, void* user_data);
|
||||
void blurred(Block& block, void* user_data);
|
||||
void setCursorArea();
|
||||
|
||||
private:
|
||||
int m_cursor_pos;
|
||||
Lux::UI::Block* m_cursor;
|
||||
};
|
||||
|
||||
|
||||
|
|
54
src/gui/decorators/cursor_decorator.cpp
Normal file
54
src/gui/decorators/cursor_decorator.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include "gui/decorators/cursor_decorator.h"
|
||||
#include "core/crc32.h"
|
||||
#include "gui/atlas.h"
|
||||
#include "gui/block.h"
|
||||
#include "gui/controls/dockable.h"
|
||||
#include "gui/gui.h"
|
||||
#include "gui/irenderer.h"
|
||||
#include "gui/texture_base.h"
|
||||
|
||||
|
||||
namespace Lux
|
||||
{
|
||||
namespace UI
|
||||
{
|
||||
|
||||
static const uint32_t dockable_hash = crc32("dockable");
|
||||
|
||||
void CursorDecorator::setVertices(Vec3* verts, float left, float top, float right, float bottom, float z) const
|
||||
{
|
||||
verts[0].set(left, top, z);
|
||||
verts[1].set(left, bottom, z);
|
||||
verts[2].set(right, bottom, z);
|
||||
verts[3].set(left, top, z);
|
||||
verts[4].set(right, bottom, z);
|
||||
verts[5].set(right, top, z);
|
||||
}
|
||||
|
||||
|
||||
void CursorDecorator::render(IRenderer& renderer, Block& block)
|
||||
{
|
||||
m_part = m_part ? m_part : m_atlas->getPart("cursor");
|
||||
|
||||
if(m_part)
|
||||
{
|
||||
setVertices(m_vertices, block.getGlobalLeft(), block.getGlobalTop(), block.getGlobalLeft() + m_part->m_pixel_width, block.getGlobalBottom(), block.getZ());
|
||||
m_part->getUvs(&m_uvs[0]);
|
||||
if(m_atlas->getTexture())
|
||||
{
|
||||
renderer.renderImage(m_atlas->getTexture(), &m_vertices[0].x, m_uvs, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CursorDecorator::create(Gui& gui, const char* atlas)
|
||||
{
|
||||
m_part = NULL;
|
||||
m_atlas = gui.loadAtlas(atlas);
|
||||
return m_atlas != NULL;
|
||||
}
|
||||
|
||||
|
||||
} // ~namespace UI
|
||||
} // ~namespace Lux
|
40
src/gui/decorators/cursor_decorator.h
Normal file
40
src/gui/decorators/cursor_decorator.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#include "core/lux.h"
|
||||
#include "core/vec3.h"
|
||||
#include "gui/atlas.h"
|
||||
#include "gui/decorator_base.h"
|
||||
|
||||
|
||||
namespace Lux
|
||||
{
|
||||
namespace UI
|
||||
{
|
||||
|
||||
class Dockable;
|
||||
class Gui;
|
||||
class IRenderer;
|
||||
class TextureBase;
|
||||
|
||||
|
||||
class LUX_GUI_API CursorDecorator : public DecoratorBase
|
||||
{
|
||||
public:
|
||||
CursorDecorator(const char* name) : DecoratorBase(name) {}
|
||||
|
||||
bool create(Gui& gui, const char* atlas);
|
||||
virtual void render(IRenderer& renderer, Block& block) LUX_OVERRIDE;
|
||||
|
||||
private:
|
||||
void setVertices(Vec3* verts, float left, float top, float right, float bottom, float z) const;
|
||||
|
||||
private:
|
||||
Atlas* m_atlas;
|
||||
const Atlas::Part* m_part;
|
||||
Vec3 m_vertices[24];
|
||||
float m_uvs[48];
|
||||
};
|
||||
|
||||
} // ~namespace UI
|
||||
} // ~namespace Lux
|
|
@ -18,15 +18,15 @@ namespace UI
|
|||
|
||||
void TextDecorator::render(IRenderer& renderer, Block& block)
|
||||
{
|
||||
float w, h;
|
||||
renderer.measureText(block.getBlockText().c_str(), &w, &h);
|
||||
if(m_is_text_centered)
|
||||
{
|
||||
renderer.renderText(block.getBlockText().c_str(), (block.getGlobalRight() + block.getGlobalLeft() - w) / 2, (float)block.getGlobalTop(), block.getZ());
|
||||
float w, h;
|
||||
renderer.measureText(block.getBlockText().c_str(), &w, &h, block.getGlobalWidth());
|
||||
renderer.renderText(block.getBlockText().c_str(), (block.getGlobalRight() + block.getGlobalLeft() - w) / 2, (float)block.getGlobalTop(), block.getZ(), block.getGlobalWidth());
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.renderText(block.getBlockText().c_str(), block.getGlobalLeft(), (float)block.getGlobalTop(), block.getZ());
|
||||
renderer.renderText(block.getBlockText().c_str(), block.getGlobalLeft(), (float)block.getGlobalTop(), block.getZ(), block.getGlobalWidth());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
|
||||
#include "core/lux.h"
|
||||
#include "gui/block.h"
|
||||
|
||||
|
||||
namespace Lux
|
||||
|
@ -26,8 +27,9 @@ namespace UI
|
|||
virtual TextureBase* loadImage(const char* name, FS::FileSystem& file_system) = 0;
|
||||
virtual void beginRender(float w, float h) = 0;
|
||||
virtual void renderImage(TextureBase* image, float* vertices, float* tex_coords, int vertex_count) = 0;
|
||||
virtual void measureText(const char* text, float* w, float* h) = 0;
|
||||
virtual void renderText(const char* text, float x, float y, float z) = 0;
|
||||
virtual Block::Area getCharArea(const char* text, int pos, float max_width) = 0;
|
||||
virtual void measureText(const char* text, float* w, float* h, float max_width) = 0;
|
||||
virtual void renderText(const char* text, float x, float y, float z, float max_width) = 0;
|
||||
virtual void pushScissorArea(float left, float top, float right, float bottom) = 0;
|
||||
virtual void popScissorArea() = 0;
|
||||
};
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#include "gui/opengl_renderer.h"
|
||||
#include <cstdio>
|
||||
#include <Windows.h>
|
||||
#include <gl/GL.h>
|
||||
#include "gui/opengl_renderer.h"
|
||||
#include "core/array.h"
|
||||
#include "core/delegate_list.h"
|
||||
#include "core/file_system.h"
|
||||
#include "core/ifile.h"
|
||||
#include "core/map.h"
|
||||
#include "core/math_utils.h"
|
||||
#include "core/pod_array.h"
|
||||
#include "core/string.h"
|
||||
#include "core/vec3.h"
|
||||
|
@ -221,7 +222,74 @@ namespace UI
|
|||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void OpenGLRenderer::measureText(const char* text, float* w, float* h)
|
||||
Block::Area OpenGLRenderer::getCharArea(const char* text, int pos, float max_width)
|
||||
{
|
||||
Block::Area area;
|
||||
if(text)
|
||||
{
|
||||
float width = 0;
|
||||
float height = 0;
|
||||
float prev_h = 0;
|
||||
const char* c = text;
|
||||
bool is_multiline = false;
|
||||
OpenGLRendererImpl::Character character;
|
||||
bool found = false;
|
||||
bool is_some_char = false;
|
||||
while(*c)
|
||||
{
|
||||
if(m_impl->m_characters.find(*c, character))
|
||||
{
|
||||
is_some_char = true;
|
||||
if(c - text == pos)
|
||||
{
|
||||
found = true;
|
||||
area.left = width;
|
||||
area.top = prev_h + character.y_offset;
|
||||
area.right = width + character.x_advance;
|
||||
area.bottom = prev_h + character.pixel_h + character.y_offset;
|
||||
area.rel_bottom = area.rel_left = area.rel_right = area.rel_top = 0;
|
||||
break;
|
||||
}
|
||||
width += character.x_advance;
|
||||
height = Math::max(height, character.pixel_h);
|
||||
if(width > max_width || *c == '\n')
|
||||
{
|
||||
is_multiline = true;
|
||||
width = 0;
|
||||
prev_h += height;
|
||||
}
|
||||
}
|
||||
else if(*c == '\n')
|
||||
{
|
||||
is_multiline = true;
|
||||
width = 0;
|
||||
prev_h += height;
|
||||
}
|
||||
++c;
|
||||
}
|
||||
if(!found)
|
||||
{
|
||||
if(is_some_char)
|
||||
{
|
||||
area.left = width;
|
||||
area.top = prev_h + character.y_offset;
|
||||
area.right = width + character.x_advance;
|
||||
area.bottom = prev_h + character.pixel_h + character.y_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
area.left = 0;
|
||||
area.right = 3;
|
||||
area.top = 0;
|
||||
area.bottom = 20;
|
||||
}
|
||||
area.rel_bottom = area.rel_left = area.rel_right = area.rel_top = 0;
|
||||
}
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::measureText(const char* text, float* w, float* h, float max_width)
|
||||
{
|
||||
if(!text)
|
||||
{
|
||||
|
@ -231,7 +299,9 @@ namespace UI
|
|||
}
|
||||
float width = 0;
|
||||
float height = 0;
|
||||
float prev_h = 0;
|
||||
const char* c = text;
|
||||
bool is_multiline = false;
|
||||
while(*c)
|
||||
{
|
||||
OpenGLRendererImpl::Character character;
|
||||
|
@ -239,11 +309,23 @@ namespace UI
|
|||
{
|
||||
width += character.x_advance;
|
||||
height = Math::max(height, character.pixel_h);
|
||||
if(width > max_width || *c == '\n')
|
||||
{
|
||||
is_multiline = true;
|
||||
width = 0;
|
||||
prev_h += height;
|
||||
}
|
||||
}
|
||||
else if(*c == '\n')
|
||||
{
|
||||
is_multiline = true;
|
||||
width = 0;
|
||||
prev_h += height;
|
||||
}
|
||||
++c;
|
||||
}
|
||||
*w = width;
|
||||
*h = height;
|
||||
*w = is_multiline ? max_width : width;
|
||||
*h = height + prev_h;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::pushScissorArea(float left, float top, float right, float bottom)
|
||||
|
@ -287,7 +369,7 @@ namespace UI
|
|||
}
|
||||
}
|
||||
|
||||
void OpenGLRenderer::renderText(const char* text, float x, float y, float z)
|
||||
void OpenGLRenderer::renderText(const char* text, float x, float y, float z, float max_width)
|
||||
{
|
||||
if(!text)
|
||||
{
|
||||
|
@ -306,13 +388,16 @@ namespace UI
|
|||
uvs.resize(len * 6);
|
||||
const char* c = text;
|
||||
float cur_x = x;
|
||||
float line_h = 0;
|
||||
float line_base = y;
|
||||
int i = 0;
|
||||
while(*c)
|
||||
{
|
||||
OpenGLRendererImpl::Character character;
|
||||
if(m_impl->m_characters.find(*c, character))
|
||||
{
|
||||
float cur_y = y + character.y_offset;
|
||||
float cur_y = line_base + character.y_offset;
|
||||
line_h = Math::max(line_h, character.pixel_h);
|
||||
verts[i*6].set(cur_x, cur_y, z);
|
||||
verts[i*6+1].set(cur_x, cur_y + character.pixel_h, z);
|
||||
verts[i*6+2].set(cur_x + character.pixel_w, cur_y + character.pixel_h, z);
|
||||
|
@ -323,6 +408,12 @@ namespace UI
|
|||
|
||||
cur_x += character.x_advance;
|
||||
|
||||
if(cur_x - x > max_width)
|
||||
{
|
||||
cur_x = x;
|
||||
line_base += line_h;
|
||||
}
|
||||
|
||||
uvs[i*6].set(character.left, character.top);
|
||||
uvs[i*6+1].set(character.left, character.bottom);
|
||||
uvs[i*6+2].set(character.right, character.bottom);
|
||||
|
@ -332,6 +423,11 @@ namespace UI
|
|||
uvs[i*6+5].set(character.right, character.top);
|
||||
++i;
|
||||
}
|
||||
else if(*c == '\n')
|
||||
{
|
||||
cur_x = x;
|
||||
line_base += line_h;
|
||||
}
|
||||
++c;
|
||||
}
|
||||
glEnable(GL_BLEND);
|
||||
|
|
|
@ -24,8 +24,9 @@ namespace UI
|
|||
virtual void loadFont(const char* path, FS::FileSystem& file_system) LUX_OVERRIDE;
|
||||
virtual void beginRender(float w, float h) LUX_OVERRIDE;
|
||||
virtual void renderImage(TextureBase* image, float* vertices, float* tex_coords, int vertex_count) LUX_OVERRIDE;
|
||||
virtual void measureText(const char* text, float* w, float* h) LUX_OVERRIDE;
|
||||
virtual void renderText(const char* text, float x, float y, float z) LUX_OVERRIDE;
|
||||
virtual Block::Area getCharArea(const char* text, int pos, float max_width) LUX_OVERRIDE;
|
||||
virtual void measureText(const char* text, float* w, float* h, float max_width) LUX_OVERRIDE;
|
||||
virtual void renderText(const char* text, float x, float y, float z, float max_width) LUX_OVERRIDE;
|
||||
virtual void pushScissorArea(float left, float top, float right, float bottom) LUX_OVERRIDE;
|
||||
virtual void popScissorArea() LUX_OVERRIDE;
|
||||
void setWindowHeight(int height);
|
||||
|
|
Loading…
Reference in a new issue