<commit_before>#include "HTTPProtocol.h"
#include "ThorsNisse/NisseService.h"

using namespace ThorsAnvil::Nisse::ProtocolHTTP;

int onHeadersComplete(HttpParser* parser)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onHeadersComplete();
    return 0;
}
int onMessageBegin(HttpParser* parser)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onMessageBegin();
    return 0;
}
int onMessageComplete(HttpParser* parser)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onMessageComplete();
    return 0;
}

int onUrl(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onUrl(at, length);
    return 0;
}
int onStatus(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onStatus(at, length);
    return 0;
}
int onHeaderField(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onHeaderField(at, length);
    return 0;
}
int onHeaderValue(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onHeaderValue(at, length);
    return 0;
}
int onBody(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onBody(at, length);
    return 0;
}

ReadRequestHandler::ReadRequestHandler(NisseService& parent, ThorsAnvil::Socket::DataSocket&& so, Binder const& binder)
    : NisseHandler(parent, so.getSocketId(), EV_READ)
    , socket(std::move(so))
    , binder(binder)
    , buffer(bufferLen)
    , bodyBegin(nullptr)
    , bodyEnd(nullptr)
    , gotValue(false)
    , messageComplete(false)
{
    settings.on_headers_complete    = ::onHeadersComplete;
    settings.on_message_begin       = ::onMessageBegin;
    settings.on_message_complete    = ::onMessageComplete;

    settings.on_header_field        = ::onHeaderField;
    settings.on_header_value        = ::onHeaderValue;
    settings.on_url                 = ::onUrl;
    settings.on_status              = ::onStatus;
    settings.on_body                = ::onBody;

    http_parser_init(&parser, HTTP_REQUEST);
    parser.data                 = this;

}

void ReadRequestHandler::eventActivate(LibSocketId /*sockId*/, short /*eventType*/)
{
    bool        more;
    std::size_t recved;
    std::tie(more, recved) = socket.getMessageData(&buffer[0], bufferLen, 0);
    std::size_t nparsed = http_parser_execute(&parser, &settings, &buffer[0], recved);

    if (parser.upgrade)
    {
        /* handle new protocol */
    }
    else if (nparsed != recved)
    {
        /* Handle error. Usually just close the connection. */
    }

    if (messageComplete)
    {
        requestComplete(std::move(socket),
                        binder,
                        method,
                        std::move(uri),
                        std::move(headers),
                        std::move(buffer),
                        bodyBegin, bodyEnd
                       );
    }
    else if (!more)
    {
        dropHandler();
    }
}

void ReadRequestHandler::requestComplete(
                     DataSocket&&    socket,
                     Binder const&   binder,
                     Method          method,
                     std::string&&   uri,
                     Headers&&       headers,
                     std::vector<char>&& buffer,
                     char const* bodyBegin, char const* bodyEnd)
{
    moveHandler<WriteResponseHandler>(std::move(socket),
                                      binder,
                                      method,
                                      std::move(uri),
                                      std::move(headers),
                                      std::move(buffer),
                                      bodyBegin, bodyEnd
                                     );
}

void ReadRequestHandler::onHeadersComplete()
{
    addCurrentHeader();
    messageComplete = true;
}
void ReadRequestHandler::onMessageBegin()
{
}
void ReadRequestHandler::onMessageComplete()
{
}
void ReadRequestHandler::onUrl(char const* at, std::size_t length)
{
    switch (parser.method)
    {
        case HTTP_DELETE:       method = Method::Delete;break;
        case HTTP_GET:          method = Method::Get;   break;
        case HTTP_HEAD:         method = Method::Head;  break;
        case HTTP_POST:         method = Method::Post;  break;
        case HTTP_PUT:          method = Method::Put;   break;
        default:
            throw std::runtime_error("ThorsAnvil::Nisse::ReadRequestHandler::onUrl: unknown HTTP Method");
    }

    uri.assign(at, length);
    gotValue    = false;
}
void ReadRequestHandler::onStatus(char const* /*at*/, std::size_t /*length*/)
{
}
void ReadRequestHandler::onHeaderField(char const* at, std::size_t length)
{
    addCurrentHeader();
    currentHead.append(at, length);
}
void ReadRequestHandler::onHeaderValue(char const* at, std::size_t length)
{
    gotValue = true;
    currentValue.append(at, length);
}
void ReadRequestHandler::onBody(char const* at, std::size_t length)
{
    bodyBegin   = at;
    bodyEnd     = at + length;
}

void ReadRequestHandler::addCurrentHeader()
{
    if (gotValue)
    {
        headers[currentHead]    = std::move(currentValue);
        gotValue = false;
        currentHead.clear();
        currentValue.clear();
    }
}

// ------------------

WriteResponseHandler::WriteResponseHandler(NisseService& parent,
                                           ThorsAnvil::Socket::DataSocket&& so,
                                           Binder const& binder,
                                           Method methodParam,
                                           std::string&& uriParam,
                                           Headers&& headersParam,
                                           std::vector<char>&& bufferParam,
                                           char const* bodyBeginParam,
                                           char const* bodyEndParam)
    : NisseHandler(parent, so.getSocketId(), EV_WRITE)
    , flusher(nullptr)
    , worker([ &parent      = *this,
                socket      = std::move(so),
               &binder      = binder,
                method      = methodParam,
                uriParam    = std::move(uriParam),
                headers     = std::move(headersParam),
                buffer      = std::move(bufferParam),
                bodyBegin   = bodyBeginParam,
                bodyEnd     = bodyEndParam
             ](Yield& yield) mutable
                {
                    URI const     uri(headers.get("Host"), std::move(uriParam));
                    Action const& action(binder.find(Method::Get, uri.host, uri.path));
                    Socket::ISocketStream   input(socket, [&yield](){yield();}, [](){}, std::move(buffer), bodyBegin, bodyEnd);
                    Socket::OSocketStream   output(socket, [&yield](){yield();}, [&parent](){parent.flushing();});
                    Request       request(method, URI(std::move(uri)), headers, input);
                    Response      response(parent, socket, output);
                    yield();
                    action(request, response);
                }
            )
{}

void WriteResponseHandler::eventActivate(LibSocketId /*sockId*/, short /*eventType*/)
{
    worker();
    if (!worker)
    {
        dropHandler();
    }
}

#ifdef COVERAGE_TEST
/*
 * This code is only compiled into the unit tests for code coverage purposes
 * It is not part of the live code.
 */
#include "ThorsNisse/NisseHandler.h"
#include "ThorsNisse/NisseService.tpp"
#include "ThorsNisse/NisseHandler.tpp"
#include "Types.h"
template void ThorsAnvil::Nisse::NisseHandler::moveHandler
    <WriteResponseHandler,
     ThorsAnvil::Socket::DataSocket,
     Binder const&,
     Method,
     std::string,
     Headers,
     std::vector<char>,
     char const*,
     char const*>
    (ThorsAnvil::Socket::DataSocket&&,
     Binder const&,
     Method&&,
     std::string&&,
     Headers&&,
     std::vector<char>&&,
     char const*&&,
     char const*&&);

template void ThorsAnvil::Nisse::NisseService::addHandler<WriteResponseHandler, ThorsAnvil::Socket::DataSocket, Binder const&, Method, std::string, Headers, std::vector<char>, char const*, char const*>(ThorsAnvil::Socket::DataSocket&&, Binder const&, Method&&, std::string&&, Headers&&, std::vector<char>&&, char const*&&, char const*&&);
#endif
<commit_msg>Fix the method<commit_after>#include "HTTPProtocol.h"
#include "ThorsNisse/NisseService.h"

using namespace ThorsAnvil::Nisse::ProtocolHTTP;

int onHeadersComplete(HttpParser* parser)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onHeadersComplete();
    return 0;
}
int onMessageBegin(HttpParser* parser)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onMessageBegin();
    return 0;
}
int onMessageComplete(HttpParser* parser)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onMessageComplete();
    return 0;
}

int onUrl(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onUrl(at, length);
    return 0;
}
int onStatus(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onStatus(at, length);
    return 0;
}
int onHeaderField(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onHeaderField(at, length);
    return 0;
}
int onHeaderValue(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onHeaderValue(at, length);
    return 0;
}
int onBody(HttpParser* parser, const char *at, std::size_t length)
{
    ReadRequestHandler* parent = reinterpret_cast<ReadRequestHandler*>(parser->data);
    parent->onBody(at, length);
    return 0;
}

ReadRequestHandler::ReadRequestHandler(NisseService& parent, ThorsAnvil::Socket::DataSocket&& so, Binder const& binder)
    : NisseHandler(parent, so.getSocketId(), EV_READ)
    , socket(std::move(so))
    , binder(binder)
    , buffer(bufferLen)
    , bodyBegin(nullptr)
    , bodyEnd(nullptr)
    , gotValue(false)
    , messageComplete(false)
{
    settings.on_headers_complete    = ::onHeadersComplete;
    settings.on_message_begin       = ::onMessageBegin;
    settings.on_message_complete    = ::onMessageComplete;

    settings.on_header_field        = ::onHeaderField;
    settings.on_header_value        = ::onHeaderValue;
    settings.on_url                 = ::onUrl;
    settings.on_status              = ::onStatus;
    settings.on_body                = ::onBody;

    http_parser_init(&parser, HTTP_REQUEST);
    parser.data                 = this;

}

void ReadRequestHandler::eventActivate(LibSocketId /*sockId*/, short /*eventType*/)
{
    bool        more;
    std::size_t recved;
    std::tie(more, recved) = socket.getMessageData(&buffer[0], bufferLen, 0);
    std::size_t nparsed = http_parser_execute(&parser, &settings, &buffer[0], recved);

    if (parser.upgrade)
    {
        /* handle new protocol */
    }
    else if (nparsed != recved)
    {
        /* Handle error. Usually just close the connection. */
    }

    if (messageComplete)
    {
        requestComplete(std::move(socket),
                        binder,
                        method,
                        std::move(uri),
                        std::move(headers),
                        std::move(buffer),
                        bodyBegin, bodyEnd
                       );
    }
    else if (!more)
    {
        dropHandler();
    }
}

void ReadRequestHandler::requestComplete(
                     DataSocket&&    socket,
                     Binder const&   binder,
                     Method          method,
                     std::string&&   uri,
                     Headers&&       headers,
                     std::vector<char>&& buffer,
                     char const* bodyBegin, char const* bodyEnd)
{
    moveHandler<WriteResponseHandler>(std::move(socket),
                                      binder,
                                      method,
                                      std::move(uri),
                                      std::move(headers),
                                      std::move(buffer),
                                      bodyBegin, bodyEnd
                                     );
}

void ReadRequestHandler::onHeadersComplete()
{
    addCurrentHeader();
    messageComplete = true;
}
void ReadRequestHandler::onMessageBegin()
{
}
void ReadRequestHandler::onMessageComplete()
{
}
void ReadRequestHandler::onUrl(char const* at, std::size_t length)
{
    switch (parser.method)
    {
        case HTTP_DELETE:       method = Method::Delete;break;
        case HTTP_GET:          method = Method::Get;   break;
        case HTTP_HEAD:         method = Method::Head;  break;
        case HTTP_POST:         method = Method::Post;  break;
        case HTTP_PUT:          method = Method::Put;   break;
        default:
            throw std::runtime_error("ThorsAnvil::Nisse::ReadRequestHandler::onUrl: unknown HTTP Method");
    }

    uri.assign(at, length);
    gotValue    = false;
}
void ReadRequestHandler::onStatus(char const* /*at*/, std::size_t /*length*/)
{
}
void ReadRequestHandler::onHeaderField(char const* at, std::size_t length)
{
    addCurrentHeader();
    currentHead.append(at, length);
}
void ReadRequestHandler::onHeaderValue(char const* at, std::size_t length)
{
    gotValue = true;
    currentValue.append(at, length);
}
void ReadRequestHandler::onBody(char const* at, std::size_t length)
{
    bodyBegin   = at;
    bodyEnd     = at + length;
}

