diff options
| -rw-r--r-- | xT/CMakeLists.txt | 25 | ||||
| -rw-r--r-- | xT/xT.cpp | 2 | ||||
| -rw-r--r-- | xT/xTq.cpp | 40 | ||||
| -rw-r--r-- | xT/xTq.h | 15 | ||||
| -rw-r--r-- | xT/xTq.qml | 105 | 
5 files changed, 181 insertions, 6 deletions
| diff --git a/xT/CMakeLists.txt b/xT/CMakeLists.txt index 8f27be3..562c15a 100644 --- a/xT/CMakeLists.txt +++ b/xT/CMakeLists.txt @@ -12,8 +12,10 @@ project (xT VERSION "${project_version}"  set (CMAKE_CXX_STANDARD 17)  set (CMAKE_CXX_STANDARD_REQUIRED ON) -find_package (Qt6 REQUIRED COMPONENTS Widgets Network Multimedia) -qt_standard_project_setup () +find_package (Qt6 REQUIRED COMPONENTS Widgets Network Multimedia +	Quick QuickControls2) +# XXX: The version requirement is probably for Qt Quick only. +qt_standard_project_setup (REQUIRES 6.5)  add_compile_options ("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")  add_compile_options ("$<$<CXX_COMPILER_ID:GNU>:-Wall;-Wextra>") @@ -77,7 +79,7 @@ else ()  endif ()  # Build the main executable and link it -find_program (awk_EXECUTABLE awk ${find_program_REQUIRE}) +find_program (awk_EXECUTABLE awk REQUIRED)  add_custom_command (OUTPUT xC-proto.cpp  	COMMAND ${CMAKE_COMMAND} -E env LC_ALL=C ${awk_EXECUTABLE}  		-f ${root}/liberty/tools/lxdrgen.awk @@ -103,11 +105,24 @@ set_target_properties (xT PROPERTIES WIN32_EXECUTABLE ON MACOSX_BUNDLE ON  # https://stackoverflow.com/questions/79079161 and resolved in Qt Creator 16.  set (QT_QML_GENERATE_QMLLS_INI ON) +# TODO(p): Perhaps do it in one-or-the-other way, +# as Qt Quick sucks on the desktop, and Qt Widgets is unusable on mobile. +qt_add_executable (xTq +	xTq.cpp ${project_config} ${project_sources} "${icon_icns}") +set_property (SOURCE xTq.qml APPEND PROPERTY QT_QML_SOURCE_TYPENAME Main) +qt_add_qml_module (xTq URI xTquick VERSION 1.0 QML_FILES xTq.qml) +add_dependencies (xTq xC-proto) +qt_add_resources (xTq "rsrc" PREFIX / FILES "${beep}" ${icon_rsrc_list}) +target_link_libraries (xTq PRIVATE +	Qt6::Quick Qt6::QuickControls2 Qt6::Network Qt6::Multimedia) +set_target_properties (xTq PROPERTIES WIN32_EXECUTABLE ON MACOSX_BUNDLE ON +	MACOSX_BUNDLE_GUI_IDENTIFIER name.janouch.xTq) +  # The files to be installed  include (GNUInstallDirs)  if (ANDROID) -	install (TARGETS xT DESTINATION .) +	install (TARGETS xTq DESTINATION .)  elseif (APPLE OR WIN32)  	install (TARGETS xT  		BUNDLE DESTINATION . @@ -144,7 +159,7 @@ if (WIN32)  		foreach (lib ${libs})  			string (STRIP "${lib}" lib)  			file (COPY "${cygroot}${lib}" DESTINATION "${bindir}") -		endforeach() +		endforeach ()  	endif ()  	]=])  endif () @@ -1,5 +1,5 @@  /* - * xT.cpp: Qt frontend for xC + * xT.cpp: Qt Widgets frontend for xC   *   * Copyright (c) 2024, Přemysl Eric Janouch <p@janouch.name>   * diff --git a/xT/xTq.cpp b/xT/xTq.cpp new file mode 100644 index 0000000..a6d48bf --- /dev/null +++ b/xT/xTq.cpp @@ -0,0 +1,40 @@ +/* + * xTq.cpp: Qt Quick frontend for xC + * + * Copyright (c) 2024, Přemysl Eric Janouch <p@janouch.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "xC-proto.cpp" + +#include <cstdint> + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +#include "xTq.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int +main(int argc, char *argv[]) +{ +	QGuiApplication app(argc, argv); + +	QQmlApplicationEngine engine; +	QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, +		&app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); +	engine.loadFromModule("xTquick", "Main"); +	return app.exec(); +} diff --git a/xT/xTq.h b/xT/xTq.h new file mode 100644 index 0000000..70a0374 --- /dev/null +++ b/xT/xTq.h @@ -0,0 +1,15 @@ +#ifndef XTQ_H +#define XTQ_H + +#include <QTcpSocket> +#include <QtQmlIntegration/qqmlintegration.h> + +class RelayConnection : public QObject { +	Q_OBJECT +	QML_ELEMENT + +public: +	QTcpSocket *socket;                 ///< Buffered relay socket +}; + +#endif // XTQ_H diff --git a/xT/xTq.qml b/xT/xTq.qml new file mode 100644 index 0000000..50063c9 --- /dev/null +++ b/xT/xTq.qml @@ -0,0 +1,105 @@ +import QtQuick +import QtQuick.Controls.Fusion +//import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { +	id: window +	width: 640 +	height: 480 +	visible: true +	title: qsTr("xT") + +	property RelayConnection connection + +	ColumnLayout { +		id: column +		anchors.fill: parent +		anchors.margins: 6 + +		ScrollView { +			id: bufferScroll +			Layout.fillWidth: true +			Layout.fillHeight: true +			TextArea { +				id: buffer +				text: qsTr("Buffer text") +			} +		} + +		RowLayout { +			id: row +			Layout.fillWidth: true + +			Label { +				Layout.fillWidth: true +				id: prompt +				text: qsTr("Prompt") +			} + +			Label { +				Layout.fillWidth: true +				id: status +				horizontalAlignment: Text.AlignRight +				text: qsTr("Status") +			} +		} + +		TextArea { +			id: input +			Layout.fillWidth: true +			text: qsTr("Input") +		} +	} + +	Component.onCompleted: {} + +	Dialog { +		id: connect +		title: "Connect to relay" +		anchors.centerIn: parent +		modal: true +		visible: true + +		onRejected: Qt.quit() +		onAccepted: { +			// TODO(p): Store the host, store the port, initiate connection. +		} + +		GridLayout { +			anchors.fill: parent +			anchors.margins: 6 +			columns: 2 + +			// It is a bit silly that one has to do everything manually. +			Keys.onReturnPressed: connect.accept() + +			Label { text: "Host:" } +			TextField { +				id: connectHost +				Layout.fillWidth: true +				// And if this doesn't work reliably, do it after open(). +				focus: true +			} +			Label { text: "Port:" } +			TextField { +				id: connectPort +				Layout.fillWidth: true +			} +		} + +		footer: DialogButtonBox { +			Button { +				text: qsTr("Connect") +				DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole +				Keys.onReturnPressed: connect.accept() +				highlighted: true +			} +			Button { +				text: qsTr("Close") +				DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole +				Keys.onReturnPressed: connect.reject() +			} +		} +	} +} | 
