ENH: font preview
Change-Id: I8151036cedcba9c57183414a9d134741bb2166a5 Signed-off-by: Stone Li <stone.li@bambulab.com>
This commit is contained in:
parent
4ee5dbb07f
commit
110d81f6f7
9 changed files with 372 additions and 26 deletions
|
@ -620,6 +620,7 @@ namespace ImGui
|
|||
// - A selectable highlights when hovered, and can display another color when selected.
|
||||
// - Neighbors selectable extend their highlight bounds in order to leave no gap between them. This is so a series of selected Selectable appear contiguous.
|
||||
IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height
|
||||
IMGUI_API bool BBLImageSelectable(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& font_size, int font_line, const ImVec4& tint_col, const ImVec2& uv0, const ImVec2& uv1, bool selected = false);
|
||||
IMGUI_API bool BBLSelectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height
|
||||
IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper.
|
||||
|
||||
|
|
|
@ -7064,6 +7064,161 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||
return pressed;
|
||||
}
|
||||
|
||||
bool ImGui::BBLImageSelectable(ImTextureID user_texture_id, const ImVec2& size_arg, const ImVec2& font_size, int font_line, const ImVec4& tint_col, const ImVec2& uv0, const ImVec2& uv1, bool selected)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems) return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
PushID((void*)(intptr_t)user_texture_id);
|
||||
const ImGuiID id = window->GetID("#BBLImageSelectable");
|
||||
PopID();
|
||||
|
||||
ImGuiSelectableFlags flags = 0;
|
||||
|
||||
// Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle.
|
||||
ImVec2 size(size_arg.x != 0.0f ? size_arg.x : 0.0f, size_arg.y != 0.0f ? size_arg.y : 0.0f);
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
pos.y += window->DC.CurrLineTextBaseOffset;
|
||||
ItemSize(size, 0.0f);
|
||||
|
||||
// Fill horizontal space
|
||||
// We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitly right-aligned sizes not visibly match other widgets.
|
||||
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
|
||||
const float min_x = span_all_columns ? window->ParentWorkRect.Min.x : pos.x;
|
||||
const float max_x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x;
|
||||
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth)) size.x = ImMax(0.0f, max_x - min_x);
|
||||
|
||||
// Text stays at the submission position, but bounding box may be extended on both sides
|
||||
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
||||
const ImVec2 text_min = ImVec2(pos.x + arrow_size, pos.y);
|
||||
const ImVec2 text_max(min_x + size.x, pos.y + size.y);
|
||||
|
||||
// Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable.
|
||||
ImRect bb(min_x, pos.y, text_max.x, text_max.y);
|
||||
if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0) {
|
||||
const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x;
|
||||
const float spacing_y = style.ItemSpacing.y;
|
||||
const float spacing_L = IM_FLOOR(spacing_x * 0.50f);
|
||||
const float spacing_U = IM_FLOOR(spacing_y * 0.50f);
|
||||
bb.Min.x -= spacing_L;
|
||||
bb.Min.y -= spacing_U;
|
||||
bb.Max.x += (spacing_x - spacing_L);
|
||||
bb.Max.y += (spacing_y - spacing_U);
|
||||
}
|
||||
// if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(0, 255, 0, 255)); }
|
||||
|
||||
// Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackground for every Selectable..
|
||||
const float backup_clip_rect_min_x = window->ClipRect.Min.x;
|
||||
const float backup_clip_rect_max_x = window->ClipRect.Max.x;
|
||||
if (span_all_columns) {
|
||||
window->ClipRect.Min.x = window->ParentWorkRect.Min.x;
|
||||
window->ClipRect.Max.x = window->ParentWorkRect.Max.x;
|
||||
}
|
||||
|
||||
bool item_add;
|
||||
if (flags & ImGuiSelectableFlags_Disabled) {
|
||||
ImGuiItemFlags backup_item_flags = g.CurrentItemFlags;
|
||||
g.CurrentItemFlags |= ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNavDefaultFocus;
|
||||
item_add = ItemAdd(bb, id);
|
||||
g.CurrentItemFlags = backup_item_flags;
|
||||
}
|
||||
else {
|
||||
item_add = ItemAdd(bb, id);
|
||||
}
|
||||
|
||||
if (span_all_columns) {
|
||||
window->ClipRect.Min.x = backup_clip_rect_min_x;
|
||||
window->ClipRect.Max.x = backup_clip_rect_max_x;
|
||||
}
|
||||
|
||||
if (!item_add) return false;
|
||||
|
||||
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
|
||||
// which would be advantageous since most selectable are not selected.
|
||||
if (span_all_columns && window->DC.CurrentColumns)
|
||||
PushColumnsBackground();
|
||||
else if (span_all_columns && g.CurrentTable)
|
||||
TablePushBackgroundChannel();
|
||||
|
||||
// We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries
|
||||
ImGuiButtonFlags button_flags = 0;
|
||||
if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; }
|
||||
if (flags & ImGuiSelectableFlags_SelectOnClick) { button_flags |= ImGuiButtonFlags_PressedOnClick; }
|
||||
if (flags & ImGuiSelectableFlags_SelectOnRelease) { button_flags |= ImGuiButtonFlags_PressedOnRelease; }
|
||||
if (flags & ImGuiSelectableFlags_Disabled) { button_flags |= ImGuiButtonFlags_Disabled; }
|
||||
if (flags & ImGuiSelectableFlags_AllowDoubleClick) { button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; }
|
||||
if (flags & ImGuiSelectableFlags_AllowItemOverlap) { button_flags |= ImGuiButtonFlags_AllowItemOverlap; }
|
||||
|
||||
if (flags & ImGuiSelectableFlags_Disabled) selected = false;
|
||||
|
||||
const bool was_selected = selected;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||
if (hovered || g.ActiveId == id) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, GetColorU32(ImGuiCol_BorderActive));
|
||||
if (arrow_size == 0) {
|
||||
RenderFrameBorder(bb.Min, ImVec2(bb.Max.x - style.WindowPadding.x, bb.Max.y), style.FrameRounding);
|
||||
}
|
||||
else {
|
||||
RenderFrameBorder(ImVec2(bb.Min.x + style.WindowPadding.x, bb.Min.y), ImVec2(bb.Max.x - style.WindowPadding.x, bb.Max.y), style.FrameRounding);
|
||||
}
|
||||
ImGui::PopStyleColor(1);
|
||||
}
|
||||
// Update NavId when clicking or when Hovering (this doesn't happen on most widgets), so navigation can be resumed with gamepad/keyboard
|
||||
if (pressed || (hovered && (flags & ImGuiSelectableFlags_SetNavIdOnHover))) {
|
||||
if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent) {
|
||||
SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, ImRect(bb.Min - window->Pos, bb.Max - window->Pos));
|
||||
g.NavDisableHighlight = true;
|
||||
}
|
||||
}
|
||||
if (pressed) MarkItemEdited(id);
|
||||
|
||||
if (flags & ImGuiSelectableFlags_AllowItemOverlap) SetItemAllowOverlap();
|
||||
|
||||
// In this branch, Selectable() cannot toggle the selection so this will never trigger.
|
||||
if (selected != was_selected) //-V547
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
|
||||
|
||||
// Render
|
||||
if (held && (flags & ImGuiSelectableFlags_DrawHoveredWhenHeld)) hovered = true;
|
||||
if (hovered || selected) {
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
||||
if (arrow_size == 0) {
|
||||
RenderFrame(bb.Min, ImVec2(bb.Max.x - style.WindowPadding.x, bb.Max.y), col, false, 0.0f);
|
||||
}
|
||||
else {
|
||||
RenderFrame(ImVec2(bb.Min.x + style.WindowPadding.x, bb.Min.y), ImVec2(bb.Max.x - style.WindowPadding.x, bb.Max.y), col, false, 0.0f);
|
||||
}
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
|
||||
}
|
||||
|
||||
if (span_all_columns && window->DC.CurrentColumns)
|
||||
PopColumnsBackground();
|
||||
else if (span_all_columns && g.CurrentTable)
|
||||
TablePopBackgroundChannel();
|
||||
|
||||
if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||
|
||||
// Render
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||
ImVec2 p_min = bb.Min + ImVec2(2 * style.ItemSpacing.x, (bb.Max.y - bb.Min.y - font_size.y) / 2);
|
||||
ImVec2 p_max = p_min + font_size;
|
||||
window->DrawList->AddImage(user_texture_id, p_min, p_max, uv0, uv1, GetColorU32(tint_col));
|
||||
|
||||
if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor();
|
||||
|
||||
// Automatically close popups
|
||||
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.CurrentItemFlags & ImGuiItemFlags_SelectableDontClosePopup))
|
||||
CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool ImGui::BBLSelectable(const char *label, bool selected, ImGuiSelectableFlags flags, const ImVec2 &size_arg)
|
||||
{
|
||||
ImGuiWindow *window = GetCurrentWindow();
|
||||
|
|
|
@ -34,7 +34,7 @@ static std::map<std::string, std::string> g_occt_fonts_maps; //map<font_name, fo
|
|||
|
||||
static const std::vector<Standard_CString> fonts_suffix{ "Bold", "Medium", "Heavy", "Italic", "Oblique", "Inclined", "Light", "Thin",
|
||||
"Semibold", "ExtraBold", "ExtraBold", "Semilight", "SemiLight", "ExtraLight", "Extralight", "Ultralight",
|
||||
"Condensed", "Ultra", "Extra", "Expanded", "Extended", "1", "2", "3", "4", "5", "6", "7", "8", "9", "Noto Sans"};
|
||||
"Condensed", "Ultra", "Extra", "Expanded", "Extended", "1", "2", "3", "4", "5", "6", "7", "8", "9", "Al Tarikh"};
|
||||
|
||||
std::map<std::string, std::string> get_occt_fonts_maps()
|
||||
{
|
||||
|
|
|
@ -1881,6 +1881,8 @@ void GLCanvas3D::render(bool only_init)
|
|||
_render_overlays();
|
||||
|
||||
if (wxGetApp().plater()->is_render_statistic_dialog_visible()) {
|
||||
ImGui::ShowMetricsWindow();
|
||||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
imgui.begin(std::string("Render statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||
imgui.text("FPS (SwapBuffers() calls per second):");
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include <wx/dcgraph.h>
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
|
@ -468,7 +469,13 @@ void GLTexture::reset()
|
|||
m_original_width = m_original_height = 0;
|
||||
}
|
||||
|
||||
bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &font, wxColor background, wxColor foreground)
|
||||
bool GLTexture::generate_from_text_string(const std::string& text_str, wxFont &font, wxColor background, wxColor foreground)
|
||||
{
|
||||
int w,h,hl;
|
||||
return generate_from_text(text_str, font, background, foreground);
|
||||
}
|
||||
|
||||
bool GLTexture::generate_from_text(const std::string &text_str, wxFont &font, wxColor background, wxColor foreground)
|
||||
{
|
||||
if (text_str.empty())
|
||||
{
|
||||
|
@ -488,7 +495,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
m_original_width = (int)w;
|
||||
m_original_height = (int)h;
|
||||
m_width = (int)next_highest_power_of_2((uint32_t)w);
|
||||
m_height = (int)next_highest_power_of_2((uint32_t)h);
|
||||
m_height = (int)next_highest_power_of_2((uint32_t)h);
|
||||
|
||||
// generates bitmap
|
||||
wxBitmap bitmap(m_width, m_height);
|
||||
|
@ -499,7 +506,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
|
||||
// draw message
|
||||
memDC.SetTextForeground(*wxWHITE);
|
||||
memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER);
|
||||
memDC.DrawLabel(msg, wxRect(0, 0, m_original_width, m_original_height), wxALIGN_CENTER);
|
||||
|
||||
memDC.SelectObject(wxNullBitmap);
|
||||
|
||||
|
@ -508,7 +515,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
|
||||
// prepare buffer
|
||||
std::vector<unsigned char> data(4 * m_width * m_height, 0);
|
||||
const unsigned char *src = image.GetData();
|
||||
const unsigned char* src = image.GetData();
|
||||
/* for debug use
|
||||
std::ofstream fout;
|
||||
fout.open(text_str+std::to_string(m_width)+"_"+std::to_string(m_height)+".rgb", std::ios::out);
|
||||
|
@ -520,7 +527,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
*dst++ = foreground.Red();
|
||||
*dst++ = foreground.Green();
|
||||
*dst++ = foreground.Blue();
|
||||
*dst++ = (unsigned char)std::min<int>(255, *src);
|
||||
*dst++ = (unsigned char)std::min<int>(255, *src);
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
|
@ -530,9 +537,9 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
glsafe(::glGenTextures(1, &m_id));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
|
||||
if (GLEW_EXT_texture_compression_s3tc)
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
else
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
|
||||
|
@ -541,6 +548,111 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GLTexture::generate_texture_from_text(const std::string& text_str, wxFont& font, int& ww, int& hh, int& hl, wxColor background, wxColor foreground)
|
||||
{
|
||||
if (text_str.empty())
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":no text string, should not happen\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString msg = _(text_str);
|
||||
wxMemoryDC memDC;
|
||||
|
||||
memDC.SetFont(font);
|
||||
|
||||
// calculates texture size
|
||||
wxCoord w, h, ll;
|
||||
wxClientDC dc(wxGetApp().GetTopWindow());
|
||||
dc.SetFont(font);
|
||||
dc.GetMultiLineTextExtent(msg, &w, &h, &ll, &font);
|
||||
|
||||
|
||||
m_original_width = (int)w;
|
||||
m_original_height = (int)h;
|
||||
m_width = (int)next_highest_power_of_2((uint32_t)w);
|
||||
m_height = (int)next_highest_power_of_2((uint32_t)h);
|
||||
ww = m_width;
|
||||
hh = m_height;
|
||||
hl = ll;
|
||||
// generates bitmap
|
||||
wxBitmap bitmap(m_width, m_height);
|
||||
|
||||
memDC.SelectObject(bitmap);
|
||||
memDC.SetBackground(wxBrush(background));
|
||||
memDC.Clear();
|
||||
|
||||
// draw message
|
||||
memDC.SetTextForeground(*wxWHITE);
|
||||
|
||||
wxGCDC dc2(memDC);
|
||||
dc2.SetFont(font);
|
||||
dc2.SetBackground(wxBrush(background));
|
||||
dc2.SetTextForeground(*wxWHITE);
|
||||
dc2.DrawLabel(msg, wxRect(0, 0, m_width, m_height), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
memDC.SelectObject(wxNullBitmap);
|
||||
|
||||
// Convert the bitmap into a linear data ready to be loaded into the GPU.
|
||||
wxImage image = bitmap.ConvertToImage();
|
||||
|
||||
// prepare buffer
|
||||
std::vector<unsigned char> data(4 * m_width * m_height, 0);
|
||||
const unsigned char* src = image.GetData();
|
||||
/* for debug use
|
||||
std::ofstream fout;
|
||||
fout.open(text_str+std::to_string(m_width)+"_"+std::to_string(m_height)+".rgb", std::ios::out);
|
||||
fout.write((const char*)src, 3 * m_width * m_height);
|
||||
fout.close();*/
|
||||
bool found = false;
|
||||
for (int h = 0; h < m_height; ++h) {
|
||||
unsigned char* dst = data.data() + 4 * h * m_width;
|
||||
for (int w = 0; w < m_width; ++w) {
|
||||
*dst++ = foreground.Red();
|
||||
*dst++ = foreground.Green();
|
||||
*dst++ = foreground.Blue();
|
||||
*dst++ = (unsigned char)std::min<int>(255, *src);
|
||||
if ((*src) != background.Red() && !found) {
|
||||
found = true;
|
||||
if (m_height - h < font.GetPointSize())
|
||||
return false;
|
||||
}
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
found = false;
|
||||
src -= 3;
|
||||
for (int h = m_height; h > 0; --h) {
|
||||
for (int w = m_width; w > 0; --w) {
|
||||
if ((*src) != background.Red() && !found) {
|
||||
found = true;
|
||||
if (h < font.GetPointSize())
|
||||
return false;
|
||||
}
|
||||
src -= 3;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
// sends buffer to gpu
|
||||
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
glsafe(::glGenTextures(1, &m_id));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
|
||||
if (GLEW_EXT_texture_compression_s3tc)
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
else
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLTexture::render_texture(unsigned int tex_id, float left, float right, float bottom, float top)
|
||||
{
|
||||
|
|
|
@ -106,7 +106,10 @@ namespace GUI {
|
|||
//BBS: add generate logic for text strings
|
||||
int m_original_width;
|
||||
int m_original_height;
|
||||
bool generate_from_text_string(const std::string &text_str, wxFont &font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
|
||||
|
||||
bool generate_texture_from_text(const std::string& text_str, wxFont& font, int& ww, int& hh, int &hl, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
|
||||
bool generate_from_text(const std::string& text_str, wxFont& font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
|
||||
bool generate_from_text_string(const std::string& text_str, wxFont& font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
|
||||
|
||||
unsigned int get_id() const { return m_id; }
|
||||
int get_width() const { return m_width; }
|
||||
|
|
|
@ -185,7 +185,7 @@ public:
|
|||
void render() { m_tooltip.clear(); on_render(); }
|
||||
void render_for_picking() { on_render_for_picking(); }
|
||||
void render_input_window(float x, float y, float bottom_limit);
|
||||
void on_change_color_mode(bool is_dark) { m_is_dark_mode = is_dark; }
|
||||
virtual void on_change_color_mode(bool is_dark) { m_is_dark_mode = is_dark; }
|
||||
|
||||
virtual std::string get_tooltip() const { return ""; }
|
||||
|
||||
|
|
|
@ -23,20 +23,66 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
static double g_normal_precise = 0.0015;
|
||||
static const wxColour FONT_TEXTURE_BG = wxColour(0, 0, 0, 0);
|
||||
static const wxColour FONT_TEXTURE_FG = *wxWHITE;
|
||||
static const int FONT_SIZE = 12;
|
||||
|
||||
|
||||
GLGizmoText::GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||
{
|
||||
}
|
||||
|
||||
GLGizmoText::~GLGizmoText()
|
||||
{
|
||||
for (int i = 0; i < m_textures.size(); i++) {
|
||||
if (m_textures[i].texture != nullptr)
|
||||
delete m_textures[i].texture;
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmoText::on_init()
|
||||
{
|
||||
m_avail_font_names = init_occt_fonts();
|
||||
update_font_texture();
|
||||
m_scale = m_imgui->get_font_size();
|
||||
m_shortcut_key = WXK_CONTROL_T;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLGizmoText::update_font_texture()
|
||||
{
|
||||
for (int i = 0; i < m_textures.size(); i++) {
|
||||
if (m_textures[i].texture != nullptr)
|
||||
delete m_textures[i].texture;
|
||||
}
|
||||
m_combo_width = 0.0f;
|
||||
m_combo_height = 0.0f;
|
||||
m_textures.clear();
|
||||
m_textures.reserve(m_avail_font_names.size());
|
||||
for (int i = 0; i < m_avail_font_names.size(); i++)
|
||||
{
|
||||
GLTexture* texture = new GLTexture();
|
||||
auto face = wxString::FromUTF8(m_avail_font_names[i]);
|
||||
auto retina_scale = m_parent.get_scale();
|
||||
wxFont font { (int)round(retina_scale * FONT_SIZE), wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, face };
|
||||
int w, h, hl;
|
||||
if (texture->generate_texture_from_text(m_avail_font_names[i], font, w, h, hl, FONT_TEXTURE_BG, FONT_TEXTURE_FG)) {
|
||||
//if (h < m_imgui->scaled(2.f)) {
|
||||
TextureInfo info;
|
||||
info.texture = texture;
|
||||
info.w = w;
|
||||
info.h = h;
|
||||
info.hl = hl;
|
||||
info.font_name = m_avail_font_names[i];
|
||||
m_textures.push_back(info);
|
||||
m_combo_width = std::max(m_combo_width, static_cast<float>(texture->m_original_width));
|
||||
//}
|
||||
}
|
||||
}
|
||||
m_combo_height = m_imgui->scaled(32.f / 15.f);
|
||||
}
|
||||
|
||||
void GLGizmoText::on_set_state()
|
||||
{
|
||||
}
|
||||
|
@ -114,6 +160,8 @@ void GLGizmoText::push_combo_style(const float scale) {
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImGuiWrapper::COL_WINDOW_BG_DARK);
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImGuiWrapper::COL_WINDOW_BG_DARK);
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImGuiWrapper::COL_WINDOW_BG_DARK);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { 1.00f, 1.00f, 1.00f, 0.0f });
|
||||
}
|
||||
else {
|
||||
|
@ -125,6 +173,8 @@ void GLGizmoText::push_combo_style(const float scale) {
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImGuiWrapper::COL_WINDOW_BG);
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImGuiWrapper::COL_WINDOW_BG);
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImGuiWrapper::COL_WINDOW_BG);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { 1.00f, 1.00f, 1.00f, 0.0f });
|
||||
}
|
||||
}
|
||||
|
@ -132,12 +182,21 @@ void GLGizmoText::push_combo_style(const float scale) {
|
|||
void GLGizmoText::pop_combo_style()
|
||||
{
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor(7);
|
||||
ImGui::PopStyleColor(9);
|
||||
}
|
||||
|
||||
// BBS
|
||||
void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
|
||||
{
|
||||
if (m_imgui->get_font_size() != m_scale) {
|
||||
m_scale = m_imgui->get_font_size();
|
||||
update_font_texture();
|
||||
}
|
||||
if (m_textures.size() == 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << "GLGizmoText has no texture";
|
||||
return;
|
||||
}
|
||||
|
||||
const float win_h = ImGui::GetWindowHeight();
|
||||
y = std::min(y, bottom_limit - win_h);
|
||||
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
|
@ -178,35 +237,31 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
|
|||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
||||
const char** cstr_font_names = (const char**)calloc(m_avail_font_names.size(), sizeof(const char*));
|
||||
for (int i = 0; i < m_avail_font_names.size(); i++)
|
||||
cstr_font_names[i] = m_avail_font_names[i].c_str();
|
||||
|
||||
m_imgui->text(_L("Font"));
|
||||
ImGui::SameLine(caption_size);
|
||||
ImGui::PushItemWidth(input_text_size + ImGui::GetFrameHeight() * 2);
|
||||
push_combo_style(currt_scale);
|
||||
int font_index = m_curr_font_idx;
|
||||
m_imgui->push_font_by_name(cstr_font_names[font_index]);
|
||||
if (ImGui::BBLBeginCombo("##Font", cstr_font_names[m_curr_font_idx], 0)) {
|
||||
if (ImGui::BBLBeginCombo("##Font", m_textures[m_curr_font_idx].font_name.c_str(), 0)) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(4.0f, 0.0f) * currt_scale);
|
||||
for (int i = 0; i < m_avail_font_names.size(); i++) {
|
||||
m_imgui->push_font_by_name(m_avail_font_names[i]);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8, 4));
|
||||
for (int i = 0; i < m_textures.size(); i++) {
|
||||
const bool is_selected = (m_curr_font_idx == i);
|
||||
if (ImGui::BBLSelectable((cstr_font_names[i] + std::string("##") + std::to_string(i)).c_str(), is_selected, 0, {input_text_size + ImGui::GetFrameHeight() * 2 , 0.0f})) {
|
||||
ImTextureID icon_id = (ImTextureID)(intptr_t)(m_textures[i].texture->get_id());
|
||||
ImVec4 tint_color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
|
||||
ImVec2 selectable_size(std::max((input_text_size + ImGui::GetFrameHeight() * 2), m_combo_width), m_combo_height);
|
||||
if (ImGui::BBLImageSelectable(icon_id, selectable_size, { (float)m_textures[i].w, (float)m_textures[i].h }, m_textures[i].hl, tint_color, { 0, 0 }, {1, 1}, is_selected)) {
|
||||
m_curr_font_idx = i;
|
||||
m_font_name = cstr_font_names[m_curr_font_idx];
|
||||
m_font_name = m_textures[m_curr_font_idx].font_name;
|
||||
}
|
||||
if (is_selected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
m_imgui->pop_font_by_name(m_avail_font_names[i]);
|
||||
}
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
m_imgui->pop_font_by_name(cstr_font_names[font_index]);
|
||||
|
||||
pop_combo_style();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "GLGizmoBase.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
|
||||
#include "../GLTexture.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -22,9 +22,27 @@ private:
|
|||
bool m_bold = true;
|
||||
bool m_italic = false;
|
||||
float m_thickness = 2.f;
|
||||
float m_combo_height = 0.0f;
|
||||
float m_combo_width = 0.0f;
|
||||
float m_scale;
|
||||
|
||||
class TextureInfo {
|
||||
public:
|
||||
GLTexture* texture { nullptr };
|
||||
int h;
|
||||
int w;
|
||||
int hl;
|
||||
|
||||
std::string font_name;
|
||||
};
|
||||
|
||||
std::vector<TextureInfo> m_textures;
|
||||
|
||||
public:
|
||||
GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
~GLGizmoText();
|
||||
|
||||
void update_font_texture();
|
||||
|
||||
protected:
|
||||
virtual bool on_init() override;
|
||||
|
|
Loading…
Reference in a new issue