]> git.zarvox.org Git - shareboard.git/blob - shareboard.cpp
Implement image insertion and placement, tool selection, and eraser.
[shareboard.git] / shareboard.cpp
1 #include "shareboard.h"
2 #include <QStackedLayout>
3
4 #include "shareboardcanvas.h"
5 #include "connectwidget.h"
6 #include "action.h"
7 #include <QDebug>
8 #include <QPainter>
9 #include <QPen>
10 #include <QImage>
11
12 Shareboard::Shareboard(QWidget* parent) : QWidget(parent) {
13         layout = new QStackedLayout(this);
14         prompt = new ConnectWidget(this);
15         canvas = new ShareboardCanvas(this);
16
17         canvas->setModel(this);
18
19         layout->addWidget(prompt);
20         layout->addWidget(canvas);
21         setLayout(layout);
22         setMinimumSize(1024,768);
23
24         // All real userIDs are positive, so we won't trigger the delete in postAction until setUserID is called
25         userID = -1;
26         viewIndex = 0;
27         viewImage = QImage(1024,768,QImage::Format_ARGB32_Premultiplied);
28         viewImage.fill(QColor(Qt::white).rgb());
29
30         QObject::connect(prompt, SIGNAL(connectToServer(QString, QString)), this, SIGNAL(connectToServer(QString, QString)));
31         QObject::connect(canvas, SIGNAL(mouseMovedTo(QPointF)), this, SLOT(handleMouseMoved(QPointF)));
32         QObject::connect(canvas, SIGNAL(segmentDrawn(QPointF,QPointF)), this, SLOT(handleSegmentDrawn(QPointF,QPointF)));
33         QObject::connect(canvas, SIGNAL(insertImage(QPointF)), this, SLOT(handleInsertImage(QPointF)));
34         qDebug() << viewImage.rect();
35 }
36
37 Shareboard::~Shareboard() {
38         for(int i = 0; i < history.size(); i++)
39                 delete history[i];
40         for(int i = 0; i < localHistory.size(); i++)
41                 delete localHistory[i];
42 }
43
44 QImage Shareboard::view() {
45         return viewImage;
46 }
47
48 int Shareboard::getDrawState() {
49         return drawState;
50 }
51
52 void Shareboard::handleMouseMoved(QPointF pos) {
53         MouseMoveAction* action = new MouseMoveAction();
54         action->userID = userID;
55         action->pos = pos;
56         emit actionHappened(action);
57         //qDebug() << "shareboard.cpp: mouse moved to" << pos;
58 }
59
60 void Shareboard::handleSegmentDrawn(QPointF start, QPointF end) {
61         // Add segment to localHistory, dispatch to connMan
62         DrawLineAction* action = new DrawLineAction();
63         action->userID = userID;
64         action->points.append(start);
65         action->points.append(end);
66         Q_ASSERT(action->points.size() >= 2);
67         emit actionHappened(action);
68         //qDebug() << "shareboard.cpp: segment drawn from" << start << "to" << end;
69 }
70
71 void Shareboard::handleInsertImage(QPointF pos) {
72         AddImageAction* action = new AddImageAction();
73         action->userID = userID;
74         action->topLeft = pos;
75         action->image = insertImage;
76         emit actionHappened(action);
77 }
78
79 void Shareboard::postAction(Action* action) {
80         if(action->userID == userID) {
81                 delete localHistory[0];
82                 localHistory.removeFirst();
83         }
84         history.append(action);
85         emit rangeChanged(history.size());
86         jumpToIndex(history.size()); // Jump to the most recent state
87 }
88
89 void Shareboard::postLocalAction(Action* action) {
90         localHistory.append(action);
91 }
92
93 void Shareboard::switchToBoard() {
94         layout->setCurrentWidget(canvas);
95 }
96
97 void Shareboard::switchToPrompt() {
98         layout->setCurrentWidget(prompt);
99 }
100
101 void Shareboard::setUserID(int id) {
102         userID = id;
103         jumpToIndex(history.size());
104 }
105
106 void Shareboard::jumpToIndex(int index) {
107         int i = 0;
108         if(index < viewIndex) {
109                 viewImage = QImage(1024,768,QImage::Format_ARGB32_Premultiplied);
110                 viewImage.fill(QColor(Qt::white).rgb());
111                 viewCursors.clear();
112                 viewUsers.clear();
113         } else {
114                 i = viewIndex;
115         }
116         QPainter p;
117         p.begin(&viewImage);
118         while(i < history.size() && i < index) {
119                 viewTime = history[i]->timestamp;
120                 viewIndex = i;
121                 Action* action = history[i];
122                 // Apply action to pixmap
123                 switch(action->type) {
124                         case Action::INVALID:
125                                 break;
126                         case Action::UserJoin:
127                                 {
128                                         UserJoinAction* a = static_cast<UserJoinAction*>(action);
129                                         viewUsers[a->userID] = a->username;
130                                         qDebug() << "Saw user" << a->username << "join";
131                                 }
132                                 break;
133                         case Action::UserPart:
134                                 {
135                                         qDebug() << "Saw user" << viewUsers[action->userID] << "part";
136                                         viewCursors.remove(action->userID);
137                                         viewUsers.remove(action->userID);
138                                 }
139                                 break;
140                         case Action::MouseMove:
141                                 {
142                                         MouseMoveAction* a = static_cast<MouseMoveAction*>(action);
143                                         viewCursors[a->userID] = a->pos;
144                                 }
145                                 break;
146                         case Action::DrawLine:
147                                 {
148                                         DrawLineAction* a = static_cast<DrawLineAction*>(action);
149                                         QPen pen(a->color);
150                                         pen.setWidth(a->width);
151                                         p.setPen(pen);
152                                         p.drawPolyline(a->points.data(), a->points.size()-1);
153                                 }
154                                 break;
155                         case Action::AddImage:
156                                 {
157                                         AddImageAction* a = static_cast<AddImageAction*>(action);
158                                         p.drawImage(a->topLeft, a->image);
159                                 }
160                         case Action::UserChat:
161                         case Action::UserSynced:
162                                 break;
163                         case Action::ClearBoard:
164                                 {
165                                         viewImage.fill(QColor(Qt::white).rgb());
166                                 }
167                                 break;
168                 }
169                 i++;
170         }
171         p.end();
172         canvas->update();
173         emit indexChanged(viewIndex);
174 }
175
176 void Shareboard::setDrawState(int newstate) {
177         drawState = newstate;
178 }
179
180 void Shareboard::setInsertImage(QImage newimage) {
181         insertImage = newimage;
182 }