40#include "moc_qgsfontbutton.cpp"
43 : QToolButton( parent )
45 , mNullFormatString( tr(
"No Format" ) )
47 setText( tr(
"Font" ) );
49 setAcceptDrops(
true );
50 connect(
this, &QAbstractButton::clicked,
this, &QgsFontButton::showSettingsDialog );
53 mMenu =
new QMenu(
this );
54 connect( mMenu, &QMenu::aboutToShow,
this, &QgsFontButton::prepareMenu );
56 setPopupMode( QToolButton::MenuButtonPopup );
59 const QSize size = QToolButton::minimumSizeHint();
62 mSizeHint = QSize( std::max( minWidth, size.width() ), std::max( size.height(), fontHeight ) );
78void QgsFontButton::showSettingsDialog()
85 if ( mExpressionContextGenerator )
92 QgsSymbolWidgetContext symbolContext;
100 mActivePanel =
new QgsTextFormatPanelWidget( mFormat, mMapCanvas,
this, mLayer.data() );
101 mActivePanel->setPanelTitle( mDialogTitle );
102 mActivePanel->setContext( symbolContext );
112 QgsTextFormatDialog dialog( mFormat, mMapCanvas,
this, QgsGuiUtils::ModalDialogFlags, mLayer.data() );
113 dialog.setWindowTitle( mDialogTitle );
114 dialog.setContext( symbolContext );
163 if ( mActivePanel && !format.
isValid() )
164 mActivePanel->acceptPanel();
169 if ( mActivePanel && format.
isValid() )
170 mActivePanel->setFormat( format );
183 QColor opaque = color;
184 opaque.setAlphaF( 1.0 );
186 if ( mNullFormatAction )
187 mNullFormatAction->setChecked(
false );
189 if ( mFormat.color() != opaque )
191 mFormat.setColor( opaque );
202 QApplication::clipboard()->setMimeData( mFormat.toMimeData() );
215 if ( mMode ==
ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
220 else if ( mMode ==
ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), font ) )
229 if ( e->type() == QEvent::ToolTip )
231 QHelpEvent *helpEvent =
static_cast<QHelpEvent *
>( e );
233 double fontSize = 0.0;
237 fontSize = mFormat.size();
241 fontSize = mFont.pointSizeF();
244 toolTip = QStringLiteral(
"<b>%1</b><br>%2<br>Size: %3" ).arg( text(), mMode ==
ModeTextRenderer ? mFormat.font().family() : mFont.family() ).arg( fontSize );
245 QToolTip::showText( helpEvent->globalPos(), toolTip );
247 return QToolButton::event( e );
252 if ( e->button() == Qt::RightButton )
254 QToolButton::showMenu();
257 else if ( e->button() == Qt::LeftButton )
259 mDragStartPosition = e->pos();
261 QToolButton::mousePressEvent( e );
268 if ( !( e->buttons() & Qt::LeftButton ) )
271 QToolButton::mouseMoveEvent( e );
275 if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
278 QToolButton::mouseMoveEvent( e );
283 QDrag *drag =
new QDrag(
this );
287 drag->setMimeData( mFormat.toMimeData() );
295 drag->setPixmap( createDragIcon( QSize( iconSize, iconSize ) ) );
296 drag->exec( Qt::CopyAction );
300bool QgsFontButton::colorFromMimeData(
const QMimeData *mimeData, QColor &resultColor,
bool &hasAlpha )
305 if ( mimeColor.isValid() )
307 resultColor = mimeColor;
321 bool hasAlpha =
false;
323 if ( mMode ==
ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) )
325 e->acceptProposedAction();
326 updatePreview( QColor(), &format );
328 else if ( mMode ==
ModeQFont && fontFromMimeData( e->mimeData(), font ) )
330 e->acceptProposedAction();
331 updatePreview( QColor(),
nullptr, &font );
333 else if ( mMode ==
ModeTextRenderer && colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
338 e->acceptProposedAction();
339 updatePreview( mimeColor );
356 bool hasAlpha =
false;
357 if ( mMode ==
ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) )
363 else if ( mMode ==
ModeQFont && fontFromMimeData( e->mimeData(), font ) )
369 else if ( mMode ==
ModeTextRenderer && colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
372 e->acceptProposedAction();
376 mFormat.setOpacity( mimeColor.alphaF() );
378 mimeColor.setAlphaF( 1.0 );
379 mFormat.setColor( mimeColor );
393 size = mFormat.size();
397 size = mFont.pointSizeF();
401 const double increment = (
event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1;
402 if (
event->angleDelta().y() > 0 )
410 size = std::max( size, 1.0 );
424 QFont newFont = mFont;
425 newFont.setPointSizeF( size );
434QPixmap QgsFontButton::createColorIcon(
const QColor &color )
const
438 QPixmap pixmap( iconSize, iconSize );
439 pixmap.fill( Qt::transparent );
445 p.setBrush( QBrush( color ) );
448 p.setPen( QColor( 197, 197, 197 ) );
449 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
454QPixmap QgsFontButton::createDragIcon( QSize size,
const QgsTextFormat *tempFormat,
const QFont *tempFont )
const
457 tempFormat = &mFormat;
462 QPixmap pixmap( size.width(), size.height() );
463 pixmap.fill( Qt::transparent );
466 p.setRenderHint( QPainter::Antialiasing );
467 const QRect rect( 0, 0, size.width(), size.height() );
469 if ( mMode ==
ModeQFont || tempFormat->
color().lightnessF() < 0.7 )
471 p.setBrush( QBrush( QColor( 255, 255, 255 ) ) );
472 p.setPen( QPen( QColor( 150, 150, 150 ), 0 ) );
476 p.setBrush( QBrush( QColor( 0, 0, 0 ) ) );
477 p.setPen( QPen( QColor( 100, 100, 100 ), 0 ) );
480 p.setBrush( Qt::NoBrush );
481 p.setPen( Qt::NoPen );
487 QgsRenderContext context;
488 QgsMapToPixel newCoordXForm;
501 ? fontSize * tempFormat->
buffer().
size() / 100
512 QRectF textRect = rect;
513 textRect.setLeft( xtrans );
514 textRect.setWidth( textRect.width() - xtrans );
515 textRect.setTop( ytrans );
516 if ( textRect.height() > 300 )
517 textRect.setHeight( 300 );
518 if ( textRect.width() > 2000 )
519 textRect.setWidth( 2000 );
526 p.setBrush( Qt::NoBrush );
527 p.setPen( QColor( 0, 0, 0 ) );
528 p.setFont( *tempFont );
529 QRectF textRect = rect;
530 textRect.setLeft( 2 );
531 p.drawText( textRect, Qt::AlignVCenter, tr(
"Aa" ) );
540void QgsFontButton::prepareMenu()
550 mNullFormatAction =
new QAction( mNullFormatString,
this );
551 mMenu->addAction( mNullFormatAction );
553 if ( !mFormat.isValid() )
555 mNullFormatAction->setCheckable(
true );
556 mNullFormatAction->setChecked(
true );
560 QWidgetAction *sizeAction =
new QWidgetAction( mMenu );
561 QWidget *sizeWidget =
new QWidget();
562 QVBoxLayout *sizeLayout =
new QVBoxLayout();
563 sizeLayout->setContentsMargins( 0, 0, 0, 3 );
564 sizeLayout->setSpacing( 2 );
566 QString fontHeaderLabel;
574 fontHeaderLabel = tr(
"Font size (pt)" );
578 QgsMenuHeader *sizeLabel =
new QgsMenuHeader( fontHeaderLabel );
579 sizeLayout->addWidget( sizeLabel );
581 QgsDoubleSpinBox *sizeSpin =
new QgsDoubleSpinBox(
nullptr );
582 sizeSpin->setDecimals( 4 );
583 sizeSpin->setMaximum( 1e+9 );
585 sizeSpin->setValue( mMode ==
ModeTextRenderer ? mFormat.size() : mFont.pointSizeF() );
586 connect( sizeSpin,
static_cast<void ( QgsDoubleSpinBox::* )(
double )
>( &QgsDoubleSpinBox::valueChanged ),
this, [
this](
double value ) {
590 if ( mNullFormatAction )
591 mNullFormatAction->setChecked(
false );
592 mFormat.setSize( value );
595 mFont.setPointSizeF( value );
601 QHBoxLayout *spinLayout =
new QHBoxLayout();
602 spinLayout->setContentsMargins( 4, 0, 4, 0 );
603 spinLayout->addWidget( sizeSpin );
604 sizeLayout->addLayout( spinLayout );
605 sizeWidget->setLayout( sizeLayout );
606 sizeAction->setDefaultWidget( sizeWidget );
607 sizeWidget->setFocusProxy( sizeSpin );
608 sizeWidget->setFocusPolicy( Qt::StrongFocus );
609 mMenu->addAction( sizeAction );
611 QMenu *recentFontMenu =
new QMenu( tr(
"Recent Fonts" ), mMenu );
613 for (
const QString &family : recentFontFamilies )
615 QAction *fontAction =
new QAction( family, recentFontMenu );
616 QFont f = fontAction->font();
618 fontAction->setFont( f );
619 fontAction->setToolTip( family );
620 recentFontMenu->addAction( fontAction );
622 || ( mMode ==
ModeQFont && family == mFont.family() ) )
624 fontAction->setCheckable(
true );
625 fontAction->setChecked(
true );
627 auto setFont = [
this, family] {
632 QgsTextFormat newFormat = mFormat;
633 QFont f = newFormat.
font();
650 connect( fontAction, &QAction::triggered,
this, setFont );
652 mMenu->addMenu( recentFontMenu );
654 QAction *configureAction =
new QAction( tr(
"Configure Format…" ),
this );
655 mMenu->addAction( configureAction );
656 connect( configureAction, &QAction::triggered,
this, &QgsFontButton::showSettingsDialog );
658 QAction *copyFormatAction =
new QAction( tr(
"Copy Format" ),
this );
659 mMenu->addAction( copyFormatAction );
661 QAction *pasteFormatAction =
new QAction( tr(
"Paste Format" ),
this );
664 QgsTextFormat tempFormat;
667 if ( mMode ==
ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
671 pasteFormatAction->setIcon( createDragIcon( QSize( iconSize, iconSize ), &tempFormat ) );
673 else if ( mMode ==
ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), tempFont ) )
675 tempFont.setPointSize( 8 );
676 pasteFormatAction->setIcon( createDragIcon( QSize( iconSize, iconSize ),
nullptr, &tempFont ) );
680 pasteFormatAction->setEnabled(
false );
682 mMenu->addAction( pasteFormatAction );
687 mMenu->addSeparator();
689 QgsColorWheel *colorWheel =
new QgsColorWheel( mMenu );
690 colorWheel->
setColor( mFormat.color() );
691 QgsColorWidgetAction *colorAction =
new QgsColorWidgetAction( colorWheel, mMenu, mMenu );
694 mMenu->addAction( colorAction );
697 QColor alphaColor = mFormat.color();
698 alphaColor.setAlphaF( mFormat.opacity() );
700 QgsColorWidgetAction *alphaAction =
new QgsColorWidgetAction( alphaRamp, mMenu, mMenu );
703 const double opacity = color.alphaF();
704 mFormat.setOpacity( opacity );
706 if ( mNullFormatAction )
707 mNullFormatAction->setChecked(
false );
711 mMenu->addAction( alphaAction );
715 QList<QgsColorScheme *>::iterator it = schemeList.begin();
716 for ( ; it != schemeList.end(); ++it )
718 QgsColorSwatchGridAction *colorAction =
new QgsColorSwatchGridAction( *it, mMenu, QStringLiteral(
"labeling" ),
this );
720 mMenu->addAction( colorAction );
725 mMenu->addSeparator();
727 QAction *copyColorAction =
new QAction( tr(
"Copy Color" ),
this );
728 mMenu->addAction( copyColorAction );
731 QAction *pasteColorAction =
new QAction( tr(
"Paste Color" ),
this );
735 bool hasAlpha =
false;
736 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
738 pasteColorAction->setIcon( createColorIcon( clipColor ) );
742 pasteColorAction->setEnabled(
false );
744 mMenu->addAction( pasteColorAction );
749void QgsFontButton::addRecentColor(
const QColor &color )
771 mExpressionContextGenerator = generator;
792bool QgsFontButton::formatFromMimeData(
const QMimeData *mimeData,
QgsTextFormat &resultFormat )
const
802bool QgsFontButton::fontFromMimeData(
const QMimeData *mimeData, QFont &resultFont )
const
814 if ( e->type() == QEvent::EnabledChange )
818 QToolButton::changeEvent( e );
824 QToolButton::showEvent( e );
829 QToolButton::resizeEvent(
event );
835void QgsFontButton::updatePreview(
const QColor &color,
QgsTextFormat *format, QFont *font )
837 if ( mShowNoFormat && !mFormat.
isValid() )
839 setIcon( QPixmap() );
843 QgsTextFormat tempFormat;
847 tempFormat = *format;
849 tempFormat = mFormat;
855 if ( color.isValid() )
862 tempFormat.
setSize( QToolButton::font().pointSizeF() - 2 );
865 QSize currentIconSize;
869 if ( !mIconSize.isValid() )
872 QStyleOptionToolButton opt;
873 initStyleOption( &opt );
874 const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
this );
877 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
878#elif defined( Q_OS_MAC )
879 mIconSize = QSize( buttonSize.width() - 10, height() - 2 );
881 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
884 currentIconSize = mIconSize;
890 currentIconSize = QSize( width() - 10, height() - 6 );
892 currentIconSize = QSize( width() - 10, height() - 12 );
896 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
902 QPixmap pixmap( currentIconSize * devicePixelRatioF() );
903 pixmap.fill( Qt::transparent );
904 pixmap.setDevicePixelRatio( devicePixelRatioF() );
907 p.setRenderHint( QPainter::Antialiasing );
908 const QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
914 QgsRenderContext context;
915 QgsMapToPixel newCoordXForm;
941 QRectF textRect = rect;
942 textRect.setLeft( xtrans );
943 textRect.setWidth( textRect.width() - xtrans );
944 textRect.setTop( ytrans );
945 if ( textRect.height() > 300 )
946 textRect.setHeight( 300 );
947 if ( textRect.width() > 2000 )
948 textRect.setWidth( 2000 );
955 p.setBrush( Qt::NoBrush );
956 p.setPen( QColor( 0, 0, 0 ) );
957 p.setFont( tempFont );
958 QRectF textRect = rect;
959 textRect.setLeft( 2 );
960 p.drawText( textRect, Qt::AlignVCenter, text() );
965 setIconSize( currentIconSize );
978 bool hasAlpha =
false;
979 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
989 mDialogTitle = title;
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
@ Points
Points (e.g., for font sizes).
@ Antialiasing
Use antialiasing while drawing.
static const double UI_SCALE_FACTOR
UI scaling factor.
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
QList< QgsColorScheme * > schemes() const
Returns all color schemes in the registry.
@ ShowInColorButtonMenu
Show scheme in color button drop-down menu.
void setBaseColor(const QColor &baseColor)
Sets the base color for the color grid.
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
void setColor(const QColor &color, bool emitSignals=false) override
void setShowClearButton(bool showClearButton)
Sets whether the widget will show a clear button.
Abstract interface for generating an expression context.
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
static QMimeData * toMimeData(const QFont &font)
Returns new mime data representing the specified font settings.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
static void addRecentFontFamily(const QString &family)
Adds a font family to the list of recently used font families.
static QFont fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QFont.
static QStringList recentFontFamilies()
Returns a list of recently used font families.
Map canvas is a class for displaying all GIS data types on a canvas.
void setParameters(double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation)
Sets parameters for use in transforming coordinates.
A bar for displaying non-blocking messages to the user.
static void addRecentColor(const QColor &color)
Adds a color to the list of recent colors.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
void setDevicePixelRatio(float ratio)
Sets the device pixel ratio.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
A utility class for dynamic handling of changes to screen properties.
void screenDpiChanged(double dpi)
Emitted whenever the screen dpi associated with the widget is changed.
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
void setExpressionContext(QgsExpressionContext *context)
Sets the optional expression context used for the widget.
QSizeF size() const
Returns the size of the background shape.
bool enabled() const
Returns whether the background is enabled.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the shape size.
Qgis::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
Qgis::RenderUnit sizeUnit() const
Returns the units for the buffer size.
double size() const
Returns the size of the buffer.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
bool enabled() const
Returns whether the buffer is enabled.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the size.
void setFont(const QFont &font)
Sets the font used for rendering text.
static QgsTextFormat fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QgsTextFormat.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
bool isValid() const
Returns true if the format is valid.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
Qgis::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
double size() const
Returns the size for rendered text.
QColor color() const
Returns the color that text will be rendered in.
QFont font() const
Returns the font used for rendering text.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based dataset.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
QFont getFont(bool &ok, const QFont &initial, const QString &title)
Show font selection dialog.