[Gui] allow to specify font for NaviCube

- the problem is that depending on the OS, the font of the NaviCube is hardly readable. For example under Windows 11, there is no Helvetica font and therefore an ugly replacement font is used. On some laptop screens the font is too large or too small etc.
- as solution this PR add the change the NaviCube's font and font size

- the PR also fixes an issue that the position (corner) of the NaviCube was not respected when the NaviCube is recreated. This fix is necessary for the PR therefore included

- as by-product the PR fixes #8082 since every change in the preferences now properly recreates the NaviCube

- the PR also removes the strange and unused class "HuuhaaClassPy"
This commit is contained in:
Uwe
2023-01-20 07:10:57 +01:00
parent e07af014e6
commit 588f2d50e4
6 changed files with 205 additions and 44 deletions

View File

@@ -36,6 +36,7 @@
#include "DlgSettingsNavigation.h"
#include "ui_DlgSettingsNavigation.h"
#include "MainWindow.h"
#include "NaviCube.h"
#include "NavigationStyle.h"
#include "View3DInventor.h"
#include "View3DInventorViewer.h"
@@ -72,7 +73,8 @@ void DlgSettingsNavigation::saveSettings()
// where we set some attributes afterwards
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/View");
QVariant data = ui->comboNavigationStyle->itemData(ui->comboNavigationStyle->currentIndex(), Qt::UserRole);
QVariant data = ui->comboNavigationStyle->itemData(ui->comboNavigationStyle->currentIndex(),
Qt::UserRole);
hGrp->SetASCII("NavigationStyle", (const char*)data.toByteArray());
int index = ui->comboOrbitStyle->currentIndex();
@@ -90,11 +92,13 @@ void DlgSettingsNavigation::saveSettings()
ui->naviCubeCorner->onSave();
ui->naviCubeToNearest->onSave();
ui->prefCubeSize->onSave();
ui->naviCubeFontSize->onSave();
bool showNaviCube = ui->groupBoxNaviCube->isChecked();
hGrp->SetBool("ShowNaviCube", showNaviCube);
QVariant camera = ui->comboNewDocView->itemData(ui->comboNewDocView->currentIndex(), Qt::UserRole);
QVariant camera = ui->comboNewDocView->itemData(ui->comboNewDocView->currentIndex(),
Qt::UserRole);
hGrp->SetASCII("NewDocumentCameraOrientation", (const char*)camera.toByteArray());
if (camera == QByteArray("Custom")) {
ParameterGrp::handle hCustom = hGrp->GetGroup("Custom");
@@ -103,6 +107,19 @@ void DlgSettingsNavigation::saveSettings()
hCustom->SetFloat("Q2", q2);
hCustom->SetFloat("Q3", q3);
}
hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/NaviCube");
hGrp->SetASCII("FontString", ui->naviCubeFontName->currentText().toLatin1());
// we changed the cube's layout, therefore we must re-initialize it
// by deleting and the subsequently recreating
auto mdi = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
if (mdi) {
auto currentView = mdi->getViewer();
currentView->deleteNavigationCube();
currentView->createNavigationCube();
}
}
void DlgSettingsNavigation::loadSettings()
@@ -117,6 +134,7 @@ void DlgSettingsNavigation::loadSettings()
ui->naviCubeCorner->onRestore();
ui->naviCubeToNearest->onRestore();
ui->prefCubeSize->onRestore();
ui->naviCubeFontSize->onRestore();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/View");
@@ -157,6 +175,24 @@ void DlgSettingsNavigation::loadSettings()
connect(ui->comboNewDocView, SIGNAL(currentIndexChanged(int)),
this, SLOT(onNewDocViewChanged(int)));
// fill up font styles
hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/NaviCube");
QByteArray defaultSansserifFont = NaviCube::getDefaultSansserifFont().family().toLatin1();
// we purposely allow all available fonts on the system
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QStringList familyNames = QFontDatabase().families(QFontDatabase::Any);
#else
QStringList familyNames = QFontDatabase::families(QFontDatabase::Any);
#endif
ui->naviCubeFontName->addItems(familyNames);
int indexFamilyNames = familyNames.indexOf(
QString::fromLatin1(hGrp->GetASCII("FontString", defaultSansserifFont).c_str()));
if (indexFamilyNames < 0)
indexFamilyNames = 0;
ui->naviCubeFontName->setCurrentIndex(indexFamilyNames);
}
void DlgSettingsNavigation::on_mouseButton_clicked()
@@ -165,10 +201,12 @@ void DlgSettingsNavigation::on_mouseButton_clicked()
Ui_MouseButtons uimb;
uimb.setupUi(&dlg);
QVariant data = ui->comboNavigationStyle->itemData(ui->comboNavigationStyle->currentIndex(), Qt::UserRole);
QVariant data =
ui->comboNavigationStyle->itemData(ui->comboNavigationStyle->currentIndex(), Qt::UserRole);
void* instance = Base::Type::createInstanceByName((const char*)data.toByteArray());
std::unique_ptr<UserNavigationStyle> ns(static_cast<UserNavigationStyle*>(instance));
uimb.groupBox->setTitle(uimb.groupBox->title()+QString::fromLatin1(" ")+ui->comboNavigationStyle->currentText());
uimb.groupBox->setTitle(uimb.groupBox->title() + QString::fromLatin1(" ")
+ ui->comboNavigationStyle->currentText());
QString descr;
descr = qApp->translate((const char*)data.toByteArray(),ns->mouseButtons(NavigationStyle::SELECTION));
descr.replace(QLatin1String("\n"), QLatin1String("<p>"));

