summaryrefslogtreecommitdiffstats
path: root/labb3/tiles/mainwindow.cpp
blob: 461d84ad0bd544f92f499cee479f7612e59e0f15 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * TDDD86 Tiles
 * This file contains the implementation of the mainwindow class.
 * See mainwindow.h for comments about each member.
 */

#include <QPointF>
#include <random>
#include "mainwindow.h"
#include "Tile.h"
#include "TileList.h"

// constants
static const int SCENE_WIDTH = 600;
static const int SCENE_HEIGHT = 400;
static const int MIN_SIZE = 20;
static const int MAX_SIZE = 100;
static const int MIN_COLOR = 50;
static const int MAX_COLOR = 255;
static const int TILE_COUNT = 50;
static const bool RANDOM = false;   // set to false for repeatable output

MainWindow::MainWindow(QWidget *parent) :
    QGraphicsView(parent)
{
    // setup graphical window
    scene = new QGraphicsScene();
    this->setScene(scene);
    this->setSceneRect(0, 0, SCENE_WIDTH, SCENE_HEIGHT);
    this->setFixedSize(sizeHint());

    // place several random tiles on the screen
    this->setWindowTitle("Tiles");
    for (int i = 0; i < TILE_COUNT; ++i) {
        addRandomTile(tlist);
    }
    tlist.drawAll(scene);
}

/*
 * Listens to mouse press events from the graphical subsystem,
 * and handles the events appropriately:
 *   - A left-click is a 'raise' action.
 *   - A shift-left-click is a 'lower' action.
 *   - A right-click (or ctrl-click) is a 'delete' action.
 *   - A shift-right-click (or shift-ctrl-click) is a 'delete all' action.
 */
void MainWindow::mousePressEvent(QMouseEvent *e)
{
    QPointF pt = mapToScene(e->pos());
    bool modified = false;
    switch (e->button()) {
    case Qt::LeftButton:
        switch (e->modifiers()) {
        case Qt::NoModifier:
            tlist.raise(pt.x(), pt.y());
            modified = true;
            break;
        case Qt::ShiftModifier:
                tlist.lower(pt.x(), pt.y());
                modified  = true;
            break;
        }
        break;
    case Qt::RightButton:
        switch (e->modifiers()) {
        case Qt::NoModifier:
            tlist.remove(pt.x(), pt.y());
            modified = true;
            break;
        case Qt::ShiftModifier:
                tlist.removeAll(pt.x(), pt.y());
                modified = true;
            break;
        }
        break;
    default:
        QGraphicsView::mousePressEvent(e);
    }
    if (modified) {
        scene->clear();
        tlist.drawAll(scene);
    }
}

/*
 * Listens to key press events from the graphical subsystem,
 * and handles the events appropriately:
 *   - 'N' creates a new random tile.
 */
void MainWindow::keyPressEvent(QKeyEvent *e)
{
    switch (e->key()) {
    case Qt::Key_N:
        addRandomTile(tlist);
        scene->clear();
        tlist.drawAll(scene);
        break;
    default:
        QGraphicsView::keyPressEvent(e);
    }
}


/*
 * Creates a new tile with a random x/y position, width, height, and color,
 * and adds it to the given tile list.
 */
void MainWindow::addRandomTile(TileList &tlist)
{
    Tile tile;
    std::random_device rd;

    // possibly use the same random numbers every time for testing
    static std::default_random_engine e(RANDOM ? rd() : 42);

    std::uniform_int_distribution<unsigned> u1(MIN_COLOR, MAX_COLOR);
    std::uniform_int_distribution<unsigned> u2(MIN_SIZE, MAX_SIZE);
    tile.width = u2(e);
    tile.height = u2(e);
    std::uniform_int_distribution<unsigned> u3(0, SCENE_WIDTH - tile.width - 1);
    std::uniform_int_distribution<unsigned> u4(0, SCENE_HEIGHT - tile.height - 1);
    tile.x = u3(e);
    tile.y = u4(e);
    tile.r = u1(e);
    tile.g = u1(e);
    tile.b = u1(e);
    tlist.addTile(tile);
}