From: Drew Fisher Date: Fri, 8 Oct 2010 03:32:01 +0000 (-0700) Subject: Complete network support, event passing, and tracking. X-Git-Url: http://git.zarvox.org/shortlog/2010?a=commitdiff_plain;h=a506aeb21f1e7cb4251b92bbf0d8d7dd716bbca9;p=shareboard.git Complete network support, event passing, and tracking. Actions are posted to the server with correct UserID. Enabled actions are currently limited to MouseMove and DrawLine. --- diff --git a/action.cpp b/action.cpp index ed5df1c..436fc0b 100644 --- a/action.cpp +++ b/action.cpp @@ -1,15 +1,21 @@ #include "action.h" +#include +#include +#include +#include "base64.h" Action::Action() { type = INVALID; mesgID = 0; userID = 0; + timestamp = QDateTime::currentDateTime(); } Action::Action(Type t) { type = t; mesgID = 0; userID = 0; + timestamp = QDateTime::currentDateTime(); } Action::~Action() { @@ -54,7 +60,9 @@ UserChatAction::~UserChatAction() { QTextStream& operator<<(QTextStream& out, const Action& action) { out << "0 " << action.userID << " " << action.timestamp.toString("yyyy-MM-ddThh:mm:ss.zzz") << " " << static_cast(action.type) ; // mesgID, userID, timestamp, mesgType switch(action.type) { - case Action::INVALID: break; + case Action::INVALID: + case Action::UserSynced: + break; case Action::UserJoin: { const UserJoinAction* a = static_cast(&action); @@ -79,8 +87,13 @@ QTextStream& operator<<(QTextStream& out, const Action& action) { case Action::AddImage: { const AddImageAction* a = static_cast(&action); - // TODO: unbackburner this - //out << " " << a->topLeft << a->image; + out << " " << a->topLeft.x() << " " << a->topLeft.y(); + QByteArray ba; + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + a->image.save(&buffer, "PNG"); + buffer.close(); + out << toBase64(ba); } break; case Action::UserChat: { diff --git a/action.h b/action.h index 25ba717..7241bb4 100644 --- a/action.h +++ b/action.h @@ -18,7 +18,8 @@ public: MouseMove=3, DrawLine=4, AddImage=5, - UserChat=6 + UserChat=6, + UserSynced=7 }; Action(); diff --git a/connectionmanager.cpp b/connectionmanager.cpp index 0e4d498..88eee47 100644 --- a/connectionmanager.cpp +++ b/connectionmanager.cpp @@ -3,6 +3,8 @@ #include #include #include "action.h" +#include "base64.h" +#include "shareboard.h" ConnectionManager::ConnectionManager(QObject* parent) : QObject(parent) { sock = new QTcpSocket(); @@ -17,6 +19,10 @@ ConnectionManager::~ConnectionManager() { if (sock) delete sock; } +void ConnectionManager::setTarget(Shareboard* t) { + board = t; +} + void ConnectionManager::joinServer(QString _username, QString host) { username = _username; quint16 port = 4260; @@ -28,6 +34,7 @@ void ConnectionManager::sendAction(Action* action) { QByteArray output; QTextStream t(&output); t << (*action); + t.flush(); qDebug() << "Sending" << output.size() << "bytes for action of type" << action->type; sock->write(output); } @@ -140,9 +147,8 @@ void ConnectionManager::haveData() { QString im; textstream >> im; // im is a base64-encoded binary string. - - - + QByteArray ba = fromBase64(im); // Convert back to binary data + action->image.loadFromData(ba, "PNG"); action->mesgID = mesgID; action->userID = userID; action->timestamp = timestamp; @@ -165,13 +171,20 @@ void ConnectionManager::haveData() { action->text = chat; break; } + case Action::UserSynced: + { + board->setUserID(userID); + qDebug() << "User is synced :)"; + continue; + } + break; default: qWarning() << "Received invalid type from server :("; continue; } Q_ASSERT(act != NULL); - // HistoryManager::instance()->newAction(action); + board->postAction(act); qDebug() << "Dispatched action with type " << act->type << " that was " << data.size() << " bytes long"; } diff --git a/connectionmanager.h b/connectionmanager.h index 74f981f..7f9263b 100644 --- a/connectionmanager.h +++ b/connectionmanager.h @@ -9,6 +9,7 @@ class Action; class QTcpSocket; +class Shareboard; class ConnectionManager : public QObject{ Q_OBJECT @@ -22,6 +23,7 @@ class ConnectionManager : public QObject{ void disconnected(); void error(QString e); public slots: + void setTarget(Shareboard* t); void joinServer(QString _username, QString host); void sendAction(Action* action); void onError(); @@ -30,6 +32,7 @@ class ConnectionManager : public QObject{ //QByteArray data; QTcpSocket* sock; QTextStream* textStream; + Shareboard* board; private slots: void haveData(); void onConnect(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 872d247..5eca4c8 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -9,21 +9,24 @@ #include "connectionmanager.h" #include "shareboard.h" +#include "action.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { createActions(); createMenus(); - connMan = new ConnectionManager(this); - board = new Shareboard(this); setCentralWidget(board); + connMan = new ConnectionManager(this); + connMan->setTarget(board); + // Connect all actions QObject::connect(board, SIGNAL(connectToServer(QString, QString)), connMan, SLOT(joinServer(QString, QString))); QObject::connect(connMan, SIGNAL(connected()), this, SLOT(switchToBoard())); QObject::connect(connMan, SIGNAL(disconnected()), this, SLOT(switchToConnect())); QObject::connect(connMan, SIGNAL(error(QString)), this, SLOT(showError(QString))); + QObject::connect(board, SIGNAL(actionHappened(Action*)), this, SLOT(marshallAction(Action*))); statusBar()->showMessage("Ready"); } @@ -64,7 +67,6 @@ void MainWindow::quit() { } void MainWindow::switchToBoard() { - // Here, we set the central widget to be the as-of-yet unimplemented Shareboard widget board->switchToBoard(); statusBar()->showMessage(QString("Switched to Shareboard drawing surface")); } @@ -78,8 +80,22 @@ void MainWindow::showError(QString error) { statusBar()->showMessage(error); } +void MainWindow::marshallAction(Action* action) { + switch(action->type) { + case Action::DrawLine: // set the action's thickness, color + { + DrawLineAction* a = static_cast(action); + a->color == Qt::blue; + a->width = 3; + } + break; + default: break; + } + board->postLocalAction(action); + connMan->sendAction(action); +} + void MainWindow::createActions() { - //joinAction = new QAction("Joi&n a board online", this); loadPastAction = new QAction("&Open a board", this); saveAction = new QAction("&Save board", this); quitAction = new QAction("&Quit", this); @@ -91,7 +107,6 @@ void MainWindow::createActions() { void MainWindow::createMenus() { fileMenu = menuBar()->addMenu("&File"); - //fileMenu->addAction(joinAction); fileMenu->addAction(loadPastAction); fileMenu->addAction(saveAction); fileMenu->addSeparator(); diff --git a/mainwindow.h b/mainwindow.h index 8f06f98..692bc3c 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -8,6 +8,7 @@ class QAction; class ConnectWidget; class ConnectionManager; class Shareboard; +class Action; class MainWindow : public QMainWindow { Q_OBJECT @@ -22,6 +23,7 @@ public slots: void switchToBoard(); void switchToConnect(); void showError(QString error); + void marshallAction(Action* action); private: void createActions(); void createMenus(); diff --git a/shareboard.cpp b/shareboard.cpp index 902c274..cd39d63 100644 --- a/shareboard.cpp +++ b/shareboard.cpp @@ -3,6 +3,8 @@ #include "shareboardcanvas.h" #include "connectwidget.h" +#include "action.h" +#include Shareboard::Shareboard(QWidget* parent) : QWidget(parent) { layout = new QStackedLayout(this); @@ -15,10 +17,46 @@ Shareboard::Shareboard(QWidget* parent) : QWidget(parent) { setMinimumSize(640,480); 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))); } Shareboard::~Shareboard() { + for(int i = 0; i < history.size(); i++) + delete history[i]; + for(int i = 0; i < localHistory.size(); i++) + delete localHistory[i]; +} + +void Shareboard::handleMouseMoved(QPointF pos) { + MouseMoveAction* action = new MouseMoveAction(); + action->userID = userID; + action->pos = pos; + localHistory.append(action); + emit actionHappened(action); + qDebug() << "shareboard.cpp: mouse moved to" << pos; +} + +void Shareboard::handleSegmentDrawn(QPointF start, QPointF end) { + // Add segment to localHistory, dispatch to connMan + DrawLineAction* action = new DrawLineAction(); + action->userID = userID; + action->points.append(start); + action->points.append(end); + emit actionHappened(action); + qDebug() << "shareboard.cpp: segment drawn from" << start << "to" << end; +} +void Shareboard::postAction(Action* action) { + if(action->userID == userID) { + delete localHistory[0]; + localHistory.removeFirst(); + } + history.append(action); +} + +void Shareboard::postLocalAction(Action* action) { + localHistory.append(action); } void Shareboard::switchToBoard() { @@ -28,3 +66,7 @@ void Shareboard::switchToBoard() { void Shareboard::switchToPrompt() { layout->setCurrentWidget(prompt); } + +void Shareboard::setUserID(int id) { + userID = id; +} diff --git a/shareboard.h b/shareboard.h index 9bfa28f..f4422b0 100644 --- a/shareboard.h +++ b/shareboard.h @@ -2,11 +2,15 @@ #define __SHAREBOARD_H__ #include +#include class QStackedLayout; class ConnectWidget; class ShareboardCanvas; +class Action; +typedef QList History; + class Shareboard : public QWidget { Q_OBJECT public: @@ -14,16 +18,25 @@ class Shareboard : public QWidget { ~Shareboard(); public slots: + void handleMouseMoved(QPointF pos); + void handleSegmentDrawn(QPointF start, QPointF end); + void postAction(Action* action); + void postLocalAction(Action* action); void switchToBoard(); void switchToPrompt(); + void setUserID(int id); signals: void connectToServer(QString, QString); + void actionHappened(Action* action); private: QStackedLayout* layout; ConnectWidget* prompt; ShareboardCanvas* canvas; + History history; + History localHistory; + int userID; }; #endif // __SHAREBOARD_H__ diff --git a/shareboard.pro b/shareboard.pro index 8ffb581..6a14cc4 100644 --- a/shareboard.pro +++ b/shareboard.pro @@ -10,5 +10,20 @@ DEPENDPATH += . INCLUDEPATH += . # Input -HEADERS += mainwindow.h action.h connectwidget.h connectionmanager.h shareboard.h shareboardcanvas.h base64.h -SOURCES += main.cpp mainwindow.cpp action.cpp connectwidget.cpp connectionmanager.cpp shareboard.cpp shareboardcanvas.cpp base64.cpp +HEADERS += \ + action.h \ + base64.h \ + connectionmanager.h \ + connectwidget.h \ + mainwindow.h \ + shareboardcanvas.h \ + shareboard.h + +SOURCES += main.cpp \ + action.cpp \ + base64.cpp \ + connectionmanager.cpp \ + connectwidget.cpp \ + mainwindow.cpp \ + shareboardcanvas.cpp \ + shareboard.cpp diff --git a/shareboardcanvas.cpp b/shareboardcanvas.cpp index 06696f2..cc2dae1 100644 --- a/shareboardcanvas.cpp +++ b/shareboardcanvas.cpp @@ -20,27 +20,35 @@ ShareboardCanvas::~ShareboardCanvas() { void ShareboardCanvas::mouseMoveEvent(QMouseEvent* event) { // Send mouse move event to network thread + emit mouseMovedTo(event->posF()); // If the button is down - if(mouseDown) + if(mouseDown) { + emit segmentDrawn(dragPath.last(), event->posF()); dragPath.append(event->posF()); + } // Trigger a repaint update(); } void ShareboardCanvas::mousePressEvent(QMouseEvent* event) { - mouseDown = true; - dragPath.append(event->posF()); // We're starting a new drag path + if(event->button() & Qt::LeftButton) { + mouseDown = true; + dragPath.append(event->posF()); // We're starting a new drag path + } // } void ShareboardCanvas::mouseReleaseEvent(QMouseEvent* event) { - mouseDown = false; - qDebug() << dragPath.size() << "mouse move events counted this drag"; - // Depending on the tool, we now dispatch different types of events - dragPath.clear(); // Clear the path; we're no longer tracking a drag + if(event->button() & Qt::LeftButton) { + mouseDown = false; + qDebug() << dragPath.size() << "mouse move events counted this drag"; + // Depending on the tool, we now dispatch different types of events + dragPath.clear(); // Clear the path; we're no longer tracking a drag + } } void ShareboardCanvas::paintEvent(QPaintEvent* event) { + Q_UNUSED(event) QPainter p(this); // Paint the background from the saved state p.drawPixmap(0, 0, *currentScene); diff --git a/shareboardcanvas.h b/shareboardcanvas.h index 693485d..c48b026 100644 --- a/shareboardcanvas.h +++ b/shareboardcanvas.h @@ -18,6 +18,9 @@ public: void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void paintEvent(QPaintEvent* event); +signals: + void mouseMovedTo(QPointF pos); + void segmentDrawn(QPointF start, QPointF end); private: bool mouseDown; QPixmap* currentScene;