summaryrefslogtreecommitdiffstats
path: root/afm-client/bower_components/foundation-icon-fonts/svgs/fi-plus.svg
blob: c4f32c8f5fb5aea22b5f1b1badccdc5e19da381e (plain)
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<path d="M84.437,39.721l-24.164,0l0-24.158c0-1.001-0.812-1.812-1.812-1.813L41.536,13.75c-1.001,0-1.812,0.812-1.812,1.813
	l-0.001,24.16l-24.159-0.001c-0.961,0-1.812,0.851-1.813,1.813l0,16.925c-0.001,0.481,0.191,0.943,0.531,1.282
	c0.339,0.339,0.801,0.531,1.282,0.53h24.16v24.165c0,0.48,0.191,0.942,0.531,1.282c0.34,0.34,0.802,0.531,1.282,0.531L58.46,86.25
	c0.48,0,0.943-0.192,1.284-0.533c0.338-0.338,0.529-0.8,0.529-1.28V60.273l24.163-0.001c0.5,0,0.953-0.202,1.282-0.53
	c0.329-0.329,0.531-0.782,0.531-1.283l0.001-16.925C86.25,40.533,85.439,39.722,84.437,39.721z"/>
</svg>
ment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * Copyright (C) 2018 Konsulko Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "message.h"
#include "messageengine.h"
#include "radio.h"
#include "radiomessage.h"
#include "responsemessage.h"

Radio::Radio (QUrl &url, QQmlContext *context, QObject * parent) :
    QObject(parent),
    m_mloop(nullptr),
    m_band(1),
    m_frequency(0),
    m_playing(false),
    m_scanning(false)
{
    m_mloop = new MessageEngine(url);
    m_context = context;

    QObject::connect(m_mloop, &MessageEngine::connected, this, &Radio::onConnected);
    QObject::connect(m_mloop, &MessageEngine::disconnected, this, &Radio::onDisconnected);
    QObject::connect(m_mloop, &MessageEngine::messageReceived, this, &Radio::onMessageReceived);
}

Radio::~Radio()
{
    delete m_mloop;
}

void Radio::setBand(int band)
{
    RadioMessage *rmsg = new RadioMessage();
    QJsonObject parameter;

    parameter.insert("band", band ? "FM": "AM");
    rmsg->createRequest("band", parameter);
    m_mloop->sendMessage(rmsg);
    delete rmsg;
}

void Radio::setFrequency(int frequency)
{
    RadioMessage *rmsg = new RadioMessage();
    QJsonObject parameter;

    if (m_scanning)
        scanStop();

    if (frequency == m_frequency)
        return;

    parameter.insert("value", QString::number(frequency));
    rmsg->createRequest("frequency", parameter);
    m_mloop->sendMessage(rmsg);
    delete rmsg;

    // To improve UI responsiveness, signal the change here immediately
    // This fixes visual glitchiness in the slider caused by the frequency
    // update event taking long enough that the QML engine gets a chance
    // to update the slider with the current value before the event with
    // the new value comes.
    m_frequency = frequency;
    emit frequencyChanged(m_frequency);
}

// control related methods

void Radio::start()
{
    RadioMessage *rmsg = new RadioMessage();
    QJsonObject parameter;

    rmsg->createRequest("start", parameter);
    m_mloop->sendMessage(rmsg);
    delete rmsg;
}

void Radio::stop()
{
    RadioMessage *rmsg = new RadioMessage();

    QJsonObject parameter;
    rmsg->createRequest("stop", parameter);
    m_mloop->sendMessage(rmsg);
    delete rmsg;
}

void Radio::scanForward()
{
    if (m_scanning)
        return;

    RadioMessage *rmsg = new RadioMessage();
    QJsonObject parameter;
    parameter.insert("direction", "forward");
    rmsg->createRequest("scan_start", parameter);
    m_mloop->sendMessage(rmsg);

    m_scanning = true;
    emit scanningChanged(m_scanning);

    delete rmsg;
}

