41 C4ConsoleQtViewportView::C4ConsoleQtViewportView(
class C4ConsoleQtViewportScrollArea *scrollarea)
42 : QOpenGLWidget(scrollarea->dock), dock(scrollarea->dock), cvp(scrollarea->cvp)
44 setAttribute(Qt::WA_ShowWithoutActivating,
true);
45 setFocusPolicy(Qt::WheelFocus);
46 setMouseTracking(
true);
47 setContextMenuPolicy(Qt::CustomContextMenu);
50 window->glwidget =
this;
52 connect(
this, &QWidget::customContextMenuRequested,
this, &C4ConsoleQtViewportView::ShowContextMenu);
55 bool C4ConsoleQtViewportView::IsPlayViewport()
const
63 qreal C4ConsoleQtViewportView::GetDevicePixelRatio()
66 auto desktop = QApplication::desktop();
67 auto screenNumber = desktop->screenNumber(
this);
69 if (screenNumber == -1)
71 auto screen = QApplication::screens()[screenNumber];
72 return screen->devicePixelRatio();
75 void C4ConsoleQtViewportView::AddSelectObjectContextEntry(
C4Object *obj, QMenu *menu)
78 if (!obj || !obj->
Status)
return;
79 int32_t object_number = obj->
Number;
80 QAction *select_object_action =
new QAction(QString(
"%1 #%2 (%3/%4)").arg(obj->
GetName()).arg(object_number).arg(obj->
GetX()).arg(obj->
GetY()), menu);
81 connect(select_object_action, &QAction::triggered, menu, [object_number]() {
82 bool add = !!(QGuiApplication::keyboardModifiers() & Qt::ShiftModifier);
86 menu->addAction(select_object_action);
92 AddSelectObjectContextEntry(cobj, submenu);
97 void C4ConsoleQtViewportView::ShowContextMenu(
const QPoint &pos)
100 if (!IsPlayViewport())
103 QMenu *menu =
new QMenu(
this);
105 auto &ui = dock->main_window->GetConsoleState()->ui;
106 menu->addSection(ui.selectionInfoLabel->text());
108 bool has_object =
false;
109 int32_t contents_count = 0;
119 for (QAction *act : { ui.actionDeleteObject, ui.actionDuplicateObject, ui.actionEjectContents })
121 act->setEnabled(has_object);
122 menu->addAction(act);
126 ui.actionEjectContents->setEnabled(
false);
128 ui.actionEjectContents->setText(QString(
"%1 (%2)").arg(
LoadResStr(
"IDS_MNU_CONTENTS")).arg((
int)contents_count));
130 auto pr = GetDevicePixelRatio();
131 int32_t x = cvp->WindowToGameX(pr * pos.x()),
132 y = cvp->WindowToGameY(pr * pos.y());
138 int itemcount = atcursor->GetSize();
141 menu->addSection(
LoadResStr(
"IDS_CNS_SELECTNEARBYOBJECTS"));
142 for (int32_t i = 0; i < itemcount; ++i)
144 AddSelectObjectContextEntry(atcursor->GetItem(i).getObj(), menu);
147 menu->popup(mapToGlobal(pos));
154 auto modifiers =
event ?
event->modifiers() : QGuiApplication::keyboardModifiers();
156 if (modifiers & Qt::ShiftModifier) result |= MK_SHIFT;
157 if (modifiers & Qt::ControlModifier) result |= MK_CONTROL;
158 if (modifiers & Qt::AltModifier) result |= MK_ALT;
162 void C4ConsoleQtViewportView::mouseMoveEvent(QMouseEvent *eventMove)
164 auto pr = GetDevicePixelRatio();
165 if (IsPlayViewport())
167 bool is_in_drawrange = (Inside<int32_t>(eventMove->x() - cvp->DrawX, 0, cvp->ViewWdt - 1)
168 && Inside<int32_t>(eventMove->y() - cvp->DrawY, 0, cvp->ViewHgt - 1));
169 this->setCursor(is_in_drawrange ? Qt::BlankCursor : Qt::CrossCursor);
174 cvp->pWindow->EditCursorMove(eventMove->x() * pr, eventMove->y() * pr,
GetShiftWParam());
179 void C4ConsoleQtViewportView::UpdateCursor()
181 Qt::CursorShape cursor;
183 cursor = Qt::SizeAllCursor;
187 cursor = Qt::CrossCursor;
188 this->setCursor(cursor);
191 void C4ConsoleQtViewportView::mousePressEvent(QMouseEvent *eventPress)
193 auto pr = GetDevicePixelRatio();
194 if (IsPlayViewport())
197 switch (eventPress->button())
210 cvp->pWindow->EditCursorMove(eventPress->x() * pr, eventPress->y() * pr,
GetShiftWParam());
211 switch (eventPress->button())
219 void C4ConsoleQtViewportView::mouseDoubleClickEvent(QMouseEvent *eventPress)
221 if (IsPlayViewport())
224 switch (eventPress->button())
232 auto pr = GetDevicePixelRatio();
237 void C4ConsoleQtViewportView::mouseReleaseEvent(QMouseEvent *releaseEvent)
239 if (IsPlayViewport())
242 switch (releaseEvent->button())
250 auto pr = GetDevicePixelRatio();
255 switch (releaseEvent->button())
263 void C4ConsoleQtViewportView::wheelEvent(QWheelEvent *event)
265 if (IsPlayViewport())
267 int delta =
event->delta() / 8;
268 if (!delta) delta =
event->delta();
269 uint32_t shift = (delta>0) ? (delta<<16) : uint32_t(delta<<16);
271 auto pr = GetDevicePixelRatio();
276 auto delta =
event->angleDelta();
277 auto modifiers = QGuiApplication::keyboardModifiers();
279 if (modifiers & Qt::ControlModifier)
286 if (modifiers & Qt::ShiftModifier)
288 cvp->ScrollView(x, y);
295 void C4ConsoleQtViewportView::focusInEvent(QFocusEvent * event)
297 dock->OnActiveChanged(
true);
298 QWidget::focusInEvent(event);
301 void C4ConsoleQtViewportView::focusOutEvent(QFocusEvent * event)
303 dock->OnActiveChanged(
false);
304 QWidget::focusOutEvent(event);
313 static C4KeyCode QtKeyToUnixScancode(
const QKeyEvent &event)
319 case Qt::Key_Home:
return K_HOME;
320 case Qt::Key_End:
return K_END;
321 case Qt::Key_PageUp:
return K_PAGEUP;
322 case Qt::Key_PageDown:
return K_PAGEDOWN;
323 case Qt::Key_Up:
return K_UP;
324 case Qt::Key_Down:
return K_DOWN;
325 case Qt::Key_Left:
return K_LEFT;
326 case Qt::Key_Right:
return K_RIGHT;
327 case Qt::Key_Clear:
return K_CENTER;
328 case Qt::Key_Insert:
return K_INSERT;
329 case Qt::Key_Delete:
return K_DELETE;
330 case Qt::Key_Menu:
return K_MENU;
331 case Qt::Key_Pause:
return K_PAUSE;
332 case Qt::Key_Print:
return K_PRINT;
333 case Qt::Key_NumLock:
return K_NUM;
334 case Qt::Key_ScrollLock:
return K_SCROLL;
337 #ifdef USE_WIN32_WINDOWS
338 switch (event.nativeVirtualKey())
340 case VK_LWIN:
return K_WIN_L;
341 case VK_RWIN:
return K_WIN_R;
342 case VK_NUMPAD1:
return K_NUM1;
343 case VK_NUMPAD2:
return K_NUM2;
344 case VK_NUMPAD3:
return K_NUM3;
345 case VK_NUMPAD4:
return K_NUM4;
346 case VK_NUMPAD5:
return K_NUM5;
347 case VK_NUMPAD6:
return K_NUM6;
348 case VK_NUMPAD7:
return K_NUM7;
349 case VK_NUMPAD8:
return K_NUM8;
350 case VK_NUMPAD9:
return K_NUM9;
351 case VK_NUMPAD0:
return K_NUM0;
353 switch (event.nativeScanCode())
355 case 285:
return K_CONTROL_R;
359 #if defined(USE_WIN32_WINDOWS) || defined(Q_OS_DARWIN)
360 return event.nativeScanCode();
363 return event.nativeScanCode() - 8;
368 void C4ConsoleQtViewportView::keyPressEvent(QKeyEvent * event)
371 C4KeyCode code = QtKeyToUnixScancode(*event);
373 bool handled =
false;
374 if (code == K_SCROLL)
376 cvp->TogglePlayerLock();
380 if (!handled) handled =
Game.
DoKeyboardInput(code,
KEYEV_Down, !!(event->modifiers() & Qt::AltModifier), !!(event->modifiers() & Qt::ControlModifier), !!(event->modifiers() & Qt::ShiftModifier), event->isAutoRepeat(),
nullptr);
381 if (!handled) handled = dock->main_window->HandleEditorKeyDown(event);
383 if (event->key() == Qt::Key_Shift || event->key() == Qt::Key_Control || event->key() == Qt::Key_Alt || event->key() == Qt::Key_AltGr)
388 event->setAccepted(handled);
391 void C4ConsoleQtViewportView::keyReleaseEvent(QKeyEvent * event)
394 C4KeyCode code = QtKeyToUnixScancode(*event);
396 bool handled =
Game.
DoKeyboardInput(code,
KEYEV_Up, !!(event->modifiers() & Qt::AltModifier), !!(event->modifiers() & Qt::ControlModifier), !!(event->modifiers() & Qt::ShiftModifier), event->isAutoRepeat(),
nullptr);
397 if (!handled) handled = dock->main_window->HandleEditorKeyUp(event);
399 if (event->key() == Qt::Key_Shift || event->key() == Qt::Key_Control || event->key() == Qt::Key_Alt || event->key() == Qt::Key_AltGr)
404 event->setAccepted(handled);
407 void C4ConsoleQtViewportView::enterEvent(QEvent *)
415 void C4ConsoleQtViewportView::leaveEvent(QEvent *)
421 void C4ConsoleQtViewportView::initializeGL()
426 void C4ConsoleQtViewportView::resizeGL(
int w,
int h)
428 auto pr = GetDevicePixelRatio();
429 cvp->UpdateOutputSize(w * pr, h * pr);
432 void C4ConsoleQtViewportView::paintGL()
434 cvp->ScrollBarsByViewPosition();
439 C4ConsoleQtViewportScrollArea::C4ConsoleQtViewportScrollArea(
class C4ConsoleQtViewportDockWidget *dock)
440 : QAbstractScrollArea(dock), dock(dock), cvp(dock->cvp->cvp), is_updating_scrollbars(0)
442 cvp->scrollarea =
this;
444 setScrollBarVisibility(
false);
447 void C4ConsoleQtViewportScrollArea::scrollContentsBy(
int dx,
int dy)
450 if (!is_updating_scrollbars)
452 cvp->SetViewX(horizontalScrollBar()->value());
453 cvp->SetViewY(verticalScrollBar()->value());
457 bool C4ConsoleQtViewportScrollArea::viewportEvent(QEvent *e)
463 void C4ConsoleQtViewportScrollArea::setupViewport(QWidget *viewport)
466 viewport->setFocusProxy(
nullptr);
467 ScrollBarsByViewPosition();
470 void C4ConsoleQtViewportScrollArea::ScrollBarsByViewPosition()
472 ++is_updating_scrollbars;
473 int x = viewport()->width() / cvp->GetZoom();
475 horizontalScrollBar()->setPageStep(x);
476 horizontalScrollBar()->setValue(cvp->GetViewX());
478 int y = viewport()->height() / cvp->GetZoom();
480 verticalScrollBar()->setPageStep(y);
481 verticalScrollBar()->setValue(cvp->GetViewY());
482 --is_updating_scrollbars;
485 void C4ConsoleQtViewportScrollArea::setScrollBarVisibility(
bool visible)
489 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
490 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
494 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
495 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
499 C4ConsoleQtViewportDockWidget::C4ConsoleQtViewportDockWidget(C4ConsoleQtMainWindow *main_window, QMainWindow *parent,
C4ViewportWindow *cvp)
500 : QDockWidget(
"", parent), main_window(main_window), cvp(cvp)
506 auto scrollarea =
new C4ConsoleQtViewportScrollArea(
this);
507 view =
new C4ConsoleQtViewportView(scrollarea);
508 scrollarea->setViewport(view);
509 setWidget(scrollarea);
510 connect(
this, SIGNAL(topLevelChanged(
bool)),
this, SLOT(TopLevelChanged(
bool)));
512 cvp->viewport_widget = view;
515 void C4ConsoleQtViewportDockWidget::mousePressEvent(QMouseEvent *eventPress)
519 QDockWidget::mousePressEvent(eventPress);
522 void C4ConsoleQtViewportDockWidget::OnActiveChanged(
bool active)
527 QColor bgclr = QApplication::palette(
this).color(QPalette::Highlight);
528 QColor fontclr = QApplication::palette(
this).color(QPalette::HighlightedText);
530 setStyleSheet(QString(
531 "QDockWidget::title { text-align: left; background: %1; padding-left: 3px; color: %2; font-weight: bold; } QDockWidget { color: %2; font-weight: bold; }").arg(bgclr.name(), fontclr.name()));
533 setStyleSheet(QString());
536 void C4ConsoleQtViewportDockWidget::TopLevelChanged(
bool is_floating)
542 void C4ConsoleQtViewportDockWidget::closeEvent(QCloseEvent * event)
544 QDockWidget::closeEvent(event);
545 if (event->isAccepted())
559 bool C4ConsoleQtViewportDockWidget::event(QEvent *e)
562 if (e->type() == QEvent::NonClientAreaMouseButtonPress || e->type() == QEvent::MouseButtonPress) view->setFocus();
563 return QDockWidget::event(e);
uint32_t GetShiftWParam(QKeyEvent *event=nullptr)
C4MouseControl MouseControl
const char * LoadResStr(const char *id)
const int32_t C4MC_Button_X1Double
const int32_t C4MC_Button_X2Up
const int32_t C4MC_Button_None
const int32_t C4MC_Button_RightDown
const int32_t C4MC_Button_MiddleUp
const int32_t C4MC_Button_RightUp
const int32_t C4MC_Button_MiddleDouble
const int32_t C4MC_Button_X1Up
const int32_t C4MC_Button_MiddleDown
const int32_t C4MC_Button_RightDouble
const int32_t C4MC_Button_LeftUp
const int32_t C4MC_Button_X1Down
const int32_t C4MC_Button_LeftDown
const int32_t C4MC_Button_LeftDouble
const int32_t C4MC_Button_X2Double
const int32_t C4MC_Button_X2Down
const int32_t C4MC_Button_Wheel
const float C4GFX_ZoomStep
StdStrBuf FormatString(const char *szFmt,...)
bool LeftButtonDown(DWORD dwKeyState)
bool HasTransformCursor() const
void SetMouseHover(bool h)
bool RightButtonDown(DWORD dwKeyState)
bool RightButtonUp(DWORD dwKeyState)
bool LeftButtonUp(DWORD dwKeyState)
void DoContextObjsel(C4Object *, bool clear)
bool Move(float iX, float iY, float zoom, DWORD dwKeyState)
C4EditCursorSelection & GetSelection()
bool DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType event_type, bool alt, bool ctrl, bool shift, bool repeated, class C4GUI::Dialog *for_dialog=nullptr, bool fPlrCtrlOnly=false, int32_t strength=-1)
C4Object * SafeObjectPointer(int32_t object_number)
int32_t GetHeight() const
bool IsViewport(C4Viewport *pViewport)
C4NotifyingObjectList Contents
int ObjectCount(C4ID id=C4ID::None) const
const char * GetName() const
C4Player * Get(int iPlayer) const
virtual const char * GetName() const
void MouseMove(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam, class C4Viewport *pVP)