void ReadRequestHandler::addCurrentHeader()
{
    if (gotValue)
    {
        headers[currentHead]    = std::move(currentValue);
        gotValue = false;
        currentHead.clear();
        currentValue.clear();
    }
}

// ------------------

class DevNullStreamBuf: public std::streambuf
{
    private:
        typedef std::streambuf::traits_type traits;
        typedef traits::int_type            int_type;
        typedef traits::char_type           char_type;

        std::size_t written;

    protected:
        virtual std::streamsize xsputn(char_type const* /*s*/,std::streamsize count) override
        {
            written += count;
            return count;
        }

        virtual std::streampos seekoff(std::streamoff /*off*/,
                                       std::ios_base::seekdir /*way*/,
                                       std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
        {
            ((void)which);
            return written;
        }
    public:
        DevNullStreamBuf()
            : written(0)
        {}
};

WriteResponseHandler::WriteResponseHandler(NisseService& parent,
                                           ThorsAnvil::Socket::DataSocket&& so,
                                           Binder const& binder,
                                           Method methodParam,
                                           std::string&& uriParam,
                                           Headers&& headersParam,
                                           std::vector<char>&& bufferParam,
                                           char const* bodyBeginParam,
                                           char const* bodyEndParam)
    : NisseHandler(parent, so.getSocketId(), EV_WRITE)
    , flusher(nullptr)
    , worker([ &parent      = *this,
                socket      = std::move(so),
               &binder      = binder,
                method      = methodParam,
                uriParam    = std::move(uriParam),
                headers     = std::move(headersParam),
                buffer      = std::move(bufferParam),
                bodyBegin   = bodyBeginParam,
                bodyEnd     = bodyEndParam
             ](Yield& yield) mutable
                {
                    URI const     uri(headers.get("Host"), std::move(uriParam));
                    Action const& action(binder.find(method, uri.host, uri.path));
                    Socket::ISocketStream   input(socket, [&yield](){yield();}, [](){}, std::move(buffer), bodyBegin, bodyEnd);
                    Socket::OSocketStream   output(socket, [&yield](){yield();}, [&parent](){parent.flushing();});
                    DevNullStreamBuf        devNullBuffer;
                    if (method == Method::Head)
                    {
                        output.rdbuf(&devNullBuffer);
                    }

                    Request       request(method, URI(std::move(uri)), headers, input);
                    Response      response(parent, socket, output);
                    yield();
                    action(request, response);
                }
            )
{}

void WriteResponseHandler::eventActivate(LibSocketId /*sockId*/, short /*eventType*/)
{
    worker();
    if (!worker)
    {
        dropHandler();
    }
}

#ifdef COVERAGE_TEST
/*
 * This code is only compiled into the unit tests for code coverage purposes
 * It is not part of the live code.
 */
#include "ThorsNisse/NisseHandler.h"
#include "ThorsNisse/NisseService.tpp"
#include "ThorsNisse/NisseHandler.tpp"
#include "Types.h"
template void ThorsAnvil::Nisse::NisseHandler::moveHandler
    <WriteResponseHandler,
     ThorsAnvil::Socket::DataSocket,
     Binder const&,
     Method,
     std::string,
     Headers,
     std::vector<char>,
     char const*,
     char const*>
    (ThorsAnvil::Socket::DataSocket&&,
     Binder const&,
     Method&&,
     std::string&&,
     Headers&&,
     std::vector<char>&&,
     char const*&&,
     char const*&&);

template void ThorsAnvil::Nisse::NisseService::addHandler<WriteResponseHandler, ThorsAnvil::Socket::DataSocket, Binder const&, Method, std::string, Headers, std::vector<char>, char const*, char const*>(ThorsAnvil::Socket::DataSocket&&, Binder const&, Method&&, std::string&&, Headers&&, std::vector<char>&&, char const*&&, char const*&&);
#endif
<|endoftext|>


<commit_before>#include "DebugDrawing.hpp"

#include <glm/gtc/matrix_transform.hpp>
#include "Shader/Shader.hpp"
#include "Shader/ShaderProgram.hpp"
#include "DebugDrawing.vert.hpp"
#include "DebugDrawing.frag.hpp"
#include "glm/gtc/constants.hpp"

#define BUFFER_OFFSET(i) ((char *)nullptr + (i))

using namespace Video;

DebugDrawing::DebugDrawing() {
    Shader* vertexShader = new Shader(DEBUGDRAWING_VERT, DEBUGDRAWING_VERT_LENGTH, GL_VERTEX_SHADER);
    Shader* fragmentShader = new Shader(DEBUGDRAWING_FRAG, DEBUGDRAWING_FRAG_LENGTH, GL_FRAGMENT_SHADER);
    shaderProgram = new ShaderProgram({ vertexShader, fragmentShader });
    delete vertexShader;
    delete fragmentShader;

    // Create point vertex array.
    glBindVertexArray(0);

    glm::vec3 point(0.f, 0.f, 0.f);
    CreateVertexArray(&point, 1, pointVertexBuffer, pointVertexArray);

    // Create line vertex array.
    glm::vec3 line[2];
    line[0] = glm::vec3(0.f, 0.f, 0.f);
    line[1] = glm::vec3(1.f, 1.f, 1.f);

    CreateVertexArray(line, 2, lineVertexBuffer, lineVertexArray);

    // Create cuboid vertex array.
    glm::vec3 box[24];
    box[0] = glm::vec3(0.f, 0.f, 0.f);
    box[1] = glm::vec3(1.f, 0.f, 0.f);
    box[2] = glm::vec3(1.f, 0.f, 0.f);
    box[3] = glm::vec3(1.f, 1.f, 0.f);
    box[4] = glm::vec3(1.f, 1.f, 0.f);
    box[5] = glm::vec3(0.f, 1.f, 0.f);
    box[6] = glm::vec3(1.f, 1.f, 0.f);
    box[7] = glm::vec3(1.f, 1.f, 1.f);
    box[8] = glm::vec3(1.f, 1.f, 1.f);
    box[9] = glm::vec3(1.f, 0.f, 1.f);
    box[10] = glm::vec3(1.f, 0.f, 1.f);
    box[11] = glm::vec3(1.f, 0.f, 0.f);
    box[12] = glm::vec3(0.f, 1.f, 0.f);
    box[13] = glm::vec3(0.f, 1.f, 1.f);
    box[14] = glm::vec3(0.f, 1.f, 1.f);
    box[15] = glm::vec3(0.f, 0.f, 1.f);
    box[16] = glm::vec3(0.f, 1.f, 0.f);
    box[17] = glm::vec3(0.f, 0.f, 0.f);
    box[18] = glm::vec3(0.f, 0.f, 1.f);
    box[19] = glm::vec3(0.f, 0.f, 0.f);
    box[20] = glm::vec3(0.f, 1.f, 1.f);
    box[21] = glm::vec3(1.f, 1.f, 1.f);
    box[22] = glm::vec3(0.f, 0.f, 1.f);
    box[23] = glm::vec3(1.f, 0.f, 1.f);

    CreateVertexArray(box, 24, cuboidVertexBuffer, cuboidVertexArray);

    // Create plane vertex array.
    glm::vec3 plane[8];
    plane[0] = glm::vec3(-1.f, -1.f, 0.f);
    plane[1] = glm::vec3(1.f, -1.f, 0.f);
    plane[2] = glm::vec3(1.f, -1.f, 0.f);
    plane[3] = glm::vec3(1.f, 1.f, 0.f);
    plane[4] = glm::vec3(1.f, 1.f, 0.f);
    plane[5] = glm::vec3(-1.f, 1.f, 0.f);
    plane[6] = glm::vec3(-1.f, 1.f, 0.f);
    plane[7] = glm::vec3(-1.f, -1.f, 0.f);

    CreateVertexArray(plane, 8, planeVertexBuffer, planeVertexArray);

    // Create sphere vertex array.
    glm::vec3* sphere;
    CreateSphere(sphere, sphereVertexCount, 5);
    CreateVertexArray(sphere, sphereVertexCount, sphereVertexBuffer, sphereVertexArray);
    delete[] sphere;
}

DebugDrawing::~DebugDrawing() {
    glDeleteBuffers(1, &cuboidVertexBuffer);
    glDeleteVertexArrays(1, &cuboidVertexArray);

    glDeleteBuffers(1, &pointVertexBuffer);
    glDeleteVertexArrays(1, &pointVertexArray);

    glDeleteBuffers(1, &lineVertexBuffer);
    glDeleteVertexArrays(1, &lineVertexArray);

    glDeleteBuffers(1, &planeVertexBuffer);
    glDeleteVertexArrays(1, &planeVertexArray);

    delete shaderProgram;
}

void DebugDrawing::StartDebugDrawing(const glm::mat4& viewProjectionMatrix) {
    shaderProgram->Use();
    glUniformMatrix4fv(shaderProgram->GetUniformLocation("viewProjection"), 1, GL_FALSE, &viewProjectionMatrix[0][0]);
}

void DebugDrawing::DrawPoint(const Point& point) {
    BindVertexArray(pointVertexArray);

    glm::mat4 model(glm::translate(glm::mat4(), point.position));

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    point.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &point.color[0]);
    glUniform1f(shaderProgram->GetUniformLocation("size"), point.size);
    glDrawArrays(GL_POINTS, 0, 1);
}

void DebugDrawing::DrawLine(const Line& line) {
    BindVertexArray(lineVertexArray);

    glm::mat4 model(glm::translate(glm::mat4(), line.startPosition) * glm::scale(glm::mat4(), line.endPosition - line.startPosition));

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    line.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &line.color[0]);
    glLineWidth(line.width);
    glDrawArrays(GL_LINES, 0, 2);
}

void DebugDrawing::DrawCuboid(const Cuboid& cuboid) {
    BindVertexArray(cuboidVertexArray);

    glm::mat4 model(glm::translate(glm::mat4(), cuboid.minCoordinates) * glm::scale(glm::mat4(), cuboid.maxCoordinates - cuboid.minCoordinates));

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    cuboid.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &cuboid.color[0]);
    glUniform1f(shaderProgram->GetUniformLocation("size"), 10.f);
    glLineWidth(cuboid.lineWidth);
    glDrawArrays(GL_LINES, 0, 24);
}

void DebugDrawing::DrawPlane(const Plane& plane) {
    BindVertexArray(planeVertexArray);

    glm::mat4 model(glm::scale(glm::mat4(), glm::vec3(plane.size * 0.5f, 1.f)));
    float yaw = atan2(plane.normal.x, plane.normal.z);
    float pitch = atan2(plane.normal.y, sqrt(plane.normal.x * plane.normal.x + plane.normal.z * plane.normal.z));
    model = glm::rotate(glm::mat4(), yaw, glm::vec3(0.f, 1.f, 0.f)) * model;
    model = glm::rotate(glm::mat4(), pitch, glm::vec3(1.f, 0.f, 0.f)) * model;
    model = glm::translate(glm::mat4(), plane.position) * model;

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    plane.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &plane.color[0]);
    glUniform1f(shaderProgram->GetUniformLocation("size"), 10.f);
    glLineWidth(plane.lineWidth);
    glDrawArrays(GL_LINES, 0, 8);
}

