Commit bc9d5714 authored by LEFEBVREJP email's avatar LEFEBVREJP email
Browse files

Merge branch 'master' into vtkchartwidget

parents f7a37061 e236d194
Pipeline #14672 passed with stages
in 7 minutes and 33 seconds
......@@ -31,10 +31,10 @@ void MarchingSquares<data_type>::clear_connected_component(int row, int col,
// search neighbors
for (int direction = 0; direction < 4; ++direction)
{
size_t nc = col + dx[direction];
size_t nr = row + dy[direction];
if (nc < 0 || nc == mColumns) continue; // out of bounds
if (nr < 0 || nr == mRows) continue; // out of bounds
int nc = col + dx[direction];
int nr = row + dy[direction];
if (nc < 0 || nc >= mColumns) continue; // out of bounds
if (nr < 0 || nr >= mRows) continue; // out of bounds
size_t nc_i = mColumns * nr + nc;
if (mBit[nc_i] == label)
{
......
......@@ -142,4 +142,6 @@ struct std::tm utc_to_time(const std::string &time, int &zone, int &daylight)
return res;
}
int ordinal(char c) { return (unsigned char)c; }
} // namespace radix
......@@ -17,6 +17,21 @@
namespace radix
{
/**
* @brief ordinal convert character to its ordinal value
* @param c char
* @return integer
*/
int RADIX_PUBLIC ordinal(char c);
/**
* @brief itoa converts integer into character
* @param number integer must be within character bounds
* @return char
*/
template <typename type = int>
char RADIX_PUBLIC itoa(type number);
/**
* @brief utc_to_time UTC time to
* @param time UTC formatted date and time
......
......@@ -33,4 +33,16 @@ std::string join(const std::string &delim, const T &x)
}
return ss.str();
}
template <typename type>
char itoa(type number)
{
char c[2];
c[0] = '0';
c[1] = '\0'; // null
if (number > type(255)) return c[0];
if (number < type(0)) return c[0];
sprintf(c, "%c", number);
return c[0];
}
} // namespace radix
......@@ -104,3 +104,36 @@ TEST(Split, NoDelim)
ASSERT_EQ(1, x.size());
EXPECT_EQ("nope", x[0]);
}
TEST(Radix, OrdinalItoa)
{
{
char c = itoa(127);
EXPECT_EQ('\x7F', c);
int i = ordinal(c);
EXPECT_EQ(127, i);
}
{
char c = itoa(0); // null
EXPECT_EQ('\0', c);
int i = ordinal(c);
EXPECT_EQ(0, i);
}
{
char c = itoa(99);
EXPECT_EQ('c', c);
int i = ordinal(c);
EXPECT_EQ(99, i);
}
{
char c = itoa(48);
EXPECT_EQ('0', c);
int i = ordinal(c);
EXPECT_EQ(48, i);
}
{
char c = itoa(140);
EXPECT_EQ('\x8C', c);
int i = ordinal(c);
EXPECT_EQ(140, i);
}
}
......@@ -23,8 +23,11 @@ TRIBITS_SUBPACKAGE(widgets)
SET(HEADERS
tabwidget.hh
tableview.hh
numberpadwidget.hh
vtkchartwidget.hh
)
# C/C++ source
SET(SOURCES
tabwidget.cc
tableview.cc
)
#
# Moc the header files
......@@ -39,9 +42,29 @@ IF(USE_QT4)
# ${RESOURCE_FILES}
#)
ELSE()
SET(HEADERS
${HEADERS}
numberpadwidget.hh
navigationactionmanager.hh
navigationmodel.hh
navigationwidget.hh
vtkchartwidget.hh
)
SET(SOURCES
${SOURCES}
numberpadwidget.cc
navigationactionmanager.cc
navigationitem.cc
navigationmodel.cc
navigationwidget.cc
vtkchartwidget.cc
)
QT5_WRAP_CPP(MOC_FILES
${HEADERS}
)
SET(HEADERS ${HEADERS}
navigationitem.hh
)
#
# Process qt resource files
#QT5_ADD_RESOURCES(RESOURCE_RESULT
......@@ -52,8 +75,6 @@ ENDIF()
SET(SOURCES
tabwidget.cc
tableview.cc
numberpadwidget.cc
vtkchartwidget.cc
)
##---------------------------------------------------------------------------##
......
......@@ -26,6 +26,26 @@ ELSE()
radixvtkchartwidget.hh
)
ENDIF()
QT5_WRAP_CPP(QMOC_FILES5
radixnavigationwidget.hh
)
TRIBITS_ADD_EXECUTABLE(radixnumberpadwidget
NOEXEPREFIX
SOURCES radixnumberpadwidget.cc ${QMOC_FILES3}
radixnumberpadwidget.hh
)
TRIBITS_ADD_EXECUTABLE(radixnavigationwidget
NOEXEPREFIX
SOURCES radixnavigationwidget.cc ${QMOC_FILES5}
radixnavigationwidget.hh
)
IF(TPL_ENABLE_VTK)
MESSAGE("VTK_USE_FILE=${VTK_USE_FILE}")
TRIBITS_ADD_EXECUTABLE(radixvtkchartwidget
NOEXEPREFIX
SOURCES radixvtkchartwidget.cc ${QMOC_FILES4}
)
ENDIF()
ENDIF()
TRIBITS_ADD_EXECUTABLE(radixtabwidget
NOEXEPREFIX
......@@ -37,15 +57,4 @@ TRIBITS_ADD_EXECUTABLE(radixtablewidget
SOURCES radixtablewidget.cc ${QMOC_FILES2}
)
TRIBITS_ADD_EXECUTABLE(radixnumberpadwidget
NOEXEPREFIX
SOURCES radixnumberpadwidget.cc ${QMOC_FILES3}
)
IF(USE_QT5 AND TPL_ENABLE_VTK)
MESSAGE("VTK_USE_FILE=${VTK_USE_FILE}")
TRIBITS_ADD_EXECUTABLE(radixvtkchartwidget
NOEXEPREFIX
SOURCES radixvtkchartwidget.cc ${QMOC_FILES4}
)
ENDIF()
/*
* @file: mainwindow.cpp
* @author: Jordan P. Lefebvre, lefebvrejp@ornl.gov
*
* Created on May 31, 2016, 10:52 PM
*/
#include "radixnavigationwidget.hh"
#include <iostream>
#include <QApplication>
#include <QGridLayout>
#include <QLabel>
#include <limits>
#include "radixwidgets/navigationactionmanager.hh"
#include "radixwidgets/navigationitem.hh"
#include "radixwidgets/navigationmodel.hh"
#include "radixwidgets/navigationwidget.hh"
using namespace radix;
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
{
setGeometry(400, 250, 542, 390);
mWidget = new NavigationWidget(this);
NavigationModel* model = mWidget->navigationModel();
NavigationItem* root = model->rootItem();
auto hello = model->addItem("Hello", root);
auto world = model->addItem("World", root);
auto hidden_beneath = model->addItem("Hidden beneath", world);
NavigationActionManager* actions = mWidget->navigationActionManager();
actions->registerAction(hello, "Hello Function 1", []() {
std::cout << "Hello function 1 executed" << std::endl;
});
actions->registerAction(hidden_beneath, "Hidden Function", []() {
std::cout << "Hidden function executed" << std::endl;
});
actions->registerAction(hidden_beneath, "Hidden Function 2", []() {
std::cout << "Hidden function2 executed" << std::endl;
});
setCentralWidget(mWidget);
}
MainWindow::~MainWindow() {}
/******************************************************************************/
/******************************** MAIN PROGRAM ********************************/
/******************************************************************************/
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
mainWindow.raise();
return app.exec();
}
#ifndef RADIX_RADIXWIDGETS_EXAMPLE_RADIXNAVIGATIONWIDGET_HH_
#define RADIX_RADIXWIDGETS_EXAMPLE_RADIXNAVIGATIONWIDGET_HH_
#include <QMainWindow>
#include <QWidget>
#include "radixwidgets/navigationwidget.hh"
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
radix::NavigationWidget *mWidget;
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // RADIX_RADIXWIDGETS_EXAMPLE_RADIXNAVIGATIONWIDGET_HH_
#include "radixwidgets/navigationactionmanager.hh"
#include <QHash>
#include <QList>
#include <QMenu>
#include "radixbug/bug.hh"
namespace radix
{
class NavigationActionManager::PImpl
{
public:
QHash<NavigationItem *, QList<std::pair<QString, std::function<void()>>>>
item_functions;
~PImpl();
};
NavigationActionManager::PImpl::~PImpl() {}
NavigationActionManager::NavigationActionManager(QObject *parent)
: p(new PImpl(), [](PImpl *impl) { delete impl; })
{
}
void NavigationActionManager::registerAction(NavigationItem *item, QString text,
std::function<void()> functor)
{
auto item_it = p->item_functions.find(item);
if (item_it == p->item_functions.end())
{
// create a new reference
QList<std::pair<QString, std::function<void()>>> list;
list.append(std::make_pair(text, functor));
p->item_functions.insert(item, list);
}
else
{
item_it.value().append(std::make_pair(text, functor));
}
}
void NavigationActionManager::itemActions(NavigationItem *item,
QMenu *menu) const
{
//
// Get the list of functors
auto functor_it = p->item_functions.find(item);
if (functor_it == p->item_functions.end()) return;
auto &list = functor_it.value();
for (int i = 0; i < list.length(); ++i)
{
menu->addAction(list[i].first, list[i].second);
}
}
} // namespace radix
#ifndef RADIX_RADIXWIDGETS_NAVIGATIONACTIONMANAGER_HH_
#define RADIX_RADIXWIDGETS_NAVIGATIONACTIONMANAGER_HH_
#include <QAction>
#include <QList>
#include <QObject>
#include <functional>
#include <memory>
#include "radixwidgets/navigationitem.hh"
namespace radix
{
class NavigationActionManager : public QObject
{
Q_OBJECT
public:
NavigationActionManager(QObject *parent = nullptr);
void registerAction(NavigationItem *item, QString text,
std::function<void()> functor);
void itemActions(NavigationItem *item, QMenu *menu) const;
private:
class PImpl;
std::unique_ptr<PImpl, void (*)(PImpl *)> p;
};
} // namespace radix
#endif /** RADIX_RADIXWIDGETS_NAVIGATIONACTIONMANAGER_HH_ */
#include "radixwidgets/navigationitem.hh"
#include "radixbug/bug.hh"
#include <QList>
namespace radix
{
class NavigationItem::PImpl
{
public:
NavigationItem *parent = nullptr;
QList<NavigationItem *> children;
QList<QVariant> data;
bool checked = false;
int type = 0;
~PImpl();
};
NavigationItem::PImpl::~PImpl() { qDeleteAll(children); }
NavigationItem::NavigationItem(QVariant data, NavigationItem *parentItem)
: p(new PImpl(), [](PImpl *impl) { delete impl; })
{
p->parent = parentItem;
p->data.append(data);
}
NavigationItem::NavigationItem(QList<QVariant> data, NavigationItem *parentItem)
: p(new PImpl(), [](PImpl *impl) { delete impl; })
{
p->parent = parentItem;
p->data = data;
}
NavigationItem::NavigationItem(NavigationItem *parentItem)
: p(new PImpl(), [](PImpl *impl) { delete impl; })
{
p->parent = parentItem;
}
int NavigationItem::type() const { return p->type; }
void NavigationItem::setType(int type) { p->type = type; }
void NavigationItem::addChild(NavigationItem *child)
{
p->children.append(child);
}
int NavigationItem::childCount() const { return p->children.size(); }
int NavigationItem::columnCount() const
{
// recursively find the largest number of columns from children
int count = p->data.size();
for (int ci = 0; ci < p->children.size(); ++ci)
{
count = std::max(count, p->children[ci]->columnCount());
}
return count;
}
QVariant NavigationItem::data(int column) const
{
if (column >= p->data.size()) return QVariant();
return p->data.value(column);
}
void NavigationItem::setData(int column, QVariant value)
{
int size = p->data.size();
for (int i = size; i <= column; ++i)
{
p->data.append(QVariant());
}
p->data[column] = value;
}
int NavigationItem::row() const
{
if (p->parent)
{
return p->parent->p->children.indexOf(const_cast<NavigationItem *>(this));
}
}
NavigationItem *NavigationItem::parentItem() { return p->parent; }
bool NavigationItem::isChecked() const { return p->checked; }
void NavigationItem::setChecked(bool checked) { p->checked = checked; }
NavigationItem *NavigationItem::child(int row)
{
return p->children.value(row);
}
} // namespace radix
#ifndef RADIX_RADIXWIDGETS_NAVIGATIONITEM_HH_
#define RADIX_RADIXWIDGETS_NAVIGATIONITEM_HH_
#include <QVariant>
#include <memory>
namespace radix
{
class NavigationItem
{
public:
NavigationItem(QVariant data, NavigationItem *parentItem = nullptr);
NavigationItem(QList<QVariant> data, NavigationItem *parentItem = nullptr);
NavigationItem(NavigationItem *parentItem = nullptr);
int type() const;
void setType(int type);
void addChild(NavigationItem *child);
NavigationItem *child(int row);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
void setData(int column, QVariant value);
int row() const;
NavigationItem *parentItem();
bool isChecked() const;
void setChecked(bool checked);
private:
class PImpl;
std::unique_ptr<PImpl, void (*)(PImpl *)> p;
};
} // namespace radix
#endif
#include "radixwidgets/navigationmodel.hh"
#include "radixwidgets/navigationitem.hh"
#include "radixbug/bug.hh"
#include <QList>
namespace radix
{
class NavigationModel::PImpl
{
public:
NavigationItem* root = nullptr;
~PImpl();
};
NavigationModel::PImpl::~PImpl()
{
if (root) delete root;
}
NavigationModel::NavigationModel(QObject* parent)
: QAbstractItemModel(parent)
, p(new PImpl(), [](PImpl* impl) { delete impl; })
{
p->root = new NavigationItem();
}
QVariant NavigationModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid()) return QVariant();
NavigationItem* item = static_cast<NavigationItem*>(index.internalPointer());
if (Qt::CheckStateRole == role && index.column() == 0)
return static_cast<int>(item->isChecked() ? Qt::Checked : Qt::Unchecked);
if (role != Qt::DisplayRole) return QVariant();
return item->data(index.column());
}
bool NavigationModel::setData(const QModelIndex& index, const QVariant& value,
int role)
{
if (Qt::CheckStateRole == role)
{
NavigationItem* item =
static_cast<NavigationItem*>(index.internalPointer());
item->setChecked(value.toBool());
// signal selection/deselection
if (item->isChecked())
emit itemChecked(index);
else
emit itemUnChecked(index);
return true;
}
return false;
}
Qt::ItemFlags NavigationModel::flags(const QModelIndex& index) const
{
if (!index.isValid()) return QAbstractItemModel::flags(index);
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (index.column() == 0) flags |= Qt::ItemIsUserCheckable;
return flags;
}
QVariant NavigationModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return p->root->data(section);
return QVariant();
}
QModelIndex NavigationModel::index(int row, int column,
const QModelIndex& parent) const
{
if (!hasIndex(row, column, parent)) return QModelIndex();
NavigationItem* parentItem;
if (!parent.isValid())
parentItem = p->root;
else
parentItem = static_cast<NavigationItem*>(parent.internalPointer());
NavigationItem* childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex NavigationModel::parent(const QModelIndex