void Radio::scanBackward()
{
    if (m_scanning)
        return;

    RadioMessage *rmsg = new RadioMessage();
    QJsonObject parameter;
    parameter.insert("direction", "backward");
    rmsg->createRequest("scan_start", parameter);
    m_mloop->sendMessage(rmsg);

    m_scanning = true;
    emit scanningChanged(m_scanning);

    delete rmsg;
}

void Radio::scanStop()
{
    RadioMessage *rmsg = new RadioMessage();

    QJsonObject parameter;
    rmsg->createRequest("scan_stop", parameter);
    m_mloop->sendMessage(rmsg);

    m_scanning = false;
    emit scanningChanged(m_scanning);

    delete rmsg;
}

void Radio::updateFrequencyBandParameters()
{
    RadioMessage *rmsg = new RadioMessage();

    QJsonObject parameter;
    parameter.insert("band", m_band ? "FM" : "AM");
    rmsg->createRequest("frequency_range", parameter);
    m_mloop->sendMessage(rmsg);
    delete rmsg;

    rmsg = new RadioMessage();
    rmsg->createRequest("frequency_step", parameter);
    m_mloop->sendMessage(rmsg);
    delete rmsg;
}

void Radio::onConnected()
{
    QStringListIterator eventIterator(events);
    RadioMessage *rmsg;

    while (eventIterator.hasNext()) {
        rmsg = new RadioMessage();
        QJsonObject parameter;
        parameter.insert("value", eventIterator.next());
        rmsg->createRequest("subscribe", parameter);
        m_mloop->sendMessage(rmsg);
        delete rmsg;
    }

    // Trigger initial update of frequency band parameters (min/max/step)
    updateFrequencyBandParameters();
}

void Radio::onDisconnected()
{
    QStringListIterator eventIterator(events);
    RadioMessage *rmsg;

    while (eventIterator.hasNext()) {
        rmsg = new RadioMessage();
        QJsonObject parameter;
        parameter.insert("value", eventIterator.next());
        rmsg->createRequest("unsubscribe", parameter);
        m_mloop->sendMessage(rmsg);
        delete rmsg;
    }
}

void Radio::onMessageReceived(MessageType type, Message *msg)
{
    if (msg->isEvent() && type == RadioEventMessage) {
        RadioMessage *rmsg = qobject_cast<RadioMessage*>(msg);

        if (rmsg->isFrequencyEvent()) {
            unsigned int frequency = rmsg->eventData().value("value").toInt();
            m_frequency = frequency;
            if (!m_scanning && (m_frequency != frequency)) {
                emit frequencyChanged(m_frequency);
            }
        } else if (rmsg->isStationFoundEvent()) {
            m_scanning = false;
            emit scanningChanged(m_scanning);

            m_frequency = rmsg->eventData().value("value").toInt();
            emit frequencyChanged(m_frequency);
        } else if (rmsg->isStatusEvent()) {
            if (rmsg->eventData().value("value") == QString("playing")) {
                m_playing = true;
                emit playingChanged(m_playing);
            } else if (rmsg->eventData().value("value") == QString("stopped")) {
                m_playing = false;
                emit playingChanged(m_playing);
            }
        }
    } else if (msg->isReply() && type == ResponseRequestMessage) {
        ResponseMessage *rmsg = qobject_cast<ResponseMessage*>(msg);

        if (rmsg->requestVerb() == "frequency_range") {
            m_minFrequency = rmsg->replyData().value("min").toInt();
            emit minFrequencyChanged(m_minFrequency);
            m_maxFrequency = rmsg->replyData().value("max").toInt();
            emit maxFrequencyChanged(m_maxFrequency);

            // Handle start up
            if (!m_frequency) {
                m_frequency = m_minFrequency;
                emit frequencyChanged(m_frequency);
            }
        } else if (rmsg->requestVerb() == "frequency_step") {
            m_frequencyStep = rmsg->replyData().value("step").toInt();
            emit frequencyStepChanged(m_frequencyStep);
        }
    }
    msg->deleteLater();
}