void DebugDrawing::DrawSphere(const Sphere& sphere) {
    BindVertexArray(sphereVertexArray);

    glm::mat4 model;

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    sphere.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &sphere.color[0]);
    glUniform1f(shaderProgram->GetUniformLocation("size"), 10.f);
    glLineWidth(sphere.lineWidth);
    glDrawArrays(GL_LINES, 0, sphereVertexCount);
}

void DebugDrawing::EndDebugDrawing() {
    glEnable(GL_DEPTH_TEST);
    BindVertexArray(0);
}

void DebugDrawing::BindVertexArray(GLuint vertexArray) {
    if (boundVertexArray != vertexArray) {
        glBindVertexArray(vertexArray);
        boundVertexArray = vertexArray;
    }
}

void DebugDrawing::CreateVertexArray(const glm::vec3* positions, unsigned int positionCount, GLuint& vertexBuffer, GLuint& vertexArray) {
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, positionCount * sizeof(glm::vec3), positions, GL_STATIC_DRAW);

    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0));

    glBindVertexArray(0);
}

// Create UV-sphere with given number of parallel and meridian lines.
void DebugDrawing::CreateSphere(glm::vec3*& positions, unsigned int& vertexCount, unsigned int detail) {
    vertexCount = (detail - 1) * detail * 2;
    positions = new glm::vec3[vertexCount];

    unsigned int i = 0;
    for (unsigned int m = 1; m < detail; ++m) {
        float meridian = glm::pi<float>() * m / detail;
        for (unsigned int p = 0; p <= detail; ++p) {
            float parallel = 2.0f * glm::pi<float>() * p / detail;
            float angle = glm::pi<float>() * 0.5f - meridian;
            float y = sin(angle);
            float x = cos(angle);
            positions[i++] = glm::vec3(x * cos(parallel), y, x * sin(parallel));
            if (p > 0 && p < detail)
                positions[i++] = glm::vec3(x * cos(parallel), y, x * sin(parallel));
        }
    }
}
<commit_msg>Parallel geometry<commit_after>#include "DebugDrawing.hpp"

#include <glm/gtc/matrix_transform.hpp>
#include "Shader/Shader.hpp"
#include "Shader/ShaderProgram.hpp"
#include "DebugDrawing.vert.hpp"
#include "DebugDrawing.frag.hpp"
#include "glm/gtc/constants.hpp"

#define BUFFER_OFFSET(i) ((char *)nullptr + (i))

using namespace Video;

DebugDrawing::DebugDrawing() {
    Shader* vertexShader = new Shader(DEBUGDRAWING_VERT, DEBUGDRAWING_VERT_LENGTH, GL_VERTEX_SHADER);
    Shader* fragmentShader = new Shader(DEBUGDRAWING_FRAG, DEBUGDRAWING_FRAG_LENGTH, GL_FRAGMENT_SHADER);
    shaderProgram = new ShaderProgram({ vertexShader, fragmentShader });
    delete vertexShader;
    delete fragmentShader;

    // Create point vertex array.
    glBindVertexArray(0);

    glm::vec3 point(0.f, 0.f, 0.f);
    CreateVertexArray(&point, 1, pointVertexBuffer, pointVertexArray);

    // Create line vertex array.
    glm::vec3 line[2];
    line[0] = glm::vec3(0.f, 0.f, 0.f);
    line[1] = glm::vec3(1.f, 1.f, 1.f);

    CreateVertexArray(line, 2, lineVertexBuffer, lineVertexArray);

    // Create cuboid vertex array.
    glm::vec3 box[24];
    box[0] = glm::vec3(0.f, 0.f, 0.f);
    box[1] = glm::vec3(1.f, 0.f, 0.f);
    box[2] = glm::vec3(1.f, 0.f, 0.f);
    box[3] = glm::vec3(1.f, 1.f, 0.f);
    box[4] = glm::vec3(1.f, 1.f, 0.f);
    box[5] = glm::vec3(0.f, 1.f, 0.f);
    box[6] = glm::vec3(1.f, 1.f, 0.f);
    box[7] = glm::vec3(1.f, 1.f, 1.f);
    box[8] = glm::vec3(1.f, 1.f, 1.f);
    box[9] = glm::vec3(1.f, 0.f, 1.f);
    box[10] = glm::vec3(1.f, 0.f, 1.f);
    box[11] = glm::vec3(1.f, 0.f, 0.f);
    box[12] = glm::vec3(0.f, 1.f, 0.f);
    box[13] = glm::vec3(0.f, 1.f, 1.f);
    box[14] = glm::vec3(0.f, 1.f, 1.f);
    box[15] = glm::vec3(0.f, 0.f, 1.f);
    box[16] = glm::vec3(0.f, 1.f, 0.f);
    box[17] = glm::vec3(0.f, 0.f, 0.f);
    box[18] = glm::vec3(0.f, 0.f, 1.f);
    box[19] = glm::vec3(0.f, 0.f, 0.f);
    box[20] = glm::vec3(0.f, 1.f, 1.f);
    box[21] = glm::vec3(1.f, 1.f, 1.f);
    box[22] = glm::vec3(0.f, 0.f, 1.f);
    box[23] = glm::vec3(1.f, 0.f, 1.f);

    CreateVertexArray(box, 24, cuboidVertexBuffer, cuboidVertexArray);

    // Create plane vertex array.
    glm::vec3 plane[8];
    plane[0] = glm::vec3(-1.f, -1.f, 0.f);
    plane[1] = glm::vec3(1.f, -1.f, 0.f);
    plane[2] = glm::vec3(1.f, -1.f, 0.f);
    plane[3] = glm::vec3(1.f, 1.f, 0.f);
    plane[4] = glm::vec3(1.f, 1.f, 0.f);
    plane[5] = glm::vec3(-1.f, 1.f, 0.f);
    plane[6] = glm::vec3(-1.f, 1.f, 0.f);
    plane[7] = glm::vec3(-1.f, -1.f, 0.f);

    CreateVertexArray(plane, 8, planeVertexBuffer, planeVertexArray);

    // Create sphere vertex array.
    glm::vec3* sphere;
    CreateSphere(sphere, sphereVertexCount, 14);
    CreateVertexArray(sphere, sphereVertexCount, sphereVertexBuffer, sphereVertexArray);
    delete[] sphere;
}

DebugDrawing::~DebugDrawing() {
    glDeleteBuffers(1, &cuboidVertexBuffer);
    glDeleteVertexArrays(1, &cuboidVertexArray);

    glDeleteBuffers(1, &pointVertexBuffer);
    glDeleteVertexArrays(1, &pointVertexArray);

    glDeleteBuffers(1, &lineVertexBuffer);
    glDeleteVertexArrays(1, &lineVertexArray);

    glDeleteBuffers(1, &planeVertexBuffer);
    glDeleteVertexArrays(1, &planeVertexArray);

    delete shaderProgram;
}

void DebugDrawing::StartDebugDrawing(const glm::mat4& viewProjectionMatrix) {
    shaderProgram->Use();
    glUniformMatrix4fv(shaderProgram->GetUniformLocation("viewProjection"), 1, GL_FALSE, &viewProjectionMatrix[0][0]);
}

void DebugDrawing::DrawPoint(const Point& point) {
    BindVertexArray(pointVertexArray);

    glm::mat4 model(glm::translate(glm::mat4(), point.position));

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    point.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &point.color[0]);
    glUniform1f(shaderProgram->GetUniformLocation("size"), point.size);
    glDrawArrays(GL_POINTS, 0, 1);
}

void DebugDrawing::DrawLine(const Line& line) {
    BindVertexArray(lineVertexArray);

    glm::mat4 model(glm::translate(glm::mat4(), line.startPosition) * glm::scale(glm::mat4(), line.endPosition - line.startPosition));

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    line.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &line.color[0]);
    glLineWidth(line.width);
    glDrawArrays(GL_LINES, 0, 2);
}

void DebugDrawing::DrawCuboid(const Cuboid& cuboid) {
    BindVertexArray(cuboidVertexArray);

    glm::mat4 model(glm::translate(glm::mat4(), cuboid.minCoordinates) * glm::scale(glm::mat4(), cuboid.maxCoordinates - cuboid.minCoordinates));

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    cuboid.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &cuboid.color[0]);
    glUniform1f(shaderProgram->GetUniformLocation("size"), 10.f);
    glLineWidth(cuboid.lineWidth);
    glDrawArrays(GL_LINES, 0, 24);
}

void DebugDrawing::DrawPlane(const Plane& plane) {
    BindVertexArray(planeVertexArray);

    glm::mat4 model(glm::scale(glm::mat4(), glm::vec3(plane.size * 0.5f, 1.f)));
    float yaw = atan2(plane.normal.x, plane.normal.z);
    float pitch = atan2(plane.normal.y, sqrt(plane.normal.x * plane.normal.x + plane.normal.z * plane.normal.z));
    model = glm::rotate(glm::mat4(), yaw, glm::vec3(0.f, 1.f, 0.f)) * model;
    model = glm::rotate(glm::mat4(), pitch, glm::vec3(1.f, 0.f, 0.f)) * model;
    model = glm::translate(glm::mat4(), plane.position) * model;

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    plane.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &plane.color[0]);
    glUniform1f(shaderProgram->GetUniformLocation("size"), 10.f);
    glLineWidth(plane.lineWidth);
    glDrawArrays(GL_LINES, 0, 8);
}

void DebugDrawing::DrawSphere(const Sphere& sphere) {
    BindVertexArray(sphereVertexArray);

    glm::mat4 model;

    glUniformMatrix4fv(shaderProgram->GetUniformLocation("model"), 1, GL_FALSE, &model[0][0]);
    sphere.depthTesting ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
    glUniform3fv(shaderProgram->GetUniformLocation("color"), 1, &sphere.color[0]);
    glUniform1f(shaderProgram->GetUniformLocation("size"), 10.f);
    glLineWidth(sphere.lineWidth);
    glDrawArrays(GL_LINES, 0, sphereVertexCount);
}

void DebugDrawing::EndDebugDrawing() {
    glEnable(GL_DEPTH_TEST);
    BindVertexArray(0);
}

void DebugDrawing::BindVertexArray(GLuint vertexArray) {
    if (boundVertexArray != vertexArray) {
        glBindVertexArray(vertexArray);
        boundVertexArray = vertexArray;
    }
}

void DebugDrawing::CreateVertexArray(const glm::vec3* positions, unsigned int positionCount, GLuint& vertexBuffer, GLuint& vertexArray) {
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, positionCount * sizeof(glm::vec3), positions, GL_STATIC_DRAW);

    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0));

    glBindVertexArray(0);
}

