1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Merge remote-tracking branch 'origin/next' into Brian-PipXtreme-V2

This commit is contained in:
Brian Webb 2012-06-20 18:34:56 -07:00
commit 04f49498b2
12 changed files with 343 additions and 79 deletions

View File

@ -554,7 +554,7 @@ void ConfigCcpmWidget::updateThrottleCurveValue(QList<double> curveValues0,doubl
for (i=0; i<internalCurveValues.length(); i++)
{
CurrentValue=m_ccpm->CurveSettings->item(i, 1 )->text().toDouble();
CurrentValue=m_ccpm->CurveSettings->item(i, 0 )->text().toDouble();
if (CurrentValue!=internalCurveValues[i])
{
m_ccpm->CurveSettings->item(i, 0)->setText(QString().sprintf("%.3f",internalCurveValues.at(i)));
@ -1224,11 +1224,10 @@ void ConfigCcpmWidget::setMixer()
}
//get the user data for the curve into the mixer settings
for (i=0;i<5;i++)
for (i=0;i<5;i++) {
mixerSettingsData.ThrottleCurve1[i] = m_ccpm->CurveSettings->item(i, 0)->text().toDouble();
for (i=0;i<5;i++)
mixerSettingsData.ThrottleCurve2[i] = m_ccpm->CurveSettings->item(i, 1)->text().toDouble();
}
//mapping of collective input to curve 2...
//MixerSettings.Curve2Source = Throttle,Roll,Pitch,Yaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5

View File

@ -46,7 +46,7 @@
#define STICK_MIN_MOVE -8
#define STICK_MAX_MOVE 8
ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent),wizardStep(wizardNone),loop(NULL),skipflag(false),transmitterType(heli)
ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent),wizardStep(wizardNone),transmitterType(heli),loop(NULL),skipflag(false)
{
manualCommandObj = ManualControlCommand::GetInstance(getObjectManager());
manualSettingsObj = ManualControlSettings::GetInstance(getObjectManager());

View File

@ -128,7 +128,7 @@ QList <Core::IConnection::device> SerialConnection::availableDevices()
foreach( QextPortInfo port, ports ) {
device d;
d.displayName=port.friendName;
d.name=port.friendName;
d.name=port.physName;
list.append(d);
}
}
@ -143,7 +143,7 @@ QIODevice *SerialConnection::openDevice(const QString &deviceName)
}
QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
foreach( QextPortInfo port, ports ) {
if(port.friendName == deviceName)
if(port.physName == deviceName)
{
//we need to handle port settings here...
PortSettings set;

View File

@ -27,6 +27,77 @@
#include "treeitem.h"
/* Constructor */
HighLightManager::HighLightManager(long checkingInterval)
{
// Start the timer and connect it to the callback
m_expirationTimer.start(checkingInterval);
connect(&m_expirationTimer, SIGNAL(timeout()), this, SLOT(checkItemsExpired()));
}
/*
* Called to add item to list. Item is only added if absent.
* Returns true if item was added, otherwise false.
*/
bool HighLightManager::add(TreeItem *itemToAdd)
{
// Lock to ensure thread safety
QMutexLocker locker(&m_listMutex);
// Check so that the item isn't already in the list
if(!m_itemsList.contains(itemToAdd))
{
m_itemsList.append(itemToAdd);
return true;
}
return false;
}
/*
* Called to remove item from list.
* Returns true if item was removed, otherwise false.
*/
bool HighLightManager::remove(TreeItem *itemToRemove)
{
// Lock to ensure thread safety
QMutexLocker locker(&m_listMutex);
// Remove item and return result
return m_itemsList.removeOne(itemToRemove);
}
/*
* Callback called periodically by the timer.
* This method checks for expired highlights and
* removes them if they are expired.
* Expired highlights are restored.
*/
void HighLightManager::checkItemsExpired()
{
// Lock to ensure thread safety
QMutexLocker locker(&m_listMutex);
// Get a mutable iterator for the list
QMutableLinkedListIterator<TreeItem*> iter(m_itemsList);
// This is the timestamp to compare with
QTime now = QTime::currentTime();
// Loop over all items, check if they expired.
while(iter.hasNext())
{
TreeItem* item = iter.next();
if(item->getHiglightExpires() < now)
{
// If expired, call removeHighlight
item->removeHighlight();
// Remove from list since it is restored.
iter.remove();
}
}
}
int TreeItem::m_highlightTimeMs = 500;
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent) :
@ -36,7 +107,6 @@ TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent) :
m_highlight(false),
m_changed(false)
{
connect(&m_timer, SIGNAL(timeout()), this, SLOT(removeHighlight()));
}
TreeItem::TreeItem(const QVariant &data, TreeItem *parent) :
@ -46,7 +116,6 @@ TreeItem::TreeItem(const QVariant &data, TreeItem *parent) :
m_changed(false)
{
m_data << data << "" << "";
connect(&m_timer, SIGNAL(timeout()), this, SLOT(removeHighlight()));
}
TreeItem::~TreeItem()
@ -108,21 +177,50 @@ void TreeItem::apply() {
child->apply();
}
/*
* Called after a value has changed to trigger highlightning of tree item.
*/
void TreeItem::setHighlight(bool highlight) {
m_highlight = highlight;
m_changed = false;
if (highlight) {
if (m_timer.isActive()) {
m_timer.stop();
// Update the expires timestamp
m_highlightExpires = QTime::currentTime().addMSecs(m_highlightTimeMs);
// Add to highlightmanager
if(m_highlightManager->add(this))
{
// Only emit signal if it was added
emit updateHighlight(this);
}
m_timer.setSingleShot(true);
m_timer.start(m_highlightTimeMs);
}
emit updateHighlight(this);
else if(m_highlightManager->remove(this))
{
// Only emit signal if it was removed
emit updateHighlight(this);
}
// If we have a parent, call recursively to update highlight status of parents.
// This will ensure that the root of a leaf that is changed also is highlighted.
// Only updates that really changes values will trigger highlight of parents.
if(m_parent)
{
m_parent->setHighlight(highlight);
}
}
void TreeItem::removeHighlight() {
m_highlight = false;
update();
//update();
emit updateHighlight(this);
}
void TreeItem::setHighlightManager(HighLightManager *mgr)
{
m_highlightManager = mgr;
}
QTime TreeItem::getHiglightExpires()
{
return m_highlightExpires;
}

View File

@ -32,10 +32,58 @@
#include "uavmetaobject.h"
#include "uavobjectfield.h"
#include <QtCore/QList>
#include <QtCore/QLinkedList>
#include <QtCore/QVariant>
#include <QTCore/QTime>
#include <QtCore/QTimer>
#include <QtCore/QObject>
#include <QtCore/QDebug>
class TreeItem;
/*
* Small utility class that handles the higlighting of
* tree grid items.
* Basicly it maintains all items due to be restored to
* non highlighted state in a linked list.
* A timer traverses this list periodically to find out
* if any of the items should be restored. All items are
* updated withan expiration timestamp when they expires.
* An item that is beeing restored is removed from the
* list and its removeHighlight() method is called. Items
* that are not expired are left in the list til next time.
* Items that are updated during the expiration time are
* left untouched in the list. This reduces unwanted emits
* of signals to the repaint/update function.
*/
class HighLightManager : public QObject
{
Q_OBJECT
public:
// Constructor taking the checking interval in ms.
HighLightManager(long checkingInterval);
// This is called when an item has been set to
// highlighted = true.
bool add(TreeItem* itemToAdd);
//This is called when an item is set to highlighted = false;
bool remove(TreeItem* itemToRemove);
private slots:
// Timer callback method.
void checkItemsExpired();
private:
// The timer checking highlight expiration.
QTimer m_expirationTimer;
// The list holding all items due to be updated.
QLinkedList<TreeItem*> m_itemsList;
//Mutex to lock when accessing list.
QMutex m_listMutex;
};
class TreeItem : public QObject
{
@ -77,11 +125,16 @@ public:
inline bool changed() { return m_changed; }
inline void setChanged(bool changed) { m_changed = changed; }
virtual void setHighlightManager(HighLightManager* mgr);
QTime getHiglightExpires();
virtual void removeHighlight();
signals:
void updateHighlight(TreeItem*);
private slots:
void removeHighlight();
private:
QList<TreeItem*> m_children;
@ -91,7 +144,8 @@ private:
TreeItem *m_parent;
bool m_highlight;
bool m_changed;
QTimer m_timer;
QTime m_highlightExpires;
HighLightManager* m_highlightManager;
public:
static const int dataColumn = 1;
private:

View File

@ -47,6 +47,8 @@ UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent) :
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
// Create highlight manager, let it run every 300 ms.
m_highlightManager = new HighLightManager(300);
connect(objManager, SIGNAL(newObject(UAVObject*)), this, SLOT(newObject(UAVObject*)));
connect(objManager, SIGNAL(newInstance(UAVObject*)), this, SLOT(newObject(UAVObject*)));
@ -56,6 +58,7 @@ UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent) :
UAVObjectTreeModel::~UAVObjectTreeModel()
{
delete m_highlightManager;
delete m_rootItem;
}
@ -67,9 +70,12 @@ void UAVObjectTreeModel::setupModelData(UAVObjectManager *objManager)
m_rootItem = new TreeItem(rootData);
m_settingsTree = new TopTreeItem(tr("Settings"), m_rootItem);
m_settingsTree->setHighlightManager(m_highlightManager);
m_rootItem->appendChild(m_settingsTree);
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"), m_rootItem);
m_nonSettingsTree->setHighlightManager(m_highlightManager);
m_rootItem->appendChild(m_nonSettingsTree);
m_rootItem->setHighlightManager(m_highlightManager);
connect(m_settingsTree, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
connect(m_nonSettingsTree, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
@ -96,6 +102,7 @@ void UAVObjectTreeModel::addDataObject(UAVDataObject *obj)
addInstance(obj, root->child(index));
} else {
DataObjectTreeItem *data = new DataObjectTreeItem(obj->getName() + " (" + QString::number(obj->getNumBytes()) + " bytes)");
data->setHighlightManager(m_highlightManager);
connect(data, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
int index = root->nameIndex(obj->getName());
root->insert(index, data);
@ -110,6 +117,7 @@ void UAVObjectTreeModel::addMetaObject(UAVMetaObject *obj, TreeItem *parent)
{
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(highlightUpdatedObject(UAVObject*)));
MetaObjectTreeItem *meta = new MetaObjectTreeItem(obj, tr("Meta Data"));
meta->setHighlightManager(m_highlightManager);
connect(meta, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
foreach (UAVObjectField *field, obj->getFields()) {
if (field->getNumElements() > 1) {
@ -132,6 +140,7 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
} else {
QString name = tr("Instance") + " " + QString::number(obj->getInstID());
item = new InstanceTreeItem(obj, name);
item->setHighlightManager(m_highlightManager);
connect(item, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
parent->appendChild(item);
}
@ -148,6 +157,7 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
void UAVObjectTreeModel::addArrayField(UAVObjectField *field, TreeItem *parent)
{
TreeItem *item = new ArrayFieldTreeItem(field->getName());
item->setHighlightManager(m_highlightManager);
connect(item, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
for (uint i = 0; i < field->getNumElements(); ++i) {
addSingleField(i, field, item);
@ -192,6 +202,7 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
default:
Q_ASSERT(false);
}
item->setHighlightManager(m_highlightManager);
connect(item, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
parent->appendChild(item);
}
@ -352,7 +363,6 @@ void UAVObjectTreeModel::highlightUpdatedObject(UAVObject *obj)
Q_ASSERT(obj);
ObjectTreeItem *item = findObjectTreeItem(obj);
Q_ASSERT(item);
item->setHighlight(true);
item->update();
QModelIndex itemIndex = index(item);
Q_ASSERT(itemIndex != QModelIndex());

View File

@ -97,6 +97,9 @@ private:
int m_recentlyUpdatedTimeout;
QColor m_recentlyUpdatedColor;
QColor m_manuallyChangedColor;
// Highlight manager to handle highlighting of tree items.
HighLightManager *m_highlightManager;
};
#endif // UAVOBJECTTREEMODEL_H

View File

@ -84,7 +84,7 @@ public:
};
ConfigTaskWidget(QWidget *parent = 0);
~ConfigTaskWidget();
virtual ~ConfigTaskWidget();
void disableMouseWheelEvents();
bool eventFilter( QObject * obj, QEvent * evt );

View File

@ -43,6 +43,7 @@ Node::Node(MixerCurveWidget *graphWidget)
setCacheMode(DeviceCoordinateCache);
setZValue(-1);
vertical = false;
value = 0;
}
void Node::addEdge(Edge *edge)
@ -98,6 +99,15 @@ void Node::verticalMove(bool flag){
vertical = flag;
}
double Node::getValue() {
return value;
}
void Node::setValue(double val) {
value = val;
}
QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
{
@ -117,11 +127,19 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
newPos.setY(h);
return newPos;
}
case ItemPositionHasChanged:
case ItemPositionHasChanged: {
foreach (Edge *edge, edgeList)
edge->adjust();
graph->itemMoved((h-newPos.y())/h);
double min = graph->getMin();
double range = graph->getMax() - min;
double ratio = (h - newPos.y()) / h;
double val = (range * ratio ) + min;
setValue(val);
graph->itemMoved(val);
break;
}
default:
break;
};

View File

@ -48,12 +48,16 @@ public:
enum { Type = UserType + 1 };
int type() const { return Type; }
void verticalMove(bool flag);
QRectF boundingRect() const;
QPainterPath shape() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void setValue(double val);
double getValue();
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
@ -61,6 +65,8 @@ protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
private:
double value;
QList<Edge *> edgeList;
QPointF newPos;
MixerCurveWidget *graph;

View File

@ -32,8 +32,6 @@
#include <QtGui>
#include <QDebug>
/*
* Initialize the widget
*/
@ -74,11 +72,48 @@ MixerCurveWidget::MixerCurveWidget(QWidget *parent) : QGraphicsView(parent)
scene->setSceneRect(plot->boundingRect());
setScene(scene);
initNodes(MixerCurveWidget::NODE_NUMELEM);
}
MixerCurveWidget::~MixerCurveWidget()
{
for (int i=0; i<nodePool.count(); i++)
delete nodePool.at(i);
for (int i=0; i<edgePool.count(); i++)
delete edgePool.at(i);
}
Node* MixerCurveWidget::getNode(int index)
{
Node* node;
if (index >= 0 && index < nodePool.count())
{
node = nodePool.at(index);
}
else {
node = new Node(this);
nodePool.append(node);
}
return node;
}
Edge* MixerCurveWidget::getEdge(int index, Node* sourceNode, Node* destNode)
{
Edge* edge;
if (index >= 0 && index < edgePool.count())
{
edge = edgePool.at(index);
edge->setSourceNode(sourceNode);
edge->setDestNode(destNode);
}
else {
edge = new Edge(sourceNode,destNode);
edgePool.append(edge);
}
return edge;
}
/**
@ -89,60 +124,62 @@ MixerCurveWidget::~MixerCurveWidget()
*/
void MixerCurveWidget::initCurve(QList<double> points)
{
if (points.length() < 2)
return; // We need at least 2 points on a curve!
// First of all, reset the list
// TODO: one edge might not get deleted properly, small mem leak maybe...
if (nodeList.count() != points.count())
initNodes(points.count());
// finally, set node positions
setCurve(points);
}
void MixerCurveWidget::initNodes(int numPoints)
{
// First of all, clear any existing list
if (nodeList.count()) {
foreach (Node *node, nodeList ) {
QList<Edge*> edges = node->edges();
foreach(Edge *edge, edges) {
if (scene()->items().contains(edge))
scene()->removeItem(edge);
else
if (edge->destNode() == node) {
delete edge;
}
else {
scene()->removeItem(edge);
}
}
scene()->removeItem(node);
delete node;
}
nodeList.clear();
scene()->removeItem(node);
}
nodeList.clear();
}
// Create the nodes and edges
Node* prevNode = 0;
for (int i=0; i<numPoints; i++) {
Node *node = getNode(i);
// Create the nodes
qreal w = plot->boundingRect().width()/(points.length()-1);
qreal h = plot->boundingRect().height();
for (int i=0; i<points.length(); i++) {
Node *node = new Node(this);
scene()->addItem(node);
nodeList.append(node);
double val = points.at(i);
if (val>curveMax)
val=curveMax;
if (val<curveMin)
val=curveMin;
val+=curveMin;
val/=(curveMax-curveMin);
node->setPos(w*i,h-val*h);
node->verticalMove(true);
}
scene()->addItem(node);
// ... and link them together:
for (int i=0; i<(points.length()-1); i++) {
scene()->addItem(new Edge(nodeList.at(i),nodeList.at(i+1)));
}
if (prevNode) {
scene()->addItem(getEdge(i, prevNode, node));
}
prevNode = node;
}
}
/**
Returns the current curve settings
*/
QList<double> MixerCurveWidget::getCurve() {
QList<double> list;
qreal h = plot->boundingRect().height();
foreach(Node *node, nodeList) {
list.append(((curveMax-curveMin)*(h-node->pos().y())/h)+curveMin);
list.append(node->getValue());
}
return list;
@ -150,11 +187,15 @@ QList<double> MixerCurveWidget::getCurve() {
/**
Sets a linear graph
*/
void MixerCurveWidget::initLinearCurve(quint32 numPoints, double maxValue)
void MixerCurveWidget::initLinearCurve(quint32 numPoints, double maxValue, double minValue)
{
Q_UNUSED(maxValue);
Q_UNUSED(minValue);
QList<double> points;
for (double i=0; i<numPoints;i++) {
points.append(maxValue*(i/(numPoints-1)));
double val = ((curveMax - curveMin) * (i/(numPoints-1))) + curveMin;
points.append(val);
}
initCurve(points);
}
@ -163,25 +204,35 @@ void MixerCurveWidget::initLinearCurve(quint32 numPoints, double maxValue)
*/
void MixerCurveWidget::setCurve(QList<double> points)
{
if (nodeList.length()<1)
{
initCurve(points);
}
else
{
qreal w = plot->boundingRect().width()/(points.length()-1);
qreal h = plot->boundingRect().height();
for (int i=0; i<points.length(); i++) {
double val = points.at(i);
if (val>curveMax)
val=curveMax;
if (val<curveMin)
val=curveMin;
val-=curveMin;
val/=(curveMax-curveMin);
nodeList.at(i)->setPos(w*i,h-val*h);
}
curveUpdating = true;
if (nodeList.count() != points.count())
initNodes(points.count());
double min = curveMin + 10;
double max = curveMax + 10;
qreal w = plot->boundingRect().width()/(points.count()-1);
qreal h = plot->boundingRect().height();
for (int i=0; i<points.count(); i++) {
double val = points.at(i);
if (val < curveMin)
val = curveMin;
if (val > curveMax)
val = curveMax;
val += 10;
val -= min;
val /= (max - min);
nodeList.at(i)->setPos(w*i, h - (val*h));
nodeList.at(i)->verticalMove(true);
}
curveUpdating = false;
emit curveUpdated(points, (double)0);
}
@ -205,8 +256,10 @@ void MixerCurveWidget::resizeEvent(QResizeEvent* event)
void MixerCurveWidget::itemMoved(double itemValue)
{
QList<double> list = getCurve();
emit curveUpdated(list, itemValue);
if (!curveUpdating) {
QList<double> list = getCurve();
emit curveUpdated(list, itemValue);
}
}
void MixerCurveWidget::setMin(double value)
@ -217,6 +270,14 @@ void MixerCurveWidget::setMax(double value)
{
curveMax = value;
}
double MixerCurveWidget::getMin()
{
return curveMin;
}
double MixerCurveWidget::getMax()
{
return curveMax;
}
void MixerCurveWidget::setRange(double min, double max)
{
curveMin = min;

View File

@ -31,6 +31,7 @@
#include <QGraphicsView>
#include <QtSvg/QSvgRenderer>
#include <QtSvg/QGraphicsSvgItem>
#include <QtCore/QPointer>
#include "mixercurvepoint.h"
#include "mixercurveline.h"
#include "uavobjectwidgetutils_global.h"
@ -45,12 +46,16 @@ public:
void itemMoved(double itemValue); // Callback when a point is moved, to be updated
void initCurve (QList<double> points);
QList<double> getCurve();
void initLinearCurve(quint32 numPoints, double maxValue);
void initLinearCurve(quint32 numPoints, double maxValue = 1, double minValue = 0);
void setCurve(QList<double>);
void setMin(double value);
double getMin();
void setMax(double value);
double getMax();
void setRange(double min, double max);
static const int NODE_NUMELEM = 5;
signals:
void curveUpdated(QList<double>, double );
@ -58,9 +63,19 @@ private slots:
private:
QGraphicsSvgItem *plot;
QList<Node*> nodePool;
QList<Edge*> edgePool;
QList<Node*> nodeList;
QList<double> points;
double curveMin;
double curveMax;
bool curveUpdating;
void initNodes(int numPoints);
Node* getNode(int index);
Edge* getEdge(int index, Node* sourceNode, Node* destNode);
protected:
void showEvent(QShowEvent *event);