File indexing completed on 2024-12-01 06:51:46
0001 /*************************************************************************** 0002 cmapwidget.cpp 0003 ------------------- 0004 begin : Sun Mar 18 2001 0005 copyright : (C) 2001 by Kmud Developer Team 0006 email : kmud-devel@kmud.de 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 ***************************************************************************/ 0017 0018 #include "cmapwidget.h" 0019 0020 #include <QBitmap> 0021 #include <QScrollArea> 0022 #include <QScrollBar> 0023 #include <QToolTip> 0024 0025 #include <kactioncollection.h> 0026 #include <kxmlguifactory.h> 0027 0028 #include <KLocalizedString> 0029 0030 #include "cmapmanager.h" 0031 #include "cmapzone.h" 0032 #include "cmaplevel.h" 0033 #include "cmappath.h" 0034 #include "cmapcmdelementproperties.h" 0035 #include "cmapview.h" 0036 #include "cmaptoolbase.h" 0037 #include "cmappluginbase.h" 0038 0039 static unsigned char move_bits[] = { 0040 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01, 0x84, 0x21, 0041 0x86, 0x61, 0xff, 0xff, 0xff, 0xff, 0x86, 0x61, 0x84, 0x21, 0x80, 0x01, 0042 0x80, 0x01, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}; 0043 0044 CMapWidget::CMapWidget(CMapView *view,CMapManager *manager,QWidget *parent) : QWidget(parent) 0045 { 0046 // Setup vars 0047 viewWidget = view; 0048 bMouseDrag = false; 0049 QBitmap mouseDragCursorShape = QBitmap::fromData (QSize(16,16), move_bits); 0050 mouseDragCursor = new QCursor( mouseDragCursorShape, mouseDragCursorShape, -1,-1); 0051 mapManager = manager; 0052 0053 initContexMenus(); 0054 0055 // FIXME_jp : set to proper size instead of test size 0056 0057 // Setup scrollview 0058 setFocusPolicy(Qt::StrongFocus); 0059 setMouseTracking(true); 0060 setFocus(); 0061 } 0062 0063 CMapWidget::~CMapWidget() 0064 { 0065 viewWidget = nullptr; 0066 } 0067 0068 /** Used to create the element context menus */ 0069 void CMapWidget::initContexMenus(void) 0070 { 0071 room_menu = (QMenu *)getView()->guiFactory()->container("room_popup",getView()); 0072 text_menu = (QMenu *)getView()->guiFactory()->container("text_popup",getView()); 0073 path_menu = (QMenu *)getView()->guiFactory()->container("path_popup",getView()); 0074 empty_menu = (QMenu *)getView()->guiFactory()->container("empty_popup",getView()); 0075 } 0076 0077 /** Used to get the views */ 0078 CMapView *CMapWidget::getView(void) 0079 { 0080 return viewWidget; 0081 } 0082 0083 /** draw the map widget */ 0084 void CMapWidget::paintEvent(QPaintEvent *ev) 0085 { 0086 QPainter p(this); 0087 CMapZone *zone = viewWidget->getCurrentlyViewedZone(); 0088 QColor color = zone->getUseDefaultBackground() ? mapManager->getMapData()->backgroundColor : zone->getBackgroundColor(); 0089 p.fillRect(ev->rect(), color); 0090 0091 drawGrid(&p); 0092 drawElements(&p); 0093 mapManager->getCurrentTool()->paint(&p); 0094 } 0095 0096 bool CMapWidget::event(QEvent *e) 0097 { 0098 if (e->type() == QEvent::ToolTip) { 0099 QHelpEvent *helpEvent = static_cast<QHelpEvent *>(e); 0100 QPoint point = helpEvent->pos(); 0101 0102 CMapView *view = getView(); 0103 CMapLevel *level = view->getCurrentlyViewedLevel(); 0104 CMapElement *element = level ? level->findElementAt(point) : nullptr; 0105 QString s; 0106 if (element) 0107 { 0108 if (element->getElementType() == ROOM) 0109 { 0110 s = ((CMapRoom*)element)->getLabel(); 0111 } 0112 else if (element->getElementType() == ZONE) 0113 { 0114 s = ((CMapZone*)element)->getLabel(); 0115 } 0116 0117 if (!s.trimmed().isEmpty()) 0118 QToolTip::showText (helpEvent->globalPos(), s, this); 0119 else 0120 QToolTip::hideText (); 0121 } 0122 } 0123 return QWidget::event(e); 0124 } 0125 0126 0127 0128 /** Draw the grid if it's visible */ 0129 void CMapWidget::drawGrid(QPainter* p) 0130 { 0131 if (!mapManager->getMapData()->gridVisable) return; 0132 0133 p->setPen(mapManager->getMapData()->gridColor); 0134 0135 QSize gridSize = mapManager->getMapData()->gridSize; 0136 int maxx = width(); 0137 int maxy = height(); 0138 0139 // Draw the lines going across 0140 for (int y = 0; y <= maxy; y += gridSize.width()) 0141 p->drawLine(0, y, maxx, y); 0142 // Draw the lines going down 0143 for (int x = 0; x <= maxx; x += gridSize.height()) 0144 p->drawLine(x, 0, x, maxy); 0145 } 0146 0147 /** Used to draw all the elments */ 0148 void CMapWidget::drawElements(QPainter *p) 0149 { 0150 CMapLevel *level = viewWidget->getCurrentlyViewedLevel(); 0151 if (!level) return; 0152 0153 CMapLevel *lowerLevel = level->getPrevLevel(); 0154 CMapLevel *upperLevel = level->getNextLevel(); 0155 0156 // Mark all paths as undrawn 0157 foreach (CMapRoom *room, *level->getRoomList()) 0158 foreach (CMapPath *path, *room->getPathList()) 0159 path->setDone(false); 0160 0161 if (lowerLevel && mapManager->getMapData()->showLowerLevel) 0162 { 0163 foreach (CMapRoom *room, *lowerLevel->getRoomList()) 0164 foreach (CMapPath *path, *room->getPathList()) 0165 path->setDone(false); 0166 } 0167 0168 if (upperLevel && mapManager->getMapData()->showUpperLevel) 0169 { 0170 foreach (CMapRoom *room, *upperLevel->getRoomList()) 0171 foreach (CMapPath *path, *room->getPathList()) 0172 path->setDone(false); 0173 } 0174 0175 // Draw the upper map elements 0176 if (lowerLevel && mapManager->getMapData()->showLowerLevel) 0177 foreach (CMapElement *element, lowerLevel->getAllElements()) 0178 element->lowerPaint(p, viewWidget->getCurrentlyViewedZone()); 0179 0180 // Paint the map elements of the current map 0181 foreach (CMapElement *element, level->getAllElements()) 0182 if (element->getDoPaint()) 0183 element->paint(p, viewWidget->getCurrentlyViewedZone()); 0184 0185 // Draw the upper map elements 0186 if (upperLevel && mapManager->getMapData()->showUpperLevel) 0187 { 0188 foreach (CMapElement *element, upperLevel->getAllElements()) 0189 element->higherPaint(p, viewWidget->getCurrentlyViewedZone()); 0190 } 0191 } 0192 0193 0194 /** The mouse release event */ 0195 void CMapWidget::mouseReleaseEvent(QMouseEvent *e) 0196 { 0197 QCursor* oldCursor; 0198 0199 switch (e->button()) 0200 { 0201 case Qt::LeftButton: 0202 // Send the mouse event to the current tool 0203 mapManager->getCurrentTool()->mouseReleaseEvent(e->pos(),e,viewWidget->getCurrentlyViewedLevel()); 0204 break; 0205 0206 case Qt::MidButton: 0207 bMouseDrag = false; 0208 oldCursor= new QCursor(cursor()); 0209 setCursor(*mouseDragCursor); 0210 delete mouseDragCursor; 0211 mouseDragCursor = oldCursor; 0212 break; 0213 0214 default: 0215 break; 0216 } 0217 0218 } 0219 0220 0221 void CMapWidget::showRoomContextMenu(void) 0222 { 0223 CMapRoom *room = (CMapRoom *) getView()->getSelectedElement(); 0224 0225 KActionCollection *acol = getView()->actionCollection(); 0226 QAction *roomSetCurrentPos = acol->action("roomCurrentPos"); 0227 QAction *roomSetLogin = acol->action("roomLoginPoint"); 0228 KSelectAction *labelMenu=(KSelectAction *) acol->action("labelMenu"); 0229 0230 roomSetCurrentPos->setEnabled(!room->getCurrentRoom()); 0231 roomSetLogin->setEnabled(!room->getLoginRoom()); 0232 0233 switch(room->getLabelPosition()) 0234 { 0235 case CMapRoom::HIDE : labelMenu->setCurrentItem(0); break; 0236 case CMapRoom::NORTH : labelMenu->setCurrentItem(1); break; 0237 case CMapRoom::NORTHEAST : labelMenu->setCurrentItem(2); break; 0238 case CMapRoom::EAST : labelMenu->setCurrentItem(3); break; 0239 case CMapRoom::SOUTHEAST : labelMenu->setCurrentItem(4); break; 0240 case CMapRoom::SOUTH : labelMenu->setCurrentItem(5); break; 0241 case CMapRoom::SOUTHWEST : labelMenu->setCurrentItem(6); break; 0242 case CMapRoom::WEST : labelMenu->setCurrentItem(7); break; 0243 case CMapRoom::NORTHWEST : labelMenu->setCurrentItem(8); break; 0244 case CMapRoom::CUSTOM : labelMenu->setCurrentItem(9); break; 0245 } 0246 0247 0248 showContextMenu (room_menu); 0249 } 0250 0251 void CMapWidget::showPathContextMenu(void) 0252 { 0253 CMapPath *path = (CMapPath *) getView()->getSelectedElement(); 0254 0255 bool twoWay = path->getOpsitePath(); 0256 0257 KActionCollection *acol = getView()->actionCollection(); 0258 KToggleAction *pathTwoWay = (KToggleAction *)acol->action("pathTwoWay"); 0259 KToggleAction *pathOneWay = (KToggleAction *)acol->action("pathOneWay"); 0260 QAction *pathEditBends = acol->action("pathEditBends"); 0261 QAction *pathDelBend = acol->action("pathDelBend"); 0262 QAction *pathAddBend = acol->action("pathAddBend"); 0263 0264 pathTwoWay->setChecked(twoWay); 0265 pathOneWay->setChecked(!twoWay); 0266 0267 CMapView *view = (CMapView *) viewWidget; 0268 pathDelBend->setEnabled(path->mouseInPathSeg(selectedPos,view->getCurrentlyViewedZone())!=-1); 0269 pathEditBends->setEnabled(path->getBendCount() > 0); 0270 pathAddBend->setEnabled(path->getSrcRoom()->getZone()==path->getDestRoom()->getZone()); 0271 0272 showContextMenu (path_menu); 0273 } 0274 0275 0276 void CMapWidget::showTextContextMenu(void) 0277 { 0278 showContextMenu (text_menu); 0279 } 0280 0281 void CMapWidget::showOtherContextMenu(void) 0282 { 0283 showContextMenu (empty_menu); 0284 } 0285 0286 void CMapWidget::showContextMenu(QMenu *menu) 0287 { 0288 CMapView *view = mapManager->getActiveView(); 0289 CMapElement *el = view->getSelectedElement(); 0290 popupMenu(el, menu, selectedPos); 0291 } 0292 0293 void CMapWidget::showContexMenu(QMouseEvent *e) 0294 { 0295 CMapLevel *level = viewWidget->getCurrentlyViewedLevel(); 0296 if (!level) return; 0297 0298 CMapView *view = mapManager->getActiveView(); 0299 view->setSelectedPos(e->pos()); 0300 selectedPos = e->pos(); 0301 0302 view->setSelectedElement(nullptr); 0303 CMapElement *element = level->findElementAt (e->pos()); 0304 if (!element) { 0305 showOtherContextMenu(); 0306 return; 0307 } 0308 0309 view->setSelectedElement(element); 0310 0311 mapManager->unsetEditElement(); 0312 switch(element->getElementType()) 0313 { 0314 case ROOM : showRoomContextMenu(); break; 0315 case PATH : showPathContextMenu(); break; 0316 case TEXT : showTextContextMenu(); break; 0317 default : showOtherContextMenu(); break; 0318 } 0319 } 0320 0321 /** This method is used to tell the plugins a menu is about to open then open the menu */ 0322 void CMapWidget::popupMenu(CMapElement *element,QMenu *menu,QPoint pos) 0323 { 0324 if (element) { 0325 for (CMapPluginBase *plugin : mapManager->getPluginList()) 0326 plugin->beforeOpenElementMenu(element); 0327 } 0328 menu->popup(mapToGlobal(pos)); 0329 } 0330 0331 /** This is called when the mouse leaves the widget */ 0332 void CMapWidget::leaveEvent(QEvent *) 0333 { 0334 // Send the mouse event to the current tool 0335 mapManager->getCurrentTool()->mouseLeaveEvent(); 0336 } 0337 0338 /** This is called when the mouse enters the widget */ 0339 void CMapWidget::enterEvent(QEvent *) 0340 { 0341 // Send the mouse event to the current tool 0342 mapManager->getCurrentTool()->mouseEnterEvent(); 0343 } 0344 0345 /** The mouse press event */ 0346 void CMapWidget::mousePressEvent(QMouseEvent *e) 0347 { 0348 QCursor* oldCursor; 0349 0350 switch (e->button()) 0351 { 0352 case Qt::RightButton: 0353 showContexMenu(e); 0354 break; 0355 0356 case Qt::MidButton: 0357 bMouseDrag = true; 0358 nMouseDragPosX = e->globalX(); 0359 nMouseDragPosY = e->globalY(); 0360 oldCursor = new QCursor(cursor()); 0361 setCursor(*mouseDragCursor); 0362 delete mouseDragCursor; 0363 mouseDragCursor = oldCursor; 0364 break; 0365 0366 case Qt::LeftButton: 0367 // Send the mouse event to the current tool 0368 //p.begin(viewport()); 0369 //p.translate(-contentsX(),-contentsY()); 0370 mapManager->getCurrentTool()->mousePressEvent(e->pos(),e,viewWidget->getCurrentlyViewedLevel()); 0371 //p.end(); 0372 0373 default: 0374 break; 0375 0376 } 0377 } 0378 0379 void CMapWidget::mouseDoubleClickEvent(QMouseEvent *e) 0380 { 0381 mapManager->getCurrentTool()->mouseDoubleClickEvent(e->pos(), e, viewWidget->getCurrentlyViewedLevel()); 0382 } 0383 0384 /** Called when the mouse is being moved */ 0385 void CMapWidget::mouseMoveEvent(QMouseEvent *e) 0386 { 0387 if (bMouseDrag) 0388 { 0389 int dx, dy; 0390 dx = e->globalX() - nMouseDragPosX; 0391 dy = e->globalY() - nMouseDragPosY; 0392 nMouseDragPosX = e->globalX(); 0393 nMouseDragPosY = e->globalY(); 0394 QScrollArea *parent = (QScrollArea *) parentWidget(); 0395 QScrollBar *sx = parent->horizontalScrollBar(); 0396 QScrollBar *sy = parent->verticalScrollBar(); 0397 sx->setValue(sx->value() + dx*3); 0398 sy->setValue(sy->value() + dy*3); 0399 } 0400 else 0401 { 0402 // Send the mouse event to the current tool 0403 mapManager->getCurrentTool()->mouseMoveEvent(e->pos(), e->modifiers(), e->buttons(), viewWidget->getCurrentlyViewedLevel()); 0404 } 0405 } 0406 0407 /** Called when a key is pressed */ 0408 void CMapWidget::keyPressEvent(QKeyEvent *e) 0409 { 0410 mapManager->getCurrentTool()->keyPressEvent(e); 0411 } 0412 0413 /** Called when a key is released */ 0414 void CMapWidget::keyReleaseEvent(QKeyEvent *e) 0415 { 0416 mapManager->getCurrentTool()->keyReleaseEvent(e); 0417 } 0418 0419 #include "moc_cmapwidget.cpp"