// Create UV-sphere with given number of parallel and meridian lines.
void DebugDrawing::CreateSphere(glm::vec3*& positions, unsigned int& vertexCount, unsigned int detail) {
    vertexCount = detail * (4 * detail - 2);
    positions = new glm::vec3[vertexCount];

    // Horizontal lines (meridians).
    unsigned int i = 0;
    for (unsigned int m = 1; m < detail; ++m) {
        float meridian = glm::pi<float>() * m / detail;
        for (unsigned int p = 0; p <= detail; ++p) {
            float parallel = 2.0f * glm::pi<float>() * p / detail;
            float angle = glm::pi<float>() * 0.5f - meridian;
            float y = sin(angle);
            float x = cos(angle);
            positions[i++] = glm::vec3(x * cos(parallel), y, x * sin(parallel));
            if (p > 0 && p < detail)
                positions[i++] = glm::vec3(x * cos(parallel), y, x * sin(parallel));
        }
    }

    // Vertical lines (parallels).
    for (unsigned int p = 0; p < detail; ++p) {
        float parallel = 2.0f * glm::pi<float>() * p / detail;
        for (unsigned int m = 0; m <= detail; ++m) {
            float meridian = glm::pi<float>() * m / detail;
            float angle = glm::pi<float>() * 0.5f - meridian;
            float y = sin(angle);
            float x = cos(angle);
            positions[i++] = glm::vec3(x * cos(parallel), y, x * sin(parallel));
            if (m > 0 && m < detail)
                positions[i++] = glm::vec3(x * cos(parallel), y, x * sin(parallel));
        }
    }
}
<|endoftext|>


<commit_before>#include "system/multirotor_vehicle_system.hpp"

MultirotorVehicleSystem::MultirotorVehicleSystem(
    Gyroscope& gyroscope,
    Accelerometer& accelerometer,
    optional<GPS *> gps,
    optional<Magnetometer *> magnetometer,
    WorldEstimator& estimator,
    InputSource& inputSource,
    MotorMapper& motorMapper,
    Communicator& communicator)
  : VehicleSystem(communicator),
    MessageListener(communicator),
    gyroscope(gyroscope),
    accelerometer(accelerometer),
    gps(gps),
    magnetometer(magnetometer),
    estimator(estimator),
    inputSource(inputSource),
    motorMapper(motorMapper),
    mode(MultirotorControlMode::ANGULAR_POS) {
  // Disarm by default. A set_arm_state_message_t message is required to enable
  // the control pipeline.
  setArmed(false);
}

void MultirotorVehicleSystem::update() {
  // Poll the gyroscope and accelerometer
  GyroscopeReading gyroReading = gyroscope.readGyro();
  AccelerometerReading accelReading = accelerometer.readAccel();
  optional<MagnetometerReading> magReading;
  optional<GPSReading> gpsReading;

  // Only use magnetometer if it is available
  if(magnetometer) {
    magReading = (*magnetometer)->readMag();
  }

  if (gps) {
    static int i=0;
    if (i++ % 100 == 0) {
      // TODO(yoos): GPS read makes board freeze
      //gpsReading = (*gps)->readGPS();
    }
  }

  // TODO: Currently copying all readings
  SensorMeasurements meas {
    .accel  = std::experimental::make_optional(accelReading),
    .accelH = std::experimental::nullopt,
    .bar    = std::experimental::nullopt,
    .gps    = gpsReading,
    .gyro   = std::experimental::make_optional(gyroReading),
    .mag    = magReading
  };

  // Update estimates
  WorldEstimate world = estimator.update(meas);

  // Poll for controller input
  ControllerInput input = inputSource.read();

  if(input.valid) {
    setArmed(input.armed);
  }

  // Run the controllers
  ActuatorSetpoint actuatorSp;
  if(isArmed() && input.valid) {
    // Run the controller pipeline as determined by the subclass
    switch(mode) {
      case MultirotorControlMode::POSITION: {
        PositionSetpoint sp {
          .lat = input.roll,
          .lon = input.pitch,
          .yawPos = input.yaw,
          .alt = input.throttle
        };
        actuatorSp = pipeline.run(world, sp, posController, attPosController, attVelController, attAccController);
        break;
      }
      case MultirotorControlMode::VELOCITY: {
        // TODO: implement
        // actuatorSp = pipeline.run(world, sp, velController, attPosController, attVelController, attAccController);
        break;
      }
      case MultirotorControlMode::ANGULAR_POS: {
        AngularPositionSetpoint sp {
          .rollPos = input.roll,
          .pitchPos = input.pitch,
          .yawPos = input.yaw,
          .throttle = input.throttle
        };
        actuatorSp = pipeline.run(world, sp, attPosController, attVelController, attAccController);
        break;
      }
      case MultirotorControlMode::ANGULAR_RATE: {
        AngularVelocitySetpoint sp {
          .rollVel = input.roll,
          .pitchVel = input.pitch,
          .yawVel = input.yaw,
          .throttle = input.throttle
        };
        actuatorSp = pipeline.run(world, sp, attVelController, attAccController);
        break;
      }
    }
  } else {
    // Run the zero controller
    actuatorSp = zeroController.run(world, actuatorSp);
  }

  // Update motor outputs
  motorMapper.run(isArmed(), actuatorSp);
}

bool MultirotorVehicleSystem::healthy() {
  bool healthy = gyroscope.healthy() && accelerometer.healthy();

  if(gps) {
    healthy &= (*gps)->healthy();
  }

  if(magnetometer) {
    healthy &= (*magnetometer)->healthy();
  }

  return healthy;
}

void MultirotorVehicleSystem::on(const protocol::message::set_arm_state_message_t& m) {
  setArmed(m.armed);
}
<commit_msg>Ensure sensors are healthy before arming.<commit_after>#include "system/multirotor_vehicle_system.hpp"

MultirotorVehicleSystem::MultirotorVehicleSystem(
    Gyroscope& gyroscope,
    Accelerometer& accelerometer,
    optional<GPS *> gps,
    optional<Magnetometer *> magnetometer,
    WorldEstimator& estimator,
    InputSource& inputSource,
    MotorMapper& motorMapper,
    Communicator& communicator)
  : VehicleSystem(communicator),
    MessageListener(communicator),
    gyroscope(gyroscope),
    accelerometer(accelerometer),
    gps(gps),
    magnetometer(magnetometer),
    estimator(estimator),
    inputSource(inputSource),
    motorMapper(motorMapper),
    mode(MultirotorControlMode::ANGULAR_POS) {
  // Disarm by default. A set_arm_state_message_t message is required to enable
  // the control pipeline.
  setArmed(false);
}

void MultirotorVehicleSystem::update() {
  // Poll the gyroscope and accelerometer
  GyroscopeReading gyroReading = gyroscope.readGyro();
  AccelerometerReading accelReading = accelerometer.readAccel();
  optional<MagnetometerReading> magReading;
  optional<GPSReading> gpsReading;

  // Only use magnetometer if it is available
  if(magnetometer) {
    magReading = (*magnetometer)->readMag();
  }

  if (gps) {
    static int i=0;
    if (i++ % 100 == 0) {
      // TODO(yoos): GPS read makes board freeze
      //gpsReading = (*gps)->readGPS();
    }
  }

  // TODO: Currently copying all readings
  SensorMeasurements meas {
    .accel  = std::experimental::make_optional(accelReading),
    .accelH = std::experimental::nullopt,
    .bar    = std::experimental::nullopt,
    .gps    = gpsReading,
    .gyro   = std::experimental::make_optional(gyroReading),
    .mag    = magReading
  };

  // Update estimates
  WorldEstimate world = estimator.update(meas);

  // Poll for controller input
  ControllerInput input = inputSource.read();

  if(input.valid && input.armed) {
    // Ensure sensors are healthy before arming, but don't disarm if sensors
    // become unhealthy.
    if(healthy()) {
      setArmed(true);
    }
  } else {
    setArmed(false);
  }

  // Run the controllers
  ActuatorSetpoint actuatorSp;
  if(isArmed() && input.valid) {
    // Run the controller pipeline as determined by the subclass
    switch(mode) {
      case MultirotorControlMode::POSITION: {
        PositionSetpoint sp {
          .lat = input.roll,
          .lon = input.pitch,
          .yawPos = input.yaw,
          .alt = input.throttle
        };
        actuatorSp = pipeline.run(world, sp, posController, attPosController, attVelController, attAccController);
        break;
      }
      case MultirotorControlMode::VELOCITY: {
        // TODO: implement
        // actuatorSp = pipeline.run(world, sp, velController, attPosController, attVelController, attAccController);
        break;
      }
      case MultirotorControlMode::ANGULAR_POS: {
        AngularPositionSetpoint sp {
          .rollPos = input.roll,
          .pitchPos = input.pitch,
          .yawPos = input.yaw,
          .throttle = input.throttle
        };
        actuatorSp = pipeline.run(world, sp, attPosController, attVelController, attAccController);
        break;
      }
      case MultirotorControlMode::ANGULAR_RATE: {
        AngularVelocitySetpoint sp {
          .rollVel = input.roll,
          .pitchVel = input.pitch,
          .yawVel = input.yaw,
          .throttle = input.throttle
        };
        actuatorSp = pipeline.run(world, sp, attVelController, attAccController);
        break;
      }
    }
  } else {
    // Run the zero controller
    actuatorSp = zeroController.run(world, actuatorSp);
  }

  // Update motor outputs
  motorMapper.run(isArmed(), actuatorSp);
}

bool MultirotorVehicleSystem::healthy() {
  bool healthy = gyroscope.healthy() && accelerometer.healthy();

  if(gps) {
    healthy &= (*gps)->healthy();
  }

  if(magnetometer) {
    healthy &= (*magnetometer)->healthy();
  }

  return healthy;
}

void MultirotorVehicleSystem::on(const protocol::message::set_arm_state_message_t& m) {
  setArmed(m.armed);
}
<|endoftext|>


<commit_before>#include "Settings.h"
#include "ui_Settings.h"
#include "DRMSetupWizard.h"

/** Settings constructor
* Initialize the settings UI
* \param p Inherited palette configuration for setting StyleSheets.
* \param parent Pointer to parent widget.
*/
Settings::Settings(QSettings* p, QWidget* parent) : QWidget(parent), ui(new Ui::Settings)
{
	ui->setupUi(this);
	this->setObjectName("settingsUI");
	this->setStyleSheet("background-color: " + p->value("Primary/SecondaryBase").toString() + ";} "
        "QLabel { color:  #ffffff;}"
        "QPushButton {"
        "color: " + p->value("Primary/LightText").toString() + "; "
        "background-color: " + p->value("Primary/DarkElement").toString() + "; "
        "border: none; margin: 0px; padding: 0px;} "
        "QPushButton:hover {"
        "background-color: " + p->value("Primary/InactiveSelection").toString() + ";} "
        "color: " + p->value("Primary/LightText").toString() + ";");

    QFont buttonFont("SourceSansPro", 9);

    ui->WizardButton->setFont(buttonFont);
    ui->WizardButton->setText("Add Games to Horizon");

    ui->ClearDatabaseButton->setFont(buttonFont);
    ui->ClearDatabaseButton->setText("Clear Database");

    ui->BodyColor->setFont(buttonFont);
    ui->BodyColor->setStyleSheet("background-color: " + p->value("Body/Background").toString() + ";}");

    ui->NavbarBG->setFont(buttonFont);
    ui->NavbarBG->setStyleSheet("background-color: " + p->value("Navbar/Background").toString() + ";}");

    ui->NavbarHover->setFont(buttonFont);
    ui->NavbarHover->setStyleSheet("background-color: " + p->value("Navbar/HoverColor").toString() + ";}");

    ui->NavbarSelected->setFont(buttonFont);
    ui->NavbarSelected->setStyleSheet("background-color: " + p->value("Navbar/SelectedColor").toString() + ";}");

	ui->TitleBarColor->setFont(buttonFont);
	ui->TitleBarColor->setStyleSheet("background-color: " + p->value("TitleBar/Color").toString() + ";}");

    ui->ResetColors->setFont(buttonFont);

    ui->label_2->setStyleSheet("{color: #FFFFFF}");
    ui->UserSettingsBox->setStyleSheet("color: #FFFFFF;} ");
    ui->ClientSettingsBox->setStyleSheet("color: #FFFFFF;} ");
    ui->StyleSettingsBox->setStyleSheet("color: #FFFFFF;} ");

    connect(ui->WizardButton, SIGNAL(clicked()), QApplication::instance(), SLOT(Settings::on_WizardButton_clicked()));
    connect(ui->BodyColor, &QPushButton::clicked, [=]() { pickSetColor(1); });
    connect(ui->NavbarBG, &QPushButton::clicked, [=]() { pickSetColor(2); });
    connect(ui->NavbarHover, &QPushButton::clicked, [=]() { pickSetColor(3); });
    connect(ui->NavbarSelected, &QPushButton::clicked, [=]() { pickSetColor(4); });
    connect(ui->TitleBarColor, &QPushButton::clicked, [=]() { pickSetColor(5); });
    connect(ui->ResetColors, SIGNAL(clicked()), QApplication::instance(), SLOT(Settings::on_ResetColors_clicked()));
    connect(ui->ClearDatabaseButton, SIGNAL(clicked()), QApplication::instance(), SLOT(Settings::on_ClearDatabaseButton_clicked()));

    if (!db.init())
    {
        QMessageBox error;
        error.critical(0, "Error!", "An error occured while trying to load the database.");
        exit(EXIT_FAILURE);
    }
}

