diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt
index cccb9b96b0..339e7a77b7 100755
--- a/interface/CMakeLists.txt
+++ b/interface/CMakeLists.txt
@@ -65,7 +65,7 @@ if (APPLE)
endif (APPLE)
-find_package(Qt4 REQUIRED QtCore QtGui QtNetwork QtOpenGL QtWebKit)
+find_package(Qt4 REQUIRED QtCore QtGui QtNetwork QtOpenGL QtWebKit QtSvg)
include(${QT_USE_FILE})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${QT_QTGUI_INCLUDE_DIR}")
diff --git a/interface/resources/images/hifi-interface-tools.svg b/interface/resources/images/hifi-interface-tools.svg
new file mode 100644
index 0000000000..311514581f
--- /dev/null
+++ b/interface/resources/images/hifi-interface-tools.svg
@@ -0,0 +1,177 @@
+
+
+
+
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 7ee0488f42..fc72aa63bd 100755
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -8,6 +8,7 @@
#include
#include
+#include
#ifdef _WIN32
#include "Syssocket.h"
@@ -63,6 +64,7 @@
#include "Util.h"
#include "renderer/ProgramObject.h"
#include "ui/TextRenderer.h"
+#include "Swatch.h"
#include "fvupdater.h"
using namespace std;
@@ -198,7 +200,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_packetCount(0),
_packetsPerSecond(0),
_bytesPerSecond(0),
- _bytesCount(0)
+ _bytesCount(0),
+ _swatch(NULL)
{
_applicationStartupTime = startup_time;
_window->setWindowTitle("Interface");
@@ -274,7 +277,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
FvUpdater::sharedUpdater()->SetFeedURL("https://s3-us-west-1.amazonaws.com/highfidelity/appcast.xml");
FvUpdater::sharedUpdater()->CheckForUpdatesSilent();
#endif
-
+
initMenu();
QRect available = desktop()->availableGeometry();
@@ -727,7 +730,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;
@@ -1252,7 +1264,11 @@ void Application::decreaseVoxelSize() {
void Application::increaseVoxelSize() {
_mouseVoxelScale *= 2;
}
-
+
+void Application::resetSwatchColors() {
+ _swatch.reset();
+}
+
static QIcon createSwatchIcon(const QColor& color) {
QPixmap map(16, 16);
map.fill(color);
@@ -1498,7 +1514,7 @@ void Application::initMenu() {
QMenu* renderMenu = menuBar->addMenu("Render");
(_renderVoxels = renderMenu->addAction("Voxels"))->setCheckable(true);
_renderVoxels->setChecked(true);
- _renderVoxels->setShortcut(Qt::Key_V);
+ _renderVoxels->setShortcut(Qt::CTRL | Qt::Key_V);
(_renderVoxelTextures = renderMenu->addAction("Voxel Textures"))->setCheckable(true);
(_renderStarsOn = renderMenu->addAction("Stars"))->setCheckable(true);
_renderStarsOn->setChecked(true);
@@ -1540,26 +1556,29 @@ 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::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::Key_R))->setCheckable(true);
_voxelModeActions->addAction(_deleteVoxelMode);
(_colorVoxelMode = voxelMenu->addAction(
- "Color Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_B))->setCheckable(true);
+ "Color Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_B))->setCheckable(true);
_voxelModeActions->addAction(_colorVoxelMode);
(_selectVoxelMode = voxelMenu->addAction(
- "Select Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_S))->setCheckable(true);
+ "Select Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_O))->setCheckable(true);
_voxelModeActions->addAction(_selectVoxelMode);
(_eyedropperMode = voxelMenu->addAction(
- "Get Color Mode", this, SLOT(updateVoxelModeActions()), Qt::CTRL | Qt::Key_G))->setCheckable(true);
+ "Get Color Mode", this, SLOT(updateVoxelModeActions()), 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);
-
+ voxelMenu->addAction("Reset Swatch Colors", this, SLOT(resetSwatchColors()));
+
_voxelPaintColor = voxelMenu->addAction("Voxel Paint Color", this,
SLOT(chooseVoxelPaintColor()), Qt::META | Qt::Key_C);
+ _swatch.setAction(_voxelPaintColor);
+
QColor paintColor(128, 128, 128);
_voxelPaintColor->setData(paintColor);
_voxelPaintColor->setIcon(createSwatchIcon(paintColor));
@@ -1690,6 +1709,14 @@ void Application::init() {
sendAvatarVoxelURLMessage(_myAvatar.getVoxels()->getVoxelURL());
+
+ _palette.init(_glWidget->width(), _glWidget->height());
+ _palette.addAction(_addVoxelMode, 0, 0);
+ _palette.addAction(_deleteVoxelMode, 0, 1);
+ _palette.addTool(&_swatch);
+ _palette.addAction(_colorVoxelMode, 0, 2);
+ _palette.addAction(_eyedropperMode, 0, 3);
+ _palette.addAction(_selectVoxelMode, 0, 4);
}
const float MAX_AVATAR_EDIT_VELOCITY = 1.0f;
@@ -1922,7 +1949,7 @@ void Application::update(float deltaTime) {
if (_bandwidthDialog) {
_bandwidthDialog->update();
}
-
+
// Update audio stats for procedural sounds
#ifndef _WIN32
_audio.setLastAcceleration(_myAvatar.getThrust());
@@ -2436,7 +2463,52 @@ void Application::displayOverlay() {
// render the webcam input frame
_webcam.renderPreview(_glWidget->width(), _glWidget->height());
-
+
+ _palette.render(_glWidget->width(), _glWidget->height());
+
+ if (_eyedropperMode->isChecked() && _voxelPaintColor->data().value() != _swatch.getColor()) {
+ QColor color = _voxelPaintColor->data().value();
+ TextRenderer textRenderer(SANS_FONT_FAMILY, 11, 50);
+ const char line1[] = "Assign this color to a swatch";
+ const char line2[] = "by choosing a key from 1 to 8.";
+
+ int left = (_glWidget->width() - POPUP_WIDTH - 2 * POPUP_MARGIN) / 2;
+ int top = _glWidget->height() / 40;
+
+ glBegin(GL_POLYGON);
+ glColor3f(0.0f, 0.0f, 0.0f);
+ for (double a = M_PI; a < 1.5f * M_PI; a += POPUP_STEP) {
+ glVertex2f(left + POPUP_MARGIN * cos(a) , top + POPUP_MARGIN * sin(a));
+ }
+ for (double a = 1.5f * M_PI; a < 2.0f * M_PI; a += POPUP_STEP) {
+ glVertex2f(left + POPUP_WIDTH + POPUP_MARGIN * cos(a), top + POPUP_MARGIN * sin(a));
+ }
+ for (double a = 0.0f; a < 0.5f * M_PI; a += POPUP_STEP) {
+ glVertex2f(left + POPUP_WIDTH + POPUP_MARGIN * cos(a), top + POPUP_HEIGHT + POPUP_MARGIN * sin(a));
+ }
+ for (double a = 0.5f * M_PI; a < 1.0f * M_PI; a += POPUP_STEP) {
+ glVertex2f(left + POPUP_MARGIN * cos(a) , top + POPUP_HEIGHT + POPUP_MARGIN * sin(a));
+ }
+ glEnd();
+
+ glBegin(GL_QUADS);
+ glColor3f(color.redF(),
+ color.greenF(),
+ color.blueF());
+ glVertex2f(left , top);
+ glVertex2f(left + SWATCH_WIDTH, top);
+ glVertex2f(left + SWATCH_WIDTH, top + SWATCH_HEIGHT);
+ glVertex2f(left , top + SWATCH_HEIGHT);
+ glEnd();
+
+ glColor3f(1.0f, 1.0f, 1.0f);
+ textRenderer.draw(left + SWATCH_WIDTH + POPUP_MARGIN, top + FIRST_LINE_OFFSET , line1);
+ textRenderer.draw(left + SWATCH_WIDTH + POPUP_MARGIN, top + SECOND_LINE_OFFSET, line2);
+ }
+ else {
+ _swatch.checkColor();
+ }
+
glPopMatrix();
}
@@ -2986,7 +3058,8 @@ void Application::loadSettings(QSettings* settings) {
settings->endGroup();
scanMenuBar(&Application::loadAction, settings);
- getAvatar()->loadData(settings);
+ getAvatar()->loadData(settings);
+ _swatch.loadData(settings);
}
@@ -3008,6 +3081,7 @@ void Application::saveSettings(QSettings* settings) {
scanMenuBar(&Application::saveAction, settings);
getAvatar()->saveData(settings);
+ _swatch.saveData(settings);
}
void Application::importSettings() {
diff --git a/interface/src/Application.h b/interface/src/Application.h
index 565df61785..60168cde20 100644
--- a/interface/src/Application.h
+++ b/interface/src/Application.h
@@ -39,6 +39,8 @@
#include "Webcam.h"
#include "renderer/GeometryCache.h"
#include "ui/ChatEntry.h"
+#include "ToolsPalette.h"
+#include "Swatch.h"
class QAction;
class QActionGroup;
@@ -139,6 +141,7 @@ private slots:
void updateVoxelModeActions();
void decreaseVoxelSize();
void increaseVoxelSize();
+ void resetSwatchColors();
void chooseVoxelPaintColor();
void loadSettings(QSettings* set = NULL);
void saveSettings(QSettings* set = NULL);
@@ -362,6 +365,8 @@ private:
int _bytesPerSecond;
int _bytesCount;
+ ToolsPalette _palette;
+ Swatch _swatch;
};
#endif /* defined(__interface__Application__) */
diff --git a/interface/src/Swatch.cpp b/interface/src/Swatch.cpp
new file mode 100644
index 0000000000..ad0e3e420a
--- /dev/null
+++ b/interface/src/Swatch.cpp
@@ -0,0 +1,169 @@
+#include "Swatch.h"
+#include
+
+Swatch::Swatch(QAction* action) :
+ Tool(action, 0, -1, -1),
+ _selected(1),
+ _textRenderer(MONO_FONT_FAMILY, 10, 100) {
+}
+
+void Swatch::reset() {
+ for (int i = 0; i < 8; ++i) {
+ _colors[i].setRgb(colorBase[i][0],
+ colorBase[i][1],
+ colorBase[i][2]);
+ }
+}
+
+QColor Swatch::getColor() {
+ return _colors[_selected - 1];
+}
+
+void Swatch::checkColor() {
+ if (_action->data().value() == _colors[_selected - 1]) {
+ return;
+ }
+
+ QPixmap map(16, 16);
+ map.fill(_colors[_selected - 1]);
+ _action->setData(_colors[_selected - 1]) ;
+ _action->setIcon(map);
+}
+
+void Swatch::saveData(QSettings* settings) {
+ settings->beginGroup("Swatch");
+
+ for (int i(0); i < SWATCH_SIZE; ++i) {
+ QString rx("R1"), gx("G1"), bx("B1");
+ rx[1] = '1' + i;
+ gx[1] = rx[1];
+ bx[1] = rx[1];
+ settings->setValue(rx, _colors[i].red());
+ settings->setValue(gx, _colors[i].green());
+ settings->setValue(bx, _colors[i].blue());
+ }
+
+ settings->endGroup();
+}
+
+void Swatch::loadData(QSettings* settings) {
+ settings->beginGroup("Swatch");
+
+ for (int i = 0; i < SWATCH_SIZE; ++i) {
+ QString rx("R1"), gx("G1"), bx("B1");
+ rx[1] = '1' + i;
+ gx[1] = rx[1];
+ bx[1] = rx[1];
+ _colors[i].setRgb(settings->value(rx, colorBase[i][0]).toInt(),
+ settings->value(gx, colorBase[i][1]).toInt(),
+ settings->value(bx, colorBase[i][2]).toInt());
+ }
+
+ settings->endGroup();
+
+ checkColor();
+}
+
+void Swatch::handleEvent(int key, bool getColor) {
+ int next(0);
+
+ switch (key) {
+ case Qt::Key_1:
+ next = 1;
+ break;
+ case Qt::Key_2:
+ next = 2;
+ break;
+ case Qt::Key_3:
+ next = 3;
+ break;
+ case Qt::Key_4:
+ next = 4;
+ break;
+ case Qt::Key_5:
+ next = 5;
+ break;
+ case Qt::Key_6:
+ next = 6;
+ break;
+ case Qt::Key_7:
+ next = 7;
+ break;
+ case Qt::Key_8:
+ next = 8;
+ break;
+ default:
+ break;
+ }
+
+ if (getColor) {
+ if (_action->data().value() != _colors[_selected - 1]) {
+ _selected = next;
+ _colors[_selected - 1] = _action->data().value();
+ }
+ } else {
+ _selected = next;
+ QPixmap map(16, 16);
+ map.fill(_colors[_selected - 1]);
+ _action->setData(_colors[_selected - 1]) ;
+ _action->setIcon(map);
+ }
+}
+
+void Swatch::render(int width, int height) {
+ char str[2];
+ int margin = 0.10f * height;
+ height = 0.75f * height;
+
+ 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() < 50) {
+ 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) - 0.2f * height, str);
+ }
+
+ glTranslated(0, 8 * (height - margin) + margin + 0.075f * height, 0);
+}
diff --git a/interface/src/Swatch.h b/interface/src/Swatch.h
new file mode 100644
index 0000000000..e167cd05c4
--- /dev/null
+++ b/interface/src/Swatch.h
@@ -0,0 +1,43 @@
+//
+// Swatch.h
+// interface
+//
+// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
+//
+
+#ifndef __interface__Swatch__
+#define __interface__Swatch__
+
+#include "Tool.h"
+#include "ui/TextRenderer.h"
+
+static const int SWATCH_SIZE = 8;
+static const int colorBase[8][3] = {{237, 175, 0},
+ {61, 211, 72},
+ {51, 204, 204},
+ {63, 169, 245},
+ {193, 99, 122},
+ {255, 54, 69},
+ {124, 36, 36},
+ {63, 35, 19}};
+
+class Swatch : public Tool {
+public:
+ Swatch(QAction* action);
+
+ QColor getColor();
+ void checkColor();
+ void saveData(QSettings* settings);
+ void loadData(QSettings* settings);
+ void reset();
+
+ void render(int width, int height);
+ void handleEvent(int key, bool getColor);
+
+private:
+ TextRenderer _textRenderer;
+ QColor _colors[SWATCH_SIZE];
+ int _selected;
+};
+
+#endif /* defined(__interface__Swatch__) */
diff --git a/interface/src/Tool.cpp b/interface/src/Tool.cpp
new file mode 100644
index 0000000000..3ad5a648e5
--- /dev/null
+++ b/interface/src/Tool.cpp
@@ -0,0 +1,51 @@
+#include "Tool.h"
+
+#include
+#include
+#include
+
+Tool::Tool(QAction *action, GLuint texture, int x, int y) :
+ _texture(texture),
+ _action(action),
+ _x(x),
+ _y(y) {
+}
+
+void Tool::setAction(QAction* action) {
+ _action = action;
+}
+
+bool Tool::isActive() {
+ return _action->isChecked();
+}
+
+void Tool::render(int width, int height) {
+ 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 / NUM_TOOLS_COLS, 1.0f - (_y + 1) / NUM_TOOLS_ROWS);
+ glVertex2f(0 , height);
+
+ glTexCoord2f((_x + 1) / NUM_TOOLS_COLS, 1.0f - (_y + 1) / NUM_TOOLS_ROWS);
+ glVertex2f(width, height);
+
+ glTexCoord2f((_x + 1) / NUM_TOOLS_COLS, 1.0f - _y / NUM_TOOLS_ROWS);
+ glVertex2f(width, 0);
+
+ glTexCoord2f( _x / NUM_TOOLS_COLS, 1.0f - _y / NUM_TOOLS_ROWS);
+ glVertex2f(0 , 0);
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+
+ glTranslated(0, 1.10f * height, 0);
+}
diff --git a/interface/src/Tool.h b/interface/src/Tool.h
new file mode 100644
index 0000000000..f0e1bae4b0
--- /dev/null
+++ b/interface/src/Tool.h
@@ -0,0 +1,55 @@
+//
+// Tool.h
+// interface
+//
+// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
+//
+
+#ifndef __interface__Tool__
+#define __interface__Tool__
+
+#include
+
+#include "InterfaceConfig.h"
+#include "Util.h"
+
+class QAction;
+
+
+// Number of rows and columns in the SVG file for the tool palette
+static const int NUM_TOOLS_ROWS = 10;
+static const int NUM_TOOLS_COLS = 2;
+static const int SWATCHS_TOOLS_COUNT = 13; // 8 swatch + 5 tools
+
+static const int WIDTH_MIN = 47; // Minimal tools width
+static const float TOOLS_RATIO = 40.0f / 60.0f; // ratio height/width of tools icons
+static const float PAL_SCREEN_RATIO = 3.0f / 100.0f; // Percentage of the screeen width the palette is going to occupy
+
+// Swatch popup consts
+static const float POPUP_STEP = 0.05f;
+static const float POPUP_MARGIN = 10.0f;
+static const int POPUP_WIDTH = 280;
+static const int POPUP_HEIGHT = 30;
+static const int SWATCH_WIDTH = 64;
+static const int SWATCH_HEIGHT = 30;
+static const int FIRST_LINE_OFFSET = 12;
+static const int SECOND_LINE_OFFSET = 28;
+
+class Tool {
+public:
+ Tool(QAction* action, GLuint texture, int x, int y);
+
+ void setAction(QAction* action);
+ bool isActive();
+ virtual void render(int width, int height);
+
+protected:
+ QAction* _action;
+ GLuint _texture;
+
+ // position in the SVG grid
+ double _x;
+ double _y;
+};
+
+#endif /* defined(__interface__Tool__) */
diff --git a/interface/src/ToolsPalette.cpp b/interface/src/ToolsPalette.cpp
new file mode 100644
index 0000000000..341a128f8a
--- /dev/null
+++ b/interface/src/ToolsPalette.cpp
@@ -0,0 +1,79 @@
+#include "ToolsPalette.h"
+
+#include
+#include
+#include
+#include
+
+void ToolsPalette::init(int screenWidth, int screenHeight) {
+ _width = (PAL_SCREEN_RATIO * screenWidth < WIDTH_MIN) ? WIDTH_MIN : PAL_SCREEN_RATIO * screenWidth;
+ _height = TOOLS_RATIO * _width;
+
+ _left = screenWidth / 150;
+ _top = (screenHeight - SWATCHS_TOOLS_COUNT * _height) / 2;
+
+ // Load SVG
+ switchToResourcesParentIfRequired();
+ QSvgRenderer renderer(QString("./resources/images/hifi-interface-tools.svg"));
+
+ // Prepare a QImage with desired characteritisc
+ QImage image(NUM_TOOLS_COLS * _width, NUM_TOOLS_ROWS * _height, 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);
+
+ 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) {
+ _width = (PAL_SCREEN_RATIO * screenWidth < WIDTH_MIN) ? WIDTH_MIN : PAL_SCREEN_RATIO * screenWidth;
+ _height = TOOLS_RATIO * _width;
+
+ _left = screenWidth / 150;
+ _top = (screenHeight - SWATCHS_TOOLS_COUNT * _height) / 2;
+
+ glPushMatrix();
+ glTranslated(_left, _top, 0);
+
+ bool show = false;
+ for (unsigned int i = 0; i < _tools.size(); ++i) {
+ if (_tools[i]->isActive()) {
+ show = true;
+ break;
+ }
+ }
+
+ if (show) {
+ for (unsigned int i = 0; i < _tools.size(); ++i) {
+ _tools[i]->render(_width, _height);
+ }
+ }
+
+ glPopMatrix();
+}
diff --git a/interface/src/ToolsPalette.h b/interface/src/ToolsPalette.h
new file mode 100644
index 0000000000..0b4ee95524
--- /dev/null
+++ b/interface/src/ToolsPalette.h
@@ -0,0 +1,35 @@
+//
+// ToolsPalette.h
+// interface
+//
+// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
+//
+
+#ifndef __interface__ToolsPalette__
+#define __interface__ToolsPalette__
+
+#include "Tool.h"
+#include "Swatch.h"
+
+#include
+
+class ToolsPalette {
+public:
+ void init(int screenWidth, int screenHeight);
+ 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 _tools;
+
+ int _top;
+ int _left;
+
+ int _width;
+ int _height;
+};
+
+#endif /* defined(__interface__ToolsPalette__) */
diff --git a/interface/src/Util.h b/interface/src/Util.h
index 24cbad9e68..2005b76438 100644
--- a/interface/src/Util.h
+++ b/interface/src/Util.h
@@ -25,7 +25,6 @@
// the standard mono font family
#define MONO_FONT_FAMILY "Courier"
-
void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * fwd, glm::vec3 * left, glm::vec3 * up);
float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos);