From 72774a5e20535eac600b114ee98686df80d65cd1 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Fri, 19 Jul 2013 17:01:38 -0700 Subject: [PATCH 1/3] First step toward pie menus --- interface/src/Application.cpp | 19 ++++++- interface/src/Application.h | 5 +- interface/src/PieMenu.cpp | 97 +++++++++++++++++++++++++++++++++++ interface/src/PieMenu.h | 48 +++++++++++++++++ 4 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 interface/src/PieMenu.cpp create mode 100644 interface/src/PieMenu.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index adb88147e9..632eb12404 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -835,6 +835,8 @@ void Application::mouseMoveEvent(QMouseEvent* event) { deleteVoxelUnderCursor(); } } + + _pieMenu.mouseMoveEvent(_mouseX, _mouseY); } } @@ -847,7 +849,10 @@ void Application::mousePressEvent(QMouseEvent* event) { _mouseDragStartedY = _mouseY; _mouseVoxelDragging = _mouseVoxel; _mousePressed = true; - maybeEditVoxelUnderCursor(); + + if (!maybeEditVoxelUnderCursor()) { + _pieMenu.mousePressEvent(_mouseX, _mouseY); + } } else if (event->button() == Qt::RightButton && checkedVoxelModeAction() != 0) { deleteVoxelUnderCursor(); @@ -862,6 +867,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { _mouseY = event->y(); _mousePressed = false; checkBandwidthMeterClick(); + + _pieMenu.mouseReleaseEvent(_mouseX, _mouseY); } } } @@ -2740,6 +2747,10 @@ void Application::displayOverlay() { _swatch.checkColor(); } + if (_pieMenu.isDisplayed()) { + _pieMenu.render(); + } + glPopMatrix(); } @@ -3147,7 +3158,7 @@ void Application::shiftPaintingColor() { } -void Application::maybeEditVoxelUnderCursor() { +bool Application::maybeEditVoxelUnderCursor() { if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) { if (_mouseVoxel.s != 0) { PACKET_TYPE message = (_destructiveAddVoxel->isChecked() ? @@ -3218,7 +3229,11 @@ void Application::maybeEditVoxelUnderCursor() { deleteVoxelUnderCursor(); } else if (_eyedropperMode->isChecked()) { eyedropperVoxelUnderCursor(); + } else { + return false; } + + return true; } void Application::deleteVoxelUnderCursor() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 9333808a27..f5f9c17883 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -42,6 +42,7 @@ #include "ViewFrustum.h" #include "VoxelSystem.h" #include "Webcam.h" +#include "PieMenu.h" class QAction; @@ -208,7 +209,7 @@ private: void setupPaintingVoxel(); void shiftPaintingColor(); - void maybeEditVoxelUnderCursor(); + bool maybeEditVoxelUnderCursor(); void deleteVoxelUnderCursor(); void eyedropperVoxelUnderCursor(); void resetSensors(); @@ -406,6 +407,8 @@ private: ToolsPalette _palette; Swatch _swatch; + + PieMenu _pieMenu; }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/PieMenu.cpp b/interface/src/PieMenu.cpp new file mode 100644 index 0000000000..73be3d12c3 --- /dev/null +++ b/interface/src/PieMenu.cpp @@ -0,0 +1,97 @@ +// +// PieMenu.cpp +// hifi +// +// Created by Clement Brisset on 7/18/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include "PieMenu.h" + +#include + +#include +#include + +PieMenu::PieMenu() : + _radiusIntern(30), + _radiusExtern(70), + _isDisplayed(false) { + + addAction(NULL); + addAction(NULL); + addAction(NULL); + addAction(NULL); + addAction(NULL); +} + +void PieMenu::init(const char *fileName, int screenWidth, int screenHeight) { + +} + +void PieMenu::addAction(QAction* action){ + _actions.push_back(action); +} + +void PieMenu::render() { + if (_actions.size() == 0) { + return; + } + + float start = M_PI / 2.0f; + float end = start + 2.0f * M_PI; + float step = 2.0f * M_PI / 100.0f; + float distance = sqrt((_mouseX - _x) * (_mouseX - _x) + + (_mouseY - _y) * (_mouseY - _y)); + + glBegin(GL_QUAD_STRIP); + glColor3f(1.0f, 1.0f, 1.0f); + for (float i = start; i < end; i += step) { + glVertex2f(_x + _radiusIntern * cos(i), _y + _radiusIntern * sin(i)); + glVertex2f(_x + _radiusExtern * cos(i), _y + _radiusExtern * sin(i)); + } + glVertex2f(_x + _radiusIntern * cos(end), _y + _radiusIntern * sin(end)); + glVertex2f(_x + _radiusExtern * cos(end), _y + _radiusExtern * sin(end)); + glEnd(); + + if (_radiusIntern < distance) { + float angle = atan2((_mouseY - _y), (_mouseX - _x)) - start; + angle = (0.0f < angle) ? angle : angle + 2.0f * M_PI; + + _selectedAction = floor(angle / (2.0f * M_PI / _actions.size())); + + start = start + _selectedAction * 2.0f * M_PI / _actions.size(); + end = start + 2.0f * M_PI / _actions.size(); + glBegin(GL_QUAD_STRIP); + glColor3f(0.0f, 0.0f, 0.0f); + for (float i = start; i < end; i += step) { + glVertex2f(_x + _radiusIntern * cos(i), _y + _radiusIntern * sin(i)); + glVertex2f(_x + _radiusExtern * cos(i), _y + _radiusExtern * sin(i)); + } + glVertex2f(_x + _radiusIntern * cos(end), _y + _radiusIntern * sin(end)); + glVertex2f(_x + _radiusExtern * cos(end), _y + _radiusExtern * sin(end)); + glEnd(); + } else { + _selectedAction = -1; + } +} + +void PieMenu::resize(int screenWidth, int screenHeight) { +} + +void PieMenu::mouseMoveEvent(int x, int y) { + _mouseX = x; + _mouseY = y; +} + +void PieMenu::mousePressEvent(int x, int y) { + _x = _mouseX = x; + _y = _mouseY = y; + _isDisplayed = true; +} + +void PieMenu::mouseReleaseEvent(int x, int y) { + // TODO + + _isDisplayed = false; +} diff --git a/interface/src/PieMenu.h b/interface/src/PieMenu.h new file mode 100644 index 0000000000..0323af8f94 --- /dev/null +++ b/interface/src/PieMenu.h @@ -0,0 +1,48 @@ +// +// PieMenu.h +// hifi +// +// Created by Clement Brisset on 7/18/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__PieMenu__ +#define __hifi__PieMenu__ + +#include + +class QAction; + +class PieMenu { +public: + PieMenu(); + + void init(const char* fileName, int screenWidth, int screenHeight); + void addAction(QAction* action); + void render(); + void resize(int screenWidth, int screenHeight); + + bool isDisplayed() const {return _isDisplayed;} + + void mouseMoveEvent (int x, int y); + void mousePressEvent (int x, int y); + void mouseReleaseEvent(int x, int y); + +private: + // position of the menu + int _x; + int _y; + int _radiusIntern; + int _radiusExtern; + + int _mouseX; + int _mouseY; + + int _selectedAction; + + bool _isDisplayed; + + std::vector _actions; +}; + +#endif /* defined(__hifi__PieMenu__) */ From fc3aa2da9b5aebad18f5cc66ed92a480300c3506 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Fri, 19 Jul 2013 17:02:45 -0700 Subject: [PATCH 2/3] Fixed typo in Tags.cpp top comments --- libraries/voxels/src/Tags.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp index e6875f36a6..7df6f227ad 100644 --- a/libraries/voxels/src/Tags.cpp +++ b/libraries/voxels/src/Tags.cpp @@ -1,5 +1,5 @@ // -// Tags.h +// Tags.cpp // hifi // // Created by Clement Brisset on 7/3/13. From d165891fe6c770bec9d39b8d189b15635a823f6e Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 24 Jul 2013 12:38:35 -0700 Subject: [PATCH 3/3] New design for pie menus --- interface/src/Application.cpp | 6 ++- interface/src/PieMenu.cpp | 83 ++++++++++++++++++++++++++--------- interface/src/PieMenu.h | 17 +++++-- 3 files changed, 80 insertions(+), 26 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ed47262942..0245585e42 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1982,7 +1982,11 @@ void Application::init() { _palette.addTool(&_swatch); _palette.addAction(_colorVoxelMode, 0, 2); _palette.addAction(_eyedropperMode, 0, 3); - _palette.addAction(_selectVoxelMode, 0, 4); + _palette.addAction(_selectVoxelMode, 0, 4); + + _pieMenu.init("./resources/images/hifi-interface-tools-v2-pie.svg", + _glWidget->width(), + _glWidget->height()); } diff --git a/interface/src/PieMenu.cpp b/interface/src/PieMenu.cpp index 73be3d12c3..1f79d46814 100644 --- a/interface/src/PieMenu.cpp +++ b/interface/src/PieMenu.cpp @@ -11,22 +11,47 @@ #include #include +#include +#include #include +#include PieMenu::PieMenu() : _radiusIntern(30), _radiusExtern(70), + _magnification(1.2f), _isDisplayed(false) { - - addAction(NULL); - addAction(NULL); - addAction(NULL); - addAction(NULL); - addAction(NULL); } void PieMenu::init(const char *fileName, int screenWidth, int screenHeight) { + // Load SVG + switchToResourcesParentIfRequired(); + QSvgRenderer renderer((QString) QString(fileName)); + // Prepare a QImage with desired characteritisc + QImage image(2 * _radiusExtern, 2 * _radiusExtern, QImage::Format_ARGB32); + image.fill(0x0); + + // Get QPainter that paints to the image + QPainter painter(&image); + renderer.render(&painter); + + //get the OpenGL-friendly image + _textureImage = QGLWidget::convertToGLFormat(image); + + glGenTextures(1, &_textureID); + glBindTexture(GL_TEXTURE_2D, _textureID); + + //generate the texture + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + _textureImage.width(), + _textureImage.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, + _textureImage.bits()); + + //texture parameters + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } void PieMenu::addAction(QAction* action){ @@ -44,15 +69,10 @@ void PieMenu::render() { float distance = sqrt((_mouseX - _x) * (_mouseX - _x) + (_mouseY - _y) * (_mouseY - _y)); - glBegin(GL_QUAD_STRIP); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, _textureID); + glColor3f(1.0f, 1.0f, 1.0f); - for (float i = start; i < end; i += step) { - glVertex2f(_x + _radiusIntern * cos(i), _y + _radiusIntern * sin(i)); - glVertex2f(_x + _radiusExtern * cos(i), _y + _radiusExtern * sin(i)); - } - glVertex2f(_x + _radiusIntern * cos(end), _y + _radiusIntern * sin(end)); - glVertex2f(_x + _radiusExtern * cos(end), _y + _radiusExtern * sin(end)); - glEnd(); if (_radiusIntern < distance) { float angle = atan2((_mouseY - _y), (_mouseX - _x)) - start; @@ -62,18 +82,36 @@ void PieMenu::render() { start = start + _selectedAction * 2.0f * M_PI / _actions.size(); end = start + 2.0f * M_PI / _actions.size(); - glBegin(GL_QUAD_STRIP); - glColor3f(0.0f, 0.0f, 0.0f); + glBegin(GL_TRIANGLE_FAN); + glTexCoord2f(0.5f, 0.5f); + glVertex2f(_x, _y); for (float i = start; i < end; i += step) { - glVertex2f(_x + _radiusIntern * cos(i), _y + _radiusIntern * sin(i)); - glVertex2f(_x + _radiusExtern * cos(i), _y + _radiusExtern * sin(i)); + glTexCoord2f(0.5f + 0.5f * cos(i), 0.5f - 0.5f * sin(i)); + glVertex2f(_x + _magnification * _radiusExtern * cos(i), + _y + _magnification * _radiusExtern * sin(i)); } - glVertex2f(_x + _radiusIntern * cos(end), _y + _radiusIntern * sin(end)); - glVertex2f(_x + _radiusExtern * cos(end), _y + _radiusExtern * sin(end)); + glTexCoord2f(0.5f + 0.5f * cos(end), 0.5f + - 0.5f * sin(end)); + glVertex2f(_x + _magnification * _radiusExtern * cos(end), + _y + _magnification * _radiusExtern * sin(end)); glEnd(); } else { _selectedAction = -1; + + glBegin(GL_QUADS); + glTexCoord2f(1, 1); + glVertex2f(_x + _radiusExtern, _y - _radiusExtern); + + glTexCoord2f(1, 0); + glVertex2f(_x + _radiusExtern, _y + _radiusExtern); + + glTexCoord2f(0, 0); + glVertex2f(_x - _radiusExtern, _y + _radiusExtern); + + glTexCoord2f(0, 1); + glVertex2f(_x - _radiusExtern, _y - _radiusExtern); + glEnd(); } + glDisable(GL_TEXTURE_2D); } void PieMenu::resize(int screenWidth, int screenHeight) { @@ -87,11 +125,14 @@ void PieMenu::mouseMoveEvent(int x, int y) { void PieMenu::mousePressEvent(int x, int y) { _x = _mouseX = x; _y = _mouseY = y; + _selectedAction = -1; _isDisplayed = true; } void PieMenu::mouseReleaseEvent(int x, int y) { - // TODO + if (0 <= _selectedAction && _selectedAction < _actions.size() && _actions[_selectedAction]) { + _actions[_selectedAction]->trigger(); + } _isDisplayed = false; } diff --git a/interface/src/PieMenu.h b/interface/src/PieMenu.h index 0323af8f94..863a91cb45 100644 --- a/interface/src/PieMenu.h +++ b/interface/src/PieMenu.h @@ -11,6 +11,11 @@ #include +#include "InterfaceConfig.h" +#include "Util.h" + +#include + class QAction; class PieMenu { @@ -29,11 +34,15 @@ public: void mouseReleaseEvent(int x, int y); private: + QImage _textureImage; + GLuint _textureID; + // position of the menu - int _x; - int _y; - int _radiusIntern; - int _radiusExtern; + int _x; + int _y; + int _radiusIntern; + int _radiusExtern; + float _magnification; int _mouseX; int _mouseY;