/** Event handler for Wizard Button
* Runs setup wizard on click
*/
void Settings::on_WizardButton_clicked()
{
    DRMSetupWizard* wiz = new DRMSetupWizard();
    wiz->show();
}

void Settings::on_ResetColors_clicked()
{
    QSettings palette(QSettings::IniFormat, QSettings::UserScope, "Horizon Launcher", "palette");

    if (palette.isWritable())
    {
        palette.beginGroup("Primary");
        palette.setValue("ActiveElement", "#FFFFFF");
        palette.setValue("InactiveSelection", "#686868");
        palette.setValue("HoverSelection", "#ADADAD");
        palette.setValue("DarkElement", "#4D5250");
        palette.setValue("LightText", "#FFFFFF");
        palette.setValue("DarkText", "#242424");
        palette.setValue("SubText", "#B2B4B3");
        palette.setValue("PrimaryBase", "#282828");
        palette.setValue("SecondaryBase", "#1F1F1F");
        palette.setValue("TertiaryBase", "#131313");
        palette.setValue("DarkestBase", "#0F0F0F");
        palette.endGroup();

        palette.beginGroup("Body");
        palette.setValue("Background", "#212121");
        palette.endGroup();

        palette.beginGroup("Navbar");
        palette.setValue("Background", "#111111");
        palette.setValue("SelectedColor", "#9351E5");
        palette.setValue("HoverColor", "#ADADAD");
        palette.endGroup();

        palette.beginGroup("TitleBar");
        palette.setValue("Color", "#F5F6F7");
        palette.endGroup();
    }

    ui->BodyColor->setStyleSheet("background-color: " + palette.value("Body/Background").toString() + ";}");
    ui->NavbarBG->setStyleSheet("background-color: " + palette.value("Navbar/Background").toString() + ";}");
    ui->NavbarHover->setStyleSheet("background-color: " + palette.value("Navbar/HoverColor").toString() + ";}");
    ui->NavbarSelected->setStyleSheet("background-color: " + palette.value("Navbar/SelectedColor").toString() + ";}");
    ui->TitleBarColor->setStyleSheet("background-color: " + palette.value("TitleBar/Color").toString() + ";}");
}

void Settings::pickSetColor(int id)
{
    QColor color = QColorDialog::getColor(Qt::white);
    updateColor(id, color);
}

void Settings::updateColor(int id, QColor color)
{
    if (!color.isValid())
    {
        return;
    }

    QSettings palette(QSettings::IniFormat, QSettings::UserScope, "Horizon Launcher", "palette");

    if (palette.isWritable())
    {
        if (id == 1) // Body/Background
        {
            palette.beginGroup("Body");
            palette.setValue("Background", color.name());
            palette.endGroup();

            ui->BodyColor->setStyleSheet("background-color: " + color.name() + ";}");
        }
        else if (id <= 4) // Navbar
        {
            palette.beginGroup("Navbar");
            if (id == 2) // Background
            {
                palette.setValue("Background", color.name());
                ui->NavbarBG->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 3) // Hover
            {
                palette.setValue("HoverColor", color.name());
                ui->NavbarHover->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 4) // Selected
            {
                palette.setValue("SelectedColor", color.name());
                ui->NavbarSelected->setStyleSheet("background-color: " + color.name() + ";}");
            }
            palette.endGroup();
        }
        else if (id == 5) //TitleBar/Color
        {
            palette.beginGroup("TitleBar");
            palette.setValue("Color", color.name());
            palette.endGroup();
            ui->TitleBarColor->setStyleSheet("background-color: " + color.name() + ";}");
        }
    }
}

void Settings::on_ClearDatabaseButton_clicked()
{
    int ret = QMessageBox(QMessageBox::Question, "Deleting Database", "Proceeding will delete the database, the database will be non-recoverable. Proceed?", QMessageBox::Yes | QMessageBox::No).exec();
    switch (ret)
    {
        case QMessageBox::Yes:
            db.reset();
            break;
        case QMessageBox::No:
            break;
        default:
            break;
    }
}

Settings::~Settings()
{
    delete ui;
}
<commit_msg>Make all colors customizable<commit_after>#include "Settings.h"
#include "ui_Settings.h"
#include "DRMSetupWizard.h"

/** Settings constructor
* Initialize the settings UI
* \param p Inherited palette configuration for setting StyleSheets.
* \param parent Pointer to parent widget.
*/
Settings::Settings(QSettings* p, QWidget* parent) : QWidget(parent), ui(new Ui::Settings)
{
    ui->setupUi(this);
    this->setObjectName("settingsUI");
    this->setStyleSheet("background-color: " + p->value("Primary/SecondaryBase").toString() + ";} "
        "QLabel { color:  #ffffff;}"
        "QPushButton {"
        "color: " + p->value("Primary/LightText").toString() + "; "
        "background-color: " + p->value("Primary/DarkElement").toString() + "; "
        "border: none; margin: 0px; padding: 0px;} "
        "QPushButton:hover {"
        "background-color: " + p->value("Primary/InactiveSelection").toString() + ";} "
        "color: " + p->value("Primary/LightText").toString() + ";");

    QFont buttonFont("SourceSansPro", 9);

    ui->WizardButton->setFont(buttonFont);
    ui->WizardButton->setText("Add Games to Horizon");

    ui->ClearDatabaseButton->setFont(buttonFont);
    ui->ClearDatabaseButton->setText("Clear Database");

    ui->BodyColor->setFont(buttonFont);
    ui->BodyColor->setStyleSheet("background-color: " + p->value("Body/Background").toString() + ";}");

    ui->NavbarBG->setFont(buttonFont);
    ui->NavbarBG->setStyleSheet("background-color: " + p->value("Navbar/Background").toString() + ";}");

    ui->NavbarHover->setFont(buttonFont);
    ui->NavbarHover->setStyleSheet("background-color: " + p->value("Navbar/HoverColor").toString() + ";}");

    ui->NavbarSelected->setFont(buttonFont);
    ui->NavbarSelected->setStyleSheet("background-color: " + p->value("Navbar/SelectedColor").toString() + ";}");

    ui->TitleBarColor->setFont(buttonFont);
    ui->TitleBarColor->setStyleSheet("background-color: " + p->value("TitleBar/Color").toString() + ";}");

    ui->ActiveElement->setFont(buttonFont);
    ui->ActiveElement->setStyleSheet("background-color: " + p->value("Primary/ActiveElement").toString() + ";}");

    ui->InactiveSelection->setFont(buttonFont);
    ui->InactiveSelection->setStyleSheet("background-color: " + p->value("Primary/InactiveSelection").toString() + ";}");

    ui->HoverSelection->setFont(buttonFont);
    ui->HoverSelection->setStyleSheet("background-color: " + p->value("Primary/HoverSelection").toString() + ";}");

    ui->DarkElement->setFont(buttonFont);
    ui->DarkElement->setStyleSheet("background-color: " + p->value("Primary/DarkElement").toString() + ";}");

    ui->LightText->setFont(buttonFont);
    ui->LightText->setStyleSheet("background-color: " + p->value("Primary/LightText").toString() + ";}");

    ui->DarkText->setFont(buttonFont);
    ui->DarkText->setStyleSheet("background-color: " + p->value("Primary/DarkText").toString() + ";}");

    ui->SubText->setFont(buttonFont);
    ui->SubText->setStyleSheet("background-color: " + p->value("Primary/SubText").toString() + ";}");

    ui->PrimaryBase->setFont(buttonFont);
    ui->PrimaryBase->setStyleSheet("background-color: " + p->value("Primary/PrimaryBase").toString() + ";}");

    ui->SecondaryBase->setFont(buttonFont);
    ui->SecondaryBase->setStyleSheet("background-color: " + p->value("Primary/SecondaryBase").toString() + ";}");

    ui->TertiaryBase->setFont(buttonFont);
    ui->TertiaryBase->setStyleSheet("background-color: " + p->value("Primary/TertiaryBase").toString() + ";}");

    ui->DarkestBase->setFont(buttonFont);
    ui->DarkestBase->setStyleSheet("background-color: " + p->value("Primary/DarkestBase").toString() + ";}");

    ui->ResetColors->setFont(buttonFont);

    ui->label_2->setStyleSheet("{color: #FFFFFF}");
    ui->UserSettingsBox->setStyleSheet("color: #FFFFFF;} ");
    ui->ClientSettingsBox->setStyleSheet("color: #FFFFFF;} ");
    ui->StyleSettingsBox->setStyleSheet("color: #FFFFFF;} ");

    connect(ui->WizardButton, SIGNAL(clicked()), QApplication::instance(), SLOT(Settings::on_WizardButton_clicked()));
    connect(ui->BodyColor, &QPushButton::clicked, [=]() { pickSetColor(1); });
    connect(ui->NavbarBG, &QPushButton::clicked, [=]() { pickSetColor(2); });
    connect(ui->NavbarHover, &QPushButton::clicked, [=]() { pickSetColor(3); });
    connect(ui->NavbarSelected, &QPushButton::clicked, [=]() { pickSetColor(4); });
    connect(ui->TitleBarColor, &QPushButton::clicked, [=]() { pickSetColor(5); });
    connect(ui->ActiveElement, &QPushButton::clicked, [=]() { pickSetColor(6); });
    connect(ui->InactiveSelection, &QPushButton::clicked, [=]() { pickSetColor(7); });
    connect(ui->HoverSelection, &QPushButton::clicked, [=]() { pickSetColor(8); });
    connect(ui->DarkElement, &QPushButton::clicked, [=]() { pickSetColor(9); });
    connect(ui->LightText, &QPushButton::clicked, [=]() { pickSetColor(10); });
    connect(ui->DarkText, &QPushButton::clicked, [=]() { pickSetColor(11); });
    connect(ui->SubText, &QPushButton::clicked, [=]() { pickSetColor(12); });
    connect(ui->PrimaryBase, &QPushButton::clicked, [=]() { pickSetColor(13); });
    connect(ui->SecondaryBase, &QPushButton::clicked, [=]() { pickSetColor(14); });
    connect(ui->TertiaryBase, &QPushButton::clicked, [=]() { pickSetColor(15); });
    connect(ui->DarkestBase, &QPushButton::clicked, [=]() { pickSetColor(16); });
    connect(ui->ResetColors, SIGNAL(clicked()), QApplication::instance(), SLOT(Settings::on_ResetColors_clicked()));
    connect(ui->ClearDatabaseButton, SIGNAL(clicked()), QApplication::instance(), SLOT(Settings::on_ClearDatabaseButton_clicked()));

    if (!db.init())
    {
        QMessageBox error;
        error.critical(0, "Error!", "An error occured while trying to load the database.");
        exit(EXIT_FAILURE);
    }
}

