Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Char widget UX improvements #9916

Merged
merged 6 commits into from May 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions python/gui/auto_generated/qgsscrollarea.sip.in
Expand Up @@ -45,11 +45,23 @@ QScrollArea itself or its child viewport().
%Docstring
Returns ``True`` if a scroll recently occurred within
the QScrollArea or its child viewport()
%End

void setVerticalOnly( bool verticalOnly );
%Docstring
Sets whether the scroll area only applies vertical.

If set to ``True``, then scroll area children will resize horizontally to match the width of
the scroll area widget.

.. versionadded:: 3.8
%End

protected:
virtual void wheelEvent( QWheelEvent *event );

virtual void resizeEvent( QResizeEvent *event );


};

Expand Down
2 changes: 2 additions & 0 deletions python/gui/auto_generated/symbology/characterwidget.sip.in
Expand Up @@ -128,6 +128,8 @@ Emitted when a character is selected in the widget.

virtual void paintEvent( QPaintEvent *event );

virtual void resizeEvent( QResizeEvent *event );


};

Expand Down
18 changes: 18 additions & 0 deletions src/gui/qgsscrollarea.cpp
Expand Up @@ -16,6 +16,7 @@
#include <QEvent>
#include <QMouseEvent>
#include "qgsscrollarea.h"
#include <QScrollBar>

// milliseconds to swallow child wheel events for after a scroll occurs
#define TIMEOUT 1000
Expand All @@ -34,6 +35,13 @@ void QgsScrollArea::wheelEvent( QWheelEvent *e )
QScrollArea::wheelEvent( e );
}

void QgsScrollArea::resizeEvent( QResizeEvent *event )
{
if ( mVerticalOnly && widget() )
widget()->setFixedWidth( event->size().width() );
QScrollArea::resizeEvent( event );
}

void QgsScrollArea::scrollOccurred()
{
mTimer.setSingleShot( true );
Expand All @@ -45,6 +53,16 @@ bool QgsScrollArea::hasScrolled() const
return mTimer.isActive();
}

void QgsScrollArea::setVerticalOnly( bool verticalOnly )
{
mVerticalOnly = verticalOnly;
if ( mVerticalOnly )
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );

if ( mVerticalOnly && widget() )
widget()->setFixedWidth( size().width() );
}

///@cond PRIVATE

ScrollAreaFilter::ScrollAreaFilter( QgsScrollArea *parent, QWidget *viewPort )
Expand Down
13 changes: 13 additions & 0 deletions src/gui/qgsscrollarea.h
Expand Up @@ -61,12 +61,25 @@ class GUI_EXPORT QgsScrollArea : public QScrollArea
*/
bool hasScrolled() const;

/**
* Sets whether the scroll area only applies vertical.
*
* If set to TRUE, then scroll area children will resize horizontally to match the width of
* the scroll area widget.
*
* \since QGIS 3.8
*/
void setVerticalOnly( bool verticalOnly );

protected:
void wheelEvent( QWheelEvent *event ) override;
void resizeEvent( QResizeEvent *event ) override;

private:
QTimer mTimer;
ScrollAreaFilter *mFilter = nullptr;
bool mVerticalOnly = false;

};

#ifndef SIP_RUN
Expand Down
69 changes: 61 additions & 8 deletions src/gui/symbology/characterwidget.cpp
Expand Up @@ -111,6 +111,7 @@ void CharacterWidget::setColumns( int columns )

void CharacterWidget::setCharacter( QChar character )
{
const bool changed = character != mLastKey;
mLastKey = character.unicode();
QWidget *widget = parentWidget();
if ( widget )
Expand All @@ -119,6 +120,9 @@ void CharacterWidget::setCharacter( QChar character )
if ( scrollArea && mLastKey < 65536 )
scrollArea->verticalScrollBar()->setValue( mLastKey / mColumns * mSquareSize );
}
if ( changed )
emit characterSelected( mLastKey );

update();
}

Expand All @@ -135,13 +139,50 @@ QSize CharacterWidget::sizeHint() const

