Mac: Implement Retina for the 3D scene, fix #97
This commit is contained in:
parent
28f1a6f256
commit
d1c569dd57
@ -169,6 +169,11 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
|
||||
endif ()
|
||||
|
||||
# Where all the bundled libraries reside?
|
||||
set(LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
set(LIBDIR_BIN ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
|
@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
include(PrecompiledHeader)
|
||||
|
||||
add_library(libslic3r_gui STATIC
|
||||
set(SLIC3R_GUI_SOURCES
|
||||
pchheader.cpp
|
||||
pchheader.hpp
|
||||
GUI/AboutDialog.cpp
|
||||
@ -127,6 +127,12 @@ add_library(libslic3r_gui STATIC
|
||||
Utils/HexFile.hpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND SLIC3R_GUI_SOURCES Utils/RetinaHelperImpl.mm)
|
||||
endif ()
|
||||
|
||||
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
||||
|
||||
target_link_libraries(libslic3r_gui libslic3r avrdude imgui)
|
||||
if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
|
||||
add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
|
||||
|
@ -59,6 +59,11 @@ void AppConfig::set_defaults()
|
||||
if (get("use_legacy_opengl").empty())
|
||||
set("use_legacy_opengl", "0");
|
||||
|
||||
#if __APPLE__
|
||||
if (get("use_retina_opengl").empty())
|
||||
set("use_retina_opengl", "1");
|
||||
#endif
|
||||
|
||||
if (get("remember_output_path").empty())
|
||||
set("remember_output_path", "1");
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "libslic3r/GCode/PreviewData.hpp"
|
||||
#include "libslic3r/Geometry.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Technologies.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "slic3r/GUI/BackgroundSlicingProcess.hpp"
|
||||
#include "slic3r/GUI/GLShader.hpp"
|
||||
@ -20,6 +21,10 @@
|
||||
#include "GUI_ObjectManipulation.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
#include "slic3r/Utils/RetinaHelper.hpp"
|
||||
#endif
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <wx/glcanvas.h>
|
||||
@ -45,6 +50,7 @@
|
||||
#include <iostream>
|
||||
#include <float.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
static const float TRACKBALLSIZE = 0.8f;
|
||||
static const float GIMBALL_LOCK_THETA_MAX = 180.0f;
|
||||
@ -59,8 +65,6 @@ static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f };
|
||||
static const float VIEW_FRONT[2] = { 0.0f, 90.0f };
|
||||
static const float VIEW_REAR[2] = { 180.0f, 90.0f };
|
||||
|
||||
static const float VARIABLE_LAYER_THICKNESS_BAR_WIDTH = 70.0f;
|
||||
static const float VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT = 22.0f;
|
||||
static const float GIZMO_RESET_BUTTON_HEIGHT = 22.0f;
|
||||
static const float GIZMO_RESET_BUTTON_WIDTH = 70.f;
|
||||
|
||||
@ -194,9 +198,10 @@ Size::Size()
|
||||
{
|
||||
}
|
||||
|
||||
Size::Size(int width, int height)
|
||||
Size::Size(int width, int height, float scale_factor)
|
||||
: m_width(width)
|
||||
, m_height(height)
|
||||
, m_scale_factor(scale_factor)
|
||||
{
|
||||
}
|
||||
|
||||
@ -220,6 +225,16 @@ void Size::set_height(int height)
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
int Size::get_scale_factor() const
|
||||
{
|
||||
return m_scale_factor;
|
||||
}
|
||||
|
||||
void Size::set_scale_factor(int scale_factor)
|
||||
{
|
||||
m_scale_factor = scale_factor;
|
||||
}
|
||||
|
||||
Rect::Rect()
|
||||
: m_left(0.0f)
|
||||
, m_top(0.0f)
|
||||
@ -869,6 +884,9 @@ GLCanvas3D::LayersEditing::~LayersEditing()
|
||||
delete m_slicing_parameters;
|
||||
}
|
||||
|
||||
const float GLCanvas3D::LayersEditing::THICKNESS_BAR_WIDTH = 70.0f;
|
||||
const float GLCanvas3D::LayersEditing::THICKNESS_RESET_BUTTON_HEIGHT = 22.0f;
|
||||
|
||||
bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename)
|
||||
{
|
||||
if (!m_shader.init(vertex_shader_filename, fragment_shader_filename))
|
||||
@ -989,7 +1007,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas)
|
||||
float w = (float)cnv_size.get_width();
|
||||
float h = (float)cnv_size.get_height();
|
||||
|
||||
return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, 0.0f, w, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT);
|
||||
return Rect(w - thickness_bar_width(canvas), 0.0f, w, h - reset_button_height(canvas));
|
||||
}
|
||||
|
||||
Rect GLCanvas3D::LayersEditing::get_reset_rect_screen(const GLCanvas3D& canvas)
|
||||
@ -998,7 +1016,7 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_screen(const GLCanvas3D& canvas)
|
||||
float w = (float)cnv_size.get_width();
|
||||
float h = (float)cnv_size.get_height();
|
||||
|
||||
return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, w, h);
|
||||
return Rect(w - thickness_bar_width(canvas), h - reset_button_height(canvas), w, h);
|
||||
}
|
||||
|
||||
Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
|
||||
@ -1010,7 +1028,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
|
||||
float zoom = canvas.get_camera_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom);
|
||||
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom);
|
||||
}
|
||||
|
||||
Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas)
|
||||
@ -1022,7 +1040,7 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas
|
||||
float zoom = canvas.get_camera_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
|
||||
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
|
||||
}
|
||||
|
||||
|
||||
@ -1033,6 +1051,8 @@ bool GLCanvas3D::LayersEditing::_is_initialized() const
|
||||
|
||||
void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const
|
||||
{
|
||||
// TODO: do this with ImGui
|
||||
|
||||
if (m_tooltip_texture.get_id() == 0)
|
||||
{
|
||||
std::string filename = resources_dir() + "/icons/variable_layer_height_tooltip.png";
|
||||
@ -1040,6 +1060,15 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas
|
||||
return;
|
||||
}
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
const float scale = canvas.get_canvas_size().get_scale_factor();
|
||||
const float width = (float)m_tooltip_texture.get_width() * scale;
|
||||
const float height = (float)m_tooltip_texture.get_height() * scale;
|
||||
#else
|
||||
const float width = (float)m_tooltip_texture.get_width();
|
||||
const float height = (float)m_tooltip_texture.get_height();
|
||||
#endif
|
||||
|
||||
float zoom = canvas.get_camera_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
float gap = 10.0f * inv_zoom;
|
||||
@ -1047,9 +1076,9 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas
|
||||
float bar_left = bar_rect.get_left();
|
||||
float reset_bottom = reset_rect.get_bottom();
|
||||
|
||||
float l = bar_left - (float)m_tooltip_texture.get_width() * inv_zoom - gap;
|
||||
float l = bar_left - width * inv_zoom - gap;
|
||||
float r = bar_left - gap;
|
||||
float t = reset_bottom + (float)m_tooltip_texture.get_height() * inv_zoom + gap;
|
||||
float t = reset_bottom + height * inv_zoom + gap;
|
||||
float b = reset_bottom + gap;
|
||||
|
||||
GLTexture::render_texture(m_tooltip_texture.get_id(), l, r, b, t);
|
||||
@ -1078,11 +1107,6 @@ void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas
|
||||
// The shader requires the original model coordinates when rendering to the texture, so we pass it the unit matrix
|
||||
m_shader.set_uniform("volume_world_matrix", UNIT_MATRIX);
|
||||
|
||||
GLsizei w = (GLsizei)m_layers_texture.width;
|
||||
GLsizei h = (GLsizei)m_layers_texture.height;
|
||||
GLsizei half_w = w / 2;
|
||||
GLsizei half_h = h / 2;
|
||||
|
||||
::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
::glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
|
||||
|
||||
@ -1263,6 +1287,25 @@ void GLCanvas3D::LayersEditing::update_slicing_parameters()
|
||||
}
|
||||
}
|
||||
|
||||
float GLCanvas3D::LayersEditing::thickness_bar_width(const GLCanvas3D &canvas)
|
||||
{
|
||||
#if ENABLE_RETINA_GL
|
||||
return canvas.get_canvas_size().get_scale_factor() * THICKNESS_BAR_WIDTH;
|
||||
#else
|
||||
return THICKNESS_BAR_WIDTH;
|
||||
#endif
|
||||
}
|
||||
|
||||
float GLCanvas3D::LayersEditing::reset_button_height(const GLCanvas3D &canvas)
|
||||
{
|
||||
#if ENABLE_RETINA_GL
|
||||
return canvas.get_canvas_size().get_scale_factor() * THICKNESS_RESET_BUTTON_HEIGHT;
|
||||
#else
|
||||
return THICKNESS_RESET_BUTTON_HEIGHT;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
const Point GLCanvas3D::Mouse::Drag::Invalid_2D_Point(INT_MAX, INT_MAX);
|
||||
const Vec3d GLCanvas3D::Mouse::Drag::Invalid_3D_Point(DBL_MAX, DBL_MAX, DBL_MAX);
|
||||
#if ENABLE_MOVE_MIN_THRESHOLD
|
||||
@ -2816,14 +2859,11 @@ void GLCanvas3D::Selection::_ensure_on_bed()
|
||||
}
|
||||
#endif // ENABLE_ENSURE_ON_BED_WHILE_SCALING
|
||||
|
||||
const float GLCanvas3D::Gizmos::OverlayIconsScale = 1.0f;
|
||||
const float GLCanvas3D::Gizmos::OverlayBorder = 5.0f;
|
||||
const float GLCanvas3D::Gizmos::OverlayGapY = 5.0f * OverlayIconsScale;
|
||||
|
||||
GLCanvas3D::Gizmos::Gizmos()
|
||||
: m_enabled(false)
|
||||
, m_current(Undefined)
|
||||
{
|
||||
set_overlay_scale(1.0);
|
||||
}
|
||||
|
||||
GLCanvas3D::Gizmos::~Gizmos()
|
||||
@ -2927,6 +2967,13 @@ void GLCanvas3D::Gizmos::set_enabled(bool enable)
|
||||
m_enabled = enable;
|
||||
}
|
||||
|
||||
void GLCanvas3D::Gizmos::set_overlay_scale(float scale)
|
||||
{
|
||||
m_overlay_icons_scale = scale;
|
||||
m_overlay_border = 5.0f * scale;
|
||||
m_overlay_gap_y = 5.0f * scale;
|
||||
}
|
||||
|
||||
std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const GLCanvas3D::Selection& selection)
|
||||
{
|
||||
std::string name = "";
|
||||
@ -2936,22 +2983,22 @@ std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, con
|
||||
|
||||
float cnv_h = (float)canvas.get_canvas_size().get_height();
|
||||
float height = _get_total_overlay_height();
|
||||
float top_y = 0.5f * (cnv_h - height) + OverlayBorder;
|
||||
float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
|
||||
for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
|
||||
{
|
||||
if ((it->second == nullptr) || !it->second->is_selectable())
|
||||
continue;
|
||||
|
||||
float icon_size = (float)it->second->get_textures_size() * OverlayIconsScale;
|
||||
float icon_size = (float)it->second->get_textures_size() * m_overlay_icons_scale;
|
||||
|
||||
bool inside = (OverlayBorder <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= OverlayBorder + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size);
|
||||
bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size);
|
||||
if (inside)
|
||||
name = it->second->get_name();
|
||||
|
||||
if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On))
|
||||
it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
|
||||
|
||||
top_y += (icon_size + OverlayGapY);
|
||||
top_y += (icon_size + m_overlay_gap_y);
|
||||
}
|
||||
|
||||
return name;
|
||||
@ -2964,15 +3011,15 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec
|
||||
|
||||
float cnv_h = (float)canvas.get_canvas_size().get_height();
|
||||
float height = _get_total_overlay_height();
|
||||
float top_y = 0.5f * (cnv_h - height) + OverlayBorder;
|
||||
float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
|
||||
for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
|
||||
{
|
||||
if ((it->second == nullptr) || !it->second->is_selectable())
|
||||
continue;
|
||||
|
||||
float icon_size = (float)it->second->get_textures_size() * OverlayIconsScale;
|
||||
float icon_size = (float)it->second->get_textures_size() * m_overlay_icons_scale;
|
||||
|
||||
bool inside = (OverlayBorder <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= OverlayBorder + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size);
|
||||
bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size);
|
||||
if (it->second->is_activable(selection) && inside)
|
||||
{
|
||||
if ((it->second->get_state() == GLGizmoBase::On))
|
||||
@ -2989,7 +3036,7 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec
|
||||
else
|
||||
it->second->set_state(GLGizmoBase::Off);
|
||||
|
||||
top_y += (icon_size + OverlayGapY);
|
||||
top_y += (icon_size + m_overlay_gap_y);
|
||||
}
|
||||
|
||||
GizmosMap::iterator it = m_gizmos.find(m_current);
|
||||
@ -3061,18 +3108,18 @@ bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const
|
||||
|
||||
float cnv_h = (float)canvas.get_canvas_size().get_height();
|
||||
float height = _get_total_overlay_height();
|
||||
float top_y = 0.5f * (cnv_h - height) + OverlayBorder;
|
||||
float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
|
||||
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
|
||||
{
|
||||
if ((it->second == nullptr) || !it->second->is_selectable())
|
||||
continue;
|
||||
|
||||
float icon_size = (float)it->second->get_textures_size() * OverlayIconsScale;
|
||||
float icon_size = (float)it->second->get_textures_size() * m_overlay_icons_scale;
|
||||
|
||||
if ((OverlayBorder <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= OverlayBorder + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size))
|
||||
if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size))
|
||||
return true;
|
||||
|
||||
top_y += (icon_size + OverlayGapY);
|
||||
top_y += (icon_size + m_overlay_gap_y);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -3345,7 +3392,7 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
float height = _get_total_overlay_height();
|
||||
float scaled_border = OverlayBorder * inv_zoom;
|
||||
float scaled_border = m_overlay_border * inv_zoom;
|
||||
|
||||
float top_x = (-0.5f * cnv_w) * inv_zoom;
|
||||
float top_y = (0.5f * height) * inv_zoom;
|
||||
@ -3390,7 +3437,7 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
|
||||
bg_uv_left = bg_uv_i_left;
|
||||
bg_i_left = bg_left;
|
||||
|
||||
if ((OverlayBorder > 0) && (bg_uv_top != bg_uv_i_top))
|
||||
if ((m_overlay_border > 0) && (bg_uv_top != bg_uv_i_top))
|
||||
{
|
||||
if (bg_uv_left != bg_uv_i_left)
|
||||
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } });
|
||||
@ -3401,15 +3448,15 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
|
||||
GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } });
|
||||
}
|
||||
|
||||
if ((OverlayBorder > 0) && (bg_uv_left != bg_uv_i_left))
|
||||
if ((m_overlay_border > 0) && (bg_uv_left != bg_uv_i_left))
|
||||
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } });
|
||||
|
||||
GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } });
|
||||
|
||||
if ((OverlayBorder > 0) && (bg_uv_right != bg_uv_i_right))
|
||||
if ((m_overlay_border > 0) && (bg_uv_right != bg_uv_i_right))
|
||||
GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } });
|
||||
|
||||
if ((OverlayBorder > 0) && (bg_uv_bottom != bg_uv_i_bottom))
|
||||
if ((m_overlay_border > 0) && (bg_uv_bottom != bg_uv_i_bottom))
|
||||
{
|
||||
if (bg_uv_left != bg_uv_i_left)
|
||||
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } });
|
||||
@ -3421,19 +3468,19 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
|
||||
}
|
||||
}
|
||||
|
||||
top_x += OverlayBorder * inv_zoom;
|
||||
top_y -= OverlayBorder * inv_zoom;
|
||||
float scaled_gap_y = OverlayGapY * inv_zoom;
|
||||
top_x += m_overlay_border * inv_zoom;
|
||||
top_y -= m_overlay_border * inv_zoom;
|
||||
float scaled_gap_y = m_overlay_gap_y * inv_zoom;
|
||||
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
|
||||
{
|
||||
if ((it->second == nullptr) || !it->second->is_selectable())
|
||||
continue;
|
||||
|
||||
float icon_size = (float)it->second->get_textures_size() * OverlayIconsScale * inv_zoom;
|
||||
float icon_size = (float)it->second->get_textures_size() * m_overlay_icons_scale * inv_zoom;
|
||||
GLTexture::render_texture(it->second->get_texture_id(), top_x, top_x + icon_size, top_y - icon_size, top_y);
|
||||
#if ENABLE_IMGUI
|
||||
if (it->second->get_state() == GLGizmoBase::On)
|
||||
it->second->render_input_window(2.0f * OverlayBorder + icon_size * zoom, 0.5f * cnv_h - top_y * zoom, selection);
|
||||
it->second->render_input_window(2.0f * m_overlay_border + icon_size * zoom, 0.5f * cnv_h - top_y * zoom, selection);
|
||||
#endif // ENABLE_IMGUI
|
||||
top_y -= (icon_size + scaled_gap_y);
|
||||
}
|
||||
@ -3448,17 +3495,17 @@ void GLCanvas3D::Gizmos::_render_current_gizmo(const GLCanvas3D::Selection& sele
|
||||
|
||||
float GLCanvas3D::Gizmos::_get_total_overlay_height() const
|
||||
{
|
||||
float height = 2.0f * OverlayBorder;
|
||||
float height = 2.0f * m_overlay_border;
|
||||
|
||||
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
|
||||
{
|
||||
if ((it->second == nullptr) || !it->second->is_selectable())
|
||||
continue;
|
||||
|
||||
height += (float)it->second->get_textures_size() * OverlayIconsScale + OverlayGapY;
|
||||
height += (float)it->second->get_textures_size() * m_overlay_icons_scale + m_overlay_gap_y;
|
||||
}
|
||||
|
||||
return height - OverlayGapY;
|
||||
return height - m_overlay_gap_y;
|
||||
}
|
||||
|
||||
float GLCanvas3D::Gizmos::_get_total_overlay_width() const
|
||||
@ -3469,10 +3516,10 @@ float GLCanvas3D::Gizmos::_get_total_overlay_width() const
|
||||
if ((it->second == nullptr) || !it->second->is_selectable())
|
||||
continue;
|
||||
|
||||
max_icon_width = std::max(max_icon_width, (float)it->second->get_textures_size() * OverlayIconsScale);
|
||||
max_icon_width = std::max(max_icon_width, (float)it->second->get_textures_size() * m_overlay_icons_scale);
|
||||
}
|
||||
|
||||
return max_icon_width + 2.0f * OverlayBorder;
|
||||
return max_icon_width + 2.0f * m_overlay_border;
|
||||
}
|
||||
|
||||
GLGizmoBase* GLCanvas3D::Gizmos::_get_current() const
|
||||
@ -3491,7 +3538,7 @@ GLCanvas3D::WarningTexture::WarningTexture()
|
||||
{
|
||||
}
|
||||
|
||||
bool GLCanvas3D::WarningTexture::generate(const std::string& msg)
|
||||
bool GLCanvas3D::WarningTexture::generate(const std::string& msg, const GLCanvas3D& canvas)
|
||||
{
|
||||
reset();
|
||||
|
||||
@ -3500,7 +3547,8 @@ bool GLCanvas3D::WarningTexture::generate(const std::string& msg)
|
||||
|
||||
wxMemoryDC memDC;
|
||||
// select default font
|
||||
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
const float scale = canvas.get_canvas_size().get_scale_factor();
|
||||
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale);
|
||||
font.MakeLarger();
|
||||
font.MakeBold();
|
||||
memDC.SetFont(font);
|
||||
@ -3648,9 +3696,18 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
|
||||
wxMemoryDC memDC;
|
||||
wxMemoryDC mask_memDC;
|
||||
|
||||
// calculate scaling
|
||||
const float scale = canvas.get_canvas_size().get_scale_factor();
|
||||
const int scaled_square = std::floor((float)Px_Square * scale);
|
||||
const int scaled_title_offset = Px_Title_Offset * scale;
|
||||
const int scaled_text_offset = Px_Text_Offset * scale;
|
||||
const int scaled_square_contour = Px_Square_Contour * scale;
|
||||
const int scaled_border = Px_Border * scale;
|
||||
|
||||
// select default font
|
||||
memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
|
||||
mask_memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
|
||||
const wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale);
|
||||
memDC.SetFont(font);
|
||||
mask_memDC.SetFont(font);
|
||||
|
||||
// calculates texture size
|
||||
wxCoord w, h;
|
||||
@ -3667,10 +3724,10 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
|
||||
max_text_height = std::max(max_text_height, (int)h);
|
||||
}
|
||||
|
||||
m_original_width = std::max(2 * Px_Border + title_width, 2 * (Px_Border + Px_Square_Contour) + Px_Square + Px_Text_Offset + max_text_width);
|
||||
m_original_height = 2 * (Px_Border + Px_Square_Contour) + title_height + Px_Title_Offset + items_count * Px_Square;
|
||||
m_original_width = std::max(2 * scaled_border + title_width, 2 * (scaled_border + scaled_square_contour) + scaled_square + scaled_text_offset + max_text_width);
|
||||
m_original_height = 2 * (scaled_border + scaled_square_contour) + title_height + scaled_title_offset + items_count * scaled_square;
|
||||
if (items_count > 1)
|
||||
m_original_height += (items_count - 1) * Px_Square_Contour;
|
||||
m_original_height += (items_count - 1) * scaled_square_contour;
|
||||
|
||||
int pow_of_two_size = (int)next_highest_power_of_2(std::max<uint32_t>(m_original_width, m_original_height));
|
||||
|
||||
@ -3694,8 +3751,8 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
|
||||
memDC.SetTextForeground(use_error_colors ? *wxWHITE : *wxBLACK);
|
||||
mask_memDC.SetTextForeground(*wxWHITE);
|
||||
|
||||
int title_x = Px_Border;
|
||||
int title_y = Px_Border;
|
||||
int title_x = scaled_border;
|
||||
int title_y = scaled_border;
|
||||
memDC.DrawText(title, title_x, title_y);
|
||||
mask_memDC.DrawText(title, title_x, title_y);
|
||||
|
||||
@ -3703,12 +3760,12 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
|
||||
mask_memDC.SetBrush(wxBrush(*wxWHITE));
|
||||
|
||||
// draw icons contours as background
|
||||
int squares_contour_x = Px_Border;
|
||||
int squares_contour_y = Px_Border + title_height + Px_Title_Offset;
|
||||
int squares_contour_width = Px_Square + 2 * Px_Square_Contour;
|
||||
int squares_contour_height = items_count * Px_Square + 2 * Px_Square_Contour;
|
||||
int squares_contour_x = scaled_border;
|
||||
int squares_contour_y = scaled_border + title_height + scaled_title_offset;
|
||||
int squares_contour_width = scaled_square + 2 * scaled_square_contour;
|
||||
int squares_contour_height = items_count * scaled_square + 2 * scaled_square_contour;
|
||||
if (items_count > 1)
|
||||
squares_contour_height += (items_count - 1) * Px_Square_Contour;
|
||||
squares_contour_height += (items_count - 1) * scaled_square_contour;
|
||||
|
||||
wxColour color(Squares_Border_Color[0], Squares_Border_Color[1], Squares_Border_Color[2]);
|
||||
wxPen pen(color);
|
||||
@ -3719,15 +3776,15 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
|
||||
mask_memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height));
|
||||
|
||||
// draw items (colored icon + text)
|
||||
int icon_x = squares_contour_x + Px_Square_Contour;
|
||||
int icon_x = squares_contour_x + scaled_square_contour;
|
||||
int icon_x_inner = icon_x + 1;
|
||||
int icon_y = squares_contour_y + Px_Square_Contour;
|
||||
int icon_y_step = Px_Square + Px_Square_Contour;
|
||||
int icon_y = squares_contour_y + scaled_square_contour;
|
||||
int icon_y_step = scaled_square + scaled_square_contour;
|
||||
|
||||
int text_x = icon_x + Px_Square + Px_Text_Offset;
|
||||
int text_y_offset = (Px_Square - max_text_height) / 2;
|
||||
int text_x = icon_x + scaled_square + scaled_text_offset;
|
||||
int text_y_offset = (scaled_square - max_text_height) / 2;
|
||||
|
||||
int px_inner_square = Px_Square - 2;
|
||||
int px_inner_square = scaled_square - 2;
|
||||
|
||||
for (const GCodePreviewData::LegendItem& item : items)
|
||||
{
|
||||
@ -3741,7 +3798,7 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
|
||||
brush.SetColour(color);
|
||||
memDC.SetPen(pen);
|
||||
memDC.SetBrush(brush);
|
||||
memDC.DrawRectangle(wxRect(icon_x, icon_y, Px_Square, Px_Square));
|
||||
memDC.DrawRectangle(wxRect(icon_x, icon_y, scaled_square, scaled_square));
|
||||
|
||||
// draw icon interior
|
||||
color.Set(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2], item_color_bytes[3]);
|
||||
@ -3850,6 +3907,9 @@ wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
|
||||
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
|
||||
: m_canvas(canvas)
|
||||
, m_context(nullptr)
|
||||
#if ENABLE_RETINA_GL
|
||||
, m_retina_helper(nullptr)
|
||||
#endif
|
||||
, m_in_render(false)
|
||||
, m_toolbar(GLToolbar::Normal)
|
||||
, m_view_toolbar(nullptr)
|
||||
@ -3889,6 +3949,15 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
|
||||
m_context = new wxGLContext(m_canvas);
|
||||
#endif // !ENABLE_USE_UNIQUE_GLCONTEXT
|
||||
m_timer.SetOwner(m_canvas);
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
m_retina_helper.reset(new RetinaHelper(canvas));
|
||||
|
||||
const bool use_retina = wxGetApp().app_config->get("use_retina_opengl") == "1";
|
||||
BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Use Retina OpenGL: " << use_retina;
|
||||
m_retina_helper->set_use_retina(use_retina);
|
||||
BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Scaling factor: " << m_retina_helper->get_scale_factor();
|
||||
#endif
|
||||
}
|
||||
|
||||
m_selection.set_volumes(&m_volumes.volumes);
|
||||
@ -5063,6 +5132,12 @@ void GLCanvas3D::on_timer(wxTimerEvent& evt)
|
||||
|
||||
void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
{
|
||||
#if ENABLE_RETINA_GL
|
||||
const float scale = m_retina_helper->get_scale_factor();
|
||||
evt.SetX(evt.GetX() * scale);
|
||||
evt.SetY(evt.GetY() * scale);
|
||||
#endif
|
||||
|
||||
#if ENABLE_IMGUI
|
||||
auto imgui = wxGetApp().imgui();
|
||||
if (imgui->update_mouse_data(evt)) {
|
||||
@ -5552,7 +5627,15 @@ Size GLCanvas3D::get_canvas_size() const
|
||||
if (m_canvas != nullptr)
|
||||
m_canvas->GetSize(&w, &h);
|
||||
|
||||
return Size(w, h);
|
||||
#if ENABLE_RETINA_GL
|
||||
const float factor = m_retina_helper->get_scale_factor();
|
||||
w *= factor;
|
||||
h *= factor;
|
||||
#else
|
||||
const float factor = 1.0;
|
||||
#endif
|
||||
|
||||
return Size(w, h, factor);
|
||||
}
|
||||
|
||||
Point GLCanvas3D::get_local_mouse_position() const
|
||||
@ -6019,6 +6102,9 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
|
||||
|
||||
#if ENABLE_IMGUI
|
||||
wxGetApp().imgui()->set_display_size((float)w, (float)h);
|
||||
#if ENABLE_RETINA_GL
|
||||
wxGetApp().imgui()->set_style_scaling(m_retina_helper->get_scale_factor());
|
||||
#endif // ENABLE_RETINA_GL
|
||||
#endif // ENABLE_IMGUI
|
||||
|
||||
// ensures that this canvas is current
|
||||
@ -6497,19 +6583,29 @@ void GLCanvas3D::_render_current_gizmo() const
|
||||
|
||||
void GLCanvas3D::_render_gizmos_overlay() const
|
||||
{
|
||||
#if ENABLE_RETINA_GL
|
||||
m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor());
|
||||
#endif
|
||||
m_gizmos.render_overlay(*this, m_selection);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_toolbar() const
|
||||
{
|
||||
#if ENABLE_RETINA_GL
|
||||
m_toolbar.set_icons_scale(m_retina_helper->get_scale_factor());
|
||||
#endif
|
||||
m_toolbar.render(*this);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_view_toolbar() const
|
||||
{
|
||||
if (m_view_toolbar != nullptr)
|
||||
if (m_view_toolbar != nullptr) {
|
||||
#if ENABLE_RETINA_GL
|
||||
m_view_toolbar->set_icons_scale(m_retina_helper->get_scale_factor());
|
||||
#endif
|
||||
m_view_toolbar->render(*this);
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_SHOW_CAMERA_TARGET
|
||||
void GLCanvas3D::_render_camera_target() const
|
||||
@ -8224,7 +8320,7 @@ void GLCanvas3D::_generate_warning_texture(const std::string& msg)
|
||||
return;
|
||||
#endif // !ENABLE_USE_UNIQUE_GLCONTEXT
|
||||
|
||||
m_warning_texture.generate(msg);
|
||||
m_warning_texture.generate(msg, *this);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_reset_warning_texture()
|
||||
@ -8254,6 +8350,10 @@ void GLCanvas3D::_resize_toolbars() const
|
||||
float zoom = get_camera_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
m_toolbar.set_icons_scale(m_retina_helper->get_scale_factor());
|
||||
#endif
|
||||
|
||||
GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation();
|
||||
|
||||
switch (m_toolbar.get_layout_type())
|
||||
@ -8297,6 +8397,10 @@ void GLCanvas3D::_resize_toolbars() const
|
||||
|
||||
if (m_view_toolbar != nullptr)
|
||||
{
|
||||
#if ENABLE_RETINA_GL
|
||||
m_view_toolbar->set_icons_scale(m_retina_helper->get_scale_factor());
|
||||
#endif
|
||||
|
||||
// places the toolbar on the bottom-left corner of the 3d scene
|
||||
float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar->get_height()) * inv_zoom;
|
||||
float left = -0.5f * (float)cnv_size.get_width() * inv_zoom;
|
||||
|
@ -2,7 +2,9 @@
|
||||
#define slic3r_GLCanvas3D_hpp_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <memory>
|
||||
|
||||
#include "libslic3r/Technologies.hpp"
|
||||
#include "3DScene.hpp"
|
||||
#include "GLToolbar.hpp"
|
||||
#include "Event.hpp"
|
||||
@ -20,6 +22,9 @@ class wxTimerEvent;
|
||||
class wxPaintEvent;
|
||||
class wxGLCanvas;
|
||||
|
||||
// Support for Retina OpenGL on Mac OS
|
||||
#define ENABLE_RETINA_GL __APPLE__
|
||||
|
||||
class GLUquadric;
|
||||
typedef class GLUquadric GLUquadricObj;
|
||||
|
||||
@ -36,6 +41,10 @@ namespace GUI {
|
||||
|
||||
class GLGizmoBase;
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
class RetinaHelper;
|
||||
#endif
|
||||
|
||||
class GeometryBuffer
|
||||
{
|
||||
std::vector<float> m_vertices;
|
||||
@ -55,16 +64,20 @@ class Size
|
||||
{
|
||||
int m_width;
|
||||
int m_height;
|
||||
float m_scale_factor;
|
||||
|
||||
public:
|
||||
Size();
|
||||
Size(int width, int height);
|
||||
Size(int width, int height, float scale_factor = 1.0);
|
||||
|
||||
int get_width() const;
|
||||
void set_width(int width);
|
||||
|
||||
int get_height() const;
|
||||
void set_height(int height);
|
||||
|
||||
int get_scale_factor() const;
|
||||
void set_scale_factor(int height);
|
||||
};
|
||||
|
||||
class Rect
|
||||
@ -297,6 +310,9 @@ class GLCanvas3D
|
||||
};
|
||||
|
||||
private:
|
||||
static const float THICKNESS_BAR_WIDTH;
|
||||
static const float THICKNESS_RESET_BUTTON_HEIGHT;
|
||||
|
||||
bool m_use_legacy_opengl;
|
||||
bool m_enabled;
|
||||
Shader m_shader;
|
||||
@ -380,6 +396,9 @@ class GLCanvas3D
|
||||
void _render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const;
|
||||
void _render_profile(const Rect& bar_rect) const;
|
||||
void update_slicing_parameters();
|
||||
|
||||
static float thickness_bar_width(const GLCanvas3D &canvas);
|
||||
static float reset_button_height(const GLCanvas3D &canvas);
|
||||
};
|
||||
|
||||
struct Mouse
|
||||
@ -690,10 +709,6 @@ public:
|
||||
private:
|
||||
class Gizmos
|
||||
{
|
||||
static const float OverlayIconsScale;
|
||||
static const float OverlayBorder;
|
||||
static const float OverlayGapY;
|
||||
|
||||
public:
|
||||
enum EType : unsigned char
|
||||
{
|
||||
@ -714,6 +729,10 @@ private:
|
||||
BackgroundTexture m_background_texture;
|
||||
EType m_current;
|
||||
|
||||
float m_overlay_icons_scale;
|
||||
float m_overlay_border;
|
||||
float m_overlay_gap_y;
|
||||
|
||||
public:
|
||||
Gizmos();
|
||||
~Gizmos();
|
||||
@ -723,6 +742,8 @@ private:
|
||||
bool is_enabled() const;
|
||||
void set_enabled(bool enable);
|
||||
|
||||
void set_overlay_scale(float scale);
|
||||
|
||||
std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection);
|
||||
void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection);
|
||||
void update_on_off_state(const Selection& selection);
|
||||
@ -812,7 +833,7 @@ private:
|
||||
public:
|
||||
WarningTexture();
|
||||
|
||||
bool generate(const std::string& msg);
|
||||
bool generate(const std::string& msg, const GLCanvas3D& canvas);
|
||||
|
||||
void render(const GLCanvas3D& canvas) const;
|
||||
};
|
||||
@ -842,6 +863,9 @@ private:
|
||||
|
||||
wxGLCanvas* m_canvas;
|
||||
wxGLContext* m_context;
|
||||
#if ENABLE_RETINA_GL
|
||||
std::unique_ptr<RetinaHelper> m_retina_helper;
|
||||
#endif
|
||||
bool m_in_render;
|
||||
LegendTexture m_legend_texture;
|
||||
WarningTexture m_warning_texture;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
@ -24,6 +26,7 @@ namespace GUI {
|
||||
|
||||
ImGuiWrapper::ImGuiWrapper()
|
||||
: m_font_texture(0)
|
||||
, m_style_scaling(1.0)
|
||||
, m_mouse_buttons(0)
|
||||
, m_disabled(false)
|
||||
{
|
||||
@ -39,18 +42,9 @@ bool ImGuiWrapper::init()
|
||||
{
|
||||
ImGui::CreateContext();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf").c_str(), 18.0f);
|
||||
if (font == nullptr) {
|
||||
font = io.Fonts->AddFontDefault();
|
||||
if (font == nullptr)
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
m_fonts.insert(FontsMap::value_type("Noto Sans Regular 18", font));
|
||||
}
|
||||
init_default_font(m_style_scaling);
|
||||
|
||||
io.IniFilename = nullptr;
|
||||
ImGui::GetIO().IniFilename = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -62,6 +56,15 @@ void ImGuiWrapper::set_display_size(float w, float h)
|
||||
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void ImGuiWrapper::set_style_scaling(float scaling)
|
||||
{
|
||||
if (!std::isnan(scaling) && !std::isinf(scaling) && scaling != m_style_scaling) {
|
||||
ImGui::GetStyle().ScaleAllSizes(scaling / m_style_scaling);
|
||||
init_default_font(scaling);
|
||||
m_style_scaling = scaling;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::update_mouse_data(wxMouseEvent& evt)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@ -198,6 +201,21 @@ bool ImGuiWrapper::want_any_input() const
|
||||
return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput;
|
||||
}
|
||||
|
||||
void ImGuiWrapper::init_default_font(float scaling)
|
||||
{
|
||||
static const float font_size = 18.0f;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->Clear();
|
||||
ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf").c_str(), font_size * scaling);
|
||||
if (font == nullptr) {
|
||||
font = io.Fonts->AddFontDefault();
|
||||
if (font == nullptr) {
|
||||
throw std::runtime_error("ImGui: Could not load deafult font");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiWrapper::create_device_objects()
|
||||
{
|
||||
create_fonts_texture();
|
||||
|
@ -21,6 +21,7 @@ class ImGuiWrapper
|
||||
|
||||
FontsMap m_fonts;
|
||||
unsigned m_font_texture;
|
||||
float m_style_scaling;
|
||||
unsigned m_mouse_buttons;
|
||||
bool m_disabled;
|
||||
|
||||
@ -32,6 +33,7 @@ public:
|
||||
void read_glsl_version();
|
||||
|
||||
void set_display_size(float w, float h);
|
||||
void set_style_scaling(float scaling);
|
||||
bool update_mouse_data(wxMouseEvent &evt);
|
||||
|
||||
void new_frame();
|
||||
@ -58,6 +60,7 @@ public:
|
||||
bool want_text_input() const;
|
||||
bool want_any_input() const;
|
||||
private:
|
||||
void init_default_font(float scaling);
|
||||
void create_device_objects();
|
||||
void create_fonts_texture();
|
||||
void render_draw_data(ImDrawData *draw_data);
|
||||
|
@ -87,6 +87,7 @@ void PreferencesDialog::build()
|
||||
option = Option (def,"show_incompatible_presets");
|
||||
m_optgroup->append_single_option_line(option);
|
||||
|
||||
// TODO: remove?
|
||||
def.label = L("Use legacy OpenGL 1.1 rendering");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("If you have rendering issues caused by a buggy OpenGL 2.0 driver, "
|
||||
@ -96,6 +97,16 @@ void PreferencesDialog::build()
|
||||
option = Option (def,"use_legacy_opengl");
|
||||
m_optgroup->append_single_option_line(option);
|
||||
|
||||
#if __APPLE__
|
||||
def.label = L("Use Retina resolution for the 3D scene");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("If enabled, the 3D scene will be rendered in Retina resolution. "
|
||||
"If you are experiencing 3D performance problems, disabling this option may help.");
|
||||
def.default_value = new ConfigOptionBool{ app_config->get("use_retina_opengl") == "1" };
|
||||
option = Option (def, "use_retina_opengl");
|
||||
m_optgroup->append_single_option_line(option);
|
||||
#endif
|
||||
|
||||
auto sizer = new wxBoxSizer(wxVERTICAL);
|
||||
sizer->Add(m_optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
|
||||
|
||||
@ -111,7 +122,8 @@ void PreferencesDialog::build()
|
||||
void PreferencesDialog::accept()
|
||||
{
|
||||
if (m_values.find("no_defaults") != m_values.end() ||
|
||||
m_values.find("use_legacy_opengl")!= m_values.end()) {
|
||||
m_values.find("use_legacy_opengl") != m_values.end() ||
|
||||
m_values.find("use_retina_opengl") != m_values.end()) {
|
||||
warning_catcher(this, _(L("You need to restart Slic3r to make the changes effective.")));
|
||||
}
|
||||
|
||||
|
29
src/slic3r/Utils/RetinaHelper.hpp
Normal file
29
src/slic3r/Utils/RetinaHelper.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef slic3r_RetinaHelper_hpp_
|
||||
#define slic3r_RetinaHelper_hpp_
|
||||
|
||||
class wxWindow;
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class RetinaHelper
|
||||
{
|
||||
public:
|
||||
RetinaHelper(wxWindow* window);
|
||||
~RetinaHelper();
|
||||
|
||||
void set_use_retina(bool value);
|
||||
bool get_use_retina();
|
||||
float get_scale_factor();
|
||||
|
||||
private:
|
||||
wxWindow* m_window;
|
||||
void* m_self;
|
||||
};
|
||||
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // RetinaHelper_h
|
15
src/slic3r/Utils/RetinaHelperImpl.hmm
Normal file
15
src/slic3r/Utils/RetinaHelperImpl.hmm
Normal file
@ -0,0 +1,15 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
class wxEvtHandler;
|
||||
|
||||
@interface RetinaHelperImpl : NSObject
|
||||
{
|
||||
NSView *view;
|
||||
wxEvtHandler* handler;
|
||||
}
|
||||
|
||||
-(id)initWithView:(NSView *)view handler:(wxEvtHandler *)handler;
|
||||
-(void)setViewWantsBestResolutionOpenGLSurface:(BOOL)value;
|
||||
-(BOOL)getViewWantsBestResolutionOpenGLSurface;
|
||||
-(float)getBackingScaleFactor;
|
||||
@end
|
111
src/slic3r/Utils/RetinaHelperImpl.mm
Normal file
111
src/slic3r/Utils/RetinaHelperImpl.mm
Normal file
@ -0,0 +1,111 @@
|
||||
// The RetinaHelper was originally written by Andreas Stahl, 2013
|
||||
|
||||
#import "RetinaHelper.hpp"
|
||||
#import "RetinaHelperImpl.hmm"
|
||||
#import <OpenGL/OpenGL.h>
|
||||
|
||||
#import "wx/window.h"
|
||||
|
||||
@implementation RetinaHelperImpl
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
RetinaHelper::RetinaHelper(wxWindow* window) :
|
||||
m_window(window)
|
||||
{
|
||||
m_self = nullptr;
|
||||
m_self = [[RetinaHelperImpl alloc] initWithView:window->GetHandle() handler:window->GetEventHandler()];
|
||||
}
|
||||
|
||||
RetinaHelper::~RetinaHelper()
|
||||
{
|
||||
[m_self release];
|
||||
}
|
||||
|
||||
void RetinaHelper::set_use_retina(bool aValue)
|
||||
{
|
||||
[(id)m_self setViewWantsBestResolutionOpenGLSurface:aValue];
|
||||
}
|
||||
|
||||
bool RetinaHelper::get_use_retina()
|
||||
{
|
||||
return [(id)m_self getViewWantsBestResolutionOpenGLSurface];
|
||||
}
|
||||
|
||||
float RetinaHelper::get_scale_factor()
|
||||
{
|
||||
return [(id)m_self getViewWantsBestResolutionOpenGLSurface] ? [(id)m_self getBackingScaleFactor] : 1.0f;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
|
||||
-(id)initWithView:(NSView *)aView handler:(wxEvtHandler *)aHandler
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
handler = aHandler;
|
||||
view = aView;
|
||||
// register for backing change notifications
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
if (nc) {
|
||||
[nc addObserver:self selector:@selector(windowDidChangeBackingProperties:)
|
||||
name:NSWindowDidChangeBackingPropertiesNotification object:nil];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) dealloc
|
||||
{
|
||||
// unregister from all notifications
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
if (nc) {
|
||||
[nc removeObserver:self];
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)setViewWantsBestResolutionOpenGLSurface:(BOOL)value
|
||||
{
|
||||
[view setWantsBestResolutionOpenGLSurface:value];
|
||||
}
|
||||
|
||||
-(BOOL)getViewWantsBestResolutionOpenGLSurface
|
||||
{
|
||||
return [view wantsBestResolutionOpenGLSurface];
|
||||
}
|
||||
|
||||
-(float)getBackingScaleFactor
|
||||
{
|
||||
return [[view window] backingScaleFactor];
|
||||
}
|
||||
|
||||
- (void)windowDidChangeBackingProperties:(NSNotification *)notification
|
||||
{
|
||||
NSWindow *theWindow = (NSWindow *)[notification object];
|
||||
|
||||
if (theWindow == [view window]) {
|
||||
CGFloat newBackingScaleFactor = [theWindow backingScaleFactor];
|
||||
CGFloat oldBackingScaleFactor = [[[notification userInfo]
|
||||
objectForKey:@"NSBackingPropertyOldScaleFactorKey"]
|
||||
doubleValue];
|
||||
|
||||
if (newBackingScaleFactor != oldBackingScaleFactor) {
|
||||
// generate a wx resize event and pass it to the handler's queue
|
||||
wxSizeEvent *event = new wxSizeEvent();
|
||||
// use the following line if this resize event should have the physical pixel resolution
|
||||
// but that is not recommended, because ordinary resize events won't do so either
|
||||
// which would necessitate a case-by-case switch in the resize handler method.
|
||||
// NSRect nsrect = [view convertRectToBacking:[view bounds]];
|
||||
NSRect nsrect = [view bounds];
|
||||
wxRect rect = wxRect(nsrect.origin.x, nsrect.origin.y, nsrect.size.width, nsrect.size.height);
|
||||
event->SetRect(rect);
|
||||
event->SetSize(rect.GetSize());
|
||||
handler->QueueEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@end
|
Loading…
Reference in New Issue
Block a user