/** Event handler for Wizard Button
* Runs setup wizard on click
*/
void Settings::on_WizardButton_clicked()
{
    DRMSetupWizard* wiz = new DRMSetupWizard();
    wiz->show();
}

void Settings::on_ResetColors_clicked()
{
    QSettings palette(QSettings::IniFormat, QSettings::UserScope, "Horizon Launcher", "palette");

    if (palette.isWritable())
    {
        palette.beginGroup("Primary");
        palette.setValue("ActiveElement", "#FFFFFF");
        palette.setValue("InactiveSelection", "#686868");
        palette.setValue("HoverSelection", "#ADADAD");
        palette.setValue("DarkElement", "#4D5250");
        palette.setValue("LightText", "#FFFFFF");
        palette.setValue("DarkText", "#242424");
        palette.setValue("SubText", "#B2B4B3");
        palette.setValue("PrimaryBase", "#282828");
        palette.setValue("SecondaryBase", "#1F1F1F");
        palette.setValue("TertiaryBase", "#131313");
        palette.setValue("DarkestBase", "#0F0F0F");
        palette.endGroup();

        palette.beginGroup("Body");
        palette.setValue("Background", "#212121");
        palette.endGroup();

        palette.beginGroup("Navbar");
        palette.setValue("Background", "#111111");
        palette.setValue("SelectedColor", "#9351E5");
        palette.setValue("HoverColor", "#ADADAD");
        palette.endGroup();

        palette.beginGroup("TitleBar");
        palette.setValue("Color", "#F5F6F7");
        palette.endGroup();
    }

    ui->BodyColor->setStyleSheet("background-color: " + palette.value("Body/Background").toString() + ";}");
    ui->NavbarBG->setStyleSheet("background-color: " + palette.value("Navbar/Background").toString() + ";}");
    ui->NavbarHover->setStyleSheet("background-color: " + palette.value("Navbar/HoverColor").toString() + ";}");
    ui->NavbarSelected->setStyleSheet("background-color: " + palette.value("Navbar/SelectedColor").toString() + ";}");
    ui->ActiveElement->setStyleSheet("background-color: " + palette.value("Primary/ActiveElement").toString() + ";}");
    ui->InactiveSelection->setStyleSheet("background-color: " + palette.value("Primary/InactiveSelection").toString() + ";}");
    ui->HoverSelection->setStyleSheet("background-color: " + palette.value("Primary/HoverSelection").toString() + ";}");
    ui->DarkElement->setStyleSheet("background-color: " + palette.value("Primary/DarkElement").toString() + ";}");
    ui->LightText->setStyleSheet("background-color: " + palette.value("Primary/LightText").toString() + ";}");
    ui->DarkText->setStyleSheet("background-color: " + palette.value("Primary/DarkText").toString() + ";}");
    ui->SubText->setStyleSheet("background-color: " + palette.value("Primary/SubText").toString() + ";}");
    ui->PrimaryBase->setStyleSheet("background-color: " + palette.value("Primary/PrimaryBase").toString() + ";}");
    ui->SecondaryBase->setStyleSheet("background-color: " + palette.value("Primary/SecondaryBase").toString() + ";}");
    ui->TertiaryBase->setStyleSheet("background-color: " + palette.value("Primary/TertiaryBase").toString() + ";}");
    ui->DarkestBase->setStyleSheet("background-color: " + palette.value("Primary/DarkestBase").toString() + ";}");
}

void Settings::pickSetColor(int id)
{
    QColor color = QColorDialog::getColor(Qt::white);
    updateColor(id, color);
}

void Settings::updateColor(int id, QColor color)
{
    if (!color.isValid())
    {
        return;
    }

    QSettings palette(QSettings::IniFormat, QSettings::UserScope, "Horizon Launcher", "palette");

    if (palette.isWritable())
    {
        if (id == 1) // Body/Background
        {
            palette.beginGroup("Body");
            palette.setValue("Background", color.name());
            palette.endGroup();

            ui->BodyColor->setStyleSheet("background-color: " + color.name() + ";}");
        }
        else if (id <= 4) // Navbar
        {
            palette.beginGroup("Navbar");
            if (id == 2) // Background
            {
                palette.setValue("Background", color.name());
                ui->NavbarBG->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 3) // Hover
            {
                palette.setValue("HoverColor", color.name());
                ui->NavbarHover->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 4) // Selected
            {
                palette.setValue("SelectedColor", color.name());
                ui->NavbarSelected->setStyleSheet("background-color: " + color.name() + ";}");
            }
            palette.endGroup();
        }
        else if (id == 5) //TitleBar/Color
        {
            palette.beginGroup("TitleBar");
            palette.setValue("Color", color.name());
            palette.endGroup();
            ui->TitleBarColor->setStyleSheet("background-color: " + color.name() + ";}");
        }
        else if (id <= 16)
        {
            palette.beginGroup("Primary");

            if (id == 6)
            {
                palette.setValue("ActiveElement", color.name());
                ui->ActiveElement->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 7)
            {
                palette.setValue("InactiveSelection", color.name());
                ui->InactiveSelection->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 8)
            {
                palette.setValue("HoverSelection", color.name());
                ui->HoverSelection->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 9)
            {
                palette.setValue("DarkElement", color.name());
                ui->DarkElement->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 10)
            {
                palette.setValue("LightText", color.name());
                ui->LightText->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 11)
            {
                palette.setValue("DarkText", color.name());
                ui->DarkText->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 12)
            {
                palette.setValue("SubText", color.name());
                ui->SubText->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 13)
            {
                palette.setValue("PrimaryBase", color.name());
                ui->PrimaryBase->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 14)
            {
                palette.setValue("SecondaryBase", color.name());
                ui->SecondaryBase->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 15)
            {
                palette.setValue("TertiaryBase", color.name());
                ui->TertiaryBase->setStyleSheet("background-color: " + color.name() + ";}");
            }
            else if (id == 16)
            {
                palette.setValue("DarkestBase", color.name());
                ui->DarkestBase->setStyleSheet("background-color: " + color.name() + ";}");
            }

            palette.endGroup();
        }
    }
}

void Settings::on_ClearDatabaseButton_clicked()
{
    int ret = QMessageBox(QMessageBox::Question, "Deleting Database", "Proceeding will delete the database, the database will be non-recoverable. Proceed?", QMessageBox::Yes | QMessageBox::No).exec();
    switch (ret)
    {
        case QMessageBox::Yes:
            db.reset();
            break;
        case QMessageBox::No:
            break;
        default:
            break;
    }
}

Settings::~Settings()
{
    delete ui;
}
<|endoftext|>


<commit_before>#pragma once

/**
* This class uses C++11's = delete to delete generated copy
* constructor and copy operator.
*/
class NonCopyable
{
protected:
    NonCopyable() = default;

private:
    NonCopyable(NonCopyable&&) = delete;
    NonCopyable(NonCopyable const&) = delete;

    NonCopyable& operator=(NonCopyable&&) = delete;
    NonCopyable& operator=(NonCopyable const&) = delete;
};
<commit_msg>Made NonCopyable movable<commit_after>#pragma once

/**
* This class uses C++11's = delete to delete generated copy
* constructor and copy operator.
*/
class NonCopyable
{
protected:
    NonCopyable() noexcept = default;
    ~NonCopyable() = default;

private:
    NonCopyable(NonCopyable const&) = delete;
    NonCopyable& operator=(NonCopyable const&) = delete;
};
<|endoftext|>


<commit_before>/*
	This file is part of the GUI library.
	Copyright (C) 2008-2012 Benjamin Eikel <benjamin@eikel.org>
	Copyright (C) 2008-2012 Claudius Jähn <claudius@uni-paderborn.de>
	Copyright (C) 2008-2012 Ralf Petring <ralf@petring.net>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "StdShapes.h"
#include "../Base/Draw.h"
#include "../Base/BasicColors.h"
#include "Colors.h"
#include <Geometry/Interpolation.h>
#include <Util/References.h>
#include <iostream>

using namespace Geometry;

namespace GUI {

//! RectShape ---|> AbstractShape
void RectShape::display(const Rect & rect,flag_t /*flag*/){
	Draw::drawFilledRect(rect,bgColor,blend);
	Draw::drawLineRect(rect,lineColor,blend);
}

//! Rect3dShape ---|> AbstractShape
void Rect3dShape::display(const Rect & rect,flag_t flags){
	Draw::draw3DRect(rect, (flags&ACTIVE)^invert , bgColor1, bgColor2);
}

//! ScrollableMarkerShape ---|> AbstractShape
void ScrollableMarkerShape::display(const Rect & rect,flag_t /*flag*/){
	if(!colorTop.isTransparent()){
		Draw::drawFilledRect(Rect(rect.getMinX(),rect.getMinY(),rect.getWidth(),width),
						colorTop,Colors::NO_COLOR,Colors::NO_COLOR,colorTop);
	}
	else if(!colorRight.isTransparent()){
		Draw::drawFilledRect(Rect(rect.getMaxX()-width,rect.getMinY(),width,rect.getHeight()),
						Colors::NO_COLOR,Colors::NO_COLOR,colorRight,colorRight);
	}
	else if(!colorBottom.isTransparent()){
		Draw::drawFilledRect(Rect(rect.getMinX(),rect.getMaxY()-width,rect.getWidth(),width),
						Colors::NO_COLOR,colorBottom,colorBottom,Colors::NO_COLOR);
	}
	else if(!colorLeft.isTransparent()){
		Draw::drawFilledRect(Rect(rect.getMinX(),rect.getMinY(),width,rect.getHeight()),
						colorLeft,colorLeft,Colors::NO_COLOR,Colors::NO_COLOR);
	}

}
//! ShadowedRectShape ---|> AbstractShape
void ShadowedRectShape::display(const Rect & rect,flag_t /*flag*/){
	Draw::drawFilledRect(rect,bgColor,blend);
	Draw::drawLineRect(rect,lineColor,blend);
	Draw::dropShadow(rect);
}

//! SliderMarkerShape ---|> AbstractShape
void SliderMarkerShape::display(const Rect & rect,flag_t flags){
	if (flags&ACTIVE)
		Draw::draw3DRect(rect,true,color1,color2);
	else
		Draw::draw3DRect(rect,false,color1,color2);
	Vec2 c=rect.getCenter();
	Draw::draw3DRect(Rect(c.x()-1 , c.y()-1 ,2,2),false,color1,color2);
}

