Skip to content

Commit

Permalink
[FEATURE][ui] Add a line edit to type character for the font marker
Browse files Browse the repository at this point in the history
The line edit also supports pasting of unicode code in decimal or
hexadecimal format (i.e. 123 or 0x2713).

In addition, the character widget now grabs the keyboard
focus and will change the selected character based on
key stroke.
  • Loading branch information
nirvn committed Apr 30, 2019
1 parent f70acf2 commit dc7bfc5
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 7 deletions.
4 changes: 4 additions & 0 deletions python/gui/auto_generated/symbology/characterwidget.sip.in
Expand Up @@ -9,6 +9,8 @@





class CharacterWidget : QWidget
{
%Docstring
Expand Down Expand Up @@ -109,6 +111,8 @@ Emitted when a character is selected in the widget.
%End

protected:
virtual void keyPressEvent( QKeyEvent *event );

virtual void mouseMoveEvent( QMouseEvent *event );

virtual void mousePressEvent( QMouseEvent *event );
Expand Down
15 changes: 15 additions & 0 deletions python/gui/auto_generated/symbology/qgssymbollayerwidget.sip.in
Expand Up @@ -695,7 +695,22 @@ Set stroke color.
%End
void setSize( double size );
void setAngle( double angle );

void setCharacter( QChar chr );
%Docstring
Set the font marker character from char.

:param chr: the char
%End

void setCharacterFromText( const QString &text );
%Docstring
Set the font marker character from a text string.

:param text: the text string

.. versionadded:: 3.8
%End

protected:

Expand Down
28 changes: 26 additions & 2 deletions src/gui/symbology/characterwidget.cpp
Expand Up @@ -52,12 +52,15 @@
#include <QPainter>
#include <QPen>
#include <QPoint>
#include <QScrollArea>
#include <QScrollBar>
#include <QToolTip>

CharacterWidget::CharacterWidget( QWidget *parent )
: QWidget( parent )
{
setMouseTracking( true );
setFocusPolicy( Qt::StrongFocus );
}

void CharacterWidget::setFont( const QFont &font )
Expand Down Expand Up @@ -109,6 +112,13 @@ void CharacterWidget::setColumns( int columns )
void CharacterWidget::setCharacter( QChar character )
{
mLastKey = character.unicode();
QWidget *widget = parentWidget();
if ( widget )
{
QScrollArea *scrollArea = qobject_cast< QScrollArea *>( widget->parent() );
if ( scrollArea && mLastKey < 65536 )
scrollArea->verticalScrollBar()->setValue( mLastKey / mColumns * mSquareSize );
}
update();
}

Expand All @@ -117,15 +127,29 @@ QSize CharacterWidget::sizeHint() const
return QSize( mColumns * mSquareSize, ( 65536 / mColumns ) * mSquareSize );
}

void CharacterWidget::keyPressEvent( QKeyEvent *event )
{
if ( !event->text().isEmpty() )
{
QChar chr = event->text().at( 0 );
if ( chr.unicode() != mLastKey )
{
setCharacter( chr );
emit characterSelected( chr );
}
}
}

void CharacterWidget::mouseMoveEvent( QMouseEvent *event )
{
QPoint widgetPosition = mapFromGlobal( event->globalPos() );
uint key = ( widgetPosition.y() / mSquareSize ) * mColumns + widgetPosition.x() / mSquareSize;

QString text = tr( "<p>Character: <span style=\"font-size: 24pt; font-family: %1\">%2</span><p>Value: 0x%3" )
QString text = tr( "<p>Character: <span style=\"font-size: 24pt; font-family: %1\">%2</span><p>Decimal: %3<p>Hex: 0x%4" )
.arg( mDisplayFont.family() )
.arg( QChar( key ) )
.arg( key, 16 );
.arg( key )
.arg( QString::number( key, 16 ) );
QToolTip::showText( event->globalPos(), text, this );
}

Expand Down
7 changes: 5 additions & 2 deletions src/gui/symbology/characterwidget.h
Expand Up @@ -47,13 +47,15 @@
#ifndef CHARACTERWIDGET_H
#define CHARACTERWIDGET_H

#include "qgis_sip.h"
#include "qgis_gui.h"

#include <QFont>
#include <QPoint>
#include <QSize>
#include <QString>
#include <QWidget>
#include "qgis_sip.h"
#include "qgis_gui.h"


