File indexing completed on 2024-05-19 07:55:16
0001 /* 0002 SPDX-FileCopyrightText: 2015 Jakob Gruber <jakob.gruber@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "scene.h" 0008 0009 #include "src/constants.h" 0010 0011 Scene::Scene(QSharedPointer<Picmi> game, QObject *parent) : 0012 QGraphicsScene(parent), m_game(game), m_position(0, 0) 0013 { 0014 init(); 0015 } 0016 0017 void Scene::forwardKeyPressEvent(QKeyEvent *event) { 0018 m_cells[xy_to_i(m_position.x(), m_position.y())]->keyPressEvent(event); 0019 } 0020 0021 void Scene::loadBanners() { 0022 m_pause_banner = new PauseBannerItem(); 0023 m_items.push_back(m_pause_banner); 0024 addItem(m_pause_banner); 0025 } 0026 0027 void Scene::loadBackground() { 0028 BackgroundItem *p = new BackgroundItem(Renderer::Background, 0, 0); 0029 m_items.push_back(p); 0030 addItem(p); 0031 } 0032 0033 void Scene::loadCells() { 0034 for (int y = 0; y < m_game->height(); y++) { 0035 for (int x = 0; x < m_game->width(); x++) { 0036 PixmapItem *p = new PixmapItem(Renderer::CellFrame, x, y); 0037 p->setZValue(ZVALUE_CELLFRAME); 0038 m_items.push_back(p); 0039 m_group->addToGroup(p); 0040 0041 GameCellItem *q = new GameCellItem(x, y, m_game, this); 0042 m_items.push_back(q); 0043 m_cells.push_back(q); 0044 m_group->addToGroup(q); 0045 0046 HighlightItem *item = new HighlightItem(Renderer::Highlight, x, y); 0047 m_items.push_back(item); 0048 m_highlights.push_back(item); 0049 m_group->addToGroup(item); 0050 } 0051 } 0052 } 0053 0054 void Scene::loadOverView() { 0055 m_overview_group = new QGraphicsItemGroup; 0056 m_overview_group->setEnabled(false); 0057 for (int y = 0; y < m_game->height(); y++) { 0058 for (int x = 0; x < m_game->width(); x++) { 0059 OverviewCellItem *q = new OverviewCellItem(x, y, m_game); 0060 m_items.push_back(q); 0061 m_overview_cells.push_back(q); 0062 m_overview_group->addToGroup(q); 0063 } 0064 } 0065 m_group->addToGroup(m_overview_group); 0066 } 0067 0068 void Scene::loadStreaks() { 0069 for (int x = 0; x < m_game->width(); x++) { 0070 StreakVBackgroundItem *p = new StreakVBackgroundItem((x % 2) ? Renderer::Streak1 : Renderer::Streak2, x); 0071 m_items.push_back(p); 0072 m_group->addToGroup(p); 0073 0074 ColStreakItem *q = new ColStreakItem(m_game, x); 0075 m_items.push_back(q); 0076 m_col_streaks.push_back(q); 0077 m_group->addToGroup(q); 0078 0079 m_streak_strings.append(q->toPlainText()); 0080 } 0081 0082 for (int y = 0; y < m_game->height(); y++) { 0083 StreakHBackgroundItem *p = new StreakHBackgroundItem((y % 2) ? Renderer::Streak1 : Renderer::Streak2, y); 0084 m_items.push_back(p); 0085 m_group->addToGroup(p); 0086 0087 RowStreakItem *q = new RowStreakItem(m_game, y); 0088 m_items.push_back(q); 0089 m_row_streaks.push_back(q); 0090 m_group->addToGroup(q); 0091 0092 m_streak_strings.append(q->toPlainText()); 0093 } 0094 } 0095 0096 void Scene::loadDividers() { 0097 for (int x = SECTION_SIZE - 1; x < m_game->width() - 1; x += SECTION_SIZE) { 0098 for (int y = 0; y < m_game->height(); y++) { 0099 PixmapItem *item = new PixmapItem(Renderer::Divider, x, y); 0100 item->setZValue(ZVALUE_DIVIDER); 0101 m_items.push_back(item); 0102 m_group->addToGroup(item); 0103 } 0104 } 0105 0106 for (int y = SECTION_SIZE - 1; y < m_game->height() - 1; y += SECTION_SIZE) { 0107 for (int x = 0; x < m_game->width(); x++) { 0108 PixmapItem *item = new PixmapItem(Renderer::Divider, x + 1, y); 0109 item->setRotation(90); 0110 item->setZValue(ZVALUE_DIVIDER); 0111 m_items.push_back(item); 0112 m_group->addToGroup(item); 0113 } 0114 } 0115 } 0116 0117 void Scene::init() { 0118 const int tilesize = Renderer::instance()->getTilesize(); 0119 const int x_offset = Renderer::instance()->getXOffset(); 0120 const int y_offset = Renderer::instance()->getYOffset(); 0121 0122 setSceneRect(QRectF(0, 0, m_game->width() * tilesize + x_offset, 0123 m_game->height() * tilesize + y_offset)); 0124 0125 m_group = new QGraphicsItemGroup; 0126 0127 loadBanners(); 0128 loadBackground(); 0129 loadCells(); 0130 loadOverView(); 0131 loadStreaks(); 0132 loadDividers(); 0133 0134 m_group->setHandlesChildEvents(false); 0135 m_group->setPos(x_offset, y_offset); 0136 addItem(m_group); 0137 0138 m_cells[0]->setFocus(); 0139 updateHighlights(); 0140 0141 connect(m_game.data(), &Picmi::gameCompleted, this, &Scene::onGameCompleted); 0142 } 0143 0144 void Scene::refresh() { 0145 for (int i = 0; i < (int)m_cells.size(); i++) { 0146 m_cells[i]->refresh(); 0147 m_overview_cells[i]->refresh(); 0148 } 0149 for (int i = 0; i < (int)m_row_streaks.size(); i++) { 0150 m_row_streaks[i]->refresh(); 0151 } 0152 for (int i = 0; i < (int)m_col_streaks.size(); i++) { 0153 m_col_streaks[i]->refresh(); 0154 } 0155 } 0156 0157 void Scene::refresh(const QPoint &p) { 0158 const int index = xy_to_i(p.x(), p.y()); 0159 0160 m_cells[index]->refresh(); 0161 m_overview_cells[index]->refresh(); 0162 m_row_streaks[p.y()]->refresh(); 0163 m_col_streaks[p.x()]->refresh(); 0164 } 0165 0166 void Scene::setPaused(bool paused) { 0167 m_game->setPaused(paused); 0168 m_group->setVisible(!paused); 0169 m_pause_banner->setVisible(paused); 0170 } 0171 0172 void Scene::press(int x, int y, Board::State state) { 0173 0174 m_position.setX(x); 0175 m_position.setY(y); 0176 m_cells[xy_to_i(x, y)]->setFocus(); 0177 updateHighlights(); 0178 0179 m_game->setState(x, y, state); 0180 0181 refresh(QPoint(x, y)); 0182 } 0183 0184 void Scene::onGameCompleted() { 0185 hideHighlights(); 0186 refresh(); 0187 } 0188 0189 void Scene::hover(int x, int y) { 0190 m_position.setX(x); 0191 m_position.setY(y); 0192 0193 m_cells[xy_to_i(x, y)]->setFocus(); 0194 0195 updateHighlights(); 0196 } 0197 0198 void Scene::updateHighlights() { 0199 for (int i = 0; i < (int)m_highlights.size(); i++) { 0200 m_highlights[i]->highlight(m_position); 0201 } 0202 } 0203 0204 void Scene::hideHighlights() { 0205 for (int i = 0; i < (int)m_highlights.size(); i++) { 0206 m_highlights[i]->setVisible(false); 0207 } 0208 } 0209 0210 void Scene::move(int dx, int dy) { 0211 int x = m_position.x() + dx; 0212 int y = m_position.y() + dy; 0213 while (x < 0) { 0214 x += m_game->width(); 0215 } 0216 while (y < 0) { 0217 y += m_game->height(); 0218 } 0219 hover(x % m_game->width(), y % m_game->height()); 0220 } 0221 0222 int Scene::xy_to_i(int x, int y) const { 0223 return y * m_game->width() + x; 0224 } 0225 0226 void Scene::setOverviewPos() { 0227 int grid = Renderer::instance()->getOverviewTilesize(); 0228 int streak_width = Renderer::instance()->getXOffset(); 0229 int streak_height = Renderer::instance()->getYOffset(); 0230 0231 /* dimensions of overview */ 0232 int height = grid * m_game->height(); 0233 int width = grid * m_game->width(); 0234 0235 int xoffset = (streak_width - width) / 2; 0236 int yoffset = (streak_height - height) / 2; 0237 0238 /* */ 0239 m_overview_group->setPos(xoffset - streak_width, yoffset - streak_height); 0240 0241 } 0242 0243 void Scene::setGroupPos(const QSize &size) { 0244 int grid = Renderer::instance()->getTilesize(); 0245 int streak_width = Renderer::instance()->getXOffset(); 0246 int streak_height = Renderer::instance()->getYOffset(); 0247 0248 /* dimensions of cell area + streaks */ 0249 int height = grid * m_game->height() + streak_height; 0250 int width = grid * m_game->width() + streak_width; 0251 0252 int xoffset = (size.width() - width) / 2; 0253 int yoffset = (size.height() - height) / 2; 0254 0255 /* m_group contains all elements of the playing field. (0,0) is located 0256 at the left upper corner of the cells area, meaning streaks are located 0257 at negative coordinates. 0258 center the entire area within the available window size */ 0259 m_group->setPos(xoffset + streak_width, yoffset + streak_height); 0260 0261 } 0262 0263 void Scene::resize(const QSize &size) { 0264 Renderer::instance()->setSize(size, m_game->width(), m_game->height(), 0265 m_streak_strings); 0266 setSceneRect(QRectF(0, 0, size.width(), size.height())); 0267 setGroupPos(size); 0268 setOverviewPos(); 0269 0270 for (int i = 0; i < (int)m_items.size(); i++) { 0271 m_items[i]->reload(size); 0272 } 0273 } 0274 0275 #include "moc_scene.cpp"