1 #include "schedulescreen.h"
2 #include "schedulepoint.h"
3 #include "globalsettings.h"
4 #include "utilities.h"
6 #include "QtDebug"
8 #include <QRect>
10 //array that holds the times the columns should be initially positioned
11 //0-23.75 in .25 increments (15 min)
12 float columnTimes [] = {5,9.5,17,22};
14 ScheduleScreen::ScheduleScreen(QWidget *parent) :
15 QWidget(parent)
16 {
17 setObjectName("ScheduleScreen");
18 //get an instance of the global configuration
19 m_globalSettings = GlobalSettings::getInstance();
21 // seqNumber will track the number of points that have been created
22 seqNumber = 0;
24 // allow user to click off points to remove blur and see all
25 connect(this, SIGNAL(clicked()), this, SLOT(unselectDay()));
26 //allow valueChanged signal to trigger updateData() slot
27 connect(this, SIGNAL(valueChanged()), this, SLOT(updateData()));
28 // create title
29 QLabel *title = new QLabel("Set your WEEKLY SCHEDULE");
30 title->setObjectName("title");
32 // create time represented by current point
33 currentTime = new QLabel();
34 currentTime->setObjectName("currentTime");
35 currentTime->setMinimumWidth(80);
37 // create back button
38 QPushButton *backButton = new QPushButton();
39 backButton->setIcon(QIcon(":/Images/glossy-blue-orb-icon-arrowback.png"));
40 backButton->setIconSize(QSize(40,40));
41 backButton->setFocusPolicy(Qt::NoFocus);
42 backButton->setObjectName("backButton");
43 connect(backButton,SIGNAL(clicked()),this,SLOT(close()));
45 // create layout for top of screen
46 QHBoxLayout *topLayout = new QHBoxLayout;
47 topLayout->addWidget(currentTime);
48 topLayout->addStretch();
49 topLayout->addWidget(title);
50 topLayout->addStretch();
51 topLayout->addWidget(backButton);
53 view = new QGraphicsView();
54 view->setBackgroundBrush(QBrush(Qt::black));
55 view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
56 view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
57 view->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
58 view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
61 // create final layout
63 QVBoxLayout *mainLayout = new QVBoxLayout;
64 mainLayout->addLayout(topLayout);
65 QHBoxLayout* viewLayout = new QHBoxLayout;
66 viewLayout->addWidget(view);
67 viewLayout->setContentsMargins(0,0,0,0);
68 viewLayout->setSpacing(0);
69 mainLayout->addLayout(viewLayout);
70 mainLayout->setContentsMargins(0,0,0,0);
71 mainLayout->setSpacing(0);
73 QWidget *sizeLimiterWidget = new QWidget;
74 sizeLimiterWidget->setMaximumSize(800, 450);
76 sizeLimiterWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
77 sizeLimiterWidget->setLayout(mainLayout);
78 sizeLimiterWidget->setContentsMargins(0,0,0,0);
79 QHBoxLayout* contentsBox = new QHBoxLayout;
80 contentsBox->setContentsMargins(0,0,0,0);
81 contentsBox->addWidget(sizeLimiterWidget);
83 // show final layout
84 setLayout(contentsBox);
86 resize(qApp->desktop()->size());
87 updateGeometry();
89 scene = NULL;
90 m_initialized = false;
91 currentPoint = NULL;
92 }
94 void ScheduleScreen::createScheduleScene()
95 {
96 QPen pen(Qt::blue);
97 QBrush brush(Qt::black);
98 QFont font = this->font();
99 font.setBold(true);
100 QFontMetrics fm(font);
102 weekHeight = (scene->height()/7.0)-(scene->height()*.025);
104 pointArea.setRect(fm.boundingRect("Wed").width()+20, 15, scene->width(), weekHeight*7);
105 timeWidth = ((pointArea.width() - pointArea.left())/4.0)-((pointArea.width() - pointArea.left())/4.0)/16;
106 timeBlockWidth = timeWidth/24.0; //15 min increments
107 pointArea.adjust(0,0,-timeBlockWidth, 0);
108 QDate date = QDate::fromString("Sun", "ddd");
110 for(int a = 0;a<7;a++)
111 {
112 pen.setColor(QColor(110+40*(a%2),110+40*(a%2),110+40*(a%2)));
113 brush.setColor(QColor(120+40*(a%2),120+40*(a%2),120+40*(a%2)));
115 scene->addRect(0,pointArea.top()+a*weekHeight,pointArea.width(),weekHeight, pen, brush);
117 pen.setColor(QColor(150,150,150));
118 brush.setColor(QColor(180,180,180));
119 scene->addRect(0,pointArea.top()+a*weekHeight,pointArea.left(),weekHeight-1, pen, brush);
121 date = date.addDays(1);
122 QString dateString = date.toString("ddd");
123 pen.setColor(QColor(50,50,50));
124 QPushButton* b = new QPushButton;
125 connect(b, SIGNAL(clicked(bool)), this, SLOT(disableRow(bool)));
126 b->setFlat(true);
127 b->setFont(font);
128 b->setFocusPolicy(Qt::NoFocus);
129 b->setMaximumWidth(pointArea.left()-4);
130 b->setMaximumHeight(weekHeight-4);
131 QPalette buttonPalette(QColor(180,180,180));
132 //buttonPalette.setColor(QPalette::Active, QPalette::Button, QColor(180,180,180));
133 b->setPalette(buttonPalette);
134 b->setCheckable(true);
135 b->setChecked(true);
136 b->setText(dateString);
137 b->setProperty("dayNumber", date.dayOfWeek()-1);
138 QGraphicsProxyWidget* textItem = new QGraphicsProxyWidget;
139 textItem->setWidget(b);
140 scene->addItem(textItem);
142 textItem->setPos(pointArea.left()/2 - textItem->boundingRect().width()/2, pointArea.top()+ a*weekHeight + weekHeight/2 - textItem->boundingRect().height()/2);
143 }
145 scene->addLine(pointArea.left(), pointArea.top()+1, pointArea.left(), scene->height()-1);
147 for(int a = 0;a<5;a++)
148 {
149 pen.setColor(QColor(110+40*(a%2),110+40*(a%2),110+40*(a%2)));
150 brush.setColor(QColor(120+40*(a%2),120+40*(a%2),120+40*(a%2)));
152 QString timeString = formatHourString(QTime(((a)*6)%24,0), m_globalSettings->timeFormat());
154 pen.setColor(QColor(200,200,200));
155 brush.setColor(QColor(200,200,200));
156 QGraphicsSimpleTextItem* textItem = scene->addSimpleText(timeString, font);
158 textItem->setBrush(brush);
159 textItem->setPos(timeBlockWidth*3+pointArea.left()+timeWidth*a - textItem->boundingRect().width()/2, pointArea.bottom() +6);
160 pen.setColor(QColor(188,188,188));
161 pen.setStyle(Qt::DashLine);
162 scene->addLine(timeBlockWidth*3+pointArea.left()+timeWidth*a, pointArea.top()+1, timeBlockWidth*3+pointArea.left()+timeWidth*a, pointArea.bottom()+3, pen);
163 }
165 }
168 void ScheduleScreen::disableRow(bool checked)
169 {
170 QPushButton* button = dynamic_cast<QPushButton* >(this->sender());
171 int index = button->property("dayNumber").toInt()*4;
173 // display only those points that are requested by weekday check boxes
174 if(checked) {
175 //enable all points in the row
176 for(int a = 0;a<4;a++)
177 {
178 pointList.at(index+a)->setDisabled(false);
180 //check each point in the column, if one is selected then select this one and break
181 for(int b=0;b<7;b++)
182 if(pointList.at(a +4*b)->selected())
183 {
184 pointList.at(index+a)->setSelected(true);
185 break;
186 }
187 }
188 button->setStyleSheet("");
189 }
190 else
191 {
192 for(int a = 0;a<4;a++)
193 pointList.at(index+a)->setDisabled(true);
194 button->setStyleSheet("color:#CCCCCC");
195 }
197 return;
199 }
201 void ScheduleScreen::showEvent(QShowEvent *e)
202 {
203 if(!m_initialized)
204 {
205 e->accept();
206 currentPoint = NULL;
207 m_initialized = true;
208 view->show();
209 QTimer::singleShot(0, this, SLOT(initializeGraphics()));
210 }
211 }
213 void ScheduleScreen::initializeGraphics()
214 {
215 initializeScene();
216 createScheduleScene();
217 addSchedulePoints();
218 }
220 void ScheduleScreen::initializeScene()
221 {
222 // create graphics view and scene
223 scene = new QGraphicsScene(0,0,view->width(), view->height());
224 view->setScene(scene);
225 }
227 void ScheduleScreen::updateData()
228 {
229 if(scene)
230 {
231 scene->clear();
232 delete scene;
233 scene = 0;
234 m_initialized = false;
235 pointList.empty();
236 QApplication::sendEvent(this, new QShowEvent);
237 }
238 }
240 void ScheduleScreen::addSchedulePoints()
241 {
242 // create all 28 schedule points with proper connections
243 // fill all points into pointList for easy access
245 for(int a=0;a<28;a++)
246 {
247 SchedulePoint *schedulePoint = new SchedulePoint(a);
248 connect(schedulePoint, SIGNAL(clicked(SchedulePoint *)), this, SLOT(selectDay(SchedulePoint*)));
249 connect(this, SIGNAL(valueChanged()), schedulePoint, SLOT(updateUnit()));
250 schedulePoint->setTimeBlockWidth(timeBlockWidth);
251 schedulePoint->setWeekHeight(weekHeight);
252 schedulePoint->setPointArea(pointArea);
253 showPoint(schedulePoint);
254 pointList.insert(a,schedulePoint);
255 }
257 }
259 void ScheduleScreen::showPoint(SchedulePoint *point)
260 {
261 // show point based on unique ID
262 point->setPos(QPoint(timeBlockWidth*3 + pointArea.left() + (timeBlockWidth * 4 * columnTimes[point->getID()%4]), pointArea.top() + weekHeight/2 + (weekHeight * ((point->getID() / 4) % 7))));
263 scene->addItem(point);
264 }
266 void ScheduleScreen::shiftLeft()
267 {
268 // shift buttons left and shift visible points left in this column unless
269 // left edge of graphics view has been reached
271 if(currentPoint->pos().x()- currentPoint->boundingRect().width()/2- timeBlockWidth > pointArea.left()) {
272 for(int i=0; i<7; i++) {
273 if(pointList.at((currentPoint->getID() + 4*i) % 28)->isVisible()) {
274 pointList.at((currentPoint->getID() + 4*i) % 28)->shiftLeft();
275 }
276 }
277 // change current time represented by position of current point
278 currentTime->setText(currentPoint->time());
279 //qDebug() << currentPoint->pos().x();
280 }
282 }
284 void ScheduleScreen::shiftRight()
285 {
286 // shift buttons right and shift visible points right in this column unless
287 // right edge of graphics view has been reached
288 if(currentPoint->pos().x()+ currentPoint->boundingRect().width()/2+ timeBlockWidth < pointArea.right()) {
289 for(int i=0; i<7; i++) {
290 if(pointList.at((currentPoint->getID() + 4*i) % 28)->isVisible()) {
291 pointList.at((currentPoint->getID() + 4*i) % 28)->shiftRight();
292 }
293 }
294 // change time to reflect new position
295 currentTime->setText(currentPoint->time());
296 //qDebug() << currentPoint->pos().x();
297 }
299 }
301 void ScheduleScreen::increaseTemp()
302 {
303 // increase temp of all visible buttons in this colummn
304 for(int i=0; i<7; i++) {
305 if(pointList.at((currentPoint->getID() + 4*i) % 28)->isVisible()) {
306 pointList.at((currentPoint->getID() + 4*i) % 28)->increaseTemp();
307 }
308 }
309 }
311 void ScheduleScreen::decreaseTemp()
312 {
313 // decrease temp of all visible buttons in this column
314 for(int i=0; i<7; i++) {
315 if(pointList.at((currentPoint->getID() + 4*i) % 28)->isVisible()) {
316 pointList.at((currentPoint->getID() + 4*i) % 28)->decreaseTemp();
317 }
318 }
319 }
321 void ScheduleScreen::selectDay(SchedulePoint *point)
322 {
323 //ifa point has already been clicked on we need to unselect it.
324 if(currentPoint)
325 unselectDay();
327 // track which is the point that has been clicked on
328 currentPoint = point;
329 // show time indicated by position of current point
330 currentTime->setText(currentPoint->time());
332 for(int a = 0; a<7; a++)
333 {
334 SchedulePoint* columnPoint = pointList.at(point->getID()%4 + a*4);
335 if(!columnPoint->disabled())
336 {
337 pointList.at(point->getID()%4 + a*4)->setSelected(true);
338 if(point!=columnPoint)
339 connect(point, SIGNAL(shareAdjustment(int, qreal)), columnPoint, SLOT(adjust(int, qreal)));
340 }
341 }
344 }
346 void ScheduleScreen::unselectDay()
347 {
348 if(!currentPoint)
349 return;
350 for(int a = 0; a<28; a++)
351 {
352 SchedulePoint* point = pointList.at(a);
354 point->setSelected(false);
355 if(currentPoint!=point)
356 disconnect(currentPoint, SIGNAL(shareAdjustment(int, qreal)), point, SLOT(adjust(int, qreal)));
358 }
359 }
361 void ScheduleScreen::mousePressEvent(QMouseEvent * /* event */)
362 {
363 // provide event handler for whole screen, so that user can click off a
364 // a column and have all points be displayed
365 emit clicked();
366 }