This commit add the remaining required functionality for the assignment.
This code has gone from decent to somewhat ugly in a rather short
timeframe, due to no longer thinking about where data belongs.
}
case Action::AddImage:
{
+ qDebug() << "Sending AddImage action!";
act = new AddImageAction();
AddImageAction* action = static_cast<AddImageAction*>(act);
qreal x = 0;
QObject::connect(board, SIGNAL(indexChanged(int)), sliderWidget, SLOT(setValue(int)));
QObject::connect(sliderWidget, SIGNAL(valueChanged(int)), board, SLOT(jumpToIndex(int)));
+ //QObject::connect(spinboxWidget, SIGNAL(valueChanged(int)), board, SLOT(setDrawState(int)));
+ //QObject::connect(spinboxWidget, SIGNAL(valueChanged(int)), this, SLOT(updateDrawState(int)));
+ QObject::connect(eraserAction, SIGNAL(triggered()), this, SLOT(useEraserTool()));
+ QObject::connect(imageAction, SIGNAL(triggered()), this, SLOT(useImageTool()));
+ QObject::connect(penAction, SIGNAL(triggered()), this, SLOT(usePenTool()));
+
+ usePenTool();
statusBar()->showMessage("Ready");
}
}
+void MainWindow::useEraserTool() {
+ board->setDrawState(spinboxWidget->value() * -1);
+}
+
+void MainWindow::usePenTool() {
+ board->setDrawState(spinboxWidget->value());
+}
+
+void MainWindow::useImageTool() {
+ QString fileName = QFileDialog::getOpenFileName(this, "Insert file:", ".", "Images (*.PNG *.png *.JPG *.jpg)");
+ if(fileName.isEmpty() )
+ return;
+ QImage im;
+ if (!im.load(fileName))
+ return;
+ board->setInsertImage(im);
+ board->setDrawState(0);
+}
+
void MainWindow::updateSliderRange(int newmax) {
sliderWidget->setRange(0, newmax);
}
case Action::DrawLine: // set the action's thickness, color
{
DrawLineAction* a = static_cast<DrawLineAction*>(action);
- a->color = lineColor;
+ if(board->getDrawState() < 0 ) // This should probably all get reworked into MainWindow...
+ a->color = QColor(Qt::white);
+ else
+ a->color = lineColor;
a->width = spinboxWidget->value();
}
break;
// Create some of the basic tool actions.
// They should also be added to an exclusive tool group.
QActionGroup* toolGroup = new QActionGroup(this);
- QAction* penAction = new QAction(QIcon("icons/pen.png"), "Pen", this);
- QAction* eraserAction = new QAction(QIcon("icons/eraser.png"), "Eraser", this);
+ penAction = new QAction(QIcon("icons/pen.png"), "Pen", this);
+ eraserAction = new QAction(QIcon("icons/eraser.png"), "Eraser", this);
penAction->setChecked(true);
toolGroup->addAction(penAction);
toolGroup->addAction(eraserAction);
// Create some other one-click actions that are not a part of the action group.
- QAction* imageAction = new QAction(QIcon("icons/import_image.png"), "Import Image", this);
+ imageAction = new QAction(QIcon("icons/import_image.png"), "Import Image", this);
clearAction = new QAction(QIcon("icons/clear.png"), "Clear", this);
// Style
QAction* restartAction = new QAction(QIcon("icons/rewind.png"), "Replay History", this);
QAction* playAction = new QAction(QIcon("icons/play.png"), "Play", this);
sliderWidget = new QSlider(Qt::Horizontal, this);
+ sliderWidget->setSingleStep(1);
+ sliderWidget->setPageStep(30);
toolBar = addToolBar("Test");
toolBar->setMovable(false);
void clearBoard();
void marshallAction(Action* action);
void updateSliderRange(int newmax);
+ void useEraserTool();
+ void useImageTool();
+ void usePenTool();
private:
void createActions();
void createMenus();
QAction* quitAction;
QAction* colorAction;
QAction* clearAction;
+ QAction* imageAction;
+ QAction* penAction;
+ QAction* eraserAction;
QSpinBox* spinboxWidget;
QSlider* sliderWidget;
ConnectionManager* connMan;
QObject::connect(prompt, SIGNAL(connectToServer(QString, QString)), this, SIGNAL(connectToServer(QString, QString)));
QObject::connect(canvas, SIGNAL(mouseMovedTo(QPointF)), this, SLOT(handleMouseMoved(QPointF)));
QObject::connect(canvas, SIGNAL(segmentDrawn(QPointF,QPointF)), this, SLOT(handleSegmentDrawn(QPointF,QPointF)));
+ QObject::connect(canvas, SIGNAL(insertImage(QPointF)), this, SLOT(handleInsertImage(QPointF)));
qDebug() << viewImage.rect();
}
return viewImage;
}
+int Shareboard::getDrawState() {
+ return drawState;
+}
+
void Shareboard::handleMouseMoved(QPointF pos) {
MouseMoveAction* action = new MouseMoveAction();
action->userID = userID;
//qDebug() << "shareboard.cpp: segment drawn from" << start << "to" << end;
}
+void Shareboard::handleInsertImage(QPointF pos) {
+ AddImageAction* action = new AddImageAction();
+ action->userID = userID;
+ action->topLeft = pos;
+ action->image = insertImage;
+ emit actionHappened(action);
+}
+
void Shareboard::postAction(Action* action) {
if(action->userID == userID) {
delete localHistory[0];
}
break;
case Action::AddImage:
- //TODO Implement this
+ {
+ AddImageAction* a = static_cast<AddImageAction*>(action);
+ p.drawImage(a->topLeft, a->image);
+ }
case Action::UserChat:
case Action::UserSynced:
break;
canvas->update();
emit indexChanged(viewIndex);
}
+
+void Shareboard::setDrawState(int newstate) {
+ drawState = newstate;
+}
+
+void Shareboard::setInsertImage(QImage newimage) {
+ insertImage = newimage;
+}
Shareboard(QWidget* parent = 0);
~Shareboard();
QImage view();
+ int getDrawState();
public slots:
void handleMouseMoved(QPointF pos);
void handleSegmentDrawn(QPointF start, QPointF end);
+ void handleInsertImage(QPointF pos);
void postAction(Action* action);
void postLocalAction(Action* action);
void switchToBoard();
void setUserID(int id);
void jumpToIndex(int index);
//void jumpToTime(QDateTime time);
+ void setDrawState(int newstate);
+ void setInsertImage(QImage newimage);
signals:
void rangeChanged(int max);
History history;
History localHistory;
int userID;
+ int drawState; // if > 0, line width. If < 0, eraser size. If == 0, image tool.
+ QImage insertImage;
// These items represent the present state of the view.
QDateTime viewTime;
QImage viewImage;
void ShareboardCanvas::mouseMoveEvent(QMouseEvent* event) {
// Send mouse move event to network thread
emit mouseMovedTo(event->posF());
+ lastPos = event->posF();
// If the button is down
if(mouseDown) {
emit segmentDrawn(dragPath.last(), event->posF());
void ShareboardCanvas::mousePressEvent(QMouseEvent* event) {
if(event->button() & Qt::LeftButton) {
+ if(board->drawState == 0) {
+ emit insertImage(event->posF());
+ return;
+ }
mouseDown = true;
dragPath.append(event->posF()); // We're starting a new drag path
}
QPainter p(this);
// Paint the background from the saved state
p.drawImage(0, 0, board->view());
- // Now paint our local changes on top of it
+ // Now paint our local changes on top of it (optional, will make things look snappier)
- //p.set
// Now paint the set of mouse cursors on top of that
QMap<int, QPointF>::const_iterator i;
for (i = board->viewCursors.constBegin(); i!=board->viewCursors.constEnd(); ++i) {
+ if(i.key() == board->userID) {
+ if( board->drawState < 0) {// Eraser mode
+ p.setPen(QColor(Qt::black));
+ p.setBrush(QColor(Qt::white));
+ p.drawEllipse(lastPos, qAbs(board->drawState), qAbs(board->drawState));
+ //p.drawEllipse(i.value(), qAbs(board->drawState), qAbs(board->drawState));
+ }
+ if( board->drawState == 0) { // Image mode
+ p.drawImage(lastPos, board->insertImage);
+ }
+ continue;
+ }
QPen pen(QColor(255,0,0,50));
pen.setCapStyle(Qt::RoundCap);
p.setPen(pen);
signals:
void mouseMovedTo(QPointF pos);
void segmentDrawn(QPointF start, QPointF end);
+ void insertImage(QPointF pos);
private:
bool mouseDown;
QVector<QPointF> dragPath;
Shareboard* board;
+ QPointF lastPos;
};
#endif //__SHAREBOARDCANVAS_H__