[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