Alignment
I used alignment earlier, and, I used additional rectangle - build rect on creation time.
I thought maybe I can do alignment in other way, but not. Other idea is to use build rect old.
I think ` build rect on creation time` is better.
All what I need now (add 1 more slVec4f and) is to set position and size of element in class constructor.
//In slGUICommon
slVec4f m_buildRectOnCreation;
Now I need to create window and button, and save position and size into this rectangle.
Change SummonWindow
slGUIWindow* slFramework::SummonGUIWindow(const slVec2f& position, const slVec2f& size)
{
slGUIWindow* newWindow = slCreate(position, size);
newWindow->SetStyle(slFramework::GetGUIStyle(slGUIStyleTheme::Light));
g_framework->m_GUIWindows.push_back(newWindow);
return newWindow;
}
Change Window Constructor
slGUIWindow::slGUIWindow(const slVec2f& position, const slVec2f& size)
:
slGUICommon(position, size)
{
m_rootElement = dynamic_cast(slCreate(this, position, size));
}
Change root element constructor
slGUIRootElement::slGUIRootElement(slGUIWindow* w, const slVec2f& position, const slVec2f& size) :
slGUIElement::slGUIElement(w, position, size)
{}
Change button constructor
slGUIButton::slGUIButton(slGUIWindow* w, const slVec2f& position, const slVec2f& size)
:
slGUIElement::slGUIElement(w, position, size)
{
SetParent(w->GetRootElement());
}
Change gui element constructor
slGUIElement::slGUIElement(slGUIWindow* w, const slVec2f& position, const slVec2f& size):
slGUICommon(position, size)
{
SL_ASSERT_ST(w);
m_window = w;
SetStyle(slFramework::GetGUIStyle(slGUIStyleTheme::Light));
}
And change slGUICommon constructor
slGUICommon::slGUICommon(const slVec2f& position, const slVec2f& size)
{
m_buildRectOnCreation.x = position.x;
m_buildRectOnCreation.y = position.y;
m_buildRectOnCreation.z = position.x + size.x;
m_buildRectOnCreation.w = position.y + size.y;
}
And it's not enough. How I can set m_buildRectOnCreation if use
m_margin?
auto btn = slCreate(guiWindow);
btn->m_margin.set(10.f);
Move m_margin in `protected` and add method? And same with m_size?
Or remove m_margin? If remove, then, if user want that rescale he just
need to do it in window callback.
Really easy to remove margin, because, it gives chaos.
REMOVED
How alignment works. For example, Aligment::Top. If button
located in left top corner, then if window changed its size (width),
it will be bigger, then button must be moved little bit closer
to window center (x axis).
Code
slVec2f parentSize(parent->m_buildRect.z - parent->m_buildRect.x, parent->m_buildRect.w - parent->m_buildRect.y);
if (parentSize.x && parentSize.y)
{
float parentRectSizeX_1 = 1.f / parentSize.x;
float parentRectSizeY_1 = 1.f / parentSize.y;
slVec2f parentCreationCenter;
parentCreationCenter.x = parent->m_buildRectOnCreation.x + ((parent->m_buildRectOnCreation.z - parent->m_buildRectOnCreation.x) * 0.5f);
parentCreationCenter.y = parent->m_buildRectOnCreation.y + ((parent->m_buildRectOnCreation.w - parent->m_buildRectOnCreation.y) * 0.5f);
slVec2f parentCurrentCenter;
parentCurrentCenter.x = parent->m_buildRect.x + ((parent->m_buildRect.z - parent->m_buildRect.x) * 0.5f);
parentCurrentCenter.y = parent->m_buildRect.y + ((parent->m_buildRect.w - parent->m_buildRect.y) * 0.5f);
float parentRectSizeDiff_X = parentCurrentCenter.x - parentCreationCenter.x;
float parentRectSizeDiff_Y = parentCurrentCenter.y - parentCreationCenter.y;
// alignment
switch (m_alignment)
{
case slGUIElement::Left:
m_buildRect.y += (int)parentRectSizeDiff_Y;
m_buildRect.w += (int)parentRectSizeDiff_Y;
break;
case slGUIElement::Top:
m_buildRect.x += (int)parentRectSizeDiff_X;
m_buildRect.z += (int)parentRectSizeDiff_X;
break;
case slGUIElement::Center:
m_buildRect.y += (int)parentRectSizeDiff_Y;
m_buildRect.w += (int)parentRectSizeDiff_Y;
m_buildRect.x += (int)parentRectSizeDiff_X;
m_buildRect.z += (int)parentRectSizeDiff_X;
break;
case slGUIElement::Right:
m_buildRect.y += (int)parentRectSizeDiff_Y;
m_buildRect.w += (int)parentRectSizeDiff_Y;
m_buildRect.x = parent->m_buildRect.z -
(parent->m_buildRectOnCreation.z - m_buildRectOnCreation.x) + parent->m_buildRectOnCreation.x;
m_buildRect.z = parent->m_buildRect.z -
(parent->m_buildRectOnCreation.z - m_buildRectOnCreation.z) + parent->m_buildRectOnCreation.x;
break;
case slGUIElement::Bottom:
m_buildRect.x += (int)parentRectSizeDiff_X;
m_buildRect.z += (int)parentRectSizeDiff_X;
m_buildRect.y = parent->m_buildRect.w -
(parent->m_buildRectOnCreation.w - m_buildRectOnCreation.y) + parent->m_buildRectOnCreation.y;
m_buildRect.w = parent->m_buildRect.w -
(parent->m_buildRectOnCreation.w - m_buildRectOnCreation.w) + parent->m_buildRectOnCreation.y;
break;
case slGUIElement::LeftTop:
break;
case slGUIElement::RightTop:
m_buildRect.x = parent->m_buildRect.z -
(parent->m_buildRectOnCreation.z - m_buildRectOnCreation.x) + parent->m_buildRectOnCreation.x;
m_buildRect.z = parent->m_buildRect.z -
(parent->m_buildRectOnCreation.z - m_buildRectOnCreation.z) + parent->m_buildRectOnCreation.x;
break;
case slGUIElement::LeftBottom:
m_buildRect.y = parent->m_buildRect.w -
(parent->m_buildRectOnCreation.w - m_buildRectOnCreation.y) + parent->m_buildRectOnCreation.y;
m_buildRect.w = parent->m_buildRect.w -
(parent->m_buildRectOnCreation.w - m_buildRectOnCreation.w) + parent->m_buildRectOnCreation.y;
break;
case slGUIElement::RightBottom:
m_buildRect.x = parent->m_buildRect.z -
(parent->m_buildRectOnCreation.z - m_buildRectOnCreation.x) + parent->m_buildRectOnCreation.x;
m_buildRect.z = parent->m_buildRect.z -
(parent->m_buildRectOnCreation.z - m_buildRectOnCreation.z) + parent->m_buildRectOnCreation.x;
m_buildRect.y = parent->m_buildRect.w -
(parent->m_buildRectOnCreation.w - m_buildRectOnCreation.y) + parent->m_buildRectOnCreation.y;
m_buildRect.w = parent->m_buildRect.w -
(parent->m_buildRectOnCreation.w - m_buildRectOnCreation.w) + parent->m_buildRectOnCreation.y;
break;
default:
break;
}
}
Text for button
Add text position into button
slVec2f m_textPosition;
Add In draw method
if (IsDrawBG())
{
if (IsEnabled())
{
if (IsClickedLMB())
{
gs->DrawGUIRectangle(m_buildRect, m_style->m_buttonMousePressBGColor1, m_style->m_buttonMousePressBGColor2, 0, 0);
if (m_textDrawCallback)
gs->DrawGUIText(m_text.c_str(), m_text.size(), m_textPosition, m_textDrawCallback);
}
else
{
if (IsCursorInRect())
{
gs->DrawGUIRectangle(m_buildRect, m_style->m_buttonMouseHoverBGColor1, m_style->m_buttonMouseHoverBGColor2, 0, 0);
if (m_textDrawCallback)
gs->DrawGUIText(m_text.c_str(), m_text.size(), m_textPosition, m_textDrawCallback);
}
else
{
gs->DrawGUIRectangle(m_buildRect, m_style->m_buttonBGColor1, m_style->m_buttonBGColor2, 0, 0);
if (m_textDrawCallback)
gs->DrawGUIText(m_text.c_str(), m_text.size(), m_textPosition, m_textDrawCallback);
}
}
}
else
{
gs->DrawGUIRectangle(m_buildRect, m_style->m_buttonDisabledBGColor1, m_style->m_buttonDisabledBGColor2, 0, 0);
if (m_textDrawCallback)
gs->DrawGUIText(m_text.c_str(), m_text.size(), m_textPosition, m_textDrawCallback);
}
}
I need to set text color. And font. I need to add default font, and
default m_textDrawCallback.
I add new project - tools/resconv.
It will put file data into .inl (.h) file.
#include "slowlib.h"
#include
#include "slowlib.base/archive/slArchive.h"
#include "slowlib.base/gs/slImage.h"
SL_LINK_LIBRARY("slowlib.base")
void to_h(const char* inFile, const char* outFile)
{
FILE* inF = 0;
fopen_s(&inF, inFile, "rb");
if (inF)
{
FILE* outF = 0;
fopen_s(&outF, outFile, "wb");
if (outF)
{
std::uintmax_t inFileSz = std::filesystem::file_size(inFile);
if (inFileSz)
{
uint8_t* fileData = (uint8_t*)malloc((size_t)inFileSz);
if (fileData)
{
fread(fileData, (size_t)inFileSz, 1, inF);
int byte_counter = 0;
for (uint32_t i = 0; i < inFileSz; ++i)
{
if (!byte_counter)
fprintf(outF, "\t");
fprintf(outF, "0x%02X, ", ((uint8_t*)fileData)[i]);
++byte_counter;
if (byte_counter == 8)
{
fprintf(outF, "\r\n");
byte_counter = 0;
}
}
}
}
fclose(outF);
}
fclose(inF);
}
}
class FrameworkCallback : public slFrameworkCallback
{
public:
FrameworkCallback() {}
virtual ~FrameworkCallback() {}
virtual void OnMessage() {};
};
int main()
{
std::filesystem::create_directory("../src/data/");
FrameworkCallback fcb;
slFramework::Start(&fcb);
to_h("../data/fonts/font.png", "../src/data/font.inl");
slFramework::Stop();
return 0;
}
I don't want to add arg commands right now.
Create default font. I need to call method, after GS creation, because,
I need to create GPU texture
Add new method in framework
static void InitDefaultFonts(slGS*);
static slGUIFont* GetDefaultFont(uint32_t);
...
static uint8_t g_defaultFontPNG[] = {
#include "../data/font.inl"
};
...
slGUIFont* slFramework::GetDefaultFont(uint32_t i)
{
return g_framework->m_GUIFontDefault;
}
void slFramework::InitDefaultFonts(slGS* gs)
{
if (!g_framework->m_GUIFontDefault)
{
slImage* img = 0;
for (uint32_t i = 0; i < slFramework::GetImageLoadersNum(); ++i)
{
auto il = slFramework::GetImageLoader(i);
for (uint32_t o = 0; o < il->GetSupportedFilesCount(); ++o)
{
auto str = il->GetSupportedFileExtension(o);
if (str == U"png")
{
img = il->Load("something/file.png", g_defaultFontPNG, 9065);
goto outFromLoops;
}
}
}
outFromLoops:;
if (!img)
return;
slTextureInfo ti;
slTexture* myFontTexture = gs->SummonTexture(img, ti);
SLSAFE_DESTROY(img);
if (!myFontTexture)
return;
g_framework->m_texturesForDestroy.push_back(myFontTexture);
slGUIFont* myFont = slFramework::SummonFont();
myFont->AddTexture(myFontTexture);
myFont->AddGlyph(U'A', slVec2f(0, 0), slPoint(11, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'B', slVec2f(10, 0), slPoint(9, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'C', slVec2f(19, 0), slPoint(9, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'D', slVec2f(27, 0), slPoint(11, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'E', slVec2f(37, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'F', slVec2f(45, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'G', slVec2f(52, 0), slPoint(11, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'H', slVec2f(62, 0), slPoint(10, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'I', slVec2f(72, 0), slPoint(4, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'J', slVec2f(76, 0), slPoint(6, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'K', slVec2f(82, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'L', slVec2f(90, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'M', slVec2f(97, 0), slPoint(13, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'N', slVec2f(110, 0), slPoint(10, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'O', slVec2f(120, 0), slPoint(11, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'P', slVec2f(131, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'Q', slVec2f(139, 0), slPoint(12, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'R', slVec2f(151, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'S', slVec2f(159, 0), slPoint(7, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'T', slVec2f(166, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'U', slVec2f(175, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'V', slVec2f(184, 0), slPoint(9, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'W', slVec2f(193, 0), slPoint(14, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'X', slVec2f(207, 0), slPoint(9, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'Y', slVec2f(216, 0), slPoint(7, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'Z', slVec2f(224, 0), slPoint(7, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'0', slVec2f(231, 0), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'1', slVec2f(239, 0), slPoint(7, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'2', slVec2f(247, 0), slPoint(7, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'3', slVec2f(1, 20), slPoint(7, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'4', slVec2f(9, 20), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'5', slVec2f(17, 20), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'6', slVec2f(25, 20), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'7', slVec2f(33, 20), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'8', slVec2f(41, 20), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'9', slVec2f(49, 20), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'a', slVec2f(57, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'b', slVec2f(65, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'c', slVec2f(73, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'd', slVec2f(80, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'e', slVec2f(89, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'f', slVec2f(96, 20), slPoint(6, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'g', slVec2f(102, 20), slPoint(6, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'h', slVec2f(109, 20), slPoint(7, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'i', slVec2f(117, 20), slPoint(3, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'j', slVec2f(120, 20), slPoint(4, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'k', slVec2f(125, 20), slPoint(7, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'l', slVec2f(132, 20), slPoint(3, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'm', slVec2f(136, 20), slPoint(12, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'n', slVec2f(148, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'o', slVec2f(157, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'p', slVec2f(165, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'q', slVec2f(173, 20), slPoint(8, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'r', slVec2f(182, 20), slPoint(6, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U's', slVec2f(188, 20), slPoint(5, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U't', slVec2f(194, 20), slPoint(5, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'u', slVec2f(199, 20), slPoint(7, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'v', slVec2f(207, 20), slPoint(7, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'w', slVec2f(214, 20), slPoint(12, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'x', slVec2f(226, 20), slPoint(7, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'y', slVec2f(233, 20), slPoint(7, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'z', slVec2f(240, 20), slPoint(7, 16), 0, slPoint(256, 256));
myFont->AddGlyph(U'~', slVec2f(1, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'`', slVec2f(9, 39), slPoint(4, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'!', slVec2f(14, 39), slPoint(4, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'?', slVec2f(19, 39), slPoint(7, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'\'', slVec2f(26, 39), slPoint(4, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'\"', slVec2f(30, 39), slPoint(5, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'@', slVec2f(37, 39), slPoint(13, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'#', slVec2f(50, 39), slPoint(9, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'№', slVec2f(59, 39), slPoint(15, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U';', slVec2f(75, 39), slPoint(3, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U':', slVec2f(80, 39), slPoint(3, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'%', slVec2f(84, 39), slPoint(11, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'&', slVec2f(95, 39), slPoint(10, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'^', slVec2f(106, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'<', slVec2f(114, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'>', slVec2f(121, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'(', slVec2f(130, 39), slPoint(5, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U')', slVec2f(134, 39), slPoint(5, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'[', slVec2f(140, 39), slPoint(5, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U']', slVec2f(144, 39), slPoint(5, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'{', slVec2f(150, 39), slPoint(5, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'}', slVec2f(154, 39), slPoint(5, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'*', slVec2f(160, 39), slPoint(6, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'.', slVec2f(167, 39), slPoint(3, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U',', slVec2f(171, 39), slPoint(3, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'/', slVec2f(174, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'\\', slVec2f(181, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'|', slVec2f(189, 39), slPoint(4, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'+', slVec2f(195, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'-', slVec2f(203, 39), slPoint(5, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'=', slVec2f(208, 39), slPoint(7, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'_', slVec2f(216, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U'$', slVec2f(233, 39), slPoint(8, 15), 0, slPoint(256, 256));
myFont->AddGlyph(U' ', slVec2f(225, 39), slPoint(8, 15), 0, slPoint(256, 256));
g_framework->m_GUIFontDefault = myFont;
}
}
Default m_textDrawCallback.
// slFramework
static slGUIDrawTextCallback* GetDefaultDrawTextCallback();
...
slGUIDrawTextCallback* slFramework::GetDefaultDrawTextCallback()
{
return &g_framework->m_defaultDrawTextCallback;
}
// callback
class DefaultGUIDrawTextCallback : public slGUIDrawTextCallback
{
public:
DefaultGUIDrawTextCallback() {}
virtual ~DefaultGUIDrawTextCallback() {}
virtual slGUIFont* OnFont(char32_t) final;
virtual slColor* OnColor(char32_t) final;
};
...
slGUIFont* DefaultGUIDrawTextCallback::OnFont(char32_t i) {
return g_framework->m_GUIFontDefault;
}
slColor* DefaultGUIDrawTextCallback::OnColor(char32_t i) {
return &g_framework->m_colorWhite;
}
But, I still have problem. I need to change text color in button,
when mouse cursor above button.
I need to create default drawtextcallback inside button?
I think, I need to create special class for button, and in future,
special classes for all GUI elements.
OR. Just like this:
Modify slGUIDrawTextCallback
enum {
Reason_default,
Reason_mouseEnter,
Reason_mouseLeave,
Reason_mouseAbove,
Reason_pressed,
Reason_active,
Reason_disabled,
/*Reason_, // others
Reason_,*/
};
uint32_t m_reason = Reason_default;
virtual slGUIFont* OnFont(uint32_t, char32_t) = 0;
virtual slColor* OnColor(uint32_t, char32_t) = 0;
Modify slGUIButton::Draw
if (IsEnabled())
{
if (IsClickedLMB())
{
gs->DrawGUIRectangle(m_buildRect, m_style->m_buttonMousePressBGColor1, m_style->m_buttonMousePressBGColor2, 0, 0);
m_textDrawCallback->m_reason = slGUIDrawTextCallback::Reason_pressed;
gs->DrawGUIText(m_text.c_str(), m_text.size(), m_textPosition, m_textDrawCallback);
}
else
{
if (IsCursorInRect())
{
gs->DrawGUIRectangle(m_buildRect, m_style->m_buttonMouseHoverBGColor1, m_style->m_buttonMouseHoverBGColor2, 0, 0);
m_textDrawCallback->m_reason = slGUIDrawTextCallback::Reason_mouseAbove;
gs->DrawGUIText(m_text.c_str(), m_text.size(), m_textPosition, m_textDrawCallback);
}
else
{
gs->DrawGUIRectangle(m_buildRect, m_style->m_buttonBGColor1, m_style->m_buttonBGColor2, 0, 0);
m_textDrawCallback->m_reason = slGUIDrawTextCallback::Reason_default;
gs->DrawGUIText(m_text.c_str(), m_text.size(), m_textPosition, m_textDrawCallback);
}
}
}
else
{
gs->DrawGUIRectangle(m_buildRect, m_style->m_buttonDisabledBGColor1, m_style->m_buttonDisabledBGColor2, 0, 0);
m_textDrawCallback->m_reason = slGUIDrawTextCallback::Reason_disabled;
gs->DrawGUIText(m_text.c_str(), m_text.size(), m_textPosition, m_textDrawCallback);
}
But I still need to add default callback class for button...
class slGUIButtonTextDrawCallback : public slGUIDrawTextCallback
{
public:
slGUIButtonTextDrawCallback() {}
virtual ~slGUIButtonTextDrawCallback() {}
virtual slGUIFont* OnFont(uint32_t r, char32_t) override;
virtual slColor* OnColor(uint32_t r, char32_t) override;
};
class slGUIButton : public slGUIElement
{
slString m_text;
slVec2f m_textPosition;
slGUIButtonTextDrawCallback m_defaultTextDrawCallback; // new
...
slGUIFont* slGUIButtonTextDrawCallback::OnFont(uint32_t r, char32_t)
{
return slFramework::GetDefaultFont(0);
}
slColor* slGUIButtonTextDrawCallback::OnColor(uint32_t r, char32_t)
{
switch (r)
{
case slGUIDrawTextCallback::Reason_pressed:
return &m_button->GetStyle()->m_buttonMousePressTextColor;
case slGUIDrawTextCallback::Reason_mouseAbove:
return &m_button->GetStyle()->m_buttonMouseHoverTextColor;
case slGUIDrawTextCallback::Reason_disabled:
return &m_button->GetStyle()->m_buttonDisabledTextColor;
}
return &m_button->GetStyle()->m_buttonTextColor;
}
slGUIButton::slGUIButton(slGUIWindow* w, const slVec2f& position, const slVec2f& size)
:
slGUIElement::slGUIElement(w, position, size)
{
SetParent(w->GetRootElement());
m_defaultTextDrawCallback.m_button = this;
m_textDrawCallback = dynamic_cast(&m_defaultTextDrawCallback);
}
Now it works. I not very much like it, but I WANT to be able to set color and
font to each symbol.
Another thing - I need to get text size. In pixels.
Because I need to move text in left top corner of buildRect,
and I need to know height. Get whole size, not just height.
// slGUIDrawTextCallback
virtual slVec2f GetTextSize(const char32_t* text)
{
slVec2f sz, position;
slVec4f rct;
if (text)
{
if (text[0] != 0)
{
const char32_t* p = &text[0u];
while ((size_t)*p++)
{
auto font = OnFont(Reason_default, *p);
slGUIFontGlyph* g = font->GetGlyphMap()[*p];
rct.x = position.x;
rct.y = position.y;
rct.z = rct.x + g->m_width;
rct.w = rct.y + g->m_height;
position.x += g->m_width + g->m_overhang + g->m_underhang + font->m_characterSpacing;
switch (*p)
{
case U' ':
position.x += font->m_spaceSize;
break;
case U'\t':
position.x += font->m_tabSize;
break;
case U'\n':
position.y += font->m_lineSpacing + font->GetMaxSize().y;
position.x = 0.f;
break;
}
if (position.x > sz.x) sz.x = position.x;
if (position.y > sz.y) sz.y = position.y;
if (g->m_height > sz.y) sz.y = (float)g->m_height;
}
}
}
return sz;
}
In button
void slGUIButton::UpdateTextPosition()
{
m_textPosition.x = m_buildRect.x;
m_textPosition.y = m_buildRect.y + m_textDrawCallback->GetTextSize(m_text.c_str()).y;
}
void slGUIButton::SetText(const slString& s)
{
m_text = s;
UpdateTextPosition();
}
Move text in center
void slGUIButton::UpdateTextPosition()
{
m_textPosition.x = m_buildRect.x;
m_textPosition.y = m_buildRect.y;
auto tsz = m_textDrawCallback->GetTextSize(m_text.c_str());
m_textPosition.y = m_buildRect.y + tsz.y;
slVec2f buttonCenter;
buttonCenter.x = (m_buildRect.z - m_buildRect.x) * 0.5f;
buttonCenter.y = (m_buildRect.w - m_buildRect.y) * 0.5f;
slVec2f textHalfLen;
textHalfLen.x = tsz.x * 0.5f;
textHalfLen.y = tsz.y * 0.5f;
m_textPosition.x = m_buildRect.x + buttonCenter.x - textHalfLen.x;
m_textPosition.y = m_buildRect.y + buttonCenter.y - textHalfLen.y;
}
Download
Please enable JavaScript to view the comments powered by Disqus.