Grid-view for the launcher
This commit is contained in:
parent
df810f7970
commit
0239d5ef44
13 changed files with 462 additions and 121 deletions
|
@ -106,6 +106,8 @@ LauncherController::LauncherController(QObject *parent, QWindow* window) :
|
||||||
LocalAircraftCache::instance()->scanDirs();
|
LocalAircraftCache::instance()->scanDirs();
|
||||||
m_aircraftModel->setPackageRoot(globals->packageRoot());
|
m_aircraftModel->setPackageRoot(globals->packageRoot());
|
||||||
|
|
||||||
|
m_aircraftGridMode = settings.value("aircraftGridMode").toBool();
|
||||||
|
|
||||||
m_subsystemIdleTimer = new QTimer(this);
|
m_subsystemIdleTimer = new QTimer(this);
|
||||||
m_subsystemIdleTimer->setInterval(10);
|
m_subsystemIdleTimer->setInterval(10);
|
||||||
connect(m_subsystemIdleTimer, &QTimer::timeout, []()
|
connect(m_subsystemIdleTimer, &QTimer::timeout, []()
|
||||||
|
@ -821,13 +823,24 @@ void LauncherController::saveConfigAs()
|
||||||
m_config->saveConfigToFile(file);
|
m_config->saveConfigToFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LauncherController::setAircraftGridMode(bool aircraftGridMode)
|
||||||
|
{
|
||||||
|
if (m_aircraftGridMode == aircraftGridMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue("aircraftGridMode", aircraftGridMode);
|
||||||
|
m_aircraftGridMode = aircraftGridMode;
|
||||||
|
emit aircraftGridModeChanged(m_aircraftGridMode);
|
||||||
|
}
|
||||||
|
|
||||||
void LauncherController::setMinWindowSize(QSize sz)
|
void LauncherController::setMinWindowSize(QSize sz)
|
||||||
{
|
{
|
||||||
if (sz == m_minWindowSize)
|
if (sz == m_minWindowSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_window->setMinimumSize(sz);
|
m_window->setMinimumSize(sz);
|
||||||
emit minWindowSizeChanged();
|
emit minWindowSizeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl LauncherController::flyIconUrl() const
|
QUrl LauncherController::flyIconUrl() const
|
||||||
|
|
|
@ -86,6 +86,7 @@ class LauncherController : public QObject
|
||||||
|
|
||||||
Q_PROPERTY(QUrl flyIconUrl READ flyIconUrl NOTIFY selectedAircraftChanged)
|
Q_PROPERTY(QUrl flyIconUrl READ flyIconUrl NOTIFY selectedAircraftChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool aircraftGridMode READ aircraftGridMode WRITE setAircraftGridMode NOTIFY aircraftGridModeChanged)
|
||||||
public:
|
public:
|
||||||
explicit LauncherController(QObject *parent, QWindow* win);
|
explicit LauncherController(QObject *parent, QWindow* win);
|
||||||
|
|
||||||
|
@ -187,6 +188,11 @@ public:
|
||||||
|
|
||||||
QUrl flyIconUrl() const;
|
QUrl flyIconUrl() const;
|
||||||
|
|
||||||
|
bool aircraftGridMode() const
|
||||||
|
{
|
||||||
|
return m_aircraftGridMode;
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void selectedAircraftChanged(QUrl selectedAircraft);
|
void selectedAircraftChanged(QUrl selectedAircraft);
|
||||||
|
@ -199,6 +205,8 @@ signals:
|
||||||
|
|
||||||
void viewCommandLine();
|
void viewCommandLine();
|
||||||
|
|
||||||
|
void aircraftGridModeChanged(bool aircraftGridMode);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setSelectedAircraft(QUrl selectedAircraft);
|
void setSelectedAircraft(QUrl selectedAircraft);
|
||||||
|
|
||||||
|
@ -217,6 +225,8 @@ public slots:
|
||||||
|
|
||||||
void openConfig();
|
void openConfig();
|
||||||
void saveConfigAs();
|
void saveConfigAs();
|
||||||
|
void setAircraftGridMode(bool aircraftGridMode);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void onAircraftInstalledCompleted(QModelIndex index);
|
void onAircraftInstalledCompleted(QModelIndex index);
|
||||||
|
@ -271,6 +281,7 @@ private:
|
||||||
bool m_inAppMode = false;
|
bool m_inAppMode = false;
|
||||||
bool m_keepRunningInAppMode = false;
|
bool m_keepRunningInAppMode = false;
|
||||||
bool m_appModeResult = true;
|
bool m_appModeResult = true;
|
||||||
|
bool m_aircraftGridMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LAUNCHERCONTROLLER_HXX
|
#endif // LAUNCHERCONTROLLER_HXX
|
||||||
|
|
6
src/GUI/assets/icons8-grid-view.svg
Normal file
6
src/GUI/assets/icons8-grid-view.svg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" version="1.1" fill="#1b7ad3" width="24px" height="24px">
|
||||||
|
<g id="surface1" fill="#1b7ad3">
|
||||||
|
<path style=" " d="M 4 4 L 4 8 L 8 8 L 8 4 Z M 10 4 L 10 8 L 14 8 L 14 4 Z M 16 4 L 16 8 L 20 8 L 20 4 Z M 4 10 L 4 14 L 8 14 L 8 10 Z M 10 10 L 10 14 L 14 14 L 14 10 Z M 16 10 L 16 14 L 20 14 L 20 10 Z M 4 16 L 4 20 L 8 20 L 8 16 Z M 10 16 L 10 20 L 14 20 L 14 16 Z M 16 16 L 16 20 L 20 20 L 20 16 Z " fill="#1b7ad3"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After (image error) Size: 564 B |
6
src/GUI/assets/icons8-menu.svg
Normal file
6
src/GUI/assets/icons8-menu.svg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 26 26" version="1.1" fill="#1b7ad3" width="26px" height="26px">
|
||||||
|
<g id="surface1" fill="#1b7ad3">
|
||||||
|
<path style=" " d="M 0 4 L 0 6 L 26 6 L 26 4 Z M 0 12 L 0 14 L 26 14 L 26 12 Z M 0 20 L 0 22 L 26 22 L 26 20 Z " fill="#1b7ad3"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After (image error) Size: 374 B |
96
src/GUI/qml/AircraftGridDelegate.qml
Normal file
96
src/GUI/qml/AircraftGridDelegate.qml
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import QtQuick 2.4
|
||||||
|
import FlightGear.Launcher 1.0
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
signal select(var uri);
|
||||||
|
signal showDetails(var uri)
|
||||||
|
|
||||||
|
readonly property bool __isSelected: (_launcher.selectedAircraft === model.uri)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width - 4
|
||||||
|
height: parent.height - 4
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#dfdfdf"
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouse
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (__isSelected) {
|
||||||
|
root.showDetails(model.uri)
|
||||||
|
} else {
|
||||||
|
root.select(model.uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: contentBox
|
||||||
|
width: parent.width
|
||||||
|
y: Style.margin
|
||||||
|
spacing: 2 //
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: thumbnailBox
|
||||||
|
width: 172
|
||||||
|
height: 128
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#7f7f7f"
|
||||||
|
width: thumbnail.width
|
||||||
|
height: thumbnail.height
|
||||||
|
|
||||||
|
ThumbnailImage {
|
||||||
|
id: thumbnail
|
||||||
|
aircraftUri: model.uri
|
||||||
|
maximumSize.width: 172
|
||||||
|
maximumSize.height: 128
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
visible: hover.containsMouse && (model.packageStatus === LocalAircraftCache.PackageNotInstalled)
|
||||||
|
text: qsTr("Install")
|
||||||
|
onClicked: {
|
||||||
|
// drill down and also start the install
|
||||||
|
_launcher.requestInstallUpdate(model.uri)
|
||||||
|
root.showDetails(model.uri)
|
||||||
|
}
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AircraftVariantChoice {
|
||||||
|
id: titleBox
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
popupFontPixelSize: Style.baseFontPixelSize
|
||||||
|
aircraft: model.uri;
|
||||||
|
currentIndex: model.activeVariant
|
||||||
|
onSelected: {
|
||||||
|
model.activeVariant = index
|
||||||
|
root.select(model.uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: hover
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
}
|
||||||
|
} // of root item
|
77
src/GUI/qml/AircraftGridView.qml
Normal file
77
src/GUI/qml/AircraftGridView.qml
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import FlightGear.Launcher 1.0 as FG
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias model: view.model
|
||||||
|
property alias header: view.header
|
||||||
|
|
||||||
|
signal showDetails(var uri);
|
||||||
|
|
||||||
|
function updateSelectionFromLauncher()
|
||||||
|
{
|
||||||
|
var row = model.indexForURI(_launcher.selectedAircraft);
|
||||||
|
if (row >= 0) {
|
||||||
|
view.currentIndex = row;
|
||||||
|
} else {
|
||||||
|
// clear selection in view, so we don't show something
|
||||||
|
// erroneous such as the previous value
|
||||||
|
view.currentIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onModelChanged: updateSelectionFromLauncher();
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: highlight
|
||||||
|
Rectangle {
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "#98A3B4" }
|
||||||
|
GradientStop { position: 1.0; color: "#5A6B83" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: view
|
||||||
|
cellWidth: width / colCount
|
||||||
|
cellHeight: 128 + Style.strutSize
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
|
||||||
|
readonly property int baseCellWidth: 172 + (Style.strutSize * 2)
|
||||||
|
readonly property int colCount: Math.floor(width / baseCellWidth)
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
right: scrollbar.left
|
||||||
|
topMargin: Style.margin
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: AircraftGridDelegate {
|
||||||
|
width: view.cellWidth
|
||||||
|
height: view.cellHeight
|
||||||
|
|
||||||
|
onSelect: {
|
||||||
|
view.currentIndex = model.index;
|
||||||
|
_launcher.selectedAircraft = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
onShowDetails: root.showDetails(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
focus: true
|
||||||
|
highlight: highlight
|
||||||
|
}
|
||||||
|
|
||||||
|
Scrollbar {
|
||||||
|
id: scrollbar
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
height: view.height
|
||||||
|
flickable: view
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,8 +6,15 @@ FocusScope
|
||||||
{
|
{
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Component.onCompleted: {
|
property var __model: null
|
||||||
aircraftList.updateSelectionFromLauncher();
|
property Component __header: null
|
||||||
|
property string __lastState: "installed"
|
||||||
|
|
||||||
|
function updateSelectionFromLauncher()
|
||||||
|
{
|
||||||
|
if (aircraftContent.item) {
|
||||||
|
aircraftContent.item.updateSelectionFromLauncher();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle
|
Rectangle
|
||||||
|
@ -16,6 +23,14 @@ FocusScope
|
||||||
height: searchButton.height + (Style.margin * 2)
|
height: searchButton.height + (Style.margin * 2)
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
GridToggleButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.margin
|
||||||
|
gridMode: !_launcher.aircraftGridMode
|
||||||
|
onClicked: _launcher.aircraftGridMode = !_launcher.aircraftGridMode
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Style.margin
|
spacing: Style.margin
|
||||||
|
@ -25,7 +40,7 @@ FocusScope
|
||||||
text: qsTr("Installed Aircraft")
|
text: qsTr("Installed Aircraft")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.state = "installed"
|
root.state = "installed"
|
||||||
aircraftList.updateSelectionFromLauncher();
|
root.updateSelectionFromLauncher();
|
||||||
}
|
}
|
||||||
active: root.state == "installed"
|
active: root.state == "installed"
|
||||||
}
|
}
|
||||||
|
@ -35,7 +50,7 @@ FocusScope
|
||||||
text: qsTr("Browse")
|
text: qsTr("Browse")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.state = "browse"
|
root.state = "browse"
|
||||||
aircraftList.updateSelectionFromLauncher();
|
root.updateSelectionFromLauncher();
|
||||||
}
|
}
|
||||||
active: root.state == "browse"
|
active: root.state == "browse"
|
||||||
}
|
}
|
||||||
|
@ -46,7 +61,7 @@ FocusScope
|
||||||
text: qsTr("Updates")
|
text: qsTr("Updates")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.state = "updates"
|
root.state = "updates"
|
||||||
aircraftList.updateSelectionFromLauncher();
|
root.updateSelectionFromLauncher();
|
||||||
}
|
}
|
||||||
active: root.state == "updates"
|
active: root.state == "updates"
|
||||||
}
|
}
|
||||||
|
@ -64,7 +79,7 @@ FocusScope
|
||||||
onSearch: {
|
onSearch: {
|
||||||
_launcher.searchAircraftModel.setAircraftFilterString(term)
|
_launcher.searchAircraftModel.setAircraftFilterString(term)
|
||||||
root.state = "search"
|
root.state = "search"
|
||||||
aircraftList.updateSelectionFromLauncher();
|
root.updateSelectionFromLauncher();
|
||||||
}
|
}
|
||||||
|
|
||||||
active: root.state == "search"
|
active: root.state == "search"
|
||||||
|
@ -80,90 +95,65 @@ FocusScope
|
||||||
anchors.top: tabBar.bottom
|
anchors.top: tabBar.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: highlight
|
|
||||||
Rectangle {
|
|
||||||
gradient: Gradient {
|
|
||||||
GradientStop { position: 0.0; color: "#98A3B4" }
|
|
||||||
GradientStop { position: 1.0; color: "#5A6B83" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: ratingsHeader
|
id: ratingsHeader
|
||||||
AircraftRatingsPanel {
|
AircraftRatingsPanel {
|
||||||
width: aircraftList.width - Style.strutSize * 2
|
width: aircraftContent.width
|
||||||
x: (aircraftList.width - width) / 2
|
onClearSelection: {
|
||||||
theList: aircraftList
|
_launcher.selectedAircraft = "";
|
||||||
|
root.updateSelectionFromLauncher()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: noDefaultCatalogHeader
|
id: noDefaultCatalogHeader
|
||||||
NoDefaultCatalogPanel {
|
NoDefaultCatalogPanel {
|
||||||
width: aircraftList.width - Style.strutSize * 2
|
width: aircraftContent.width
|
||||||
x: (aircraftList.width - width) / 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: updateAllHeader
|
id: updateAllHeader
|
||||||
UpdateAllPanel {
|
UpdateAllPanel {
|
||||||
width: aircraftList.width - Style.strutSize * 2
|
width: aircraftContent.width
|
||||||
x: (aircraftList.width - width) / 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
Component {
|
||||||
id: aircraftList
|
id: emptyHeader
|
||||||
|
Item {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: aircraftContent
|
||||||
|
source: _launcher.aircraftGridMode ? "qrc:///qml/AircraftGridView.qml"
|
||||||
|
: "qrc:///qml/AircraftListView.qml"
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
top: tabBarDivider.bottom
|
top: tabBarDivider.bottom
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
right: scrollbar.left
|
right: parent.right
|
||||||
topMargin: Style.margin
|
topMargin: Style.margin
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: AircraftCompactDelegate {
|
Binding {
|
||||||
onSelect: {
|
target: aircraftContent.item
|
||||||
aircraftList.currentIndex = model.index;
|
property: "model"
|
||||||
_launcher.selectedAircraft = uri;
|
value: root.__model
|
||||||
}
|
|
||||||
|
|
||||||
onShowDetails: root.showDetails(uri)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clip: true
|
Binding {
|
||||||
focus: true
|
target: aircraftContent.item
|
||||||
|
property: "header"
|
||||||
|
value: root.__header
|
||||||
|
}
|
||||||
|
|
||||||
// prevent mouse wheel interactions when the details view is
|
Connections {
|
||||||
// visible, since it has its own flickable
|
target: aircraftContent.item
|
||||||
enabled: !detailsView.visible
|
onShowDetails: root.showDetails(uri)
|
||||||
|
|
||||||
highlight: highlight
|
|
||||||
highlightMoveDuration: __realHighlightMoveDuration
|
|
||||||
|
|
||||||
// saved here becuase we need to reset highlightMoveDuration
|
|
||||||
// when doing a progrmatic set
|
|
||||||
readonly property int __realHighlightMoveDuration: 200
|
|
||||||
|
|
||||||
function updateSelectionFromLauncher()
|
|
||||||
{
|
|
||||||
model.selectVariantForAircraftURI(_launcher.selectedAircraft);
|
|
||||||
var row = model.indexForURI(_launcher.selectedAircraft);
|
|
||||||
if (row >= 0) {
|
|
||||||
// sequence here is necessary so progrommatic moves
|
|
||||||
// are instant
|
|
||||||
highlightMoveDuration = 0;
|
|
||||||
currentIndex = row;
|
|
||||||
highlightMoveDuration = __realHighlightMoveDuration;
|
|
||||||
} else {
|
|
||||||
// clear selection in view, so we don't show something
|
|
||||||
// erroneous such as the previous value
|
|
||||||
currentIndex = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +163,7 @@ FocusScope
|
||||||
left: parent.left
|
left: parent.left
|
||||||
top: tabBar.bottom
|
top: tabBar.bottom
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
right: scrollbar.left
|
right: parent.right
|
||||||
}
|
}
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
@ -182,49 +172,42 @@ FocusScope
|
||||||
visible: (root.state == "updates") && (_launcher.aircraftWithUpdatesModel.count == 0)
|
visible: (root.state == "updates") && (_launcher.aircraftWithUpdatesModel.count == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
Scrollbar {
|
|
||||||
id: scrollbar
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: tabBar.bottom
|
|
||||||
height: aircraftList.height
|
|
||||||
flickable: aircraftList
|
|
||||||
}
|
|
||||||
|
|
||||||
state: "installed"
|
state: "installed"
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "installed"
|
name: "installed"
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: aircraftList
|
target: root
|
||||||
model: _launcher.installedAircraftModel
|
__model: _launcher.installedAircraftModel
|
||||||
|
__header: emptyHeader
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
State {
|
State {
|
||||||
name: "search"
|
name: "search"
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: aircraftList
|
target: root
|
||||||
model: _launcher.searchAircraftModel
|
__model: _launcher.searchAircraftModel
|
||||||
header: null
|
__header: emptyHeader
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
State {
|
State {
|
||||||
name: "browse"
|
name: "browse"
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: aircraftList
|
target: root
|
||||||
model: _launcher.browseAircraftModel
|
__model: _launcher.browseAircraftModel
|
||||||
header: _addOns.showNoOfficialHangar ? noDefaultCatalogHeader : ratingsHeader
|
__header: _addOns.showNoOfficialHangar ? noDefaultCatalogHeader : ratingsHeader
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
State {
|
State {
|
||||||
name: "updates"
|
name: "updates"
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: aircraftList
|
target: root
|
||||||
model: _launcher.aircraftWithUpdatesModel
|
__model: _launcher.aircraftWithUpdatesModel
|
||||||
header: (_launcher.aircraftWithUpdatesModel.count > 0) ? updateAllHeader : null
|
__header: (_launcher.aircraftWithUpdatesModel.count > 0) ? updateAllHeader : emptyHeader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -239,6 +222,8 @@ FocusScope
|
||||||
|
|
||||||
function goBack()
|
function goBack()
|
||||||
{
|
{
|
||||||
|
// details view can change the aircraft URI / variant
|
||||||
|
updateSelectionFromLauncher();
|
||||||
detailsView.visible = false;
|
detailsView.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,15 +235,9 @@ FocusScope
|
||||||
Button {
|
Button {
|
||||||
anchors { left: parent.left; top: parent.top; margins: Style.margin }
|
anchors { left: parent.left; top: parent.top; margins: Style.margin }
|
||||||
width: Style.strutSize
|
width: Style.strutSize
|
||||||
|
|
||||||
id: backButton
|
id: backButton
|
||||||
text: "< Back"
|
text: "< Back"
|
||||||
onClicked: {
|
onClicked: root.goBack();
|
||||||
// ensure that if the variant was changed inside the detailsView,
|
|
||||||
// that we update our selection correctly
|
|
||||||
aircraftList.updateSelectionFromLauncher();
|
|
||||||
root.goBack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
80
src/GUI/qml/AircraftListView.qml
Normal file
80
src/GUI/qml/AircraftListView.qml
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import FlightGear.Launcher 1.0 as FG
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias model: aircraftList.model
|
||||||
|
property alias header: aircraftList.header
|
||||||
|
|
||||||
|
signal showDetails(var uri);
|
||||||
|
|
||||||
|
function updateSelectionFromLauncher()
|
||||||
|
{
|
||||||
|
model.selectVariantForAircraftURI(_launcher.selectedAircraft);
|
||||||
|
var row = model.indexForURI(_launcher.selectedAircraft);
|
||||||
|
if (row >= 0) {
|
||||||
|
// sequence here is necessary so progrommatic moves
|
||||||
|
// are instant
|
||||||
|
aircraftList.highlightMoveDuration = 0;
|
||||||
|
aircraftList.currentIndex = row;
|
||||||
|
aircraftList.highlightMoveDuration = aircraftList.__realHighlightMoveDuration;
|
||||||
|
} else {
|
||||||
|
// clear selection in view, so we don't show something
|
||||||
|
// erroneous such as the previous value
|
||||||
|
aircraftList.currentIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onModelChanged: updateSelectionFromLauncher()
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: highlight
|
||||||
|
Rectangle {
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "#98A3B4" }
|
||||||
|
GradientStop { position: 1.0; color: "#5A6B83" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: aircraftList
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
right: scrollbar.left
|
||||||
|
topMargin: Style.margin
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: AircraftCompactDelegate {
|
||||||
|
onSelect: {
|
||||||
|
aircraftList.currentIndex = model.index;
|
||||||
|
_launcher.selectedAircraft = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
onShowDetails: root.showDetails(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
highlight: highlight
|
||||||
|
highlightMoveDuration: __realHighlightMoveDuration
|
||||||
|
|
||||||
|
// saved here becuase we need to reset highlightMoveDuration
|
||||||
|
// when doing a progrmatic set
|
||||||
|
readonly property int __realHighlightMoveDuration: 200
|
||||||
|
}
|
||||||
|
|
||||||
|
Scrollbar {
|
||||||
|
id: scrollbar
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
height: aircraftList.height
|
||||||
|
flickable: aircraftList
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,8 @@ import "."
|
||||||
|
|
||||||
ListHeaderBox
|
ListHeaderBox
|
||||||
{
|
{
|
||||||
property ListView theList: null
|
id: root
|
||||||
|
signal clearSelection();
|
||||||
|
|
||||||
contents: [
|
contents: [
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ ListHeaderBox
|
||||||
onClicked: {
|
onClicked: {
|
||||||
// clear selection so we don't jump to the selected item
|
// clear selection so we don't jump to the selected item
|
||||||
// each time the proxy model changes.
|
// each time the proxy model changes.
|
||||||
theList.currentIndex = -1;
|
root.clearSelection();
|
||||||
editRatingsPanel.visible = true
|
editRatingsPanel.visible = true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,13 @@ Rectangle {
|
||||||
|
|
||||||
implicitHeight: title.implicitHeight
|
implicitHeight: title.implicitHeight
|
||||||
|
|
||||||
radius: 4
|
radius: Style.roundRadius
|
||||||
border.color: Style.frameColor
|
border.color: Style.frameColor
|
||||||
border.width: headingMouseArea.containsMouse ? 1 : 0
|
border.width: headingMouseArea.containsMouse ? 1 : 0
|
||||||
color: headingMouseArea.containsMouse ? "#7fffffff" : "transparent"
|
color: headingMouseArea.containsMouse ? "#7fffffff" : "transparent"
|
||||||
|
|
||||||
|
readonly property int centerX: width / 2
|
||||||
|
|
||||||
readonly property bool __enabled: aircraftInfo.numVariants > 1
|
readonly property bool __enabled: aircraftInfo.numVariants > 1
|
||||||
|
|
||||||
property alias aircraft: aircraftInfo.uri
|
property alias aircraft: aircraftInfo.uri
|
||||||
|
@ -28,33 +30,53 @@ Rectangle {
|
||||||
|
|
||||||
signal selected(var index)
|
signal selected(var index)
|
||||||
|
|
||||||
Text {
|
|
||||||
id: title
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.right: upDownIcon.left
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 4
|
|
||||||
anchors.rightMargin: 4
|
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.pixelSize: Style.baseFontPixelSize * 2
|
|
||||||
text: aircraftInfo.name
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
|
|
||||||
elide: Text.ElideRight
|
|
||||||
maximumLineCount: 1
|
|
||||||
color: headingMouseArea.containsMouse ? Style.themeColor : Style.baseTextColor
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: upDownIcon
|
// Image {
|
||||||
source: "qrc:///up-down-arrow"
|
// id: upDownIcon
|
||||||
anchors.right: parent.right
|
// source: "qrc:///up-down-arrow"
|
||||||
anchors.rightMargin: 8
|
// x: root.centerX + Math.min(title.implicitWidth * 0.5, title.width * 0.5)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
// anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: __enabled
|
// visible: __enabled
|
||||||
|
// }
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: title.implicitHeight
|
||||||
|
width: childrenRect.width
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: title
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
// this ugly logic is to keep the up-down arrow at the right
|
||||||
|
// hand side of the text, but allow the font scaling to work if
|
||||||
|
// we're short on horizontal space
|
||||||
|
width: Math.min(implicitWidth,
|
||||||
|
root.width - (Style.margin * 2) - (__enabled ? upDownIcon.implicitWidth : 0))
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
font.pixelSize: Style.baseFontPixelSize * 2
|
||||||
|
text: aircraftInfo.name
|
||||||
|
fontSizeMode: Text.Fit
|
||||||
|
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
color: headingMouseArea.containsMouse ? Style.themeColor : Style.baseTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: upDownIcon
|
||||||
|
source: "qrc:///up-down-arrow"
|
||||||
|
// x: root.centerX + Math.min(title.implicitWidth * 0.5, title.width * 0.5)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: __enabled
|
||||||
|
width: __enabled ? implicitWidth : 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
43
src/GUI/qml/GridToggleButton.qml
Normal file
43
src/GUI/qml/GridToggleButton.qml
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
radius: Style.roundRadius
|
||||||
|
border.width: 1
|
||||||
|
border.color: Style.themeColor
|
||||||
|
width: height
|
||||||
|
height: Style.baseFontPixelSize + Style.margin * 2
|
||||||
|
color: mouse.containsMouse ? Style.minorFrameColor : "white"
|
||||||
|
|
||||||
|
property bool gridMode: false
|
||||||
|
|
||||||
|
signal clicked();
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: icon
|
||||||
|
width: parent.width - Style.margin
|
||||||
|
height: parent.height - Style.margin
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: root.gridMode ? "qrc:///svg/icon-grid-view"
|
||||||
|
: "qrc:///svg/icon-list-view"
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouse
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: root.clicked();
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.left: root.right
|
||||||
|
anchors.leftMargin: Style.margin
|
||||||
|
anchors.verticalCenter: root.verticalCenter
|
||||||
|
visible: mouse.containsMouse
|
||||||
|
color: Style.baseTextColor
|
||||||
|
font.pixelSize: Style.baseFontPixelSize
|
||||||
|
text: root.gridMode ? qsTr("Switch to grid view")
|
||||||
|
: qsTr("Switch to list view")
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,8 @@ Item {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: contentBox
|
id: contentBox
|
||||||
width: parent.width
|
width: parent.width - Style.strutSize * 2
|
||||||
|
x: Style.strutSize
|
||||||
height: Style.strutSize
|
height: Style.strutSize
|
||||||
y: Style.margin
|
y: Style.margin
|
||||||
color: "white"
|
color: "white"
|
||||||
|
|
|
@ -123,6 +123,10 @@
|
||||||
<file>qml/RouteLegsView.qml</file>
|
<file>qml/RouteLegsView.qml</file>
|
||||||
<file>qml/OverlayMenu.qml</file>
|
<file>qml/OverlayMenu.qml</file>
|
||||||
<file>qml/PopupChoiceItem.qml</file>
|
<file>qml/PopupChoiceItem.qml</file>
|
||||||
|
<file>qml/AircraftGridDelegate.qml</file>
|
||||||
|
<file>qml/AircraftGridView.qml</file>
|
||||||
|
<file>qml/AircraftListView.qml</file>
|
||||||
|
<file>qml/GridToggleButton.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/preview">
|
<qresource prefix="/preview">
|
||||||
<file alias="close-icon">preview-close.png</file>
|
<file alias="close-icon">preview-close.png</file>
|
||||||
|
@ -139,5 +143,7 @@
|
||||||
<file alias="toolbox-aircraft">assets/icons8-aircraft.svg</file>
|
<file alias="toolbox-aircraft">assets/icons8-aircraft.svg</file>
|
||||||
<file alias="toolbox-fly-alt">assets/icons8-rocket.svg</file>
|
<file alias="toolbox-fly-alt">assets/icons8-rocket.svg</file>
|
||||||
<file alias="toolbox-fly-heli">assets/icons8-helicopter.svg</file>
|
<file alias="toolbox-fly-heli">assets/icons8-helicopter.svg</file>
|
||||||
|
<file alias="icon-grid-view">assets/icons8-grid-view.svg</file>
|
||||||
|
<file alias="icon-list-view">assets/icons8-menu.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
Loading…
Add table
Reference in a new issue