void CharacterWidget::keyPressEvent( QKeyEvent *event )
{
if ( !event->text().isEmpty() )
QFontMetrics fm( mDisplayFont );

if ( event->key() == Qt::Key_Right )
{
int next = std::min( mLastKey + 1, 0xfffc );
while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
{
next++;
}
setCharacter( QChar( next ) );
}
else if ( event->key() == Qt::Key_Left )
{
int next = mLastKey - 1;
while ( next > 0 && !fm.inFont( QChar( next ) ) )
{
next--;
}
setCharacter( QChar( next ) );
}
else if ( event->key() == Qt::Key_Down )
{
int next = std::min( mLastKey + mColumns, 0xfffc );
while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
{
next = std::min( next + mColumns, 0xfffc );
}
setCharacter( QChar( next ) );
}
else if ( event->key() == Qt::Key_Up )
{
int next = std::max( 0, mLastKey - mColumns );
while ( next > 0 && !fm.inFont( QChar( next ) ) )
{
next = std::max( 0, next - mColumns );
}
setCharacter( QChar( next ) );
}
else if ( !event->text().isEmpty() )
{
QChar chr = event->text().at( 0 );
if ( chr.unicode() != mLastKey )
{
setCharacter( chr );
emit characterSelected( chr );
}
}
}
Expand Down Expand Up @@ -175,15 +216,18 @@ void CharacterWidget::mousePressEvent( QMouseEvent *event )
void CharacterWidget::paintEvent( QPaintEvent *event )
{
QPainter painter( this );
QPalette palette = qApp->palette();
painter.fillRect( event->rect(), QBrush( palette.color( QPalette::Base ) ) );
painter.setFont( mDisplayFont );

QRect redrawRect = event->rect();
int beginRow = redrawRect.top() / mSquareSize;
int endRow = redrawRect.bottom() / mSquareSize;
int beginColumn = redrawRect.left() / mSquareSize;
int endColumn = redrawRect.right() / mSquareSize;
int endColumn = std::min( mColumns - 1, redrawRect.right() / mSquareSize );

QPalette palette = qApp->palette();
QRectF backgroundRect = event->rect();
backgroundRect.setWidth( std::min( backgroundRect.width(), ( endColumn + 1 ) * mSquareSize - backgroundRect.left() ) );
painter.fillRect( backgroundRect, QBrush( palette.color( QPalette::Base ) ) );

painter.setPen( QPen( palette.color( QPalette::Mid ) ) );
for ( int row = beginRow; row <= endRow; ++row )
Expand All @@ -206,9 +250,18 @@ void CharacterWidget::paintEvent( QPaintEvent *event )
if ( key == mLastKey )
painter.fillRect( column * mSquareSize + 1, row * mSquareSize + 1, mSquareSize, mSquareSize, QBrush( palette.color( QPalette::Highlight ) ) );

painter.drawText( column * mSquareSize + ( mSquareSize / 2 ) - fontMetrics.width( QChar( key ) ) / 2,
row * mSquareSize + 4 + fontMetrics.ascent(),
QString( QChar( key ) ) );
if ( fontMetrics.inFont( QChar( key ) ) )
{
painter.drawText( column * mSquareSize + ( mSquareSize / 2 ) - fontMetrics.width( QChar( key ) ) / 2,
row * mSquareSize + 4 + fontMetrics.ascent(),
QString( QChar( key ) ) );
}
}
}
}

void CharacterWidget::resizeEvent( QResizeEvent *event )
{
mColumns = event->size().width() / mSquareSize;
QWidget::resizeEvent( event );
}
1 change: 1 addition & 0 deletions src/gui/symbology/characterwidget.h
Expand Up @@ -161,6 +161,7 @@ class GUI_EXPORT CharacterWidget : public QWidget
void mouseMoveEvent( QMouseEvent *event ) override;
void mousePressEvent( QMouseEvent *event ) override;
void paintEvent( QPaintEvent *event ) override;
void resizeEvent( QResizeEvent *event ) override;

private:
QFont mDisplayFont;
Expand Down
1 change: 1 addition & 0 deletions src/gui/symbology/qgssymbollayerwidget.cpp
Expand Up @@ -3253,6 +3253,7 @@ QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *

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

btnColor->setAllowOpacity( true );
btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
Expand Down
2 changes: 1 addition & 1 deletion src/ui/symbollayer/widget_fontmarker.ui
Expand Up @@ -360,7 +360,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<width>0</width>
<height>40</height>
</size>
</property>
Expand Down