diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1df3fe0..e8953bd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,72 +1,72 @@
project(kruler)
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
set(QT_MIN_VERSION "5.2.0")
find_package(ECM 1.7.0 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
add_definitions(-DTRANSLATION_DOMAIN="kruler")
include(KDEInstallDirs)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(KDECMakeSettings)
include(ECMInstallIcons)
include(FeatureSummary)
include(ECMAddAppIcon)
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
Core
Widgets
)
find_package(KF5 REQUIRED COMPONENTS
DocTools
I18n
Notifications
WindowSystem
XmlGui
)
if (NOT APPLE)
find_package(X11)
set (KRULER_HAVE_X11 ${X11_FOUND})
if (X11_FOUND)
find_package(XCB COMPONENTS XCB)
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED X11Extras)
endif()
endif()
configure_file(krulerconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/krulerconfig.h)
add_subdirectory( pics )
add_subdirectory( doc )
########### next target ###############
-set(kruler_SRCS qautosizelabel.cpp klineal.cpp main.cpp krulersystemtray.cpp)
+set(kruler_SRCS klineal.cpp main.cpp krulersystemtray.cpp)
ki18n_wrap_ui(kruler_SRCS cfg_appearance.ui cfg_advanced.ui)
kconfig_add_kcfg_files(kruler_SRCS kruler.kcfgc)
file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/pics/*-apps-kruler.png")
ecm_add_app_icon(kruler_SRCS ICONS ${ICONS_SRCS})
add_executable(kruler ${kruler_SRCS})
target_link_libraries(kruler KF5::I18n KF5::Notifications KF5::WindowSystem KF5::XmlGui)
if (X11_FOUND)
target_link_libraries(kruler Qt5::X11Extras ${XCB_LIBRARIES})
endif()
install(TARGETS kruler ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
########### install files ###############
install( PROGRAMS org.kde.kruler.desktop DESTINATION ${KDE_INSTALL_APPDIR} )
install( FILES org.kde.kruler.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} )
install( FILES kruler.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR} )
install( FILES move.wav DESTINATION ${KDE_INSTALL_DATADIR}/kruler/sounds )
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/cfg_appearance.ui b/cfg_appearance.ui
index 9c13e27..be80ac5 100644
--- a/cfg_appearance.ui
+++ b/cfg_appearance.ui
@@ -1,94 +1,80 @@
Mathias Soeken
ConfigAppearance
0
0
400
300
0
-
Background color:
-
-
Font:
-
-
Show tray icon
- -
-
-
- Show rotation buttons
-
-
-
- -
-
-
- Show close button
-
-
-
KColorButton
QPushButton
KFontRequester
QWidget
kcfg_BgColor
kcfg_TrayIcon
toggled(bool)
kcfg_CloseButtonVisible
setEnabled(bool)
172
100
183
127
diff --git a/doc/index.docbook b/doc/index.docbook
index 5de9947..e56417c 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -1,440 +1,244 @@
]>
The &kruler; Handbook
Lauri
Watts
&Lauri.Watts.mail;
&FDLNotice;
2001
&Lauri.Watts;
2015-05-15
Applications 15.04
&kruler; can be used to measure objects on the screen.
KDE
KRuler
kdegraphics
Introduction
&kruler; is a very simple application, with only one aim in life. To
-measure pixel distances and colors on your screen. It is useful for working on
-layout of dialogs, web pages &etc;
+measure pixel distances on your screen. It is useful for working on layout
+of dialogs, web pages &etc;
To start &kruler;, choose ApplicationsGraphics
More Applications
Screen Ruler from your application menu.
&kruler;
&kruler;
Clicking with the &LMB; on the &kruler; will turn the cursor to a cross
with four arrows and enables you to drag &kruler; around the screen.
-When you move the mouse over &kruler;, your cursor will turn into an
-elongated arrow, with a circle at one end. As you move the cursor, &kruler; will
-display how far from the point marked 0 the circle on the
-end of the cursor currently is. &kruler; will also display the
-&HTML; color code of the color currently under the circle.
-This is very useful for picking out colors from an image. If you move the
-mouse far enough that the arrow cursor is no longer touching &kruler;, the
-cursor will revert to normal, allowing you to carry on working with your other
-applications.
+When you move the mouse over &kruler;, your cursor will turn into a
+red arrow. As you move the cursor, &kruler; will
+display how far from the origin the cursor currently is.
+
+
+You can resize the ruler by moving the mouse over the handle on the
+left or right edges of &kruler; (the top or bottom edges when it is oriented
+vertically), holding down the &LMB; and dragging the handle.
-You can change the orientation in three different ways:
+You can change the orientation in two different ways:
Clicking the &MMB; switches the ruler from vertical to horizontal orientation
-By clicking the rotation buttons to turn 90 degrees to the left or right.
-If the rotation buttons are not displayed on the ruler, enable them with Show
-rotation buttons in the settings dialog
Using the context menu, described in the next chapter
Credits and License
&kruler;
Copyright 2000, 2001 Till Krech till@snafu.de
Copyright 2009 Mathias Soeken msoeken@tzi.de
Thanks to Gunnstein Lye gl@ez.no for the initial port to
&kde; 2
Documentation Copyright &Lauri.Watts;
&Lauri.Watts.mail;
&underFDL;
&underGPL;
&documentation.index;
diff --git a/doc/kruler.png b/doc/kruler.png
index 78712b3..d231218 100644
Binary files a/doc/kruler.png and b/doc/kruler.png differ
diff --git a/klineal.cpp b/klineal.cpp
index 1a3ba8b..70050e5 100644
--- a/klineal.cpp
+++ b/klineal.cpp
@@ -1,1225 +1,939 @@
/***************************************************************************
klineal.cpp - description
-------------------
Begin : Fri Oct 13 2000
Copyright : 2000 by Till Krech
2008 by Mathias Soeken
+ 2017 by Aurélien Gâteau
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "klineal.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "krulerconfig.h"
#ifdef KRULER_HAVE_X11
#include
#include
#endif
#include "kruler.h"
#include "krulersystemtray.h"
-#include "qautosizelabel.h"
#include "ui_cfg_appearance.h"
#include "ui_cfg_advanced.h"
-/**
- * this is our cursor bitmap:
- * a line 48 pixels long with an arrow pointing down
- * and a sqare with a one pixel hole at the top (end)
- */
-static const uchar cursorBits[] = {
- 0x38, 0x28, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10,
-};
+static const int RESIZE_HANDLE_LENGTH = 7;
+static const int RESIZE_HANDLE_THICKNESS = 24;
+static const qreal RESIZE_HANDLE_OPACITY = 0.3;
+
+static const int SMALL_TICK_SIZE = 6;
+static const int MEDIUM1_TICK_SIZE = 10;
+static const int MEDIUM2_TICK_SIZE = 15;
+static const int LARGE_TICK_SIZE = 18;
+static const qreal TICK_OPACITY = 0.3;
+
+static const int THICKNESS = 70;
+
+static const qreal OVERLAY_OPACITY = 0.1;
+static const qreal OVERLAY_BORDER_OPACITY = 0.3;
+
+static const int INDICATOR_MARGIN = 6;
+static const int INDICATOR_RECT_RADIUS = 3;
+static const qreal INDICATOR_RECT_OPACITY = 0.6;
+
+static const int CURSOR_SIZE = 15; // Must be an odd number
/**
* create the thingy with no borders and set up
* its members
*/
KLineal::KLineal( QWidget *parent )
: QWidget( parent ),
- mDragging( false ),
- mShortEdgeLen( 70 ),
+ mRulerState( StateNone ),
mCloseAction( 0 ),
- mLenMenu( 0 ), // INFO This member could be eventually deleted
- // since if mFullScreenAction is initialized
- // mLenMenu should have been, too.
- mFullScreenAction( 0 ),
mScaleDirectionAction( 0 ),
mCenterOriginAction( 0 ),
mOffsetAction( 0 ),
mClicked( false ),
mActionCollection( 0 ),
- mCloseButton( 0 ),
mTrayIcon( 0 )
{
setAttribute( Qt::WA_TranslucentBackground );
KWindowSystem::setType( winId(), NET::Override ); // or NET::Normal
KWindowSystem::setState( winId(), NET::KeepAbove );
setWindowTitle( i18nc( "@title:window", "KRuler" ) );
- setMinimumSize( 60, 60 );
+ setMinimumSize( THICKNESS, THICKNESS );
setMaximumSize( 8000, 8000 );
- setWhatsThis( i18n( "This is a tool to measure pixel distances and colors on the screen. "
+ setWhatsThis( i18n( "This is a tool to measure pixel distances on the screen. "
"It is useful for working on layouts of dialogs, web pages etc." ) );
setMouseTracking( true );
- QBitmap bim = QBitmap::fromData( QSize( 8, 48 ), cursorBits, QImage::Format_Mono );
- QMatrix m;
- m.rotate( 90.0 );
- mNorthCursor = QCursor( bim, bim, 3, 47 );
- bim = bim.transformed( m );
- mEastCursor = QCursor( bim, bim, 0, 3 );
- bim = bim.transformed( m );
- mSouthCursor = QCursor( bim, bim, 4, 0 );
- bim = bim.transformed( m );
- mWestCursor = QCursor( bim, bim, 47, 4 );
-
- mCurrentCursor = mNorthCursor;
mColor = RulerSettings::self()->bgColor();
mScaleFont = RulerSettings::self()->scaleFont();
- mLongEdgeLen = RulerSettings::self()->length();
- mOrientation = RulerSettings::self()->orientation();
+ int len = RulerSettings::self()->length();
+ mHorizontal = RulerSettings::self()->horizontal();
mLeftToRight = RulerSettings::self()->leftToRight();
mOffset = RulerSettings::self()->offset();
mRelativeScale = RulerSettings::self()->relativeScale();
mAlwaysOnTopLayer = RulerSettings::self()->alwaysOnTop();
- mLabel = new QAutoSizeLabel( this );
- mLabel->setGeometry( 0, height() - 12, 32, 12 );
- mLabel->setWhatsThis( i18n( "This is the current distance measured in pixels." ) );
- mColorLabel = new QAutoSizeLabel( this );
- mColorLabel->setAutoFillBackground( true );
- QFont colorFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
- mColorLabel->setFont( colorFont );
- mColorLabel->move( mLabel->pos() + QPoint(0, 20) );
- mColorLabel->setWhatsThis(i18n("This is the current color in hexadecimal rgb representation"
- " as you may use it in HTML or as a QColor name. "
- "The rectangles background shows the color of the pixel inside the "
- "little square at the end of the line cursor." ) );
-
- mBtnRotateLeft = new QToolButton( this );
- mBtnRotateLeft->setIcon( QIcon::fromTheme( QStringLiteral( "object-rotate-left" ) ) );
- mBtnRotateLeft->setToolTip( i18n( "Turn Left" ) );
- connect(mBtnRotateLeft, &QToolButton::clicked, this, &KLineal::turnLeft);
-
- mBtnRotateRight = new QToolButton( this );
- mBtnRotateRight->setIcon( QIcon::fromTheme( QStringLiteral( "object-rotate-right" ) ) );
- mBtnRotateRight->setToolTip( i18n( "Turn Right" ) );
- connect(mBtnRotateRight, &QToolButton::clicked, this, &KLineal::turnRight);
-
- resize( QSize( mLongEdgeLen, mShortEdgeLen ) );
+ if ( mHorizontal ) {
+ resize( QSize( len, THICKNESS ) );
+ } else {
+ resize( QSize( THICKNESS, len ) );
+ }
+
+ createCrossCursor();
//BEGIN setup menu and actions
mActionCollection = new KActionCollection( this );
mActionCollection->setConfigGroup( QStringLiteral( "Actions" ) );
mMenu = new QMenu( this );
mMenu->addSection( i18n( "KRuler" ) );
- QMenu *oriMenu = new QMenu( i18n( "&Orientation"), this );
- addAction( oriMenu, QIcon::fromTheme( QStringLiteral( "kruler-north" ) ), i18nc( "Turn Kruler North", "&North" ),
- this, SLOT(setNorth()), Qt::Key_N, QStringLiteral( "turn_north" ) );
- addAction( oriMenu, QIcon::fromTheme( QStringLiteral( "kruler-east" ) ), i18nc( "Turn Kruler East", "&East" ),
- this, SLOT(setEast()), Qt::Key_E, QStringLiteral( "turn_east" ) );
- addAction( oriMenu, QIcon::fromTheme( QStringLiteral( "kruler-south" ) ), i18nc( "Turn Kruler South", "&South" ),
- this, SLOT(setSouth()), Qt::Key_S, QStringLiteral( "turn_south" ) );
- addAction( oriMenu, QIcon::fromTheme( QStringLiteral( "kruler-west" ) ), i18nc( "Turn Kruler West", "&West" ),
- this, SLOT(setWest()), Qt::Key_W, QStringLiteral( "turn_west" ) );
- addAction( oriMenu, QIcon::fromTheme( QStringLiteral( "object-rotate-right" ) ), i18n( "&Turn Right" ),
- this, SLOT(turnRight()), Qt::Key_R, QStringLiteral( "turn_right" ) );
- addAction( oriMenu, QIcon::fromTheme( QStringLiteral( "object-rotate-left" ) ), i18n( "Turn &Left" ),
- this, SLOT(turnLeft()), Qt::Key_L, QStringLiteral( "turn_left" ) );
- mMenu->addMenu( oriMenu );
-
- mLenMenu = new QMenu( i18n( "&Length" ), this );
- addAction( mLenMenu, QIcon(), i18nc( "Make Kruler Height Short", "&Short" ),
- this, SLOT(setShortLength()), Qt::CTRL + Qt::Key_S, QStringLiteral( "length_short" ) );
- addAction( mLenMenu, QIcon(), i18nc( "Make Kruler Height Medium", "&Medium" ),
- this, SLOT(setMediumLength()), Qt::CTRL + Qt::Key_M, QStringLiteral( "length_medium" ) );
- addAction( mLenMenu, QIcon(), i18nc( "Make Kruler Height Tall", "&Tall" ),
- this, SLOT(setTallLength()), Qt::CTRL + Qt::Key_T, QStringLiteral( "length_tall" ) );
- addAction( mLenMenu, QIcon(), i18n("&Full Screen Width"),
- this, SLOT(setFullLength()), Qt::CTRL + Qt::Key_F, QStringLiteral( "length_full_length" ) );
- mLenMenu->addSeparator();
- addAction( mLenMenu, QIcon(), i18n( "Length..." ),
- this, SLOT(slotLength()), QKeySequence(), QStringLiteral( "set_length" ) );
- mMenu->addMenu( mLenMenu );
+ addAction( mMenu, QIcon::fromTheme( QStringLiteral( "object-rotate-left" ) ), i18n( "Rotate" ),
+ this, SLOT(rotate()), Qt::Key_R, QStringLiteral( "turn_right" ) );
QMenu* scaleMenu = new QMenu( i18n( "&Scale" ), this );
mScaleDirectionAction = addAction( scaleMenu, QIcon(), i18n( "Right to Left" ),
this, SLOT(switchDirection()), Qt::Key_D, QStringLiteral( "right_to_left" ) );
mCenterOriginAction = addAction( scaleMenu, QIcon(), i18n( "Center Origin" ),
this, SLOT(centerOrigin()), Qt::Key_C, QStringLiteral( "center_origin" ) );
mCenterOriginAction->setEnabled( !mRelativeScale );
mOffsetAction = addAction( scaleMenu, QIcon(), i18n( "Offset..." ),
this, SLOT(slotOffset()), Qt::Key_O, QStringLiteral( "set_offset" ) );
mOffsetAction->setEnabled( !mRelativeScale );
scaleMenu->addSeparator();
QAction *relativeScaleAction = addAction( scaleMenu, QIcon(), i18n( "Percentage" ),
0, 0, QKeySequence(), QStringLiteral( "toggle_percentage" ) );
relativeScaleAction->setCheckable( true );
relativeScaleAction->setChecked( mRelativeScale );
connect(relativeScaleAction, &QAction::toggled, this, &KLineal::switchRelativeScale);
mMenu->addMenu( scaleMenu );
mOpacity = RulerSettings::self()->opacity();
QMenu* opacityMenu = new QMenu( i18n( "O&pacity" ), this );
QWidgetAction *opacityAction = new QWidgetAction( this );
QSlider *slider = new QSlider( this );
slider->setMinimum( 0 );
slider->setMaximum( 255 );
slider->setSingleStep( 1 );
slider->setOrientation( Qt::Horizontal );
slider->setValue( RulerSettings::self()->opacity() );
connect(slider, &QSlider::valueChanged, this, &KLineal::slotOpacity);
opacityAction->setDefaultWidget( slider );
opacityMenu->addAction( opacityAction );
mMenu->addMenu( opacityMenu );
QAction *keyBindings = mActionCollection->addAction( KStandardAction::KeyBindings, this, SLOT(slotKeyBindings()) );
mMenu->addAction( keyBindings );
QAction *preferences = mActionCollection->addAction( KStandardAction::Preferences, this, SLOT(slotPreferences()) );
mMenu->addAction( preferences );
mMenu->addSeparator();
- QAction *copyColorAction = mActionCollection->addAction( KStandardAction::Copy, this, SLOT(copyColor()) );
- copyColorAction->setText( i18n( "Copy Color" ) );
- mMenu->addAction( copyColorAction );
- mMenu->addSeparator();
mMenu->addMenu( ( new KHelpMenu( this, KAboutData::applicationData(), true ) )->menu() );
mMenu->addSeparator();
if ( RulerSettings::self()->trayIcon() ) {
createSystemTray();
}
QAction *quit = mActionCollection->addAction( KStandardAction::Quit, qApp, SLOT(quit()) );
mMenu->addAction( quit );
mActionCollection->associateWidget( this );
mActionCollection->readSettings();
mLastClickPos = geometry().topLeft() + QPoint( width() / 2, height() / 2 );
setWindowFlags( mAlwaysOnTopLayer ? Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
: Qt::FramelessWindowHint );
- hideLabel();
- setOrientation( mOrientation );
-
+ setHorizontal( mHorizontal );
}
KLineal::~KLineal()
{
delete mTrayIcon;
}
-void KLineal::createSystemTray()
+void KLineal::createCrossCursor()
{
- if ( !mCloseAction ) {
- mCloseAction = mActionCollection->addAction( KStandardAction::Close, this, SLOT(slotClose()) );
- mMenu->addAction( mCloseAction );
-
- mCloseButton = new QToolButton( this );
- mCloseButton->setIcon( mCloseAction->icon() );
- mCloseButton->setToolTip( mCloseAction->text().remove( QLatin1Char( '&' ) ) );
- connect(mCloseButton, &QToolButton::clicked, this, &KLineal::slotClose);
- } else {
- mCloseAction->setVisible( true );
+ QPixmap pix( CURSOR_SIZE, CURSOR_SIZE );
+ int halfSize = CURSOR_SIZE / 2;
+ {
+ pix.fill( Qt::transparent );
+ QPainter painter( &pix );
+ painter.setPen( Qt::red );
+ painter.drawLine( 0, halfSize, CURSOR_SIZE - 1, halfSize );
+ painter.drawLine( halfSize, 0, halfSize, CURSOR_SIZE - 1 );
}
+ mCrossCursor = QCursor( pix, halfSize, halfSize );
+}
+
+void KLineal::createSystemTray()
+{
+ mCloseAction = mActionCollection->addAction( KStandardAction::Close, this, SLOT(slotClose()) );
+ mMenu->addAction( mCloseAction );
if ( !mTrayIcon ) {
mTrayIcon = new KRulerSystemTray( QStringLiteral( "kruler" ), this, mActionCollection );
mTrayIcon->setCategory( KStatusNotifierItem::ApplicationStatus );
}
}
QAction* KLineal::addAction( QMenu *menu, const QIcon& icon, const QString& text,
const QObject* receiver, const char* member,
const QKeySequence &shortcut, const QString& name )
{
QAction *action = new QAction( icon, text, mActionCollection );
mActionCollection->setDefaultShortcut( action, shortcut );
if ( receiver ) {
connect( action, SIGNAL(triggered()), receiver, member );
}
menu->addAction( action );
mActionCollection->addAction( name, action );
return action;
}
void KLineal::slotClose()
{
hide();
}
void KLineal::slotQuit()
{
qApp->quit();
}
void KLineal::move( int x, int y )
{
move( QPoint( x, y ) );
}
void KLineal::move(const QPoint &p)
{
setGeometry( QRect( p, size() ) );
}
QPoint KLineal::pos() const
{
return frameGeometry().topLeft();
}
int KLineal::x() const
{
return pos().x();
}
int KLineal::y() const
{
return pos().y();
}
void KLineal::drawBackground( QPainter& painter )
{
QColor a, b, bg = mColor;
QLinearGradient gradient;
- switch ( mOrientation ) {
- case North:
+ if ( mHorizontal ) {
a = bg.light( 120 );
b = bg.dark( 130 );
gradient = QLinearGradient( 1, 0, 1, height() );
- break;
-
- case South:
- b = bg.light( 120 );
- a = bg.dark( 130 );
- gradient = QLinearGradient( 1, 0, 1, height() );
- break;
-
- case West:
+ } else {
a = bg.light( 120 );
b = bg.dark( 130 );
gradient = QLinearGradient( 0, 1, width(), 1 );
- break;
-
- case East:
- b = bg.light( 120 );
- a = bg.dark( 130 );
- gradient = QLinearGradient( 0, 1, width(), 1 );
- break;
}
a.setAlpha( mOpacity );
b.setAlpha( mOpacity );
gradient.setColorAt( 0, a );
gradient.setColorAt( 1, b );
painter.fillRect( rect(), QBrush( gradient ) );
}
-void KLineal::setOrientation( int inOrientation )
+void KLineal::setHorizontal( bool horizontal )
{
QRect r = frameGeometry();
- int nineties = (int)inOrientation - (int)mOrientation;
- mOrientation = ( inOrientation + 4 ) % 4;
- QPoint center = mLastClickPos, newTopLeft;
+ if ( mHorizontal != horizontal ) {
+ r.setSize( r.size().transposed() );
+ }
+ mHorizontal = horizontal;
+ QPoint center = mLastClickPos;
if ( mClicked ) {
center = mLastClickPos;
mClicked = false;
} else {
center = r.topLeft() + QPoint( width() / 2, height() / 2 );
}
- if ( nineties % 2 ) {
- newTopLeft = QPoint( center.x() - height() / 2, center.y() - width() / 2 );
- } else {
- newTopLeft = r.topLeft();
- }
-
- if ( mOrientation == North || mOrientation == South ) {
- r.setSize( QSize( mLongEdgeLen, mShortEdgeLen ) );
- } else {
- r.setSize( QSize( mShortEdgeLen, mLongEdgeLen ) );
- }
-
+ QPoint newTopLeft = QPoint( center.x() - height() / 2, center.y() - width() / 2 );
r.moveTo(newTopLeft);
QRect desktop = QApplication::desktop()->screenGeometry( this );
+ if ( r.width() > desktop.width() ) {
+ r.setWidth( desktop.width() );
+ }
+
+ if ( r.height() > desktop.height() ) {
+ r.setHeight( desktop.height() );
+ }
+
if ( r.top() < desktop.top() ) {
r.moveTop( desktop.top() );
}
if ( r.bottom() > desktop.bottom() ) {
r.moveBottom( desktop.bottom() );
}
if ( r.left() < desktop.left() ) {
r.moveLeft( desktop.left() );
}
if ( r.right() > desktop.right() ) {
r.moveRight( desktop.right() );
}
setGeometry( r );
- switch( mOrientation ) {
- case North:
- mLabel->move( 4, height()-mLabel->height() - 4 );
- mColorLabel->move( mLabel->pos() + QPoint( 0, -20 ) );
- mCurrentCursor = mNorthCursor;
- break;
-
- case South:
- mLabel->move( 4, 4 );
- mColorLabel->move( mLabel->pos() + QPoint( 0, 20 ) );
- mCurrentCursor = mSouthCursor;
- break;
-
- case East:
- mLabel->move( 4, 4 );
- mColorLabel->move( mLabel->pos() + QPoint( 0, 20 ) );
- mCurrentCursor = mEastCursor;
- break;
-
- case West:
- mLabel->move( width()-mLabel->width() - 4, 4 );
- mColorLabel->move( mLabel->pos() + QPoint( -5, 20 ) );
- mCurrentCursor = mWestCursor;
- break;
- }
-
- adjustButtons();
-
- if ( mLenMenu && mFullScreenAction ) {
- mFullScreenAction->setText( mOrientation % 2 ? i18n( "&Full Screen Height" ) : i18n( "&Full Screen Width" ) );
- }
updateScaleDirectionMenuItem();
- setCursor( mCurrentCursor );
- repaint();
saveSettings();
}
-void KLineal::setNorth()
-{
- setOrientation( North );
-}
-
-void KLineal::setEast()
+void KLineal::rotate()
{
- setOrientation( East );
-}
-
-void KLineal::setSouth()
-{
- setOrientation( South );
-}
-
-void KLineal::setWest()
-{
- setOrientation( West );
-}
-
-void KLineal::turnRight()
-{
- setOrientation( mOrientation - 1 );
-}
-
-void KLineal::turnLeft()
-{
- setOrientation( mOrientation + 1 );
-}
-
-void KLineal::reLength( int percentOfScreen )
-{
- if ( percentOfScreen < 10 ) {
- return;
- }
-
- QRect r = QApplication::desktop()->screenGeometry( this );
-
- if ( mOrientation == North || mOrientation == South ) {
- mLongEdgeLen = r.width() * percentOfScreen / 100;
- resize( mLongEdgeLen, height() );
- } else {
- mLongEdgeLen = r.height() * percentOfScreen / 100;
- resize( width(), mLongEdgeLen );
- }
-
- if ( x() + width() < 10 ) {
- move( 10, y() );
- }
-
- if ( y() + height() < 10 ) {
- move( x(), 10 );
- }
-
- adjustButtons();
- saveSettings();
-}
-
-void KLineal::reLengthAbsolute( int length )
-{
- if ( length < 100 ) {
- return;
- }
-
- mLongEdgeLen = length;
- if ( mOrientation == North || mOrientation == South ) {
- resize( mLongEdgeLen, height() );
- } else {
- resize( width(), mLongEdgeLen );
- }
-
- if ( x() + width() < 10 ) {
- move( 10, y() );
- }
-
- if ( y() + height() < 10 ) {
- move( x(), 10 );
- }
-
- adjustButtons();
- saveSettings();
+ setHorizontal( !mHorizontal );
}
void KLineal::updateScaleDirectionMenuItem()
{
if ( !mScaleDirectionAction ) return;
QString label;
- if ( mOrientation == North || mOrientation == South ) {
+ if ( mHorizontal ) {
label = mLeftToRight ? i18n( "Right to Left" ) : i18n( "Left to Right" );
} else {
label = mLeftToRight ? i18n( "Bottom to Top" ) : i18n( "Top to Bottom" );
}
mScaleDirectionAction->setText( label );
}
-void KLineal::setShortLength()
+QRect KLineal::beginRect() const
{
- reLength( 30 );
+ int shortLen = RESIZE_HANDLE_THICKNESS;
+ return mHorizontal
+ ? QRect( 0, ( height() - shortLen ) / 2 + 1, RESIZE_HANDLE_LENGTH, shortLen )
+ : QRect( ( width() - shortLen ) / 2, 0, shortLen, RESIZE_HANDLE_LENGTH );
}
-void KLineal::setMediumLength()
+QRect KLineal::endRect() const
{
- reLength( 50 );
+ int shortLen = RESIZE_HANDLE_THICKNESS;
+ return mHorizontal
+ ? QRect( width() - RESIZE_HANDLE_LENGTH, ( height() - shortLen ) / 2 + 1, RESIZE_HANDLE_LENGTH, shortLen )
+ : QRect( ( width() - shortLen ) / 2, height() - RESIZE_HANDLE_LENGTH, shortLen, RESIZE_HANDLE_LENGTH );
}
-void KLineal::setTallLength()
+Qt::CursorShape KLineal::resizeCursor() const
{
- reLength( 75 );
-}
-
-void KLineal::setFullLength()
-{
- reLength( 100 );
+ return mHorizontal ? Qt::SizeHorCursor : Qt::SizeVerCursor;
}
void KLineal::switchDirection()
{
mLeftToRight = !mLeftToRight;
updateScaleDirectionMenuItem();
repaint();
- adjustLabel();
saveSettings();
}
void KLineal::centerOrigin()
{
- mOffset = -( mLongEdgeLen / 2 );
+ mOffset = -( length() / 2 );
repaint();
- adjustLabel();
saveSettings();
}
void KLineal::slotOffset()
{
bool ok;
int newOffset = QInputDialog::getInt( this, i18nc( "@title:window", "Scale Offset" ),
i18n( "Offset:" ), mOffset,
-2147483647, 2147483647, 1, &ok );
if ( ok ) {
mOffset = newOffset;
repaint();
- adjustLabel();
saveSettings();
}
}
-void KLineal::slotLength()
-{
- bool ok;
- QRect r = QApplication::desktop()->screenGeometry( this );
- int width = ( ( mOrientation == North ) || ( mOrientation == South ) ) ? r.width() : r.height();
- int newLength = QInputDialog::getInt( this, i18nc( "@title:window", "Ruler Length" ),
- i18n( "Length:" ), mLongEdgeLen,
- 0, width, 1, &ok );
-
- if ( ok ) {
- reLengthAbsolute( newLength );
- }
-}
-
void KLineal::slotOpacity( int value )
{
mOpacity = value;
repaint();
RulerSettings::self()->setOpacity( value );
RulerSettings::self()->save();
}
void KLineal::slotKeyBindings()
{
KShortcutsDialog::configure( mActionCollection );
}
void KLineal::slotPreferences()
{
KConfigDialog *dialog = new KConfigDialog( this, QStringLiteral( "settings" ), RulerSettings::self() );
Ui::ConfigAppearance appearanceConfig;
QWidget *appearanceConfigWidget = new QWidget( dialog );
appearanceConfig.setupUi( appearanceConfigWidget );
- appearanceConfig.kcfg_CloseButtonVisible->setEnabled( appearanceConfig.kcfg_TrayIcon->isChecked() );
dialog->addPage( appearanceConfigWidget, i18n( "Appearance" ), QStringLiteral( "preferences-desktop-default-applications" ) );
#ifdef KRULER_HAVE_X11
// Advanced page only contains the "Native moving" and "Always on top" settings, disable when not running on X11
if ( QX11Info::isPlatformX11() ) {
Ui::ConfigAdvanced advancedConfig;
QWidget *advancedConfigWidget = new QWidget( dialog );
advancedConfig.setupUi( advancedConfigWidget );
dialog->addPage( advancedConfigWidget, i18n( "Advanced" ), QStringLiteral( "preferences-other" ) );
}
#endif
connect(dialog, &KConfigDialog::settingsChanged, this, &KLineal::loadConfig);
dialog->exec();
delete dialog;
}
void KLineal::loadConfig()
{
mColor = RulerSettings::self()->bgColor();
mScaleFont = RulerSettings::self()->scaleFont();
mAlwaysOnTopLayer = RulerSettings::self()->alwaysOnTop();
saveSettings();
setWindowFlags( mAlwaysOnTopLayer ? Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
: Qt::FramelessWindowHint );
if ( RulerSettings::self()->trayIcon() ) {
if ( !mTrayIcon ) {
createSystemTray();
- //need to adjust button
- adjustButtons();
}
} else {
delete mTrayIcon;
mTrayIcon = 0;
if ( mCloseAction ) {
mCloseAction->setVisible( false );
}
}
show();
repaint();
}
void KLineal::switchRelativeScale( bool checked )
{
mRelativeScale = checked;
mCenterOriginAction->setEnabled( !mRelativeScale );
mOffsetAction->setEnabled( !mRelativeScale );
repaint();
- adjustLabel();
saveSettings();
}
/**
* save the ruler color to the config file
*/
void KLineal::saveSettings()
{
RulerSettings::self()->setBgColor( mColor );
RulerSettings::self()->setScaleFont( mScaleFont );
- RulerSettings::self()->setLength( mLongEdgeLen );
- RulerSettings::self()->setOrientation( mOrientation );
+ RulerSettings::self()->setLength( length() );
+ RulerSettings::self()->setHorizontal( mHorizontal );
RulerSettings::self()->setLeftToRight( mLeftToRight );
RulerSettings::self()->setOffset( mOffset );
RulerSettings::self()->setRelativeScale( mRelativeScale );
RulerSettings::self()->setAlwaysOnTop( mAlwaysOnTopLayer );
RulerSettings::self()->save();
}
-void KLineal::copyColor()
-{
- QApplication::clipboard()->setText( mColorLabel->text() );
-}
-
/**
* lets the context menu appear at current cursor position
*/
void KLineal::showMenu()
{
QPoint pos = QCursor::pos();
mMenu->popup( pos );
}
-/**
- * overwritten to switch the value label and line cursor on
- */
-void KLineal::enterEvent( QEvent *inEvent )
+bool KLineal::isResizing() const
{
- Q_UNUSED( inEvent );
-
- if ( !mDragging ) {
- showLabel();
- }
+ return mouseGrabber() == this && ( mRulerState == StateBegin || mRulerState == StateEnd );
}
-/**
- * overwritten to switch the value label and line cursor off
- */
-void KLineal::leaveEvent( QEvent *inEvent )
+int KLineal::length() const
{
- Q_UNUSED( inEvent );
-
- if ( !geometry().contains( QCursor::pos() ) ) {
- hideLabel();
- }
+ return mHorizontal ? width() : height();
}
-/**
- * shows the value lable
- */
-void KLineal::showLabel()
+QPoint KLineal::localCursorPos() const
{
- adjustLabel();
- mLabel->show();
- mColorLabel->show();
- if ( RulerSettings::self()->rotateButtonsVisible() ) {
- mBtnRotateLeft->show();
- mBtnRotateRight->show();
- }
- if ( mCloseButton &&
- RulerSettings::self()->closeButtonVisible() &&
- RulerSettings::self()->trayIcon()) {
- mCloseButton->show();
- }
+ // For some reason mapFromGlobal( QCursor::pos() ) thinks the ruler is at 0, 0 at startup.
+ // compute the position ourselves to avoid that.
+ return QCursor::pos() - pos();
}
-/**
- * hides the value label
- */
-void KLineal::hideLabel()
+QString KLineal::indicatorText() const
{
- mLabel->hide();
- mColorLabel->hide();
- mBtnRotateLeft->hide();
- mBtnRotateRight->hide();
- if ( mCloseButton ) {
- mCloseButton->hide();
- }
-}
-
-/**
- * updates the current value label
- */
-void KLineal::adjustLabel()
-{
- QString s;
- QPoint cpos = QCursor::pos();
-
- int digit = ( mOrientation == North || mOrientation == South ) ? cpos.x() - x() : cpos.y() - y();
-
+ int xy = mHorizontal ? localCursorPos().x() : localCursorPos().y();
if ( !mRelativeScale ) {
- if ( mLeftToRight ) {
- digit += mOffset;
- } else {
- digit = mLongEdgeLen - digit + mOffset;
- }
+ int len = mLeftToRight ? xy + 1 : length() - xy;
+ return i18n( "%1 px", len );
} else {
- // INFO: Perhaps use float also for displaying relative value
- digit = (int)( ( digit * 100.f ) / mLongEdgeLen );
+ int len = ( xy * 100.f ) / length();
if ( !mLeftToRight ) {
- digit = 100 - digit;
+ len = 100 - len;
}
- }
-
- s.sprintf( "%d%s", digit, ( mRelativeScale ? "%" : " px" ) );
- mLabel->setText( s );
-}
-
-/**
- * Updates the position of the tool buttons
- */
-void KLineal::adjustButtons()
-{
- switch( mOrientation ) {
- case North:
- mBtnRotateLeft->move( mLongEdgeLen / 2 - 28, height() - 31 );
- mBtnRotateRight->move( mLongEdgeLen / 2 + 2, height() - 31 );
- if ( mCloseButton ) {
- mCloseButton->move( width() - 31, height() - 31 );
- }
- break;
-
- case South:
- mBtnRotateLeft->move( mLongEdgeLen / 2 - 28, 5 );
- mBtnRotateRight->move( mLongEdgeLen / 2 + 2, 5 );
- if ( mCloseButton ) {
- mCloseButton->move( width() - 31, 5 );
- }
- break;
-
- case East:
- mBtnRotateLeft->move( 5, mLongEdgeLen / 2 - 28 );
- mBtnRotateRight->move( 5, mLongEdgeLen / 2 + 2 );
- if ( mCloseButton ) {
- mCloseButton->move( 5, height() - 31 );
- }
- break;
-
- case West:
- mBtnRotateLeft->move( width() - 31, mLongEdgeLen / 2 - 28 );
- mBtnRotateRight->move( width() - 31, mLongEdgeLen / 2 + 2 );
- if ( mCloseButton ) {
- mCloseButton->move( width() - 31, height() - 31 );
- }
- break;
+ return i18n( "%1%", len );
}
}
void KLineal::keyPressEvent( QKeyEvent *e )
{
QPoint dist;
switch ( e->key() ) {
case Qt::Key_F1:
KHelpClient::invokeHelp();
return;
case Qt::Key_Left:
dist.setX( -1 );
break;
case Qt::Key_Right:
dist.setX( 1 );
break;
case Qt::Key_Up:
dist.setY( -1 );
break;
case Qt::Key_Down:
dist.setY( 1 );
break;
default:
QWidget::keyPressEvent(e);
return;
}
if ( e->modifiers() & Qt::ShiftModifier ) {
dist *= 10;
}
move( pos() + dist );
KNotification::event( QString(), QStringLiteral( "cursormove" ), QString() );
}
-/**
- * overwritten to handle the line cursor which is a separate widget outside the main
- * window. Also used for dragging.
- */
+void KLineal::leaveEvent( QEvent *e )
+{
+ Q_UNUSED( e );
+ update();
+}
+
void KLineal::mouseMoveEvent( QMouseEvent *inEvent )
{
Q_UNUSED( inEvent );
- if ( mDragging && this == mouseGrabber() ) {
-#ifdef KRULER_HAVE_X11
- if ( !QX11Info::isPlatformX11() || !RulerSettings::self()->nativeMoving() ) {
-#endif
+ if ( mRulerState >= StateMove ) {
+ if ( mouseGrabber() != this ) {
+ return;
+ }
+ if ( mRulerState == StateMove ) {
move( QCursor::pos() - mDragOffset );
-#ifdef KRULER_HAVE_X11
+ } else if ( mRulerState == StateBegin ) {
+ QRect r = geometry();
+ if ( mHorizontal ) {
+ r.setLeft( QCursor::pos().x() - mDragOffset.x() );
+ } else {
+ r.setTop( QCursor::pos().y() - mDragOffset.y() );
+ }
+ setGeometry( r );
+ } else if ( mRulerState == StateEnd ) {
+ QPoint end = QCursor::pos() + mDragOffset - pos();
+ QSize size = mHorizontal
+ ? QSize( end.x(), height() )
+ : QSize( width(), end.y() );
+ resize( size );
}
-#endif
} else {
- QPoint p = QCursor::pos();
-
- switch ( mOrientation ) {
- case North:
- p.setY( p.y() - 46 );
- break;
-
- case East:
- p.setX( p.x() + 46 );
- break;
-
- case West:
- p.setX( p.x() - 46 );
- break;
-
- case South:
- p.setY( p.y() + 46 );
- break;
- }
-
- QColor color = pixelColor( p );
- int h, s, v;
- color.getHsv( &h, &s, &v );
- mColorLabel->setText( color.name().toUpper() );
- QPalette palette = mColorLabel->palette();
- palette.setColor( mColorLabel->backgroundRole(), color );
- if ( v < 255 / 2 ) {
- v = 255;
+ QPoint cpos = localCursorPos();
+ mRulerState = StateNone;
+ if ( beginRect().contains( cpos ) || endRect().contains( cpos) ) {
+ setCursor( resizeCursor() );
} else {
- v = 0;
+ setCursor( mCrossCursor );
}
- color.setHsv( h, s, v );
- palette.setColor( mColorLabel->foregroundRole(), color );
- mColorLabel->setPalette( palette );
- adjustLabel();
+ update();
}
}
/**
* overwritten for dragging and context menu
*/
void KLineal::mousePressEvent( QMouseEvent *inEvent )
{
mLastClickPos = QCursor::pos();
- hideLabel();
QRect gr = geometry();
- mDragOffset = mLastClickPos - QPoint( gr.left(), gr.top() );
+ mDragOffset = mLastClickPos - gr.topLeft();
if ( inEvent->button() == Qt::LeftButton ) {
-#ifdef KRULER_HAVE_X11
- if ( QX11Info::isPlatformX11() && RulerSettings::self()->nativeMoving() ) {
- xcb_ungrab_pointer( QX11Info::connection(), QX11Info::appTime() );
- NETRootInfo wm_root( QX11Info::connection(), NET::WMMoveResize );
- wm_root.moveResizeRequest( winId(), inEvent->globalX(), inEvent->globalY(), NET::Move );
- } else {
-#endif
- if ( !mDragging ) {
- grabMouse( Qt::SizeAllCursor );
- mDragging = true;
+ if ( mRulerState < StateMove ) {
+ if ( beginRect().contains( mDragOffset ) ) {
+ mRulerState = StateBegin;
+ grabMouse( resizeCursor() );
+ } else if ( endRect().contains( mDragOffset ) ) {
+ mDragOffset = gr.bottomRight() - mLastClickPos;
+ mRulerState = StateEnd;
+ grabMouse( resizeCursor() );
+ } else {
+ if ( nativeMove() ) {
+ startNativeMove( inEvent );
+ } else {
+ mRulerState = StateMove;
+ grabMouse( Qt::SizeAllCursor );
+ }
}
-#ifdef KRULER_HAVE_X11
}
-#endif
} else if ( inEvent->button() == Qt::MidButton ) {
mClicked = true;
- turnLeft();
+ rotate();
} else if ( inEvent->button() == Qt::RightButton ) {
showMenu();
}
}
+#ifdef KRULER_HAVE_X11
+bool KLineal::nativeMove() const
+{
+ return QX11Info::isPlatformX11() && RulerSettings::self()->nativeMoving();
+}
+
+void KLineal::startNativeMove( QMouseEvent *inEvent )
+{
+ xcb_ungrab_pointer( QX11Info::connection(), QX11Info::appTime() );
+ NETRootInfo wm_root( QX11Info::connection(), NET::WMMoveResize );
+ wm_root.moveResizeRequest( winId(), inEvent->globalX(), inEvent->globalY(), NET::Move );
+}
+
+void KLineal::stopNativeMove( QMouseEvent *inEvent )
+{
+ NETRootInfo wm_root( QX11Info::connection(), NET::WMMoveResize );
+ wm_root.moveResizeRequest( winId(), inEvent->globalX(), inEvent->globalY(), NET::MoveResizeCancel );
+}
+#else
+bool KLineal::nativeMove() const
+{
+ return false;
+}
+
+void KLineal::startNativeMove( QMouseEvent *inEvent )
+{
+ Q_UNUSED( inEvent );
+}
+
+void KLineal::stopNativeMove( QMouseEvent *inEvent )
+{
+ Q_UNUSED( inEvent );
+}
+#endif
+
/**
* overwritten for dragging
*/
void KLineal::mouseReleaseEvent( QMouseEvent *inEvent )
{
- Q_UNUSED( inEvent );
-
-#ifdef KRULER_HAVE_X11
- if ( QX11Info::isPlatformX11() && RulerSettings::self()->nativeMoving() ) {
- NETRootInfo wm_root( QX11Info::connection(), NET::WMMoveResize );
- wm_root.moveResizeRequest( winId(), inEvent->globalX(), inEvent->globalY(), NET::MoveResizeCancel );
- } else {
-#endif
- if ( mDragging ) {
- mDragging = false;
- releaseMouse();
- }
-#ifdef KRULER_HAVE_X11
+ if ( mRulerState != StateNone ) {
+ mRulerState = StateNone;
+ releaseMouse();
+ saveSettings();
+ } else if ( nativeMove() ) {
+ stopNativeMove( inEvent );
}
-#endif
-
- showLabel();
}
void KLineal::wheelEvent( QWheelEvent *e )
{
int numDegrees = e->delta() / 8;
int numSteps = numDegrees / 15;
// changing offset
if ( e->buttons() == Qt::LeftButton ) {
if ( !mRelativeScale ) {
- mLabel->show();
mOffset += numSteps;
repaint();
- mLabel->setText( i18n( "Offset: %1", mOffset ) );
saveSettings();
}
- } else { // changing length
- int oldLen = mLongEdgeLen;
- int newLength = mLongEdgeLen + numSteps;
- reLengthAbsolute( newLength );
- mLabel->setText( i18n( "Length: %1 px", mLongEdgeLen ) );
-
- // when holding shift relength at the other side
- if ( e->modifiers() & Qt::ShiftModifier ) {
- int change = mLongEdgeLen - oldLen;
-
- QPoint dist;
-
- if ( mOrientation == North || mOrientation == South ) {
- dist.setX( -change );
- } else {
- dist.setY( -change );
- }
-
- move( pos() + dist );
- }
}
QWidget::wheelEvent( e );
}
/**
* draws the scale according to the orientation
*/
void KLineal::drawScale( QPainter &painter )
{
painter.setPen( Qt::black );
QFont font = mScaleFont;
painter.setFont( font );
- QFontMetrics metrics = painter.fontMetrics();
- int longLen;
- int shortStart;
- int w = width();
- int h = height();
-
- // draw a frame around the whole thing
- // (for some unknown reason, this doesn't show up anymore)
- switch ( mOrientation ) {
- case North:
- default:
- shortStart = 0;
- longLen = w;
- painter.drawLine( 0, 0, 0, h - 1 );
- painter.drawLine( 0, h - 1, w - 1, h - 1 );
- painter.drawLine( w - 1, h - 1, w - 1, 0 );
- break;
-
- case East:
- shortStart = w;
- longLen = h;
- painter.drawLine( 0, 0, 0, h - 1 );
- painter.drawLine( 0, h - 1, w - 1, h - 1 );
- painter.drawLine( w - 1, 0, 0, 0 );
- break;
-
- case South:
- shortStart = h;
- longLen = w;
- painter.drawLine( 0, 0, 0, h - 1 );
- painter.drawLine( w - 1, h - 1, w - 1, 0 );
- painter.drawLine( w - 1, 0, 0, 0 );
- break;
-
- case West:
- shortStart = 0;
- longLen = h;
- painter.drawLine( 0, h - 1, w - 1, h - 1 );
- painter.drawLine( w - 1, h - 1, w - 1, 0 );
- painter.drawLine( w - 1, 0, 0, 0 );
- break;
- }
+ int longLen = length();
if ( !mRelativeScale ) {
int digit;
int len;
- for ( int x = 0; x < longLen; ++x ) {
+ // Draw from -1 to longLen rather than from 0 to longLen - 1 to take into
+ // account the offset applied in drawScaleTick
+ for ( int x = -1; x <= longLen; ++x ) {
if ( mLeftToRight ) {
digit = x + mOffset;
} else {
digit = longLen - x + mOffset;
}
if ( digit % 2 ) continue;
- len = 6;
-
- if ( digit % 10 == 0 ) len = 10;
- if ( digit % 20 == 0 ) len = 15;
- if ( digit % 100 == 0 ) len = 18;
+ if ( digit % 100 == 0 ) {
+ len = LARGE_TICK_SIZE;
+ } else if ( digit % 20 == 0 ) {
+ len = MEDIUM2_TICK_SIZE;
+ } else if (digit % 10 == 0) {
+ len = MEDIUM1_TICK_SIZE;
+ } else {
+ len = SMALL_TICK_SIZE;
+ }
- if ( digit % 20 == 0 ) {
- font.setBold( digit % 100 == 0 );
- painter.setFont( font );
+ if ( digit % 100 == 0 && digit != 0 ) {
QString units;
units.sprintf( "%d", digit );
- QSize textSize = metrics.size( Qt::TextSingleLine, units );
- int tw = textSize.width();
- int th = textSize.height();
-
- switch ( mOrientation ) {
- case North:
- painter.drawText( x - tw / 2, shortStart + len + th, units );
- break;
-
- case South:
- painter.drawText( x - tw / 2, shortStart - len - 2, units );
- break;
-
- case East:
- painter.drawText( shortStart - len - tw - 2, x + th / 2 - 2, units );
- break;
-
- case West:
- painter.drawText( shortStart + len + 2, x + th / 2 - 2, units );
- break;
- }
+ drawScaleText( painter, x, units );
}
- switch( mOrientation ) {
- case North:
- painter.drawLine( x, shortStart, x, shortStart + len );
- break;
- case South:
- painter.drawLine( x, shortStart, x, shortStart - len );
- break;
- case East:
- painter.drawLine( shortStart, x, shortStart - len, x );
- break;
- case West:
- painter.drawLine( shortStart, x, shortStart + len, x );
- break;
- }
+ drawScaleTick( painter, x, len );
}
} else {
float step = longLen / 100.f;
int len;
- font.setBold( true );
- painter.setFont( font );
-
for ( int i = 0; i <= 100; ++i ) {
int x = (int)( i * step );
- len = ( i % 10 ) ? 6 : 15;
- if ( i % 10 == 0 ) {
+ if ( i % 10 == 0 && i != 0 && i != 100 ) {
QString units;
int value = mLeftToRight ? i : ( 100 - i );
units.sprintf( "%d%%", value );
- QSize textSize = metrics.size( Qt::TextSingleLine, units );
- int tw = textSize.width();
- int th = textSize.height();
-
- switch ( mOrientation ) {
- case North:
- painter.drawText( x - tw / 2, shortStart + len + th, units );
- break;
-
- case South:
- painter.drawText( x - tw / 2, shortStart - len - 2, units );
- break;
-
- case East:
- painter.drawText( shortStart - len - tw - 2, x + th / 2 - 2, units );
- break;
-
- case West:
- painter.drawText( shortStart + len + 2, x + th / 2 - 2, units );
- break;
- }
+ drawScaleText( painter, x, units );
+ len = MEDIUM2_TICK_SIZE;
+ } else {
+ len = SMALL_TICK_SIZE;
}
- switch( mOrientation ) {
- case North:
- painter.drawLine( x, shortStart, x, shortStart + len );
- break;
- case South:
- painter.drawLine( x, shortStart, x, shortStart - len );
- break;
- case East:
- painter.drawLine( shortStart, x, shortStart - len, x );
- break;
- case West:
- painter.drawLine( shortStart, x, shortStart + len, x );
- break;
- }
+ drawScaleTick( painter, x, len );
}
}
}
+void KLineal::drawScaleText( QPainter &painter, int x, const QString &text )
+{
+ QFontMetrics metrics = painter.fontMetrics();
+ QSize textSize = metrics.size( Qt::TextSingleLine, text );
+ int w = width();
+ int h = height();
+ int tw = textSize.width();
+ int th = metrics.ascent();
+
+ if ( mHorizontal ) {
+ painter.drawText( x - tw / 2, (h + th) / 2, text );
+ } else {
+ painter.drawText( (w - tw) / 2, x + th / 2, text );
+ }
+}
+
+void KLineal::drawScaleTick( QPainter &painter, int x, int len )
+{
+ painter.setOpacity( TICK_OPACITY );
+ int w = width();
+ int h = height();
+ // Offset by one because we are measuring lengths, not positions, so when the
+ // indicator is at position 0 it measures a length of 1 pixel.
+ if ( mLeftToRight ) {
+ --x;
+ } else {
+ ++x;
+ }
+ if ( mHorizontal ) {
+ painter.drawLine( x, 0, x, len );
+ painter.drawLine( x, h, x, h - len );
+ } else {
+ painter.drawLine( 0, x, len, x );
+ painter.drawLine( w, x, w - len, x );
+ }
+ painter.setOpacity( 1 );
+}
+
+void KLineal::drawResizeHandle( QPainter &painter, Qt::Edge edge )
+{
+ QRect rect;
+ switch ( edge ) {
+ case Qt::LeftEdge:
+ case Qt::TopEdge:
+ rect = beginRect();
+ break;
+ case Qt::RightEdge:
+ case Qt::BottomEdge:
+ rect = endRect();
+ break;
+ }
+ painter.setOpacity( RESIZE_HANDLE_OPACITY );
+ if ( mHorizontal ) {
+ int y1 = ( THICKNESS - RESIZE_HANDLE_THICKNESS ) / 2;
+ int y2 = y1 + RESIZE_HANDLE_THICKNESS - 1;
+ for ( int x = rect.left() + 1; x < rect.right(); x += 2 ) {
+ painter.drawLine( x, y1, x, y2 );
+ }
+ } else {
+ int x1 = ( THICKNESS - RESIZE_HANDLE_THICKNESS ) / 2;
+ int x2 = x1 + RESIZE_HANDLE_THICKNESS - 1;
+ for ( int y = rect.top() + 1; y < rect.bottom(); y += 2 ) {
+ painter.drawLine( x1, y, x2, y );
+ }
+ }
+ painter.setOpacity( 1 );
+}
+
+void KLineal::drawIndicatorOverlay( QPainter &painter, int xy )
+{
+ painter.setPen( Qt::red );
+ painter.setOpacity( OVERLAY_OPACITY );
+ if ( mHorizontal ) {
+ QPointF p1( mLeftToRight ? 0 : width(), 0 );
+ QPointF p2( xy, THICKNESS );
+ QRectF rect( p1, p2 );
+ painter.fillRect( rect, Qt::red );
+
+ painter.setOpacity( OVERLAY_BORDER_OPACITY );
+ painter.drawLine( xy, 0, xy, THICKNESS );
+ } else {
+ QPointF p1( 0, mLeftToRight ? 0 : height() );
+ QPointF p2( THICKNESS, xy );
+ QRectF rect( p1, p2 );
+ painter.fillRect( rect, Qt::red );
+
+ painter.setOpacity( OVERLAY_BORDER_OPACITY );
+ painter.drawLine( 0, xy, THICKNESS, xy );
+ }
+}
+
+void KLineal::drawIndicatorText( QPainter &painter, int xy )
+{
+ QString text = indicatorText();
+ painter.setFont( font() );
+ QFontMetrics fm = QFontMetrics( font() );
+ int tx, ty;
+ int tw = fm.width( text );
+ if ( mHorizontal ) {
+ tx = xy + INDICATOR_MARGIN;
+ if ( tx + tw > width() ) {
+ tx = xy - tw - INDICATOR_MARGIN;
+ }
+ ty = height() - SMALL_TICK_SIZE - INDICATOR_RECT_RADIUS;
+ } else {
+ tx = ( width() - tw ) / 2;
+ ty = xy + fm.ascent() + INDICATOR_MARGIN;
+ if ( ty > height() ) {
+ ty = xy - INDICATOR_MARGIN;
+ }
+ }
+
+ // Draw background rect
+ painter.setRenderHint( QPainter::Antialiasing );
+ painter.setOpacity( INDICATOR_RECT_OPACITY );
+ painter.setBrush( Qt::red );
+ QRectF bgRect( tx, ty - fm.ascent() + 1, tw, fm.ascent() );
+ bgRect.adjust( -INDICATOR_RECT_RADIUS, -INDICATOR_RECT_RADIUS, INDICATOR_RECT_RADIUS, INDICATOR_RECT_RADIUS );
+ bgRect.translate( 0.5, 0.5 );
+ painter.drawRoundedRect( bgRect, INDICATOR_RECT_RADIUS, INDICATOR_RECT_RADIUS );
+
+ // Draw text
+ painter.setOpacity( 1 );
+ painter.setPen( Qt::white );
+ painter.drawText( tx, ty, text );
+}
+
/**
* actually draws the ruler
*/
void KLineal::paintEvent(QPaintEvent *inEvent )
{
Q_UNUSED( inEvent );
QPainter painter( this );
drawBackground( painter );
drawScale( painter );
-}
-QColor KLineal::pixelColor(const QPoint &p)
-{
- const QDesktopWidget *desktop = QApplication::desktop();
- QScreen *screen = QGuiApplication::screens().at(desktop->screenNumber());
- const QPixmap pixmap = screen->grabWindow(desktop->winId(), p.x(), p.y(), 1, 1);
- return QColor(pixmap.toImage().pixel(QPoint(0, 0)));
+ drawResizeHandle( painter, mHorizontal ? Qt::LeftEdge : Qt::TopEdge );
+ drawResizeHandle( painter, mHorizontal ? Qt::RightEdge : Qt::BottomEdge );
+ if ( underMouse() && !isResizing() ) {
+ int xy = mHorizontal ? localCursorPos().x() : localCursorPos().y();
+ drawIndicatorOverlay( painter, xy );
+ drawIndicatorText( painter, xy );
+ }
}
-
diff --git a/klineal.h b/klineal.h
index ef75632..efea641 100644
--- a/klineal.h
+++ b/klineal.h
@@ -1,135 +1,127 @@
/***************************************************************************
klineal.h - description
-------------------
begin : Fri Oct 13 2000
Copyright : (C) 2000 - 2008 by Till Krech
(C) 2009 by Mathias Soeken
+ (C) 2017 by Aurélien Gâteau
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef KLINEAL_H
#define KLINEAL_H
#include
class QAction;
-class QAutoSizeLabel;
class QIcon;
class QMenu;
class QToolButton;
class KActionCollection;
class KRulerSystemTray;
class KLineal : public QWidget {
Q_OBJECT
public:
- enum { North = 0, West, South, East };
-
KLineal( QWidget *parent = 0 );
~KLineal();
void move( int x, int y );
void move( const QPoint &p );
QPoint pos() const;
int x() const;
int y() const;
protected:
void keyPressEvent( QKeyEvent *e );
+ void leaveEvent( QEvent *e );
void mousePressEvent( QMouseEvent *e );
void mouseReleaseEvent( QMouseEvent *e );
void mouseMoveEvent( QMouseEvent *e );
void wheelEvent( QWheelEvent *e );
void paintEvent( QPaintEvent *e );
- void enterEvent( QEvent *e );
- void leaveEvent( QEvent *e );
void createSystemTray();
private:
+ void createCrossCursor();
QAction* addAction( QMenu *menu, const QIcon& icon, const QString& text,
const QObject* receiver, const char* member,
const QKeySequence &shortcut, const QString& name );
void drawScale( QPainter &painter );
void drawBackground( QPainter &painter );
- void reLength( int percentOfScreen );
- void reLengthAbsolute( int length );
+ void drawScaleText( QPainter &painter, int x, const QString &text );
+ void drawScaleTick( QPainter &painter, int x, int length );
+ void drawResizeHandle( QPainter &painter, Qt::Edge edge );
+ void drawIndicatorOverlay( QPainter &painter, int xy );
+ void drawIndicatorText( QPainter &painter, int xy );
void updateScaleDirectionMenuItem();
- QColor pixelColor( const QPoint &p );
- bool mDragging;
+ QRect beginRect() const;
+ QRect midRect() const;
+ QRect endRect() const;
+ Qt::CursorShape resizeCursor() const;
+ bool nativeMove() const;
+ void startNativeMove( QMouseEvent *e );
+ void stopNativeMove( QMouseEvent *e );
+ QString indicatorText() const;
+
+ enum RulerState {
+ StateNone,
+ StateMove,
+ StateBegin,
+ StateEnd
+ };
+ QCursor mCrossCursor;
+ RulerState mRulerState;
QPoint mLastClickPos;
QPoint mDragOffset;
- QAutoSizeLabel *mLabel;
- QAutoSizeLabel *mColorLabel;
- int mOrientation;
- int mLongEdgeLen;
- int mShortEdgeLen;
+ bool mHorizontal;
QMenu *mMenu;
QAction *mCloseAction;
- QMenu *mLenMenu;
- QAction *mFullScreenAction;
QAction *mScaleDirectionAction;
QAction *mCenterOriginAction;
QAction *mOffsetAction;
QColor mColor;
- QCursor mCurrentCursor;
- QCursor mNorthCursor;
- QCursor mEastCursor;
- QCursor mWestCursor;
- QCursor mSouthCursor;
- QCursor mDragCursor;
QFont mScaleFont;
bool mAlwaysOnTopLayer;
bool mClicked;
bool mLeftToRight;
int mOffset;
bool mRelativeScale;
KActionCollection *mActionCollection;
int mOpacity;
- QToolButton *mBtnRotateLeft, *mBtnRotateRight;
- QToolButton *mCloseButton;
KRulerSystemTray *mTrayIcon;
+ void setHorizontal( bool horizontal );
+
+ bool isResizing() const;
+ int length() const;
+ QPoint localCursorPos() const;
+
public slots:
- void setOrientation( int );
- void setNorth();
- void setEast();
- void setSouth();
- void setWest();
- void turnLeft();
- void turnRight();
+ void rotate();
void showMenu();
- void hideLabel();
- void showLabel();
- void adjustLabel();
- void adjustButtons();
- void setShortLength();
- void setMediumLength();
- void setTallLength();
- void setFullLength();
void switchDirection();
void centerOrigin();
void slotOffset();
- void slotLength();
void slotOpacity( int value );
void slotKeyBindings();
void slotPreferences();
void switchRelativeScale( bool checked );
- void copyColor();
void saveSettings();
void slotClose();
void slotQuit();
void loadConfig();
};
#endif
diff --git a/kruler.kcfg b/kruler.kcfg
index c51ae61..efcb870 100644
--- a/kruler.kcfg
+++ b/kruler.kcfg
@@ -1,60 +1,52 @@
QFontDatabase
QColor(255, 200, 80)
600
QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont)
-
-
- 2
+
+
+ true
true
0
false
false
255
-
-
- false
-
-
-
- false
-
false
true
diff --git a/qautosizelabel.cpp b/qautosizelabel.cpp
deleted file mode 100644
index 2b98349..0000000
--- a/qautosizelabel.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-// //
-// Copyright (C) 2008 Mathias Soeken //
-// //
-// This program is free software; you can redistribute it and/or //
-// modify it under the terms of the GNU General Public License //
-// as published by the Free Software Foundation; either version 2 //
-// of the License, or (at your option) any later version. //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program; if not, write to the Free Software //
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA //
-// 02110-1301, USA. //
-////////////////////////////////////////////////////////////////////////////
-
-#include "qautosizelabel.h"
-
-#include
-
-QAutoSizeLabel::QAutoSizeLabel( QWidget *parent, Qt::WindowFlags f )
- : QLabel( parent, f )
-{
- resize();
-}
-
-QAutoSizeLabel::QAutoSizeLabel( const QString &text, QWidget *parent, Qt::WindowFlags f )
- : QLabel( text, parent, f )
-{
- resize();
-}
-
-QAutoSizeLabel::~QAutoSizeLabel()
-{
-}
-
-void QAutoSizeLabel::setText( const QString &text )
-{
- QLabel::setText( text );
- resize();
-}
-
-void QAutoSizeLabel::resize()
-{
- QFontMetrics fm( font(), this );
- QLabel::resize( fm.size( Qt::TextSingleLine, text() ) );
-}
-
-
diff --git a/qautosizelabel.h b/qautosizelabel.h
deleted file mode 100644
index ce65470..0000000
--- a/qautosizelabel.h
+++ /dev/null
@@ -1,41 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-// //
-// Copyright (C) 2008 Mathias Soeken //
-// //
-// This program is free software; you can redistribute it and/or //
-// modify it under the terms of the GNU General Public License //
-// as published by the Free Software Foundation; either version 2 //
-// of the License, or (at your option) any later version. //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program; if not, write to the Free Software //
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA //
-// 02110-1301, USA. //
-////////////////////////////////////////////////////////////////////////////
-
-#ifndef QAUTOSIZELABEL_H
-#define QAUTOSIZELABEL_H
-
-#include
-
-class QAutoSizeLabel : public QLabel {
- Q_OBJECT
-
- public:
- explicit QAutoSizeLabel( QWidget *parent = 0, Qt::WindowFlags f = 0 );
- explicit QAutoSizeLabel( const QString &text, QWidget *parent = 0, Qt::WindowFlags f = 0 );
- virtual ~QAutoSizeLabel();
-
- public Q_SLOTS:
- void setText( const QString &text );
-
- private:
- void resize();
-};
-
-#endif