138 lines · 3.8 KB · C++
RawDownload
////  PieMenu.cpp//  hifi////  Created by Clement Brisset on 7/18/13.//  Copyright (c) 2013 High Fidelity, Inc. All rights reserved.// #include "PieMenu.h" #include <cmath> #include <QAction>#include <QSvgRenderer>#include <QPainter>#include <QGLWidget>#include <SharedUtil.h> PieMenu::PieMenu() :    _radiusIntern(30),    _radiusExtern(70),    _magnification(1.2f),    _isDisplayed(false) {} 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){    _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));     glEnable(GL_TEXTURE_2D);    glBindTexture(GL_TEXTURE_2D, _textureID);     glColor3f(1.0f, 1.0f, 1.0f);     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_TRIANGLE_FAN);        glTexCoord2f(0.5f, 0.5f);        glVertex2f(_x, _y);        for (float i = start; i < end; i += step) {            glTexCoord2f(0.5f + 0.5f * cos(i), 0.5f - 0.5f * sin(i));            glVertex2f(_x + _magnification * _radiusExtern * cos(i),                       _y + _magnification * _radiusExtern * sin(i));        }        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) {} void PieMenu::mouseMoveEvent(int x, int y) {    _mouseX = x;    _mouseY = 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) {    if (0 <= _selectedAction && _selectedAction < _actions.size() && _actions[_selectedAction]) {        _actions[_selectedAction]->trigger();    }     _isDisplayed = false;}