View File

@@ -7,13 +7,13 @@
<x>0</x>
<y>0</y>
<width>500</width>
<height>391</height>
<height>394</height>
</rect>
</property>
<property name="windowTitle">
<string>Navigation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBoxNaviCube">
<property name="title">
@@ -117,7 +117,7 @@
</item>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="2" column="0" colspan="2">
<widget class="Gui::PrefCheckBox" name="naviCubeToNearest">
<property name="toolTip">
<string>Rotates to nearest possible state when clicking a cube face</string>
@@ -136,14 +136,37 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="2" column="3">
<widget class="QLabel" name="TextLabel3">
<property name="text">
<string>Font name:</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="Gui::PrefComboBox" name="naviCubeFontName">
<property name="toolTip">
<string>Corner where navigation cube is shown</string>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>FontString</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>NaviCube</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Cube size</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="Gui::PrefSpinBox" name="prefCubeSize">
<property name="toolTip">
<string>Size of the navigation cube</string>
@@ -171,6 +194,44 @@
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="TextLabel4">
<property name="text">
<string>Font size:</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="Gui::PrefSpinBox" name="naviCubeFontSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Font size for the NaviCube text&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>FontSize</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>NaviCube</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@@ -51,7 +51,6 @@
#include "Application.h"
#include "Command.h"
#include "MainWindow.h"
#include "View3DInventorViewer.h"
#include "View3DInventor.h"
@@ -120,6 +119,7 @@ public:
void OnChange(ParameterGrp::SubjectType& rCaller, ParameterGrp::MessageType Reason) override;
bool processSoEvent(const SoEvent* ev);
private:
bool mousePressed(short x, short y);
bool mouseReleased(short x, short y);
@@ -146,6 +146,7 @@ private:
QString str(const char* str);
char* enum2str(int);
QMenu* createNaviCubeMenu();
public:
enum { //
TEX_FRONT = 1, // 0 is reserved for 'nothing picked'
@@ -213,6 +214,8 @@ public:
bool m_MightDrag = false;
double m_BorderWidth;
NaviCube::Corner m_Corner = NaviCube::TopRightCorner;
int m_CubeTextSize = 0;
std::string m_CubeTextString;
QtGLFramebufferObject* m_PickingFramebuffer;
@@ -251,7 +254,6 @@ bool NaviCube::processSoEvent(const SoEvent* ev) {
return m_NaviCubeImplementation->processSoEvent(ev);
}
vector<string> NaviCubeImplementation::m_commands;
vector<string> NaviCubeImplementation::m_labels;
@@ -261,21 +263,44 @@ void NaviCube::setCorner(Corner c) {
m_NaviCubeImplementation->m_PrevHeight = 0;
}
// sets a default sansserif font
// the Helvetica font is a good start for most OSes
QFont NaviCube::getDefaultSansserifFont()
{
QFont font(QString::fromLatin1("Helvetica"));
if (font.styleHint() & QFont::SansSerif)
return font;
// on Windows 11 there is no longer a Helvetia font
// therefore if we did not found a Helvetica font check for
// the DejaVu Sans which is in Windows 11
font.setFamily(QString::fromLatin1("DejaVu Sans"));
// on Windows 11 sansserif fonts like DejaVu Sans does not have the
// styleHint QFont::SansSerif but QFont::AnyStyle
// however, in future they might have, thus allow both
if (font.styleHint() == QFont::SansSerif || font.styleHint() == QFont::AnyStyle)
return font;
return font; // We failed, but return whatever we have anyway
}
NaviCubeImplementation::NaviCubeImplementation(
Gui::View3DInventorViewer* viewer) {
m_View3DInventorViewer = viewer;
auto hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/NaviCube");
auto hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/NaviCube");
hGrp->Attach(this);
OnChange(*hGrp, "TextColor");
OnChange(*hGrp, "FrontColor");
OnChange(*hGrp, "HiliteColor");
OnChange(*hGrp, "ButtonColor");
OnChange(*hGrp, "CornerNaviCube");
OnChange(*hGrp, "CubeSize");
OnChange(*hGrp, "BorderWidth");
OnChange(*hGrp, "BorderColor");
OnChange(*hGrp, "FontSize");
OnChange(*hGrp, "FontString");
m_PickingFramebuffer = nullptr;
m_Menu = createNaviCubeMenu();
@@ -294,10 +319,11 @@ NaviCubeImplementation::~NaviCubeImplementation() {
delete* t;
}
void NaviCubeImplementation::OnChange(ParameterGrp::SubjectType& rCaller, ParameterGrp::MessageType reason)
void NaviCubeImplementation::OnChange(ParameterGrp::SubjectType& rCaller,
ParameterGrp::MessageType reason)
{
const auto& rGrp = static_cast<ParameterGrp&>(rCaller);
if (strcmp(reason, "TextColor") == 0) {
m_TextColor.setRgba(rGrp.GetUnsigned(reason, QColor(0, 0, 0, 255).rgba()));
}
@@ -310,15 +336,25 @@ void NaviCubeImplementation::OnChange(ParameterGrp::SubjectType& rCaller, Parame
else if (strcmp(reason, "ButtonColor") == 0) {
m_ButtonColor.setRgba(rGrp.GetUnsigned(reason, QColor(226, 233, 239, 128).rgba()));
}
else if (strcmp(reason, "CornerNaviCube") == 0) {
m_Corner = static_cast<NaviCube::Corner>(rGrp.GetInt(reason, 1));
}
else if (strcmp(reason, "CubeSize") == 0) {
m_CubeWidgetSize = (rGrp.GetInt(reason, 132));
m_CubeWidgetSize = rGrp.GetInt(reason, 132);
}
else if (strcmp(reason, "BorderWidth") == 0) {
m_BorderWidth = rGrp.GetFloat("BorderWidth", 1.1);
m_BorderWidth = rGrp.GetFloat(reason, 1.1);
}
else if (strcmp(reason, "BorderColor") == 0) {
m_BorderColor.setRgba(rGrp.GetUnsigned(reason, QColor(50, 50, 50, 255).rgba()));
}
else if (strcmp(reason, "FontSize") == 0) {
m_CubeTextSize = rGrp.GetInt(reason, 100);
}
else if (strcmp(reason, "FontString") == 0) {
m_CubeTextString = (rGrp.GetASCII(
reason, NaviCube::getDefaultSansserifFont().family().toStdString().c_str()));
}
}
char* NaviCubeImplementation::enum2str(int positionEnum) {
@@ -381,7 +417,9 @@ auto convertWeights = [](int weight) -> QFont::Weight {
return QFont::Thin;
};
GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, const char* text, int shape) {
GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, const char* text,
int shape)
{
int texSize = m_CubeWidgetSize * m_OverSample;
float gapi = texSize * gap;
QImage image(texSize, texSize, QImage::Format_ARGB32);
@@ -391,17 +429,22 @@ GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, cons
paint.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
if (text) {
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/NaviCube");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/NaviCube");
paint.setPen(Qt::white);
QFont sansFont(str("Helvetica"), 0.18 * texSize);
QFont sansFont;
// check the user settings
QString fontString = QString::fromUtf8((hGrp->GetASCII("FontString")).c_str());
if (fontString.isEmpty()) {
// load a font as start
sansFont.fromString(NaviCube::getDefaultSansserifFont().family());
sansFont.setPointSize(int(0.18 * texSize));
// Improving readability
sansFont.setWeight(convertWeights(hGrp->GetInt("FontWeight", 87)));
sansFont.setStretch(hGrp->GetInt("FontStretch", 62));
}
else {
sansFont.fromString(fontString);
// store font size and name
hGrp->SetInt("FontSize", sansFont.pointSize());
hGrp->SetASCII("FontString", sansFont.family().toStdString());
}
// Override fromString
if (hGrp->GetInt("FontWeight") > 0) {
@@ -410,13 +453,18 @@ GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, cons
if (hGrp->GetInt("FontStretch") > 0) {
sansFont.setStretch(hGrp->GetInt("FontStretch"));
}
sansFont.fromString(QString::fromStdString(m_CubeTextString));
sansFont.setPointSize(m_CubeTextSize);
paint.setFont(sansFont);
paint.drawText(QRect(0, 0, texSize, texSize), Qt::AlignCenter, qApp->translate("Gui::NaviCube", text));
paint.drawText(
QRect(0, 0, texSize, texSize), Qt::AlignCenter, qApp->translate("Gui::NaviCube", text));
}
else if (shape == SHAPE_SQUARE) {
QPainterPath pathSquare;
auto rectSquare = QRectF(gapi, gapi, (qreal)texSize - 2.0 * gapi, (qreal)texSize - 2.0 * gapi);
// Qt's coordinate system is x->left y->down, this must be taken into account on operations
auto rectSquare =
QRectF(gapi, gapi, (qreal)texSize - 2.0 * gapi, (qreal)texSize - 2.0 * gapi);
// Qt's coordinate system is x->left y->down,
// this must be taken into account on operations
pathSquare.moveTo(rectSquare.left() , rectSquare.bottom() - gapi);
pathSquare.lineTo(rectSquare.left() + gapi , rectSquare.bottom());
pathSquare.lineTo(rectSquare.right() - gapi , rectSquare.bottom());
@@ -461,7 +509,6 @@ GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, cons
return texture->textureId();
}
GLuint NaviCubeImplementation::createButtonTex(QtGLWidget* gl, int button) {
int texSize = m_CubeWidgetSize * m_OverSample;
QImage image(texSize, texSize, QImage::Format_ARGB32);
@@ -693,9 +740,9 @@ void NaviCubeImplementation::addFace(float gap, const Vector3f& x, const Vector3
}
// TEX_TOP, TEX_FRONT_FACE, TEX_TOP
// TEX_TOP frontTex,
// TEX_FRONT_FACE pickTex,
// TEX_TOP pickId
// TEX_TOP frontTex,
// TEX_FRONT_FACE pickTex,
// TEX_TOP pickId
Face* FaceFront = new Face(
m_IndexArray.size(),
4,
@@ -963,7 +1010,8 @@ void NaviCubeImplementation::handleResize() {
void NaviCubeImplementation::drawNaviCube(bool pickMode) {
// initializes stuff here when we actually have a context
// FIXME actually now that we have Qt5, we could probably do this earlier (as we do not need the opengl context)
// FIXME actually now that we have Qt5, we could probably do this earlier
// (as we do not need the opengl context)
if (!m_NaviCubeInitialised) {
auto gl = static_cast<QtGLWidget*>(m_View3DInventorViewer->viewport());
if (!gl)
@@ -1060,7 +1108,8 @@ void NaviCubeImplementation::drawNaviCube(bool pickMode) {
if (!pickMode) {
// Draw the axes
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/NaviCube");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/NaviCube");
bool ShowCS = hGrp->GetBool("ShowCS", 1);
if (ShowCS) {
glDisable(GL_TEXTURE_2D);
@@ -1103,8 +1152,8 @@ void NaviCubeImplementation::drawNaviCube(bool pickMode) {
for (int pass = 0; pass < 3; pass++) {
for (vector<Face*>::iterator f = m_Faces.begin(); f != m_Faces.end(); f++) {
//if (pickMode) { // pick should not be drawn in tree passes
// glColor3ub((*f)->m_PickId, 0, 0);
// glBindTexture(GL_TEXTURE_2D, (*f)->m_PickTextureId);
// glColor3ub((*f)->m_PickId, 0, 0);
// glBindTexture(GL_TEXTURE_2D, (*f)->m_PickTextureId);
//} else {
if (pass != (*f)->m_RenderPass)
continue;
@@ -1132,7 +1181,8 @@ void NaviCubeImplementation::drawNaviCube(bool pickMode) {
if (pass != f->m_RenderPass)
continue;
if (f->m_TextureId == f->m_PickTextureId) {
if (f->m_PickTexId == TEX_FRONT_FACE || f->m_PickTexId == TEX_EDGE_FACE || f->m_PickTexId == TEX_CORNER_FACE) {
if (f->m_PickTexId == TEX_FRONT_FACE || f->m_PickTexId == TEX_EDGE_FACE
|| f->m_PickTexId == TEX_CORNER_FACE) {
glBegin(GL_POLYGON);
for (const Vector3f& v : m_VertexArrays2[f->m_PickId]) {
glVertex3f(v[0], v[1], v[2]);
@@ -1730,7 +1780,6 @@ bool NaviCubeImplementation::processSoEvent(const SoEvent* ev) {
return false;
}
QString NaviCubeImplementation::str(const char* str) {
return QString::fromLatin1(str);
}
@@ -1745,8 +1794,6 @@ void NaviCube::setNaviCubeLabels(const std::vector<std::string>& labels)
NaviCubeImplementation::m_labels = labels;
}
DEF_3DV_CMD(ViewIsometricCmd)
ViewIsometricCmd::ViewIsometricCmd()
: Command("ViewIsometricCmd")

View File

@@ -41,22 +41,18 @@ public:
BottomLeftCorner,
BottomRightCorner
};
NaviCube(Gui::View3DInventorViewer* viewer) ;
NaviCube(Gui::View3DInventorViewer* viewer);
virtual ~NaviCube();
void drawNaviCube();
void createContextMenu(const std::vector<std::string>& cmd);
bool processSoEvent(const SoEvent* ev);
void setCorner(Corner);
static QFont getDefaultSansserifFont();
static void setNaviCubeCommands(const std::vector<std::string>& cmd);
static void setNaviCubeLabels(const std::vector<std::string>& labels);
private:
NaviCubeImplementation* m_NaviCubeImplementation;
};
class HuuhaaClassPy : public Py::PythonExtension<HuuhaaClassPy> {
public:
Py::Object huuhaa(const Py::Tuple&);
static void init_type() ;
};
#endif /* SRC_GUI_NAVICUBE_H_ */

View File

@@ -1176,6 +1176,23 @@ NaviCube* View3DInventorViewer::getNavigationCube() const
return naviCube;
}
void View3DInventorViewer::createNavigationCube()
{
if (!naviCube) {
naviCube = new NaviCube(this);
naviCubeEnabled = true;
}
}
void View3DInventorViewer::deleteNavigationCube()
{
if (naviCube) {
delete naviCube;
naviCube = nullptr;
naviCubeEnabled = false;
}
}
void View3DInventorViewer::setAxisCross(bool on)
{
SoNode* scene = getSceneGraph();

View File

@@ -387,6 +387,8 @@ public:
bool isEnabledNaviCube() const;
void setNaviCubeCorner(int);
NaviCube* getNavigationCube() const;
void createNavigationCube();
void deleteNavigationCube();
void setEnabledVBO(bool b);
bool isEnabledVBO() const;
void setRenderCache(int);