//! TabHeaderShape ---|> AbstractShape
void TabHeaderShape::display(const Rect & rect,flag_t flags){
	if (flags&ACTIVE)
		Draw::drawTab(rect,color1,color2,color3);
	else
		Draw::drawTab(rect,Colors::NO_COLOR,color2,color1);
}

//! Rounded3dRectShape ---|> AbstractShape
void Rounded3dRectShape::display(const Rect & rect,flag_t flags){
	const bool down=flags&ACTIVE;
	if (bgColor1 != Colors::NO_COLOR){
		std::vector<float> vertices;
		std::vector<uint32_t> colors;
		vertices.reserve(8*2);
		colors.reserve(8);

		colors.insert(colors.end(),4, (down ? bgColor2:bgColor1).getAsUInt());
		vertices.push_back(rect.getMaxX());				vertices.push_back(rect.getMinY()+roundnessTR);
		vertices.push_back(rect.getMaxX()-roundnessTR);	vertices.push_back(rect.getMinY());
		vertices.push_back(rect.getMinX()+roundnessTL);	vertices.push_back(rect.getMinY());
		vertices.push_back(rect.getMinX());				vertices.push_back(rect.getMinY()+roundnessTL);

		colors.insert(colors.end(),4,(down ? bgColor1:bgColor2).getAsUInt());
		vertices.push_back(rect.getMinX());				vertices.push_back(rect.getMaxY()-roundnessBL);
		vertices.push_back(rect.getMinX()+roundnessBL);	vertices.push_back(rect.getMaxY());
		vertices.push_back(rect.getMaxX()-roundnessBR);	vertices.push_back(rect.getMaxY());
		vertices.push_back(rect.getMaxX());				vertices.push_back(rect.getMaxY()-roundnessBR);

		Draw::drawTriangleFan(vertices,colors);
	}

	{	// draw border
		const Util::Color4ub c1 = down ? Colors::BRIGHT_COLOR : Colors::DARK_COLOR;
		const Util::Color4ub c2 = down ? Colors::DARK_COLOR   : Colors::BRIGHT_COLOR;

		std::vector<float> vertices;
		std::vector<uint32_t> colors;
		vertices.reserve(10*2);
		colors.reserve(10);

		const Geometry::Rect_i r2(rect);
		Geometry::Rect r3(r2);
		r3.moveRel(0.5f,0.5f);

		colors.insert(colors.end(),5,c1.getAsUInt());
		vertices.push_back(r3.getMinX());				vertices.push_back(r3.getMaxY()-roundnessBL);
		vertices.push_back(r3.getMinX()+roundnessBL);	vertices.push_back(r3.getMaxY());
		vertices.push_back(r3.getMaxX()-roundnessBR);	vertices.push_back(r3.getMaxY());
		vertices.push_back(r3.getMaxX());				vertices.push_back(r3.getMaxY()-roundnessBR);
		vertices.push_back(r3.getMaxX());				vertices.push_back(r3.getMinY()+roundnessTR);

		colors.insert(colors.end(),5,c2.getAsUInt());
		vertices.push_back(r3.getMaxX());				vertices.push_back(r3.getMinY()+roundnessTR);
		vertices.push_back(r3.getMaxX()-roundnessTR);	vertices.push_back(r3.getMinY());
		vertices.push_back(r3.getMinX()+roundnessTL);	vertices.push_back(r3.getMinY());
		vertices.push_back(r3.getMinX());				vertices.push_back(r3.getMinY()+roundnessTL);
		vertices.push_back(r3.getMinX());				vertices.push_back(r3.getMaxY()-roundnessBL);
		Draw::drawLine(vertices,colors,1.0);
	}
}
//
//! ResizerShape ---|> AbstractShape
void ResizerShape::display(const Rect & rect,flag_t /*flag*/){
	const float w=floorf(rect.getWidth()/4.0f);
	const float h=floorf(rect.getWidth()/4.0f);
	const float x=floorf(rect.getX());
	const float y=floorf(rect.getY());
	Draw::drawFilledRect(Rect(x + floorf(w*2.75f), y+ floorf(h*0.25f), w,h) ,color,blend);

	Draw::drawFilledRect(Rect(x + floorf(w*1.5f) , y+ floorf(h*1.5f), w,h) ,color,blend);
	Draw::drawFilledRect(Rect(x + floorf(w*2.75f), y+ floorf(h*1.5f), w,h) ,color,blend);

	Draw::drawFilledRect(Rect(x + floorf(w*0.25f), y+ floorf(h*2.75f), w,h) ,color,blend);
	Draw::drawFilledRect(Rect(x + floorf(w*1.5f) , y+ floorf(h*2.75f), w,h) ,color,blend);
	Draw::drawFilledRect(Rect(x + floorf(w*2.75f), y+ floorf(h*2.75f), w,h) ,color,blend);
}//

//! TriangleAtCornerShape ---|> AbstractShape
void TriangleAtCornerShape::display(const Rect & rect,flag_t flags){
	std::vector<float> vertices;
	std::vector<uint32_t> colors;
	vertices.reserve(3*2);
	colors.reserve(3);

	colors.insert(colors.end(),3, color.getAsUInt());

	const Geometry::Vec2 corner = rect.getCorner(CORNER_XY);
	vertices.push_back(corner.x());				vertices.push_back(corner.y());
	vertices.push_back(corner.x());				vertices.push_back(corner.y()-size);
	vertices.push_back(corner.x()-size);		vertices.push_back(corner.y());

	Draw::drawTriangleFan(vertices,colors);
}

//! TriangleSelectorShape ---|> AbstractShape
void TriangleSelectorShape::display(const Rect & rect,flag_t flags){
	std::vector<float> vertices;
	std::vector<uint32_t> colors;
	vertices.reserve(3*2);
	colors.reserve(3);

	colors.insert(colors.end(),3, color.getAsUInt());

	const float sideLength = std::min(rect.getWidth(),rect.getHeight());
	const float halfSideLength = sideLength*0.5;
	const float h = std::sqrt( sideLength*sideLength - halfSideLength*halfSideLength );
	const float halfH = h*0.5;
	const Geometry::Vec2 center = rect.getCenter();
	if(flags&ACTIVE){
		vertices.push_back(center.x()-halfSideLength);		vertices.push_back(center.y()-halfH);
		vertices.push_back(center.x());						vertices.push_back(center.y()+halfH);
		vertices.push_back(center.x()+halfSideLength);		vertices.push_back(center.y()-halfH);
	}else{
		vertices.push_back(center.x()-halfH);				vertices.push_back(center.y()-halfSideLength);
		vertices.push_back(center.x()-halfH);				vertices.push_back(center.y()+halfSideLength);
		vertices.push_back(center.x()+halfH);				vertices.push_back(center.y());
	}
	Draw::drawTriangleFan(vertices,colors);
}

//! GridShape ---|> AbstractShape
void GridShape::display(const Rect & rect,flag_t /*flag*/){
	std::vector<float> vertices;
	std::vector<uint32_t> colors;

	// horizontal lines
	if(hDistance>0){
		int count=0;
		for(float pos=0;pos<=rect.getHeight();pos+=hDistance){
			colors.insert(colors.end(),2,(((count++ % (hNumMinors+1)) ==0) ? majorColor : minorColor).getAsUInt());
			vertices.push_back(0);						vertices.push_back(pos);
			vertices.push_back(rect.getWidth());		vertices.push_back(pos);
		}
	}
	// vertical lines
	if(vDistance>0){
		int count=0;
		for(float pos=0;pos<=rect.getWidth();pos+=vDistance){
			colors.insert(colors.end(),2,(((count++ % (vNumMinors+1)) ==0) ? majorColor : minorColor).getAsUInt());
			vertices.push_back(pos);					vertices.push_back(0);
			vertices.push_back(pos);					vertices.push_back(rect.getHeight());
		}
	}
	Draw::drawLines(vertices,colors);
}

//! CrossShape ---|> AbstractShape
void CrossShape::display(const Rect & rect,flag_t flags){
	Draw::drawCross(rect,flags&ACTIVE ? color2 : color1,lineWidth);
}

//! StraightLineShape ---|> LineShape
void StraightLineShape::displayLine(const std::vector<Geometry::Vec2> & points,flag_t){
	std::vector<float> vertices;
	vertices.reserve(points.size()*2);
	for(auto & point : points){
		vertices.push_back(static_cast<int>(point.x())+0.5f);
		vertices.push_back(static_cast<int>(point.y())+0.5f);
	}

	std::vector<uint32_t> colors;
	colors.insert(colors.end(),vertices.size(),color.getAsUInt());
	Draw::drawLine(vertices,colors,lineWidth,true);
}

//! SmoothConnectorShape ---|> LineShape
void SmoothConnectorShape::displayLine(const std::vector<Geometry::Vec2> & points,flag_t){
	std::vector<float> vertices;
	for(size_t i=1;i<points.size();++i){
		const Geometry::Vec2 p0(points[i-1]); // startPoint
		const Geometry::Vec2 p3(points[i]); // endPoint
		const float d = std::min(p0.distance(p3)*0.4,100.0);
		const Geometry::Vec2 p1(p0+Geometry::Vec2(d,0));
		const Geometry::Vec2 p2(p3-Geometry::Vec2(d,0));

		vertices.push_back(p0.x());
		vertices.push_back(p0.y());
		for(float t=0.0;t<=1.00;t += t<0.5 ? ((t*t)+0.1)*0.1 : (( (1.0-t)*(1.0-t))+0.1)*0.1 ){
			const Geometry::Vec2 p_t = Interpolation::cubicBezier(p0, p1, p2, p3, t);
			vertices.push_back(p_t.x());
			vertices.push_back(p_t.y());
		}
	}
	std::vector<uint32_t> colors;
	colors.insert(colors.end(),vertices.size(),color.getAsUInt());
	Draw::drawLine(vertices,colors,lineWidth,true);
}

}
<commit_msg>StdShapes: Fix warning.<commit_after>/*
	This file is part of the GUI library.
	Copyright (C) 2008-2012 Benjamin Eikel <benjamin@eikel.org>
	Copyright (C) 2008-2012 Claudius Jähn <claudius@uni-paderborn.de>
	Copyright (C) 2008-2012 Ralf Petring <ralf@petring.net>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "StdShapes.h"
#include "../Base/Draw.h"
#include "../Base/BasicColors.h"
#include "Colors.h"
#include <Geometry/Interpolation.h>
#include <Util/References.h>
#include <iostream>

using namespace Geometry;

namespace GUI {

//! RectShape ---|> AbstractShape
void RectShape::display(const Rect & rect,flag_t /*flag*/){
	Draw::drawFilledRect(rect,bgColor,blend);
	Draw::drawLineRect(rect,lineColor,blend);
}

//! Rect3dShape ---|> AbstractShape
void Rect3dShape::display(const Rect & rect,flag_t flags){
	Draw::draw3DRect(rect, (flags&ACTIVE)^invert , bgColor1, bgColor2);
}

