[fondue-commits] [SCM] Fondue Font Editor branch, master, updated. 2cf97815e81742c38cb4fdfac148a651cc5fd446
Eugeniy Meshcheryakov
eugen at debian.org
Mon Apr 28 23:58:52 UTC 2008
The following commit has been merged in the master branch:
commit 2cf97815e81742c38cb4fdfac148a651cc5fd446
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date: Tue Apr 29 01:58:35 2008 +0200
add tools window and implement several edit modes
diff --git a/gui/glyphcell.cxx b/gui/glyphcell.cxx
index bf5d3f3..2546c39 100644
--- a/gui/glyphcell.cxx
+++ b/gui/glyphcell.cxx
@@ -28,7 +28,8 @@
#include "fontdocument.h"
GlyphCell::GlyphCell(Glyph *glyph) : QGraphicsView(), m_glyph(glyph),
- m_rubberBand(0), m_rubberActive(false)
+ m_rubberBand(0), m_rubberActive(false), m_pointerMove(false),
+ m_pointerMoved(false)
{
Q_ASSERT(m_glyph);
@@ -39,10 +40,12 @@ GlyphCell::GlyphCell(Glyph *glyph) : QGraphicsView(), m_glyph(glyph),
QGraphicsScene *scene = new QGraphicsScene(this);
scene->setSceneRect(-5000, -5000, 10000, 10000);
setScene(scene);
- setTransformationAnchor(AnchorUnderMouse);
+ setTransformationAnchor(NoAnchor);
gg = new GlyphGraphics(this, m_glyph);
fitGlyph();
+
+ setEditMode(Pointer);
}
void GlyphCell::wheelEvent(QWheelEvent *event)
@@ -182,29 +185,154 @@ void GlyphCell::moveSelection(const QPointF &offset)
void GlyphCell::mousePressEvent(QMouseEvent *event)
{
- m_actionOrigin = event->pos();
- if (!m_rubberBand)
- m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
- m_rubberBand->setGeometry(QRect(m_actionOrigin, QSize()));
- m_rubberBand->show();
- m_rubberActive = true;
+ bool startSelection = false;
+
+ if (m_editMode == Pointer) {
+ // deside wheter to start selection or move selected points
+ // if there is control point under mouse, start moving points
+ // else - show a rubber band
+ QList<QGraphicsItem *> itms = items(event->pos());
+ // find a point, if possible
+ ControlPoint *pt = 0;
+ foreach (QGraphicsItem *i, itms) {
+ if (i->type() == ControlPoint::Type) {
+ pt = dynamic_cast<ControlPoint *>(i);
+ Q_ASSERT(pt);
+ break;
+ }
+ }
+ if (pt) {
+ // user clicked at a control point
+ // start moving, if there is selection...
+ if (!scene()->selectedItems().isEmpty())
+ m_actionOrigin = event->pos();
+ m_pointerMove = true;
+ m_pointerMoved = false;
+ }
+ else
+ startSelection = true;
+ }
+ if (startSelection || m_editMode == Zoom) {
+ m_actionOrigin = event->pos();
+ if (!m_rubberBand)
+ m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
+ m_rubberBand->setGeometry(QRect(m_actionOrigin, QSize()));
+ m_rubberBand->show();
+ m_rubberActive = true;
+ }
+ else if (m_editMode == Hand) {
+ m_actionOrigin = event->pos();
+ setCursor(Qt::ClosedHandCursor);
+ }
}
void GlyphCell::mouseMoveEvent(QMouseEvent *event)
{
- if (m_rubberActive) {
- Q_ASSERT(m_rubberBand);
- m_rubberBand->setGeometry(QRect(m_actionOrigin, event->pos()).normalized());
+ if (event->buttons() != Qt::NoButton) {
+ if (m_rubberActive) {
+ Q_ASSERT(m_rubberBand);
+ m_rubberBand->setGeometry(QRect(m_actionOrigin, event->pos()).normalized());
+ }
+ else if (m_pointerMove) {
+ moveSelection(mapToScene(event->pos()) - mapToScene(m_actionOrigin));
+ m_actionOrigin = event->pos();
+ m_pointerMoved = true;
+ }
+ else if (m_editMode == Hand) {
+ // simple translate() does not work good...
+ QMatrix mtx = matrix();
+ QMatrix newMtx(mtx.m11(), mtx.m12(),
+ mtx.m21(), mtx.m22(),
+ mtx.dx()-m_actionOrigin.x() + event->pos().x(),
+ mtx.dy()-m_actionOrigin.y() + event->pos().y());
+ setMatrix(newMtx);
+ m_actionOrigin = event->pos();
+ }
}
+// qDebug() << "move";
}
void GlyphCell::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
+ Q_ASSERT(scene());
+
if (m_rubberActive) {
Q_ASSERT(m_rubberBand);
m_rubberBand->hide();
m_rubberActive = false;
+
+ if (!m_rubberBand->geometry().isEmpty()) {
+ if (m_editMode == Pointer) {
+ // select
+ bool altSelection = event->modifiers() & Qt::ShiftModifier;
+ QList<QGraphicsItem *> selItems = items(m_rubberBand->geometry(),
+ rubberBandSelectionMode());
+ if (!altSelection)
+ scene()->clearSelection();
+
+ foreach (QGraphicsItem *i, selItems) {
+ if (altSelection)
+ i->setSelected(!i->isSelected());
+ else
+ i->setSelected(true);
+ }
+ }
+ else if (m_editMode == Zoom) {
+ // zoom area
+ QRectF rect = mapToScene(m_rubberBand->geometry()).boundingRect();
+ fitInView(rect, Qt::KeepAspectRatio);
+ }
+ return;
+ }
+ }
+
+ // rubber band is not active, or nothing was selected
+ // handle just mouse click
+ if (m_editMode == Pointer) {
+ if (!m_pointerMove || !m_pointerMoved) {
+ bool altSelection = event->modifiers() & Qt::ShiftModifier;
+
+ if (!altSelection)
+ scene()->clearSelection();
+
+ // TODO handle several items at this position
+ QGraphicsItem *i = itemAt(event->pos());
+ if (i) {
+ if (altSelection)
+ i->setSelected(!i->isSelected());
+ else
+ i->setSelected(true);
+ }
+ }
+ m_pointerMove = false;
+ m_pointerMoved = false;
+ }
+ else if (m_editMode == Hand)
+ setCursor(Qt::OpenHandCursor);
+}
+
+GlyphCell::EditMode GlyphCell::editMode() const
+{
+ return m_editMode;
+}
+
+void GlyphCell::setEditMode(EditMode mode)
+{
+ if (mode != m_editMode) {
+ m_editMode = mode;
+
+ // reset rubber band, just in case
+ m_rubberActive = false;
+ if (m_rubberBand)
+ m_rubberBand->hide();
+
+ // TODO add zoom cursor
+ if (mode == Hand)
+ setCursor(Qt::OpenHandCursor);
+ else
+ unsetCursor();
+
+ emit editModeChanged(mode);
}
- // TODO
}
diff --git a/gui/glyphcell.h b/gui/glyphcell.h
index 12e8cf0..9a195ea 100644
--- a/gui/glyphcell.h
+++ b/gui/glyphcell.h
@@ -24,11 +24,25 @@ class QRubberBand;
class GlyphCell : public QGraphicsView
{
Q_OBJECT
+ Q_ENUMS(GlyphCell::EditMode)
public:
GlyphCell(Glyph *glyph);
void wheelEvent(QWheelEvent *event);
+
+ enum EditMode {
+ Pointer,
+ Contour,
+ OffContour,
+ Split,
+ Hand,
+ Zoom
+ };
+ EditMode editMode() const;
public slots:
+ void setEditMode(GlyphCell::EditMode mode);
void fitGlyph();
+signals:
+ void editModeChanged(GlyphCell::EditMode);
protected:
void drawForeground(QPainter *painter, const QRectF &rect);
void mouseDoubleClickEvent(QMouseEvent *e);
@@ -44,6 +58,9 @@ private:
QPoint m_actionOrigin;
bool m_rubberActive;
+ bool m_pointerMove;
+ bool m_pointerMoved;
+ EditMode m_editMode;
};
#endif
diff --git a/gui/glypheditwidget.cxx b/gui/glypheditwidget.cxx
index 3a27ba3..80abadd 100644
--- a/gui/glypheditwidget.cxx
+++ b/gui/glypheditwidget.cxx
@@ -1,4 +1,4 @@
-/* Copyright © 2007 Євгеній Мещеряков <eugen at debian.org>
+/* Copyright © 2007-2008 Євгеній Мещеряков <eugen at debian.org>
*
* 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
@@ -18,7 +18,6 @@
#include <QMenu>
#include <QAction>
#include <QMenuBar>
-#include <QDockWidget>
#include <QGridLayout>
#include <QToolButton>
#include <QApplication>
@@ -27,6 +26,7 @@
#include <QModelIndex>
#include "glyphsmodel.h"
#include <QDebug>
+#include "glyphtoolswidget.h"
GlyphEditWidget::GlyphEditWidget(QWidget *parent, GlyphsModel *model, const QModelIndex &index) : QMainWindow(parent)
{
@@ -59,6 +59,12 @@ GlyphEditWidget::GlyphEditWidget(QWidget *parent, GlyphsModel *model, const QMod
connect(doc, SIGNAL(fontNameChanged()), this, SLOT(updateWindowTitle()));
connect(m_glyph, SIGNAL(glyphNameChanged(const QString &, const QString &)),
this, SLOT(updateWindowTitle()));
+
+ connect(cell, SIGNAL(editModeChanged(GlyphCell::EditMode)),
+ glyphToolsDock, SLOT(setEditMode(GlyphCell::EditMode)));
+ connect(glyphToolsDock, SIGNAL(editModeChanged(GlyphCell::EditMode)),
+ cell, SLOT(setEditMode(GlyphCell::EditMode)));
+
updateWindowTitle();
}
@@ -92,10 +98,10 @@ void GlyphEditWidget::createMenus()
void GlyphEditWidget::createDockWindows()
{
- QDockWidget *dock = new QDockWidget("Tools", this);
- dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
- addDockWidget(Qt::LeftDockWidgetArea, dock);
- viewMenu->addAction(dock->toggleViewAction());
+ glyphToolsDock = new GlyphToolsWidget(this);
+ glyphToolsDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+ addDockWidget(Qt::LeftDockWidgetArea, glyphToolsDock);
+ viewMenu->addAction(glyphToolsDock->toggleViewAction());
}
void GlyphEditWidget::glyphsAboutToBeRemoved(int start, int end)
diff --git a/gui/glypheditwidget.h b/gui/glypheditwidget.h
index 7fa0183..d333774 100644
--- a/gui/glypheditwidget.h
+++ b/gui/glypheditwidget.h
@@ -1,4 +1,4 @@
-/* Copyright © 2007 Євгеній Мещеряков <eugen at debian.org>
+/* Copyright © 2007-2008 Євгеній Мещеряков <eugen at debian.org>
*
* 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
@@ -21,6 +21,7 @@ class GlyphCell;
class Glyph;
class QModelIndex;
class GlyphsModel;
+class GlyphToolsWidget;
class GlyphEditWidget : public QMainWindow
{
@@ -41,6 +42,7 @@ private:
QMenu *viewMenu;
GlyphCell *cell;
+ GlyphToolsWidget *glyphToolsDock;
Glyph *m_glyph;
};
diff --git a/gui/glyphtoolswidget.cxx b/gui/glyphtoolswidget.cxx
new file mode 100644
index 0000000..07c806e
--- /dev/null
+++ b/gui/glyphtoolswidget.cxx
@@ -0,0 +1,122 @@
+/* Copyright © 2008 Євгеній Мещеряков <eugen at debian.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+#include "glyphtoolswidget.h"
+#include <QGridLayout>
+#include <QToolButton>
+#include <QButtonGroup>
+#include <QFrame>
+#include <QIcon>
+
+QToolButton *GlyphToolsWidget::createToolButton(const QIcon &icon)
+{
+ QToolButton *button = new QToolButton;
+ button->setCheckable(true);
+ button->setIconSize(QSize(24, 24));
+ button->setFixedSize(32, 32);
+ button->setIcon(icon);
+ return button;
+}
+
+GlyphToolsWidget::GlyphToolsWidget(QWidget *parent) : QDockWidget("Tools", parent),
+ m_lastMode(GlyphCell::Pointer)
+{
+
+ // XXX FIXME TODO use resources or place those files somewhere
+ m_pointerButton = createToolButton(QIcon("icons/arrow.png"));
+ m_contourButton = createToolButton(QIcon());
+ m_offContourButton = createToolButton(QIcon());
+ m_splitButton = createToolButton(QIcon());
+ m_handButton = createToolButton(QIcon("icons/hand.png"));
+ m_zoomButton = createToolButton(QIcon("icons/magnify.png"));
+
+ m_pointerButton->setChecked(true);
+
+ QButtonGroup *group = new QButtonGroup(this);
+ group->addButton(m_pointerButton);
+ group->addButton(m_contourButton);
+ group->addButton(m_offContourButton);
+ group->addButton(m_splitButton);
+ group->addButton(m_handButton);
+ group->addButton(m_zoomButton);
+
+ QGridLayout *grid = new QGridLayout;
+ grid->setMargin(2);
+ grid->setSpacing(0);
+
+ grid->addWidget(m_pointerButton, 0, 0);
+ grid->addWidget(m_contourButton, 0, 1);
+ grid->addWidget(m_offContourButton, 1, 0);
+ grid->addWidget(m_splitButton, 1, 1);
+ grid->addWidget(m_handButton, 2, 0);
+ grid->addWidget(m_zoomButton, 2, 1);
+ grid->setRowStretch(3, 1);
+
+ QFrame *frame = new QFrame;
+ frame->setLayout(grid);
+
+ setWidget(frame);
+
+ connect(m_pointerButton, SIGNAL(clicked(bool)), this, SLOT(pointerButtonClicked(bool)));
+ connect(m_contourButton, SIGNAL(clicked(bool)), this, SLOT(contourButtonClicked(bool)));
+ connect(m_offContourButton, SIGNAL(clicked(bool)), this, SLOT(offContourButtonClicked(bool)));
+ connect(m_splitButton, SIGNAL(clicked(bool)), this, SLOT(splitButtonClicked(bool)));
+ connect(m_handButton, SIGNAL(clicked(bool)), this, SLOT(handButtonClicked(bool)));
+ connect(m_zoomButton, SIGNAL(clicked(bool)), this, SLOT(zoomButtonClicked(bool)));
+}
+
+void GlyphToolsWidget::setEditMode(GlyphCell::EditMode mode)
+{
+ if (mode != m_lastMode) {
+ m_lastMode = mode;
+
+ switch (mode) {
+ case GlyphCell::Pointer:
+ m_pointerButton->setChecked(true);
+ break;
+ case GlyphCell::Contour:
+ m_contourButton->setChecked(true);
+ break;
+ case GlyphCell::OffContour:
+ m_offContourButton->setChecked(true);
+ break;
+ case GlyphCell::Split:
+ m_splitButton->setChecked(true);
+ break;
+ case GlyphCell::Hand:
+ m_handButton->setChecked(true);
+ break;
+ case GlyphCell::Zoom:
+ m_zoomButton->setChecked(true);
+ break;
+ }
+
+ emit editModeChanged(mode);
+ }
+}
+
+#define BUTTON_SWITCH(name, mode) \
+void GlyphToolsWidget::name##ButtonClicked(bool checked) \
+{ \
+ if (checked) \
+ setEditMode(GlyphCell::mode); \
+}
+
+BUTTON_SWITCH(pointer, Pointer)
+BUTTON_SWITCH(contour, Contour)
+BUTTON_SWITCH(offContour, OffContour)
+BUTTON_SWITCH(split, Split)
+BUTTON_SWITCH(hand, Hand)
+BUTTON_SWITCH(zoom, Zoom)
diff --git a/gui/glyphtoolswidget.h b/gui/glyphtoolswidget.h
new file mode 100644
index 0000000..57cb513
--- /dev/null
+++ b/gui/glyphtoolswidget.h
@@ -0,0 +1,53 @@
+/* Copyright © 2008 Євгеній Мещеряков <eugen at debian.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GLYPHTOOLSWIDGET_H
+#define GLYPHTOOLSWIDGET_H
+#include <QDockWidget>
+#include "glyphcell.h"
+
+class QToolButton;
+class QIcon;
+
+class GlyphToolsWidget : public QDockWidget
+{
+ Q_OBJECT
+public:
+ GlyphToolsWidget(QWidget *parent = 0);
+public slots:
+ void setEditMode(GlyphCell::EditMode mode);
+signals:
+ void editModeChanged(GlyphCell::EditMode mode);
+private slots:
+ void pointerButtonClicked(bool checked);
+ void contourButtonClicked(bool checked);
+ void offContourButtonClicked(bool checked);
+ void splitButtonClicked(bool checked);
+ void handButtonClicked(bool checked);
+ void zoomButtonClicked(bool checked);
+private:
+ QToolButton *createToolButton(const QIcon &icon);
+
+ QToolButton *m_pointerButton;
+ QToolButton *m_contourButton;
+ QToolButton *m_offContourButton;
+ QToolButton *m_splitButton;
+ QToolButton *m_handButton;
+ QToolButton *m_zoomButton;
+
+ GlyphCell::EditMode m_lastMode;
+};
+
+#endif
diff --git a/gui/gui.rules b/gui/gui.rules
index 525ed60..e333f08 100644
--- a/gui/gui.rules
+++ b/gui/gui.rules
@@ -19,7 +19,8 @@ libfonduegui_a_SOURCES = \
gui/cvteditor.cxx \
gui/maxpeditor.cxx \
gui/glyphitem.cxx \
- gui/documentinfoeditor.cxx
+ gui/documentinfoeditor.cxx \
+ gui/glyphtoolswidget.cxx
nodist_libfonduegui_a_SOURCES = \
gui/ttihighlighter.moc.cxx \
@@ -40,7 +41,8 @@ nodist_libfonduegui_a_SOURCES = \
gui/glyphgraphics.moc.cxx \
gui/documentinfoeditor.moc.cxx \
gui/controlpoint.moc.cxx \
- gui/glyphitem.moc.cxx
+ gui/glyphitem.moc.cxx \
+ gui/glyphtoolswidget.moc.cxx
gui/instnames.tbl.cxx: data/instructions.xml
gui/instnames.tbl.cxx: DATAFILE=$(srcdir)/data/instructions.xml
@@ -66,7 +68,8 @@ noinst_HEADERS += \
gui/cvteditor.h \
gui/maxpeditor.h \
gui/glyphitem.h \
- gui/documentinfoeditor.h
+ gui/documentinfoeditor.h \
+ gui/glyphtoolswidget.h
CLEANFILES += gui/*.moc.cxx gui/*.tbl.cxx
EXTRA_DIST += gui/instnames.xsl
--
Fondue Font Editor
More information about the fondue-commits
mailing list