Commit 04367f0b authored by Jasem Mutlaq's avatar Jasem Mutlaq

More progress. Motion and speed controls work. WIll implement the rest soon....

More progress. Motion and speed controls work. WIll implement the rest soon. The GUI needs improvement in coloring, sizes, theming, separators..etc
parent f762a15b
......@@ -1036,5 +1036,7 @@ if(NOT BUILD_KSTARS_LITE)
install(FILES kstars.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR})
if(INDI_FOUND)
install(FILES ekos/mount/mountbox.qml DESTINATION ${KDE_INSTALL_DATADIR}/kstars/ekos/mount/qml)
install(DIRECTORY ekos/mount/ DESTINATION ${KDE_INSTALL_DATADIR}/kstars/ekos/mount/qml
FILES_MATCHING PATTERN "*.png")
endif()
endif(NOT BUILD_KSTARS_LITE)
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1408 960v-128q0-26-19-45t-45-19h-502l189-189q19-19 19-45t-19-45l-91-91q-18-18-45-18t-45 18l-362 362-91 91q-18 18-18 45t18 45l91 91 362 362q18 18 45 18t45-18l91-91q18-18 18-45t-18-45l-189-189h502q26 0 45-19t19-45zm256-64q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/></svg>
\ No newline at end of file
......@@ -83,6 +83,8 @@ Mount::Mount()
connect(stopB, SIGNAL(clicked()), this, SLOT(stop()));
connect(saveB, SIGNAL(clicked()), this, SLOT(save()));
connect(slewSpeedCombo, SIGNAL(activated(int)), this, SLOT(setSlewRate(int)));
connect(minAltLimit, SIGNAL(editingFinished()), this, SLOT(saveLimits()));
connect(maxAltLimit, SIGNAL(editingFinished()), this, SLOT(saveLimits()));
......@@ -105,9 +107,21 @@ Mount::Mount()
// QML Stuff
m_BaseView = new QQuickView();
QString MountBox_Location = KSPaths::locate(QStandardPaths::AppDataLocation, "ekos/mount/qml/mountbox.qml");
QString MountBox_Location;
#if defined(Q_OS_OSX)
MountBox_Location = QCoreApplication::applicationDirPath()+"/../Resources/data/ekos/mount/qml/mountbox.qml";
if(!QFileInfo(MountBox_Location).exists())
MountBox_Location = KSPaths::locate(QStandardPaths::AppDataLocation, "ekos/mount/qml/mountbox.qml");
#elif defined(Q_OS_WIN)
MountBox_Location = KSPaths::locate(QStandardPaths::GenericDataLocation, "ekos/mount/qml/mountbox.qml");
#else
MountBox_Location = KSPaths::locate(QStandardPaths::AppDataLocation, "ekos/mount/qml/mountbox.qml");
#endif
m_BaseView->setSource(QUrl::fromLocalFile(MountBox_Location));
m_BaseView->setTitle(i18n("Mount Tool Box"));
m_BaseView->setTitle(i18n("Mount Control"));
// Theming?
m_BaseView->setColor(Qt::black);
m_BaseObj = m_BaseView->rootObject();
......@@ -116,7 +130,20 @@ Mount::Mount()
///Use instead of KDeclarative
m_Ctxt->setContextObject(new KLocalizedContext(m_BaseView));
m_BaseView->setResizeMode(QQuickView::SizeRootObjectToView);
m_Ctxt->setContextProperty("mount", this);
m_BaseView->setMaximumSize(QSize(200, 480));
m_BaseView->setMinimumSize(QSize(200, 480));
m_SpeedSlider = m_BaseObj->findChild<QQuickItem *>("speedSliderObject");
m_SpeedLabel = m_BaseObj->findChild<QQuickItem *>("speedLabelObject");
m_raValue = m_BaseObj->findChild<QQuickItem *>("raValueObject");
m_deValue = m_BaseObj->findChild<QQuickItem *>("deValueObject");
m_azValue = m_BaseObj->findChild<QQuickItem *>("azValueObject");
m_altValue = m_BaseObj->findChild<QQuickItem *>("altValueObject");
m_haValue = m_BaseObj->findChild<QQuickItem *>("haValueObject");
m_zaValue = m_BaseObj->findChild<QQuickItem *>("zaValueObject");
}
Mount::~Mount()
......@@ -189,13 +216,22 @@ void Mount::syncTelescopeInfo()
slewSpeedCombo->addItem(i18nc(libindi_strings_context, svp->sp[i].label));
int index = IUFindOnSwitchIndex(svp);
slewSpeedCombo->setCurrentIndex(index);
connect(slewSpeedCombo, SIGNAL(activated(int)), currentTelescope, SLOT(setSlewRate(int)), Qt::UniqueConnection);
slewSpeedCombo->setCurrentIndex(index);
// QtQuick
m_SpeedSlider->setEnabled(true);
m_SpeedSlider->setProperty("to", svp->nsp-1);
m_SpeedSlider->setProperty("value", index);
m_SpeedLabel->setProperty("text", slewSpeedCombo->currentText());
m_SpeedLabel->setEnabled(true);
}
else
{
slewSpeedCombo->setEnabled(false);
disconnect(slewSpeedCombo, SIGNAL(activated(int)), currentTelescope, SLOT(setSlewRate(int)));
// QtQuick
m_SpeedSlider->setEnabled(false);
m_SpeedLabel->setEnabled(false);
}
if (currentTelescope->canPark())
......@@ -226,9 +262,14 @@ void Mount::updateTelescopeCoords()
telescopeCoord.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
raOUT->setText(telescopeCoord.ra().toHMSString());
m_raValue->setProperty("text", telescopeCoord.ra().toHMSString());
decOUT->setText(telescopeCoord.dec().toDMSString());
m_deValue->setProperty("text", telescopeCoord.dec().toDMSString());
azOUT->setText(telescopeCoord.az().toDMSString());
m_azValue->setProperty("text", telescopeCoord.az().toDMSString());
altOUT->setText(telescopeCoord.alt().toDMSString());
m_altValue->setProperty("text", telescopeCoord.alt().toDMSString());
dms lst = KStarsData::Instance()->geo()->GSTtoLST( KStarsData::Instance()->clock()->utc().gst() );
dms ha( lst.Degrees() - telescopeCoord.ra().Degrees() );
......@@ -239,10 +280,14 @@ void Mount::updateTelescopeCoords()
sgn = '-';
}
haOUT->setText( QString("%1%2").arg(sgn).arg( ha.toHMSString() ) );
m_haValue->setProperty("text", haOUT->text());
lstOUT->setText(lst.toHMSString());
double currentAlt = telescopeCoord.altRefracted().Degrees();
m_zaValue->setProperty("text", dms(90-currentAlt).toDMSString());
if (minAltLimit->isEnabled()
&& ( currentAlt < minAltLimit->value() || currentAlt > maxAltLimit->value()))
{
......@@ -327,12 +372,27 @@ void Mount::updateNumber(INumberVectorProperty * nvp)
}
}
bool Mount::setSlewRate(int index)
{
if (currentTelescope && slewSpeedCombo->isEnabled())
return currentTelescope->setSlewRate(index);
return false;
}
void Mount::updateSwitch(ISwitchVectorProperty * svp)
{
if (!strcmp(svp->name, "TELESCOPE_SLEW_RATE"))
{
int index = IUFindOnSwitchIndex(svp);
slewSpeedCombo->blockSignals(true);
slewSpeedCombo->setCurrentIndex(index);
slewSpeedCombo->blockSignals(false);
m_SpeedSlider->setProperty("value", index);
m_SpeedLabel->setProperty("text", slewSpeedCombo->currentText());
}
/*else if (!strcmp(svp->name, "TELESCOPE_PARK"))
{
......@@ -372,6 +432,19 @@ void Mount::clearLog()
emit newLog();
}
void Mount::motionCommand(int command, int NS, int WE)
{
if (NS != -1)
{
currentTelescope->MoveNS(static_cast<ISD::Telescope::TelescopeMotionNS>(NS), static_cast<ISD::Telescope::TelescopeMotionCommand>(command));
}
if (WE != -1)
{
currentTelescope->MoveWE(static_cast<ISD::Telescope::TelescopeMotionWE>(WE), static_cast<ISD::Telescope::TelescopeMotionCommand>(command));
}
}
void Mount::move()
{
QObject * obj = sender();
......@@ -579,6 +652,14 @@ bool Mount::slew(double RA, double DEC)
return currentTelescope->Slew(RA, DEC);
}
bool Mount::sync(double RA, double DEC)
{
if (currentTelescope == NULL || currentTelescope->isConnected() == false)
return false;
return currentTelescope->Sync(RA, DEC);
}
bool Mount::abort()
{
return currentTelescope->Abort();
......
......@@ -85,12 +85,20 @@ class Mount : public QWidget, public Ui::Mount
* @param DEC Declination in degrees.
* @return true if the command is sent successfully, false otherwise.
*/
Q_SCRIPTABLE bool slew(double RA, double DEC);
Q_INVOKABLE Q_SCRIPTABLE bool slew(double RA, double DEC);
/** DBUS interface function.
* Sync the mount to the RA/DEC (JNow).
* @param RA Right ascention is hours.
* @param DEC Declination in degrees.
* @return true if the command is sent successfully, false otherwise.
*/
Q_INVOKABLE Q_SCRIPTABLE bool sync(double RA, double DEC);
/** DBUS interface function.
* Get equatorial coords (JNow). An array of doubles is returned. First element is RA in hours. Second elements is DEC in degrees.
*/
Q_SCRIPTABLE QList<double> getEquatorialCoords();
Q_INVOKABLE Q_SCRIPTABLE QList<double> getEquatorialCoords();
/** DBUS interface function.
* Get Horizontal coords. An array of doubles is returned. First element is Azimuth in degrees. Second elements is Altitude in degrees.
......@@ -106,18 +114,18 @@ class Mount : public QWidget, public Ui::Mount
* Aborts the mount motion
* @return true if the command is sent successfully, false otherwise.
*/
Q_SCRIPTABLE bool abort();
Q_INVOKABLE Q_SCRIPTABLE bool abort();
/** DBUS interface function.
* Get the mount slew status ("Idle","Complete", "Busy", "Error")
*/
Q_SCRIPTABLE IPState getSlewStatus();
Q_INVOKABLE Q_SCRIPTABLE IPState getSlewStatus();
/** DBUS interface function.
* Get telescope and guide scope info. An array of doubles is returned in order.
* Primary Telescope Focal Length (mm), Primary Telescope Aperture (mm), Guide Telescope Focal Length (mm), Guide Telescope Aperture (mm)
*/
Q_SCRIPTABLE QList<double> getTelescopeInfo();
Q_INVOKABLE Q_SCRIPTABLE QList<double> getTelescopeInfo();
/** DBUS interface function.
* Set telescope and guide scope info. All measurements is in millimeters.
......@@ -131,22 +139,24 @@ class Mount : public QWidget, public Ui::Mount
/** DBUS interface function.
* Can mount park?
*/
Q_SCRIPTABLE bool canPark();
Q_INVOKABLE Q_SCRIPTABLE bool canPark();
/** DBUS interface function.
* Park mount
*/
Q_SCRIPTABLE bool park();
Q_INVOKABLE Q_SCRIPTABLE bool park();
/** DBUS interface function.
* Unpark mount
*/
Q_SCRIPTABLE bool unpark();
Q_INVOKABLE Q_SCRIPTABLE bool unpark();
/** DBUS interface function.
* Return parking status of the mount.
*/
Q_SCRIPTABLE ParkingStatus getParkingStatus();
Q_INVOKABLE Q_SCRIPTABLE ParkingStatus getParkingStatus();
Q_INVOKABLE bool setSlewRate(int index);
/** @}*/
......@@ -185,6 +195,14 @@ class Mount : public QWidget, public Ui::Mount
*/
void move();
/**
* @brief move Issues motion command to the mount to move in a particular direction based the request NS and WE values
* @param command Either ISD::Telescope::MOTION_START (0) or ISD::Telescope::MOTION_STOP (1)
* @param NS is either -1 for no direction, or ISD::Telescope::MOTION_NORTH (0), or ISD::Telescope::MOTION_SOUTH (1)
* @param WE is either -1 for no direction, or ISD::Telescope::MOTION_WEST (0), or ISD::Telescope::MOTION_EAST (1)
*/
void motionCommand(int command, int NS, int WE);
/**
* @brief stop Aborts telescope motion
*/
......@@ -241,6 +259,9 @@ class Mount : public QWidget, public Ui::Mount
QQuickItem * m_BaseObj=nullptr;
QQmlContext * m_Ctxt=nullptr;
QQuickItem * m_SpeedSlider=nullptr, *m_SpeedLabel=nullptr, *m_raValue=nullptr, *m_deValue=nullptr,
*m_azValue=nullptr, *m_altValue=nullptr, *m_haValue=nullptr, *m_zaValue=nullptr;
};
}
......
......@@ -160,7 +160,7 @@
<item>
<widget class="QPushButton" name="mountToolBoxB">
<property name="text">
<string>Mount Tool Box</string>
<string>Mount Control Box</string>
</property>
</widget>
</item>
......@@ -297,13 +297,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearAlignmentModelB">
<property name="text">
<string>Clear Alignment Model</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
......@@ -317,6 +310,13 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="clearAlignmentModelB">
<property name="text">
<string>Clear Alignment Model</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
......
......@@ -2,62 +2,623 @@ import QtQuick 2.5
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1
Item {
width: 320
Rectangle {
id: rectangle
width: 200
height: 480
color: "#000000"
property color buttonColor: "gainsboro"
ColumnLayout {
id: mainVerticalLayout
anchors.fill: parent
ColumnLayout
{
id: columnLayout
GridLayout {
id: gridLayout
anchors.fill: parent
id: mountMotionLayout
width: 200
height: 150
Layout.minimumHeight: 150
Layout.minimumWidth: 200
Layout.maximumHeight: 150
Layout.maximumWidth: 200
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.fillWidth: true
rows: 3
columns: 3
Button
{
id: northWest
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: northWest.pressed ? "red" : rectangle.buttonColor
}
onPressAndHold:
{
mount.motionCommand(0, 0, 0);
}
onReleased:
{
mount.motionCommand(1, 0, 0);
}
Image {
width: 50
anchors.fill: parent
source: "go-northwest.png"
}
}
Button {
id: neButton
Image
id: north
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: north.pressed ? "red" : rectangle.buttonColor
}
onPressAndHold:
{
mount.motionCommand(0, 0, -1);
}
onReleased:
{
source: "qrc:/icons/go-nw.svg"
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
mount.motionCommand(1, 0, -1);
}
Image {
width: 50
anchors.fill: parent
source: "go-north.png"
}
}
Button {
id: button1
id: northEast
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: northEast.pressed ? "red" : rectangle.buttonColor
}
onPressAndHold:
{
mount.motionCommand(0, 0, 1);
}
onReleased:
{
mount.motionCommand(1, 0, 1);
}
Image {
width: 50
anchors.fill: parent
source: "go-northeast.png"
}
}
Button {
id: button2
id: west
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: west.pressed ? "red" : rectangle.buttonColor
}
onPressAndHold:
{
mount.motionCommand(0, -1, 0);
}
onReleased:
{
mount.motionCommand(1, -1, 0);
}
Image {
width: 50
anchors.fill: parent
source: "go-west.png"
}
}
Button {
id: button3
id: stop
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: stop.pressed ? "red" : rectangle.buttonColor
}
Image {
width: 50
anchors.fill: parent
source: "stop.png"
}
onClicked:
{
mount.abort();
}
}
Button {
id: button4
id: east
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: east.pressed ? "red" : rectangle.buttonColor
}
onPressAndHold:
{
mount.motionCommand(0, -1, 1);
}
onReleased:
{
mount.motionCommand(1, -1, 1);
}
Image {
width: 50
anchors.fill: parent
source: "go-east.png"
}
}
Button {
id: button5
id: southWest
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: southWest.pressed ? "red" : rectangle.buttonColor
}
onPressAndHold:
{
mount.motionCommand(0, 1, 0);
}
onReleased:
{
mount.motionCommand(1, 1, 0);
}
Image {
width: 50
anchors.fill: parent
source: "go-southwest.png"
}
}
Button {
id: button6
id: south
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: south.pressed ? "red" : rectangle.buttonColor
}
onPressAndHold:
{
mount.motionCommand(0, 1, -1);
}
onReleased:
{
mount.motionCommand(1, 1, -1);
}
Image {
width: 50
anchors.fill: parent
source: "go-south.png"
}
}
Button {
id: button7
id: southEast
width: 52
height: 54
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle
{
color: southEast.pressed ? "red" : rectangle.buttonColor
}
onPressAndHold:
{
mount.motionCommand(0, 1, 1);
}
onReleased:
{
mount.motionCommand(1, 1, 1);
}