//! ScrollableMarkerShape ---|> AbstractShape
void ScrollableMarkerShape::display(const Rect & rect,flag_t /*flag*/){
	if(!colorTop.isTransparent()){
		Draw::drawFilledRect(Rect(rect.getMinX(),rect.getMinY(),rect.getWidth(),width),
						colorTop,Colors::NO_COLOR,Colors::NO_COLOR,colorTop);
	}
	else if(!colorRight.isTransparent()){
		Draw::drawFilledRect(Rect(rect.getMaxX()-width,rect.getMinY(),width,rect.getHeight()),
						Colors::NO_COLOR,Colors::NO_COLOR,colorRight,colorRight);
	}
	else if(!colorBottom.isTransparent()){
		Draw::drawFilledRect(Rect(rect.getMinX(),rect.getMaxY()-width,rect.getWidth(),width),
						Colors::NO_COLOR,colorBottom,colorBottom,Colors::NO_COLOR);
	}
	else if(!colorLeft.isTransparent()){
		Draw::drawFilledRect(Rect(rect.getMinX(),rect.getMinY(),width,rect.getHeight()),
						colorLeft,colorLeft,Colors::NO_COLOR,Colors::NO_COLOR);
	}

}
//! ShadowedRectShape ---|> AbstractShape
void ShadowedRectShape::display(const Rect & rect,flag_t /*flag*/){
	Draw::drawFilledRect(rect,bgColor,blend);
	Draw::drawLineRect(rect,lineColor,blend);
	Draw::dropShadow(rect);
}

//! SliderMarkerShape ---|> AbstractShape
void SliderMarkerShape::display(const Rect & rect,flag_t flags){
	if (flags&ACTIVE)
		Draw::draw3DRect(rect,true,color1,color2);
	else
		Draw::draw3DRect(rect,false,color1,color2);
	Vec2 c=rect.getCenter();
	Draw::draw3DRect(Rect(c.x()-1 , c.y()-1 ,2,2),false,color1,color2);
}

//! TabHeaderShape ---|> AbstractShape
void TabHeaderShape::display(const Rect & rect,flag_t flags){
	if (flags&ACTIVE)
		Draw::drawTab(rect,color1,color2,color3);
	else
		Draw::drawTab(rect,Colors::NO_COLOR,color2,color1);
}

//! Rounded3dRectShape ---|> AbstractShape
void Rounded3dRectShape::display(const Rect & rect,flag_t flags){
	const bool down=flags&ACTIVE;
	if (bgColor1 != Colors::NO_COLOR){
		std::vector<float> vertices;
		std::vector<uint32_t> colors;
		vertices.reserve(8*2);
		colors.reserve(8);

		colors.insert(colors.end(),4, (down ? bgColor2:bgColor1).getAsUInt());
		vertices.push_back(rect.getMaxX());				vertices.push_back(rect.getMinY()+roundnessTR);
		vertices.push_back(rect.getMaxX()-roundnessTR);	vertices.push_back(rect.getMinY());
		vertices.push_back(rect.getMinX()+roundnessTL);	vertices.push_back(rect.getMinY());
		vertices.push_back(rect.getMinX());				vertices.push_back(rect.getMinY()+roundnessTL);

		colors.insert(colors.end(),4,(down ? bgColor1:bgColor2).getAsUInt());
		vertices.push_back(rect.getMinX());				vertices.push_back(rect.getMaxY()-roundnessBL);
		vertices.push_back(rect.getMinX()+roundnessBL);	vertices.push_back(rect.getMaxY());
		vertices.push_back(rect.getMaxX()-roundnessBR);	vertices.push_back(rect.getMaxY());
		vertices.push_back(rect.getMaxX());				vertices.push_back(rect.getMaxY()-roundnessBR);

		Draw::drawTriangleFan(vertices,colors);
	}

	{	// draw border
		const Util::Color4ub c1 = down ? Colors::BRIGHT_COLOR : Colors::DARK_COLOR;
		const Util::Color4ub c2 = down ? Colors::DARK_COLOR   : Colors::BRIGHT_COLOR;

		std::vector<float> vertices;
		std::vector<uint32_t> colors;
		vertices.reserve(10*2);
		colors.reserve(10);

		const Geometry::Rect_i r2(rect);
		Geometry::Rect r3(r2);
		r3.moveRel(0.5f,0.5f);

		colors.insert(colors.end(),5,c1.getAsUInt());
		vertices.push_back(r3.getMinX());				vertices.push_back(r3.getMaxY()-roundnessBL);
		vertices.push_back(r3.getMinX()+roundnessBL);	vertices.push_back(r3.getMaxY());
		vertices.push_back(r3.getMaxX()-roundnessBR);	vertices.push_back(r3.getMaxY());
		vertices.push_back(r3.getMaxX());				vertices.push_back(r3.getMaxY()-roundnessBR);
		vertices.push_back(r3.getMaxX());				vertices.push_back(r3.getMinY()+roundnessTR);

		colors.insert(colors.end(),5,c2.getAsUInt());
		vertices.push_back(r3.getMaxX());				vertices.push_back(r3.getMinY()+roundnessTR);
		vertices.push_back(r3.getMaxX()-roundnessTR);	vertices.push_back(r3.getMinY());
		vertices.push_back(r3.getMinX()+roundnessTL);	vertices.push_back(r3.getMinY());
		vertices.push_back(r3.getMinX());				vertices.push_back(r3.getMinY()+roundnessTL);
		vertices.push_back(r3.getMinX());				vertices.push_back(r3.getMaxY()-roundnessBL);
		Draw::drawLine(vertices,colors,1.0);
	}
}
//
//! ResizerShape ---|> AbstractShape
void ResizerShape::display(const Rect & rect,flag_t /*flag*/){
	const float w=floorf(rect.getWidth()/4.0f);
	const float h=floorf(rect.getWidth()/4.0f);
	const float x=floorf(rect.getX());
	const float y=floorf(rect.getY());
	Draw::drawFilledRect(Rect(x + floorf(w*2.75f), y+ floorf(h*0.25f), w,h) ,color,blend);

	Draw::drawFilledRect(Rect(x + floorf(w*1.5f) , y+ floorf(h*1.5f), w,h) ,color,blend);
	Draw::drawFilledRect(Rect(x + floorf(w*2.75f), y+ floorf(h*1.5f), w,h) ,color,blend);

	Draw::drawFilledRect(Rect(x + floorf(w*0.25f), y+ floorf(h*2.75f), w,h) ,color,blend);
	Draw::drawFilledRect(Rect(x + floorf(w*1.5f) , y+ floorf(h*2.75f), w,h) ,color,blend);
	Draw::drawFilledRect(Rect(x + floorf(w*2.75f), y+ floorf(h*2.75f), w,h) ,color,blend);
}//

//! TriangleAtCornerShape ---|> AbstractShape
void TriangleAtCornerShape::display(const Rect & rect,flag_t/* flags*/){
	std::vector<float> vertices;
	std::vector<uint32_t> colors;
	vertices.reserve(3*2);
	colors.reserve(3);

	colors.insert(colors.end(),3, color.getAsUInt());

	const Geometry::Vec2 corner = rect.getCorner(CORNER_XY);
	vertices.push_back(corner.x());				vertices.push_back(corner.y());
	vertices.push_back(corner.x());				vertices.push_back(corner.y()-size);
	vertices.push_back(corner.x()-size);		vertices.push_back(corner.y());

	Draw::drawTriangleFan(vertices,colors);
}

//! TriangleSelectorShape ---|> AbstractShape
void TriangleSelectorShape::display(const Rect & rect,flag_t flags){
	std::vector<float> vertices;
	std::vector<uint32_t> colors;
	vertices.reserve(3*2);
	colors.reserve(3);

	colors.insert(colors.end(),3, color.getAsUInt());

	const float sideLength = std::min(rect.getWidth(),rect.getHeight());
	const float halfSideLength = sideLength*0.5;
	const float h = std::sqrt( sideLength*sideLength - halfSideLength*halfSideLength );
	const float halfH = h*0.5;
	const Geometry::Vec2 center = rect.getCenter();
	if(flags&ACTIVE){
		vertices.push_back(center.x()-halfSideLength);		vertices.push_back(center.y()-halfH);
		vertices.push_back(center.x());						vertices.push_back(center.y()+halfH);
		vertices.push_back(center.x()+halfSideLength);		vertices.push_back(center.y()-halfH);
	}else{
		vertices.push_back(center.x()-halfH);				vertices.push_back(center.y()-halfSideLength);
		vertices.push_back(center.x()-halfH);				vertices.push_back(center.y()+halfSideLength);
		vertices.push_back(center.x()+halfH);				vertices.push_back(center.y());
	}
	Draw::drawTriangleFan(vertices,colors);
}

//! GridShape ---|> AbstractShape
void GridShape::display(const Rect & rect,flag_t /*flag*/){
	std::vector<float> vertices;
	std::vector<uint32_t> colors;

	// horizontal lines
	if(hDistance>0){
		int count=0;
		for(float pos=0;pos<=rect.getHeight();pos+=hDistance){
			colors.insert(colors.end(),2,(((count++ % (hNumMinors+1)) ==0) ? majorColor : minorColor).getAsUInt());
			vertices.push_back(0);						vertices.push_back(pos);
			vertices.push_back(rect.getWidth());		vertices.push_back(pos);
		}
	}
	// vertical lines
	if(vDistance>0){
		int count=0;
		for(float pos=0;pos<=rect.getWidth();pos+=vDistance){
			colors.insert(colors.end(),2,(((count++ % (vNumMinors+1)) ==0) ? majorColor : minorColor).getAsUInt());
			vertices.push_back(pos);					vertices.push_back(0);
			vertices.push_back(pos);					vertices.push_back(rect.getHeight());
		}
	}
	Draw::drawLines(vertices,colors);
}

//! CrossShape ---|> AbstractShape
void CrossShape::display(const Rect & rect,flag_t flags){
	Draw::drawCross(rect,flags&ACTIVE ? color2 : color1,lineWidth);
}

//! StraightLineShape ---|> LineShape
void StraightLineShape::displayLine(const std::vector<Geometry::Vec2> & points,flag_t){
	std::vector<float> vertices;
	vertices.reserve(points.size()*2);
	for(auto & point : points){
		vertices.push_back(static_cast<int>(point.x())+0.5f);
		vertices.push_back(static_cast<int>(point.y())+0.5f);
	}

	std::vector<uint32_t> colors;
	colors.insert(colors.end(),vertices.size(),color.getAsUInt());
	Draw::drawLine(vertices,colors,lineWidth,true);
}

//! SmoothConnectorShape ---|> LineShape
void SmoothConnectorShape::displayLine(const std::vector<Geometry::Vec2> & points,flag_t){
	std::vector<float> vertices;
	for(size_t i=1;i<points.size();++i){
		const Geometry::Vec2 p0(points[i-1]); // startPoint
		const Geometry::Vec2 p3(points[i]); // endPoint
		const float d = std::min(p0.distance(p3)*0.4,100.0);
		const Geometry::Vec2 p1(p0+Geometry::Vec2(d,0));
		const Geometry::Vec2 p2(p3-Geometry::Vec2(d,0));

		vertices.push_back(p0.x());
		vertices.push_back(p0.y());
		for(float t=0.0;t<=1.00;t += t<0.5 ? ((t*t)+0.1)*0.1 : (( (1.0-t)*(1.0-t))+0.1)*0.1 ){
			const Geometry::Vec2 p_t = Interpolation::cubicBezier(p0, p1, p2, p3, t);
			vertices.push_back(p_t.x());
			vertices.push_back(p_t.y());
		}
	}
	std::vector<uint32_t> colors;
	colors.insert(colors.end(),vertices.size(),color.getAsUInt());
	Draw::drawLine(vertices,colors,lineWidth,true);
}

}
<|endoftext|>