Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ debian/x0-db-install
debian/x0-db-install-tpl
debian/x0-msg-server
debian/.debhelper
_codeql_detected_source_root
cpp/build/
90 changes: 90 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#-------1---------2---------3---------4---------5---------6---------7--------#
#- Copyright WEB/codeX, clickIT 2011 - 2025 -#
#-------1---------2---------3---------4---------5---------6---------7--------#
#- -#
#-------1---------2---------3---------4---------5---------6---------7--------#
#- x0 C++ Framework - CMake Build Configuration -#
#-------1---------2---------3---------4---------5---------6---------7--------#

cmake_minimum_required(VERSION 3.16)
project(x0-cpp VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

# Find required packages
find_package(Qt6 COMPONENTS Core Widgets QUIET)
if(NOT Qt6_FOUND)
find_package(Qt5 5.15 COMPONENTS Core Widgets REQUIRED)
set(QT_LIBS Qt5::Core Qt5::Widgets)
else()
set(QT_LIBS Qt6::Core Qt6::Widgets)
endif()

# nlohmann/json - Header-only library
# Can be installed via: apt-get install nlohmann-json3-dev
# Or fetched automatically
include(FetchContent)
FetchContent_Declare(
json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.11.3
)
FetchContent_MakeAvailable(json)

# Include directories
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

# Library source files (without main.cpp)
set(X0_LIB_SOURCES
src/x0BaseElement.cpp
src/x0BaseObject.cpp
src/x0Factory.cpp
src/x0Screen.cpp
src/x0Reactor.cpp
src/x0ObjDiv.cpp
src/x0ObjButton.cpp
)

# Header files
set(X0_HEADERS
include/x0BaseElement.h
include/x0BaseObject.h
include/x0Factory.h
include/x0Screen.h
include/x0Reactor.h
include/x0ObjDiv.h
include/x0ObjButton.h
)

# Create static library
add_library(x0-lib STATIC ${X0_LIB_SOURCES} ${X0_HEADERS})
target_link_libraries(x0-lib PUBLIC
${QT_LIBS}
nlohmann_json::nlohmann_json
)

# Create main executable
add_executable(x0-app src/main.cpp)
target_link_libraries(x0-app PRIVATE x0-lib)

# Create test executable for validating examples
add_executable(x0-test-examples test/test_examples.cpp)
target_link_libraries(x0-test-examples PRIVATE
x0-lib
nlohmann_json::nlohmann_json
)

# Enable testing
enable_testing()

# Define examples directory path
set(EXAMPLES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../example")
add_test(NAME test_examples COMMAND x0-test-examples "${EXAMPLES_DIR}")

# Install targets
install(TARGETS x0-app DESTINATION bin)
install(FILES ${X0_HEADERS} DESTINATION include/x0)
174 changes: 174 additions & 0 deletions cpp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# x0 C++ Framework

C++ variant of the x0 JavaScript framework using **Qt** for graphical rendering and **nlohmann::json** for configuration management.

## Overview

This directory contains a C++ implementation of the x0 framework, providing equivalent functionality to the JavaScript version in `/www/`. The C++ variant is designed for desktop applications requiring native performance and Qt-based graphical output.

## Architecture

The C++ framework mirrors the JavaScript architecture:

| JavaScript (`/www/`) | C++ (`/cpp/`) | Description |
|---------------------------|------------------------|------------------------------------------------|
| `sysBaseDOMElement.js` | `x0BaseElement.h/cpp` | Base element wrapping Qt widgets |
| `sysBaseObject.js` | `x0BaseObject.h/cpp` | Hierarchical object with children |
| `sysFactory.js` | `x0Factory.h/cpp` | Object factory and screen management |
| `sysScreen.js` | `x0Screen.h/cpp` | Screen/view management |
| `sysReactor.js` | `x0Reactor.h/cpp` | Event system |
| `sysObjDiv.js` | `x0ObjDiv.h/cpp` | Container widget (QFrame) |
| `sysObjButton.js` | `x0ObjButton.h/cpp` | Button widget (QPushButton) |

## Dependencies

- **Qt 5.15+** or **Qt 6.x** (Core, Widgets modules)
- **nlohmann/json 3.x** (automatically fetched via CMake)
- **CMake 3.16+**

## Building

### Prerequisites

```bash
# Ubuntu/Debian
sudo apt-get install cmake qt6-base-dev

# Or for Qt5
sudo apt-get install cmake qtbase5-dev
```

### Build Steps

```bash
cd cpp
mkdir build && cd build
cmake ..
make -j$(nproc)
```

### Running

```bash
./x0-app
```

## Usage Example

```cpp
#include "x0Factory.h"
#include "x0Screen.h"
#include "x0ObjDiv.h"
#include "x0ObjButton.h"

using namespace x0;

int main() {
// Load configuration
json skeleton = loadFromFile("skeleton.json");
json dataObject = loadFromFile("objects.json");

// Initialize factory
x0Factory& factory = x0Factory::instance();
factory.setDataSkeleton(skeleton);
factory.setDataObject(dataObject);
factory.init();

// Access screens and objects
x0Screen* screen = factory.getScreenById("MainScreen");
x0BaseObject* button = factory.getObjectById("MyButton");

return 0;
}
```

## JSON Configuration

The C++ framework uses the same JSON configuration format as the JavaScript version:

### Skeleton Configuration
```json
{
"MainScreen": [
{"MainDiv": {"RefID": "MainScreen"}},
{"WelcomeText": {"RefID": "MainDiv"}},
{"ActionButton": {"RefID": "MainDiv"}}
]
}
```

### Object Configuration
```json
{
"ActionButton": {
"Type": "Button",
"Attributes": {
"Style": "btn btn-primary",
"TextID": "BTN.SUBMIT",
"OnClick": "/api/submit",
"FireEvents": ["DataRefresh"]
}
}
}
```

## Class Hierarchy

```
QObject
└── x0BaseElement (Qt widget wrapper)
└── x0BaseObject (hierarchical object)
├── x0ObjDiv (container)
└── x0ObjButton (button)

x0Factory (singleton, object management)
x0Screen (screen/view container)
x0Reactor (event dispatching)
```

## Features

- **Hierarchical Object Model**: Parent-child relationships with recursive rendering
- **JSON Configuration**: Load UI definitions from JSON files
- **Qt Integration**: Native desktop widgets with Qt
- **Event System**: Register and dispatch events across objects
- **Screen Management**: Multiple screens with switching support
- **Object Factory**: Dynamic object creation by type

## Extending

To add new widget types:

1. Create header in `include/`:
```cpp
// x0ObjMyWidget.h
class x0ObjMyWidget : public x0BaseObject {
Q_OBJECT
public:
void createWidget(const QString& objectId) override;
void init() override;
};
```

2. Create implementation in `src/`:
```cpp
// x0ObjMyWidget.cpp
void x0ObjMyWidget::createWidget(const QString& objectId) {
m_widget = std::make_unique<QMyWidget>();
m_widget->setObjectName(objectId);
}
```

3. Register in factory:
```cpp
x0Factory::instance().registerObjectType("MyWidget",
[]() { return std::make_shared<x0ObjMyWidget>(); });
```

## License

AGPL-3.0 - See [../LICENSE](../LICENSE)

## Contributing

See [../CONTRIBUTING.md](../CONTRIBUTING.md)
109 changes: 109 additions & 0 deletions cpp/include/x0BaseElement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//-------1---------2---------3---------4---------5---------6---------7--------//
//- Copyright WEB/codeX, clickIT 2011 - 2025 -//
//-------1---------2---------3---------4---------5---------6---------7--------//
//- -//
//-------1---------2---------3---------4---------5---------6---------7--------//
//- x0 C++ Framework - Base Element (Qt Widget Wrapper) -//
//-------1---------2---------3---------4---------5---------6---------7--------//
//- Equivalent to JavaScript: sysBaseDOMElement.js -//
//-------1---------2---------3---------4---------5---------6---------7--------//

#ifndef X0_BASE_ELEMENT_H
#define X0_BASE_ELEMENT_H

#include <QWidget>
#include <QString>
#include <QMap>
#include <memory>
#include <nlohmann/json.hpp>

namespace x0 {

using json = nlohmann::json;

/**
* @brief Base element class wrapping Qt widgets
*
* This class provides the foundation for all UI elements in the x0 C++ framework.
* It manages the underlying Qt widget and provides methods for styling,
* visibility control, and event handling - equivalent to sysBaseDOMElement.js.
*/
class x0BaseElement : public QObject {
Q_OBJECT

public:
explicit x0BaseElement(QObject* parent = nullptr);
virtual ~x0BaseElement();

// Widget management
virtual void createWidget(const QString& objectId);
virtual QWidget* getWidget() const;
void setParentWidget(QWidget* parent);

// Style management
void setStyleClass(const QString& styleClass);
void addStyleClass(const QString& styleClass);
void removeStyleClass(const QString& styleClass);
bool hasStyleClass(const QString& styleClass) const;
QString getStyleClasses() const;

// Value management
void setValue(const QString& value);
QString getValue() const;

// Visibility
void setVisibleState(const QString& state);
QString getVisibleState() const;
void switchVisibleState();

// Enable/Disable
void enable();
void disable();
bool isEnabled() const;

// Attributes
void setAttribute(const QString& attribute, const QString& value);
QString getAttribute(const QString& attribute) const;
void setAttributes(const QMap<QString, QString>& attributes);

// Style properties
void setStyleTop(int top);
void setStyleLeft(int left);
void setStyleWidth(int width);
void setStyleHeight(int height);
void setStyleZIndex(int zIndex);
void applyStyleAttributes();

// Object identification
QString getObjectId() const { return m_objectId; }
void setObjectId(const QString& id) { m_objectId = id; }
QString getParentId() const { return m_parentId; }
void setParentId(const QString& id) { m_parentId = id; }

protected:
std::unique_ptr<QWidget> m_widget;
QString m_objectId;
QString m_parentId;
QString m_value;
QString m_styleClass;
QString m_visibleState;
QMap<QString, QString> m_attributes;

// Style positioning
int m_styleTop = -1;
int m_styleLeft = -1;
int m_styleWidth = -1;
int m_styleHeight = -1;
int m_styleZIndex = -1;

QStringList m_styleClasses;

signals:
void visibilityChanged(bool visible);
void styleChanged();
void valueChanged(const QString& value);
};

} // namespace x0

#endif // X0_BASE_ELEMENT_H
Loading
Loading