class QMouseEvent;
class QPaintEvent;
Expand Down Expand Up @@ -148,6 +150,7 @@ class GUI_EXPORT CharacterWidget : public QWidget
void characterSelected( QChar character );

protected:
void keyPressEvent( QKeyEvent *event ) override;
void mouseMoveEvent( QMouseEvent *event ) override;
void mousePressEvent( QMouseEvent *event ) override;
void paintEvent( QPaintEvent *event ) override;
Expand Down
36 changes: 35 additions & 1 deletion src/gui/symbology/qgssymbollayerwidget.cpp
Expand Up @@ -3251,7 +3251,7 @@ QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *
mOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );

widgetChar = new CharacterWidget;
widgetChar = new CharacterWidget();
scrollArea->setWidget( widgetChar );

btnColor->setAllowOpacity( true );
Expand Down Expand Up @@ -3284,6 +3284,8 @@ QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *
connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
connect( widgetChar, &CharacterWidget::characterSelected, this, &QgsFontMarkerSymbolLayerWidget::setCharacter );
connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );

connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
}

Expand All @@ -3308,6 +3310,7 @@ void QgsFontMarkerSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer )
widgetChar->setFont( layerFont );
widgetChar->setCharacter( mLayer->character() );
widgetChar->blockSignals( false );
whileBlocking( mCharLineEdit )->setText( mLayer->character() );

//block
whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
Expand Down Expand Up @@ -3385,9 +3388,40 @@ void QgsFontMarkerSymbolLayerWidget::setAngle( double angle )
emit changed();
}

void QgsFontMarkerSymbolLayerWidget::setCharacterFromText( const QString &text )
{
if ( text.isEmpty() )
return;

// take the last character of a string for a better experience when users cycle through several characters on their keyboard
QChar chr = text.back();
if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
{
bool ok = false;
unsigned int value = text.toUInt( &ok, 0 );
if ( ok )
chr = QChar( value );
}
else if ( text.contains( QRegularExpression( QStringLiteral( "^[0-9]{1,}$" ) ) ) )
{
bool ok = false;
unsigned int value = text.toUInt( &ok, 10 );
if ( ok )
chr = QChar( value );
}

if ( chr != mLayer->character() )
{
mLayer->setCharacter( chr );
whileBlocking( widgetChar )->setCharacter( mLayer->character() );
emit changed();
}
}

void QgsFontMarkerSymbolLayerWidget::setCharacter( QChar chr )
{
mLayer->setCharacter( chr );
whileBlocking( mCharLineEdit )->setText( chr );
emit changed();
}

Expand Down
12 changes: 12 additions & 0 deletions src/gui/symbology/qgssymbollayerwidget.h
Expand Up @@ -932,8 +932,20 @@ class GUI_EXPORT QgsFontMarkerSymbolLayerWidget : public QgsSymbolLayerWidget, p
void setColorStroke( const QColor &color );
void setSize( double size );
void setAngle( double angle );

/**
* Set the font marker character from char.
* \param chr the char
*/
void setCharacter( QChar chr );

/**
* Set the font marker character from a text string.
* \param text the text string
* \since QGIS 3.8
*/
void setCharacterFromText( const QString &text );

protected:
QgsFontMarkerSymbolLayer *mLayer = nullptr;
CharacterWidget *widgetChar = nullptr;
Expand Down
18 changes: 16 additions & 2 deletions src/ui/symbollayer/widget_fontmarker.ui
Expand Up @@ -303,7 +303,21 @@
</property>
</widget>
</item>
<item row="13" column="3">
<item row="14" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Character</string>
</property>
</widget>
</item>
<item row="14" column="1" colspan="2">
<widget class="QLineEdit" name="mCharLineEdit">
<property name="toolTip">
<string>Type in a character directly, or enter its decimal/hexadecimal value.</string>
</property>
</widget>
</item>
<item row="14" column="3">
<widget class="QgsPropertyOverrideButton" name="mCharDDBtn">
<property name="text">
<string>…</string>
Expand All @@ -317,7 +331,7 @@
</property>
</widget>
</item>
<item row="13" column="0" colspan="3">
<item row="13" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QgsScrollArea" name="scrollArea">
Expand Down

0 comments on commit dc7bfc5

Please sign in to comment.