#19368 - Improve editing/building workflow in Interface

This commit is contained in:
atlante45 2013-06-25 00:24:21 +02:00
parent 517ff0f3cf
commit d6c70ea6ca
10 changed files with 413 additions and 7 deletions

View file

@ -65,7 +65,7 @@ if (APPLE)
endif (APPLE)
find_package(Qt4 REQUIRED QtCore QtGui QtNetwork QtOpenGL)
find_package(Qt4 REQUIRED QtCore QtGui QtNetwork QtOpenGL QtSvg)
include(${QT_USE_FILE})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${QT_QTGUI_INCLUDE_DIR}")

View file

@ -8,6 +8,7 @@
#include <sstream>
#include <stdlib.h>
#include <cmath>
#ifdef _WIN32
#include "Syssocket.h"
@ -60,6 +61,7 @@
#include "Util.h"
#include "renderer/ProgramObject.h"
#include "ui/TextRenderer.h"
#include "Swatch.h"
using namespace std;
@ -636,7 +638,16 @@ void Application::keyPressEvent(QKeyEvent* event) {
deleteVoxelUnderCursor();
}
break;
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
_swatch->handleEvent(event->key(), _eyedropperMode->isChecked());
break;
default:
event->ignore();
break;
@ -1296,10 +1307,10 @@ void Application::initMenu() {
_voxelModeActions->setExclusive(false); // exclusivity implies one is always checked
(_addVoxelMode = voxelMenu->addAction(
"Add Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_A))->setCheckable(true);
"Add Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_V))->setCheckable(true);
_voxelModeActions->addAction(_addVoxelMode);
(_deleteVoxelMode = voxelMenu->addAction(
"Delete Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_D))->setCheckable(true);
"Delete Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_R))->setCheckable(true);
_voxelModeActions->addAction(_deleteVoxelMode);
(_colorVoxelMode = voxelMenu->addAction(
"Color Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_B))->setCheckable(true);
@ -1310,7 +1321,7 @@ void Application::initMenu() {
(_eyedropperMode = voxelMenu->addAction(
"Get Color Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_G))->setCheckable(true);
_voxelModeActions->addAction(_eyedropperMode);
voxelMenu->addAction("Decrease Voxel Size", this, SLOT(decreaseVoxelSize()), QKeySequence::ZoomOut);
voxelMenu->addAction("Increase Voxel Size", this, SLOT(increaseVoxelSize()), QKeySequence::ZoomIn);
@ -1437,6 +1448,15 @@ void Application::init() {
loadSettings();
sendAvatarVoxelURLMessage(_myAvatar.getVoxels()->getVoxelURL());
_swatch = new Swatch(_voxelPaintColor);
_palette.init();
_palette.addAction(_addVoxelMode, 0, 0);
_palette.addAction(_deleteVoxelMode, 0, 1);
_palette.addTool(_swatch);
_palette.addAction(_colorVoxelMode, 0, 2);
_palette.addAction(_eyedropperMode, 0, 3);
}
const float MAX_AVATAR_EDIT_VELOCITY = 1.0f;
@ -1643,7 +1663,7 @@ void Application::update(float deltaTime) {
}
}
}
// Update audio stats for procedural sounds
#ifndef _WIN32
_audio.setLastAcceleration(_myAvatar.getThrust());
@ -2158,7 +2178,50 @@ void Application::displayOverlay() {
// render the webcam input frame
_webcam.renderPreview(_glWidget->width(), _glWidget->height());
_palette.render(_glWidget->width(), _glWidget->height());
if (_eyedropperMode->isChecked()) {
QColor color(_voxelPaintColor->data().value<QColor>());
TextRenderer textRenderer(SANS_FONT_FAMILY, -1, 100);
const char* line1("Assign this color to a swatch");
const char* line2("by choosing a key from 1 to 8.");
double step(0.05f);
int left(_glWidget->width()/100.0f);
int top(_glWidget->height()*7.0f/10.0f);
double margin(10.0f);
glBegin(GL_POLYGON);
glColor3f(0.0f, 0.0f, 0.0f);
for (double a(M_PI); a < 1.5f*M_PI; a += step) {
glVertex2f(left + margin*cos(a), top + margin*sin(a));
}
for (double a(1.5f*M_PI); a < 2.0f*M_PI; a += step) {
glVertex2f(left + 300 + margin*cos(a), top + margin*sin(a));
}
for (double a(0.0f); a < 0.5f*M_PI; a += step) {
glVertex2f(left + 300 + margin*cos(a), top + 30 + margin*sin(a));
}
for (double a(0.5f*M_PI); a < 1.0f*M_PI; a += step) {
glVertex2f(left + margin*cos(a), top + 30 + margin*sin(a));
}
glEnd();
glBegin(GL_QUADS);
glColor3f(color.redF(),
color.greenF(),
color.blueF());
glVertex2f(left, top);
glVertex2f(left + 64, top);
glVertex2f(left + 64, top + 30);
glVertex2f(left, top + 30);
glEnd();
glColor3f(1.0f, 1.0f, 1.0f);
textRenderer.draw(left + 74, top + 10, line1);
textRenderer.draw(left + 74, top + 30, line2);
}
glPopMatrix();
}

View file

@ -33,6 +33,8 @@
#include "VoxelSystem.h"
#include "Webcam.h"
#include "ui/ChatEntry.h"
#include "ToolsPalette.h"
#include "Swatch.h"
class QAction;
class QActionGroup;
@ -309,6 +311,9 @@ private:
int _packetsPerSecond;
int _bytesPerSecond;
int _bytesCount;
ToolsPalette _palette;
Swatch* _swatch;
};
#endif /* defined(__interface__Application__) */

125
interface/src/Swatch.cpp Normal file
View file

@ -0,0 +1,125 @@
#include "Swatch.h"
#include <iostream>
Swatch::Swatch(QAction* action) : Tool(action, 0, -1, -1),
_selected(1),
_margin(4),
_textRenderer(SANS_FONT_FAMILY, -1, 100) {
_width = 62;
_height = 30;
_colors[0].setRgb(128, 128, 128);
_colors[1].setRgb(255, 0, 0);
_colors[2].setRgb(0, 255, 0);
_colors[3].setRgb(0, 0, 255);
_colors[4].setRgb(255, 0, 255);
_colors[5].setRgb(255, 255, 0);
_colors[6].setRgb(0, 255, 255);
_colors[7].setRgb(0, 0, 0);
QPixmap map(16, 16);
map.fill(_colors[0]);
_action->setData(_colors[_selected - 1]) ;
_action->setIcon(map);
}
void Swatch::handleEvent(int key, bool getColor) {
switch (key) {
case Qt::Key_1:
_selected = 1;
break;
case Qt::Key_2:
_selected = 2;
break;
case Qt::Key_3:
_selected = 3;
break;
case Qt::Key_4:
_selected = 4;
break;
case Qt::Key_5:
_selected = 5;
break;
case Qt::Key_6:
_selected = 6;
break;
case Qt::Key_7:
_selected = 7;
break;
case Qt::Key_8:
_selected = 8;
break;
default:
break;
}
if (getColor) {
_colors[_selected - 1] = _action->data().value<QColor>();
}
else {
QPixmap map(16, 16);
map.fill(_colors[_selected - 1]);
_action->setData(_colors[_selected - 1]) ;
_action->setIcon(map);
}
}
void Swatch::render(int screenWidth, int screenHeight) {
char str[2];
glBegin(GL_QUADS);
glColor3f(0.0f, 0.0f, 0.0f);
glVertex2f(0, 8*(_height - _margin) + _margin);
glVertex2f(_width, 8*(_height - _margin) + _margin);
glVertex2f(_width, 0);
glVertex2f(0, 0);
glEnd();
for (unsigned int i(0); i < SWATCH_SIZE; ++i) {
glBegin(GL_QUADS);
glColor3f(_colors[i].redF(),
_colors[i].greenF(),
_colors[i].blueF());
glVertex2f(_margin, (i + 1)*(_height - _margin));
glVertex2f(_width - _margin, (i + 1)*(_height - _margin));
glVertex2f(_width - _margin, i*(_height - _margin) + _margin);
glVertex2f(_margin, i*(_height - _margin) + _margin);
glEnd();
if (_colors[i].lightness() < 100) {
glBegin(GL_LINES);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(_margin, (i + 1)*(_height - _margin));
glVertex2f(_width - _margin, (i + 1)*(_height - _margin));
glVertex2f(_width - _margin, (i + 1)*(_height - _margin));
glVertex2f(_width - _margin, i*(_height - _margin) + _margin);
glVertex2f(_width - _margin, i*(_height - _margin) + _margin);
glVertex2f(_margin, i*(_height - _margin) + _margin);
glVertex2f(_margin, i*(_height - _margin) + _margin);
glVertex2f(_margin, (i + 1)*(_height - _margin));
glEnd();
}
else {
glColor3f(0.0f, 0.0f, 0.0f);
}
if (_selected == i + 1) {
glBegin(GL_TRIANGLES);
glVertex2f(_margin, (i + 1)*(_height - _margin) - _margin);
glVertex2f(_width/4 - _margin, i*(_height - _margin) + _height/2.0f);
glVertex2f(_margin, i*(_height - _margin) + _margin + _margin);
glEnd();
}
sprintf(str, "%d", i + 1);
_textRenderer.draw(3*_width/4, (i + 1)*(_height - _margin) - 6, str);
}
glTranslated(0, 8*(_height - _margin) + _margin + 5, 0);
}

30
interface/src/Swatch.h Normal file
View file

@ -0,0 +1,30 @@
//
// Swatch.h
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Swatch__
#define __interface__Swatch__
#define SWATCH_SIZE 8
#include "Tool.h"
#include "ui/TextRenderer.h"
class Swatch : public Tool {
public:
Swatch(QAction* action);
void render(int screenWidth, int screenHeight);
void handleEvent(int key, bool getColor);
private:
TextRenderer _textRenderer;
QColor _colors[SWATCH_SIZE];
int _selected;
int _margin;
};
#endif /* defined(__interface__Swatch__) */

45
interface/src/Tool.cpp Normal file
View file

@ -0,0 +1,45 @@
#include "Tool.h"
#include <QSvgRenderer>
#include <QPainter>
#include <QGLWidget>
Tool::Tool(QAction *action, GLuint texture, int x, int y) : _texture(texture),
_action(action),
_x(x),
_y(y),
_width(62),
_height(40) {
}
void Tool::render(int screenWidth, int screenHeight) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _texture);
if (_action == 0 || _action->isChecked()) {
glColor3f(1.0f, 1.0f, 1.0f); // reset gl color
}
else {
glColor3f(0.3f, 0.3f, 0.3f);
}
glBegin(GL_QUADS);
glTexCoord2f(_x/TOOLS_COLS, 1.0f - (_y + 1)/TOOLS_ROWS);
glVertex2f(0, _height);
glTexCoord2f((_x + 1)/TOOLS_COLS, 1.0f - (_y + 1)/TOOLS_ROWS);
glVertex2f(_width, _height);
glTexCoord2f((_x + 1)/TOOLS_COLS, 1.0f - _y/TOOLS_ROWS);
glVertex2f(_width, 0);
glTexCoord2f(_x/TOOLS_COLS, 1.0f - _y/TOOLS_ROWS);
glVertex2f(0, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glTranslated(0, _height + 5, 0);
}

41
interface/src/Tool.h Normal file
View file

@ -0,0 +1,41 @@
//
// Tool.h
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Tool__
#define __interface__Tool__
#include <QAction>
#include "InterfaceConfig.h"
#include "Util.h"
class QAction;
// tool size
static double _width;
static double _height;
class Tool {
public:
Tool(QAction *action, GLuint texture, int x, int y);
virtual void render(int screenWidth, int screenHeight);
protected:
QAction* _action;
GLuint _texture;
// position in the SVG grid
double _x;
double _y;
// tool size
double _width;
double _height;
};
#endif /* defined(__interface__Tool__) */

View file

@ -0,0 +1,60 @@
#include "ToolsPalette.h"
#include <QSvgRenderer>
#include <QPainter>
#include <QGLWidget>
ToolsPalette::ToolsPalette() {
// Load SVG
QSvgRenderer renderer(QString("./resources/images/hifi-interface-tools.svg"));
// Prepare a QImage with desired characteritisc
QImage image(124, 400, QImage::Format_ARGB32);
// Get QPainter that paints to the image
QPainter painter(&image);
renderer.render(&painter);
//get the OpenGL-friendly image
_textureImage = QGLWidget::convertToGLFormat(image);
}
void ToolsPalette::init(int top, int left) {
_top = top;
_left = left;
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 ToolsPalette::addAction(QAction* action, int x, int y) {
Tool* tmp = new Tool(action, _textureID, x, y);
_tools.push_back(tmp);
}
void ToolsPalette::addTool(Tool *tool) {
_tools.push_back(tool);
}
void ToolsPalette::render(int screenWidth, int screenHeight) {
glPushMatrix();
glTranslated(_left, _top, 0);
for (unsigned int i(0); i < _tools.size(); ++i) {
_tools[i]->render(screenWidth, screenHeight);
}
glPopMatrix();
}

View file

@ -0,0 +1,34 @@
//
// ToolsPalette.h
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__ToolsPalette__
#define __interface__ToolsPalette__
#include <Tool.h>
#include <vector>
class ToolsPalette {
public:
ToolsPalette();
void init(int top = 200, int left = 10);
void addAction(QAction* action, int x, int y);
void addTool(Tool *tool);
void render(int screenWidth, int screenHeight);
private:
QImage _textureImage;
GLuint _textureID;
std::vector<Tool*> _tools;
int _top;
int _left;
};
#endif /* defined(__interface__ToolsPalette__) */

View file

@ -25,6 +25,9 @@
// the standard mono font family
#define MONO_FONT_FAMILY "Courier"
// Number of rows and columns in the SVG file for the tool palette
#define TOOLS_ROWS 10
#define TOOLS_COLS 2
void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * fwd, glm::vec3 * left, glm::vec3 * up);