Compare commits
No commits in common. "cd7d44a5a51d1baa1cfd22cdd625230100cac3c4" and "9648c7c040a388d891639d3a5cc46ad522821771" have entirely different histories.
cd7d44a5a5
...
9648c7c040
30 changed files with 185 additions and 1079 deletions
|
|
@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 4.0)
|
||||||
project(SHinterface VERSION 1.0 LANGUAGES CXX)
|
project(SHinterface VERSION 1.0 LANGUAGES CXX)
|
||||||
|
|
||||||
# Set C++ standard
|
# Set C++ standard
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# Enable all warnings
|
# Enable all warnings
|
||||||
|
|
|
||||||
529
remote.html
529
remote.html
|
|
@ -1,529 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>SHInterface Control</title>
|
|
||||||
<link rel="icon" type="image/x-icon" href="UVOSicon.bmp">
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
||||||
margin: 0;
|
|
||||||
padding: 15px;
|
|
||||||
background-color: #32343d;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
color: #333;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.status {
|
|
||||||
padding: 10px 30px 10px 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
margin-top: 0px;
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.status::after {
|
|
||||||
content: '↻';
|
|
||||||
position: absolute;
|
|
||||||
right: 15px;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
.connected {
|
|
||||||
background-color: #d4edda;
|
|
||||||
color: #0F0F0F;
|
|
||||||
}
|
|
||||||
.disconnected {
|
|
||||||
background-color: #FF4733;
|
|
||||||
color: #0F0F0F;
|
|
||||||
}
|
|
||||||
.item-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
.item-card {
|
|
||||||
background: #707177;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 15px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.item-info {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
.item-name {
|
|
||||||
font-weight: normal;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.item-id {
|
|
||||||
font-size: 0.8em;
|
|
||||||
color: #c9c9c9;
|
|
||||||
}
|
|
||||||
.toggle-switch {
|
|
||||||
position: relative;
|
|
||||||
width: 50px;
|
|
||||||
height: 25px;
|
|
||||||
background-color: #ccc;
|
|
||||||
border-radius: 25px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
}
|
|
||||||
.toggle-switch.active {
|
|
||||||
background-color: #313665;
|
|
||||||
}
|
|
||||||
.toggle-knob {
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
left: 2px;
|
|
||||||
width: 21px;
|
|
||||||
height: 21px;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
transition: transform 0.3s;
|
|
||||||
}
|
|
||||||
.toggle-switch.active .toggle-knob {
|
|
||||||
transform: translateX(25px);
|
|
||||||
}
|
|
||||||
.tab-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: calc(100vh - 85px);
|
|
||||||
}
|
|
||||||
.tabs {
|
|
||||||
display: flex;
|
|
||||||
background-color: #4a4c56;
|
|
||||||
border-radius: 8px 8px 0 0;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.tab {
|
|
||||||
flex: 1;
|
|
||||||
padding: 12px;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #4a4c56;
|
|
||||||
color: #ccc;
|
|
||||||
transition: all 0.3s;
|
|
||||||
border-bottom: 3px solid transparent;
|
|
||||||
}
|
|
||||||
.tab.active {
|
|
||||||
background-color: #707177;
|
|
||||||
color: white;
|
|
||||||
border-bottom-color: #4CAF50;
|
|
||||||
}
|
|
||||||
.tab-content {
|
|
||||||
display: none;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
overflow-y: auto;
|
|
||||||
height: 100%;
|
|
||||||
transition: transform 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
.tab-content.active {
|
|
||||||
display: flex;
|
|
||||||
transform: translateX(0);
|
|
||||||
}
|
|
||||||
.item-list, .sensor-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.sensor-card {
|
|
||||||
background: #707177;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 12px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.sensor-info {
|
|
||||||
font-size: 0.8em;
|
|
||||||
color: #c9c9c9;
|
|
||||||
}
|
|
||||||
.sensor-value-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
|
||||||
.sensor-name {
|
|
||||||
font-weight: normal;
|
|
||||||
margin-bottom: 3px;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.sensor-value {
|
|
||||||
font-size: 1.2em;
|
|
||||||
font-weight: bold;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.refresh-btn {
|
|
||||||
display: block;
|
|
||||||
margin: 20px auto;
|
|
||||||
padding: 10px 20px;
|
|
||||||
background-color: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.refresh-btn:hover {
|
|
||||||
background-color: #45a049;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="status disconnected" id="status" onclick="connectAndRefresh()">Disconnected</div>
|
|
||||||
|
|
||||||
<div class="tab-container">
|
|
||||||
<div class="tabs">
|
|
||||||
<div class="tab active" onclick="switchTab(0)">Items</div>
|
|
||||||
<div class="tab" onclick="switchTab(1)">Sensors</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="items-tab" class="tab-content active">
|
|
||||||
<div class="item-list" id="itemList"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="sensors-tab" class="tab-content">
|
|
||||||
<div class="sensor-list" id="sensorList"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
let socket;
|
|
||||||
let items = {};
|
|
||||||
let sensors = {};
|
|
||||||
const wsUrl = 'https://' + 'local.uvos.xyz/shws';
|
|
||||||
|
|
||||||
function connectAndRefresh() {
|
|
||||||
if (socket && socket.readyState === WebSocket.OPEN) {
|
|
||||||
refreshItems();
|
|
||||||
refreshSensors();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket = new WebSocket(wsUrl);
|
|
||||||
|
|
||||||
socket.onopen = function(e) {
|
|
||||||
console.log('Connected to WebSocket');
|
|
||||||
document.getElementById('status').className = 'status connected';
|
|
||||||
document.getElementById('status').textContent = 'Connected';
|
|
||||||
refreshItems();
|
|
||||||
refreshSensors();
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onclose = function(e) {
|
|
||||||
console.log('Disconnected from WebSocket');
|
|
||||||
document.getElementById('status').className = 'status disconnected';
|
|
||||||
document.getElementById('status').textContent = 'Disconnected';
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onerror = function(e) {
|
|
||||||
console.error('WebSocket error:', e);
|
|
||||||
document.getElementById('status').className = 'status disconnected';
|
|
||||||
document.getElementById('status').textContent = 'Error: ' + e.message;
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onmessage = function(event) {
|
|
||||||
console.log('Message received:', event.data);
|
|
||||||
try {
|
|
||||||
const json = JSON.parse(event.data);
|
|
||||||
handleMessage(json);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Error parsing JSON:', e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshItems() {
|
|
||||||
if (socket && socket.readyState === WebSocket.OPEN) {
|
|
||||||
const message = {
|
|
||||||
MessageType: 'GetItems',
|
|
||||||
Data: []
|
|
||||||
};
|
|
||||||
socket.send(JSON.stringify(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshSensors() {
|
|
||||||
if (socket && socket.readyState === WebSocket.OPEN) {
|
|
||||||
const message = {
|
|
||||||
MessageType: 'GetSensors',
|
|
||||||
Data: []
|
|
||||||
};
|
|
||||||
socket.send(JSON.stringify(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMessage(json) {
|
|
||||||
if (json.MessageType === 'ItemUpdate') {
|
|
||||||
const fullList = json.FullList || false;
|
|
||||||
|
|
||||||
if (fullList) {
|
|
||||||
items = {}; // Clear existing items
|
|
||||||
json.Data.forEach(item => {
|
|
||||||
items[item.ItemId] = item;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
json.Data.forEach(item => {
|
|
||||||
items[item.ItemId].Value = item.Value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
renderItems();
|
|
||||||
} else if (json.MessageType === 'SensorUpdate') {
|
|
||||||
const fullList = json.FullList || false;
|
|
||||||
|
|
||||||
if (fullList) {
|
|
||||||
sensors = {}; // Clear existing sensors
|
|
||||||
}
|
|
||||||
|
|
||||||
json.Data.forEach(sensor => {
|
|
||||||
const key = `${sensor.SensorType}-${sensor.Id}`;
|
|
||||||
sensors[key] = sensor;
|
|
||||||
});
|
|
||||||
|
|
||||||
renderSensors();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderItems() {
|
|
||||||
const itemList = document.getElementById('itemList');
|
|
||||||
itemList.innerHTML = '';
|
|
||||||
|
|
||||||
if (Object.keys(items).length === 0) {
|
|
||||||
itemList.innerHTML = '<div style="text-align: center; color: #666; padding: 20px;">No items found</div>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.values(items).forEach(item => {
|
|
||||||
const itemCard = document.createElement('div');
|
|
||||||
itemCard.className = 'item-card';
|
|
||||||
|
|
||||||
const value = item.Value || 0;
|
|
||||||
const type = item.ValueType || 0; // Default to BOOL
|
|
||||||
|
|
||||||
let controlHtml = '';
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 0: // ITEM_VALUE_BOOL
|
|
||||||
const isActive = value > 0;
|
|
||||||
controlHtml = `
|
|
||||||
<div class="toggle-switch ${isActive ? 'active' : ''}"
|
|
||||||
onclick="toggleItem(${item.ItemId}, ${!isActive})">
|
|
||||||
<div class="toggle-knob"></div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
break;
|
|
||||||
case 1: // ITEM_VALUE_UINT
|
|
||||||
controlHtml = `
|
|
||||||
<input type="number"
|
|
||||||
value="${value}"
|
|
||||||
min="0" max="255"
|
|
||||||
onchange="setUintItem(${item.ItemId}, this.value)"
|
|
||||||
style="width: 80px; padding: 5px; border-radius: 5px; border: 1px solid #ddd;">
|
|
||||||
`;
|
|
||||||
break;
|
|
||||||
case 2: // ITEM_VALUE_NO_VALUE
|
|
||||||
controlHtml = '<div style="color: #b9b9b9;">No control</div>';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
itemCard.innerHTML = `
|
|
||||||
<div class="item-info">
|
|
||||||
<div class="item-name">${item.Name}</div>
|
|
||||||
<div class="item-id">ItemId: ${item.ItemId} | Type: ${getTypeName(type)}</div>
|
|
||||||
</div>
|
|
||||||
${controlHtml}
|
|
||||||
`;
|
|
||||||
|
|
||||||
itemList.appendChild(itemCard);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleItem(itemId, newValue) {
|
|
||||||
if (!socket || socket.readyState !== WebSocket.OPEN) {
|
|
||||||
alert('Not connected to server');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const message = {
|
|
||||||
MessageType: 'ItemUpdate',
|
|
||||||
Data: [{
|
|
||||||
ItemId: itemId,
|
|
||||||
Value: newValue ? 1 : 0
|
|
||||||
}],
|
|
||||||
FullList: false
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.send(JSON.stringify(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUintItem(itemId, value) {
|
|
||||||
if (!socket || socket.readyState !== WebSocket.OPEN) {
|
|
||||||
alert('Not connected to server');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert to integer and clamp to 0-255
|
|
||||||
const intValue = Math.min(255, Math.max(0, parseInt(value) || 0));
|
|
||||||
|
|
||||||
const message = {
|
|
||||||
MessageType: 'ItemUpdate',
|
|
||||||
Data: [{
|
|
||||||
ItemId: itemId,
|
|
||||||
Value: intValue
|
|
||||||
}],
|
|
||||||
FullList: false
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.send(JSON.stringify(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTypeName(type) {
|
|
||||||
switch (type) {
|
|
||||||
case 0: return 'BOOL';
|
|
||||||
case 1: return 'UINT';
|
|
||||||
case 2: return 'NO_VALUE';
|
|
||||||
default: return 'UNKNOWN';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchTab(tabIndex) {
|
|
||||||
const tabs = document.querySelectorAll('.tab');
|
|
||||||
const tabContents = document.querySelectorAll('.tab-content');
|
|
||||||
|
|
||||||
tabs.forEach((tab, index) => {
|
|
||||||
tab.classList.toggle('active', index === tabIndex);
|
|
||||||
});
|
|
||||||
|
|
||||||
tabContents.forEach((content, index) => {
|
|
||||||
content.classList.toggle('active', index === tabIndex);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderSensors() {
|
|
||||||
const sensorList = document.getElementById('sensorList');
|
|
||||||
sensorList.innerHTML = '';
|
|
||||||
|
|
||||||
if (Object.keys(sensors).length === 0) {
|
|
||||||
sensorList.innerHTML = '<div style="text-align: center; color: #666; padding: 20px;">No sensors found</div>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.values(sensors).forEach(sensor => {
|
|
||||||
const sensorCard = document.createElement('div');
|
|
||||||
sensorCard.className = 'sensor-card';
|
|
||||||
|
|
||||||
let typeName = '';
|
|
||||||
switch (sensor.SensorType) {
|
|
||||||
case 0: typeName = 'Door'; break;
|
|
||||||
case 1: typeName = 'Temperature'; break;
|
|
||||||
case 2: typeName = 'Humidity'; break;
|
|
||||||
case 3: typeName = 'Pressure'; break;
|
|
||||||
case 4: typeName = 'Brightness'; break;
|
|
||||||
case 5: typeName = 'Button'; break;
|
|
||||||
case 6: typeName = 'ADC'; break;
|
|
||||||
case 7: typeName = 'CO2'; break;
|
|
||||||
case 8: typeName = 'Formaldehyde'; break;
|
|
||||||
case 9: typeName = 'PM2.5'; break;
|
|
||||||
case 10: typeName = 'Total VOC'; break;
|
|
||||||
case 16: typeName = 'Occupancy'; break;
|
|
||||||
case 17: typeName = 'Sun Altitude'; break;
|
|
||||||
default: typeName = 'Unknown';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Truncate to 2 decimal places
|
|
||||||
const fieldValue = Number(sensor.Field).toFixed(2);
|
|
||||||
|
|
||||||
sensorCard.innerHTML = `
|
|
||||||
<div>
|
|
||||||
<div class="sensor-name">${sensor.Name}</div>
|
|
||||||
<div class="sensor-info">Type: ${typeName} | ID: ${sensor.Id}</div>
|
|
||||||
</div>
|
|
||||||
<div class="sensor-value-container">
|
|
||||||
<div class="sensor-value">
|
|
||||||
${fieldValue} ${sensor.Unit || ''}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
sensorList.appendChild(sensorCard);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTypeName(type) {
|
|
||||||
switch (type) {
|
|
||||||
case 0: return 'BOOL';
|
|
||||||
case 1: return 'UINT';
|
|
||||||
case 2: return 'NO_VALUE';
|
|
||||||
default: return 'UNKNOWN';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Touch/swipe support for mobile
|
|
||||||
let touchStartX = -1;
|
|
||||||
let touchEndX = -1;
|
|
||||||
|
|
||||||
function handleTouchStart(event) {
|
|
||||||
touchStartX = event.changedTouches[0].screenX;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTouchMove(event) {
|
|
||||||
touchEndX = event.changedTouches[0].screenX;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTouchEnd() {
|
|
||||||
const diff = touchStartX - touchEndX;
|
|
||||||
if (touchStartX > 0 && touchEndX > 0) {
|
|
||||||
if (diff > 100) { // Swipe left
|
|
||||||
const activeTab = document.querySelector('.tab.active');
|
|
||||||
const tabIndex = Array.from(document.querySelectorAll('.tab')).indexOf(activeTab);
|
|
||||||
if (tabIndex < 1) {
|
|
||||||
switchTab(tabIndex + 1);
|
|
||||||
}
|
|
||||||
} else if (diff < -100) { // Swipe right
|
|
||||||
const activeTab = document.querySelector('.tab.active');
|
|
||||||
const tabIndex = Array.from(document.querySelectorAll('.tab')).indexOf(activeTab);
|
|
||||||
if (tabIndex > 0) {
|
|
||||||
switchTab(tabIndex - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
touchStartX = -1
|
|
||||||
touchEndX = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add touch event listeners
|
|
||||||
document.addEventListener('touchstart', handleTouchStart, false);
|
|
||||||
document.addEventListener('touchmove', handleTouchMove, false);
|
|
||||||
document.addEventListener('touchend', handleTouchEnd, false);
|
|
||||||
|
|
||||||
// Auto-connect when page loads
|
|
||||||
window.onload = function() {
|
|
||||||
setTimeout(connectAndRefresh, 500);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -24,7 +24,6 @@ void Actor::performValueAction(uint8_t value)
|
||||||
ItemUpdateRequest request;
|
ItemUpdateRequest request;
|
||||||
request.type = ITEM_UPDATE_ACTOR;
|
request.type = ITEM_UPDATE_ACTOR;
|
||||||
request.payload = ItemData(QRandomGenerator::global()->generate(), "Item", value);
|
request.payload = ItemData(QRandomGenerator::global()->generate(), "Item", value);
|
||||||
request.changes.value = true;
|
|
||||||
sigItemUpdate(request);
|
sigItemUpdate(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,12 +47,9 @@ void Actor::makeInactive()
|
||||||
QString Actor::actionName()
|
QString Actor::actionName()
|
||||||
{
|
{
|
||||||
QString string;
|
QString string;
|
||||||
if(triggerValue == 0 )
|
if(triggerValue == 0 ) string = "off";
|
||||||
string = "off";
|
else if(triggerValue == 1 ) string = "on";
|
||||||
else if(triggerValue == 1 )
|
else string = "value to " + QString::number(triggerValue);
|
||||||
string = "on";
|
|
||||||
else
|
|
||||||
string = "value to " + QString::number(triggerValue);
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,13 @@ public:
|
||||||
virtual void load(const QJsonObject& json, const bool preserve = false);
|
virtual void load(const QJsonObject& json, const bool preserve = false);
|
||||||
|
|
||||||
uint8_t getRepeat();
|
uint8_t getRepeat();
|
||||||
virtual QString getName() const;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
virtual void makeActive();
|
virtual void makeActive();
|
||||||
virtual void makeInactive();
|
virtual void makeInactive();
|
||||||
|
virtual QString getName() const;
|
||||||
void doTick();
|
void doTick();
|
||||||
void changeTime(const QDateTime& time);
|
void changeTime(const QDateTime& time);
|
||||||
void setRepeat(const uint8_t repeat);
|
void setRepeat(const uint8_t repeat);
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,11 @@ TimerActor::TimerActor(const int timeoutSec, QObject *parent): Actor(parent), ti
|
||||||
timer.setSingleShot(true);
|
timer.setSingleShot(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerActor::onItemUpdated(ItemUpdateRequest update)
|
void TimerActor::onValueChanged(uint8_t state)
|
||||||
{
|
{
|
||||||
if(update.changes.value && ((update.payload.getValue() && !triggerValue) || (!update.payload.getValue() && triggerValue)))
|
if((state && !triggerValue) || (!state && triggerValue))
|
||||||
{
|
{
|
||||||
qDebug()<<"Timer started";
|
if(timer.isActive()) timer.stop();
|
||||||
if(timer.isActive())
|
|
||||||
timer.stop();
|
|
||||||
timer.setInterval(timeoutMsec_);
|
timer.setInterval(timeoutMsec_);
|
||||||
timer.start();
|
timer.start();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,15 @@ private slots:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
virtual void onItemUpdated(ItemUpdateRequest update) override;
|
virtual void onValueChanged(uint8_t state);
|
||||||
void setTimeout(const int timeoutSec);
|
void setTimeout(const int timeoutSec);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TimerActor(const int timeoutSec = 60, QObject *parent = nullptr);
|
explicit TimerActor(const int timeoutSec = 60, QObject *parent = nullptr);
|
||||||
virtual QString getName() const override;
|
virtual QString getName() const;
|
||||||
|
|
||||||
int getTimeout();
|
int getTimeout();
|
||||||
|
|
||||||
virtual void store(QJsonObject& json) override;
|
virtual void store(QJsonObject& json);
|
||||||
virtual void load(const QJsonObject& json, bool preserve) override;
|
virtual void load(const QJsonObject& json, bool preserve);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,5 @@ FixedItemSource::FixedItemSource(Microcontroller* micro, QObject *parent):
|
||||||
|
|
||||||
void FixedItemSource::refresh()
|
void FixedItemSource::refresh()
|
||||||
{
|
{
|
||||||
std::vector<ItemAddRequest> requests;
|
gotItems({powerItem, rgbItem, auxItem}, ITEM_UPDATE_BACKEND);
|
||||||
|
|
||||||
ItemAddRequest request;
|
|
||||||
request.type = ITEM_UPDATE_BACKEND;
|
|
||||||
|
|
||||||
request.payload = powerItem;
|
|
||||||
requests.push_back(request);
|
|
||||||
|
|
||||||
request.payload = rgbItem;
|
|
||||||
requests.push_back(request);
|
|
||||||
|
|
||||||
request.payload = auxItem;
|
|
||||||
requests.push_back(request);
|
|
||||||
|
|
||||||
gotItems(requests);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
|
||||||
ItemData::ItemData(uint32_t itemIdIn, QString name, uint8_t value, bool loaded, bool hidden, item_value_type_t type, QString groupName):
|
ItemData::ItemData(uint32_t itemIdIn, QString name, uint8_t value, bool loaded, bool hidden, item_value_type_t type):
|
||||||
name_(name), value_(value), itemId_(itemIdIn), loaded_(loaded), hidden_(hidden), type_(type), groupName_(groupName)
|
name_(name), value_(value), itemId_(itemIdIn), loaded_(loaded), hidden_(hidden), type_(type)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -46,49 +46,19 @@ uint32_t ItemData::id() const
|
||||||
|
|
||||||
void ItemData::store(QJsonObject &json)
|
void ItemData::store(QJsonObject &json)
|
||||||
{
|
{
|
||||||
storeWithChanges(json, ItemFieldChanges(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemData::storeWithChanges(QJsonObject& json, const ItemFieldChanges& changes)
|
|
||||||
{
|
|
||||||
json["ItemId"] = static_cast<double>(itemId_);
|
|
||||||
json["ValueType"] = type_;
|
|
||||||
if(changes.name)
|
|
||||||
json["Name"] = name_;
|
json["Name"] = name_;
|
||||||
if(changes.value)
|
json["ItemId"] = static_cast<double>(itemId_);
|
||||||
json["Value"] = static_cast<double>(value_);
|
json["Value"] = static_cast<double>(value_);
|
||||||
if(changes.groupName)
|
|
||||||
json["GroupName"] = groupName_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemData::load(const QJsonObject &json, const bool preserve)
|
void ItemData::load(const QJsonObject &json, const bool preserve)
|
||||||
{
|
{
|
||||||
loadWithChanges(json, preserve);
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemFieldChanges ItemData::loadWithChanges(const QJsonObject& json, const bool preserve)
|
|
||||||
{
|
|
||||||
ItemFieldChanges changes;
|
|
||||||
if(!preserve)
|
if(!preserve)
|
||||||
{
|
{
|
||||||
if(json.contains("Name"))
|
name_ = json["Name"].toString(name_);
|
||||||
{
|
|
||||||
name_ = json["Name"].toString();
|
|
||||||
changes.name = true;
|
|
||||||
}
|
|
||||||
if(json.contains("Value"))
|
|
||||||
{
|
|
||||||
value_ = json["Value"].toInt();
|
|
||||||
changes.value = true;
|
|
||||||
}
|
|
||||||
if(json.contains("GroupName"))
|
|
||||||
{
|
|
||||||
groupName_ = json["GroupName"].toString();
|
|
||||||
changes.groupName = true;
|
|
||||||
}
|
|
||||||
itemId_ = static_cast<uint32_t>(json["ItemId"].toDouble(0));
|
itemId_ = static_cast<uint32_t>(json["ItemId"].toDouble(0));
|
||||||
|
value_ = json["Value"].toInt();
|
||||||
}
|
}
|
||||||
return changes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemData::getLoaded() const
|
bool ItemData::getLoaded() const
|
||||||
|
|
@ -101,23 +71,15 @@ void ItemData::setLoaded(bool loaded)
|
||||||
loaded_ = loaded;
|
loaded_ = loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemData::hasChanged(const ItemData& other) const
|
bool ItemData::hasChanged(const ItemData& other)
|
||||||
{
|
{
|
||||||
ItemFieldChanges changes(true);
|
if(other != *this)
|
||||||
return hasChanged(other, changes);
|
return false;
|
||||||
}
|
if(other.getName() != getName())
|
||||||
|
|
||||||
bool ItemData::hasChanged(const ItemData& other, const ItemFieldChanges& changes) const
|
|
||||||
{
|
|
||||||
if(changes.name && other.getName() != getName())
|
|
||||||
return true;
|
return true;
|
||||||
if(changes.value && other.getValue() != getValue())
|
if(other.getValue() != getValue())
|
||||||
return true;
|
return true;
|
||||||
if(changes.hidden && other.isHidden() != isHidden())
|
if(other.getLoaded() != getLoaded())
|
||||||
return true;
|
|
||||||
if(changes.groupName && other.getGroupName() != getGroupName())
|
|
||||||
return true;
|
|
||||||
if(changes.actors)
|
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -137,20 +99,10 @@ item_value_type_t ItemData::getValueType()
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ItemData::getGroupName() const
|
|
||||||
{
|
|
||||||
return groupName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemData::setGroupName(QString groupName)
|
|
||||||
{
|
|
||||||
groupName_ = groupName;
|
|
||||||
}
|
|
||||||
|
|
||||||
//item
|
//item
|
||||||
|
|
||||||
Item::Item(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): QObject(parent), ItemData (itemIdIn, name,
|
Item::Item(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): QObject(parent), ItemData (itemIdIn, name,
|
||||||
value, false, false, ITEM_VALUE_BOOL, "All")
|
value)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -179,6 +131,7 @@ void Item::store(QJsonObject &json)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
json["Actors"] = actorsArray;
|
json["Actors"] = actorsArray;
|
||||||
|
json["ValueType"] = type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::load(const QJsonObject &json, const bool preserve)
|
void Item::load(const QJsonObject &json, const bool preserve)
|
||||||
|
|
@ -203,21 +156,13 @@ Item& Item::operator=(const ItemData& other)
|
||||||
value_ = other.getValue();
|
value_ = other.getValue();
|
||||||
itemId_ = other.id();
|
itemId_ = other.id();
|
||||||
hidden_ = other.isHidden();
|
hidden_ = other.isHidden();
|
||||||
groupName_ = other.getGroupName();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::requestUpdate(ItemUpdateRequest update)
|
void Item::requestUpdate(ItemUpdateRequest update)
|
||||||
{
|
{
|
||||||
assert(update.type != ITEM_UPDATE_INVALID);
|
assert(update.type != ITEM_UPDATE_INVALID);
|
||||||
assert(!update.changes.isNone());
|
if(update.type != ITEM_UPDATE_LOADED && value_ == update.payload.getValue())
|
||||||
|
|
||||||
if(update.type == ITEM_UPDATE_LOADED)
|
|
||||||
{
|
|
||||||
qDebug()<<__func__<<update.changes.actors<<update.newActors.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!hasChanged(update.payload, update.changes))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(update.type == ITEM_UPDATE_ACTOR && override_)
|
if(update.type == ITEM_UPDATE_ACTOR && override_)
|
||||||
|
|
@ -225,24 +170,20 @@ void Item::requestUpdate(ItemUpdateRequest update)
|
||||||
|
|
||||||
qDebug()<<"Item Update Request for"<<getName()<<" type "<<update.type<<" value "<<update.payload.getValue();
|
qDebug()<<"Item Update Request for"<<getName()<<" type "<<update.type<<" value "<<update.payload.getValue();
|
||||||
|
|
||||||
if(update.type != ITEM_UPDATE_LOADED && update.type != ITEM_UPDATE_BACKEND &&
|
if(update.type != ITEM_UPDATE_LOADED &&
|
||||||
(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY) &&
|
update.type != ITEM_UPDATE_BACKEND &&
|
||||||
update.changes.value)
|
(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY))
|
||||||
enactValue(update.payload.getValue());
|
enactValue(update.payload.getValue());
|
||||||
|
|
||||||
|
if(update.type != ITEM_UPDATE_LOADED)
|
||||||
if(update.changes.value)
|
|
||||||
value_ = update.payload.getValue();
|
|
||||||
if(update.changes.name)
|
|
||||||
name_ = update.payload.getName();
|
|
||||||
if(update.changes.hidden)
|
|
||||||
hidden_ = update.payload.isHidden();
|
|
||||||
if(update.changes.groupName)
|
|
||||||
groupName_ = update.payload.getGroupName();
|
|
||||||
if(update.changes.type)
|
|
||||||
type_ = update.payload.getValueType();
|
|
||||||
if(update.changes.actors)
|
|
||||||
{
|
{
|
||||||
|
value_ = update.payload.getValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name_ = update.payload.getName();
|
||||||
|
//itemId_ = update.payload.id();
|
||||||
|
hidden_ = update.payload.isHidden();
|
||||||
actors_.clear();
|
actors_.clear();
|
||||||
for(std::shared_ptr<Actor>& actor : update.newActors)
|
for(std::shared_ptr<Actor>& actor : update.newActors)
|
||||||
addActor(actor);
|
addActor(actor);
|
||||||
|
|
@ -348,12 +289,14 @@ std::shared_ptr<Item> Item::loadItem(const QJsonObject& json)
|
||||||
return newItem;
|
return newItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemUpdateRequest Item::createValueUpdateRequest(item_update_type_t type,
|
ItemUpdateRequest Item::createValueUpdateRequest(uint8_t value,
|
||||||
|
item_update_type_t type,
|
||||||
bool withActors)
|
bool withActors)
|
||||||
{
|
{
|
||||||
ItemUpdateRequest update;
|
ItemUpdateRequest update;
|
||||||
update.type = type;
|
update.type = type;
|
||||||
update.payload = *this;
|
update.payload = *this;
|
||||||
|
update.payload.setValueData(value);
|
||||||
if(withActors)
|
if(withActors)
|
||||||
update.newActors = actors_;
|
update.newActors = actors_;
|
||||||
return update;
|
return update;
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ class Actor;
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ITEM_VALUE_BOOL = 0,
|
ITEM_VALUE_BOOL = 0,
|
||||||
ITEM_VALUE_UINT,
|
ITEM_VALUE_UINT,
|
||||||
ITEM_VALUE_NO_VALUE,
|
ITEM_VALUE_NO_VALUE
|
||||||
ITEM_VALUE_ENUM,
|
|
||||||
} item_value_type_t;
|
} item_value_type_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -24,9 +23,6 @@ typedef enum {
|
||||||
ITEM_UPDATE_INVALID
|
ITEM_UPDATE_INVALID
|
||||||
} item_update_type_t;
|
} item_update_type_t;
|
||||||
|
|
||||||
struct ItemFieldChanges;
|
|
||||||
struct ItemUpdateRequest;
|
|
||||||
|
|
||||||
class ItemData
|
class ItemData
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -36,8 +32,6 @@ protected:
|
||||||
bool loaded_;
|
bool loaded_;
|
||||||
bool hidden_;
|
bool hidden_;
|
||||||
item_value_type_t type_;
|
item_value_type_t type_;
|
||||||
QString groupName_;
|
|
||||||
std::vector<QString> valueNames_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ItemData(uint32_t itemIdIn = QRandomGenerator::global()->generate(),
|
ItemData(uint32_t itemIdIn = QRandomGenerator::global()->generate(),
|
||||||
|
|
@ -45,8 +39,7 @@ public:
|
||||||
uint8_t value = 0,
|
uint8_t value = 0,
|
||||||
bool loaded = false,
|
bool loaded = false,
|
||||||
bool hidden = false,
|
bool hidden = false,
|
||||||
item_value_type_t type = ITEM_VALUE_BOOL,
|
item_value_type_t type = ITEM_VALUE_BOOL);
|
||||||
QString groupName = "");
|
|
||||||
|
|
||||||
inline bool operator==(const ItemData& in) const
|
inline bool operator==(const ItemData& in) const
|
||||||
{
|
{
|
||||||
|
|
@ -59,8 +52,7 @@ public:
|
||||||
|
|
||||||
uint32_t id() const;
|
uint32_t id() const;
|
||||||
|
|
||||||
bool hasChanged(const ItemData& other) const;
|
bool hasChanged(const ItemData& other);
|
||||||
bool hasChanged(const ItemData& other, const ItemFieldChanges& changes) const;
|
|
||||||
void setName(QString name);
|
void setName(QString name);
|
||||||
uint8_t getValue() const;
|
uint8_t getValue() const;
|
||||||
void setValueData(uint8_t value);
|
void setValueData(uint8_t value);
|
||||||
|
|
@ -69,15 +61,19 @@ public:
|
||||||
bool isHidden() const;
|
bool isHidden() const;
|
||||||
void setHidden(bool hidden);
|
void setHidden(bool hidden);
|
||||||
item_value_type_t getValueType();
|
item_value_type_t getValueType();
|
||||||
QString getGroupName() const;
|
|
||||||
void setGroupName(QString groupName);
|
|
||||||
void storeWithChanges(QJsonObject& json, const ItemFieldChanges& changes);
|
|
||||||
ItemFieldChanges loadWithChanges(const QJsonObject& json, const bool preserve = false);
|
|
||||||
virtual QString getName() const;
|
virtual QString getName() const;
|
||||||
virtual void store(QJsonObject& json);
|
virtual void store(QJsonObject& json);
|
||||||
virtual void load(const QJsonObject& json, const bool preserve = false);
|
virtual void load(const QJsonObject& json, const bool preserve = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ItemUpdateRequest
|
||||||
|
{
|
||||||
|
item_update_type_t type = ITEM_UPDATE_INVALID;
|
||||||
|
ItemData payload;
|
||||||
|
std::vector<std::shared_ptr<Actor> > newActors;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Item: public QObject, public ItemData
|
class Item: public QObject, public ItemData
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -108,7 +104,8 @@ public:
|
||||||
void setActorsActive(bool in);
|
void setActorsActive(bool in);
|
||||||
void setOverride(const bool in);
|
void setOverride(const bool in);
|
||||||
bool getOverride();
|
bool getOverride();
|
||||||
ItemUpdateRequest createValueUpdateRequest(item_update_type_t type,
|
ItemUpdateRequest createValueUpdateRequest(uint8_t value,
|
||||||
|
item_update_type_t type,
|
||||||
bool withActors = false);
|
bool withActors = false);
|
||||||
|
|
||||||
virtual void store(QJsonObject& json);
|
virtual void store(QJsonObject& json);
|
||||||
|
|
@ -121,52 +118,3 @@ protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ItemFieldChanges
|
|
||||||
{
|
|
||||||
bool name :1;
|
|
||||||
bool value :1;
|
|
||||||
bool hidden :1;
|
|
||||||
bool type :1;
|
|
||||||
bool groupName :1;
|
|
||||||
bool actors :1;
|
|
||||||
ItemFieldChanges(bool defaultVal = false)
|
|
||||||
{
|
|
||||||
name = defaultVal;
|
|
||||||
value = defaultVal;
|
|
||||||
hidden = defaultVal;
|
|
||||||
type = defaultVal;
|
|
||||||
groupName = defaultVal;
|
|
||||||
actors = false;
|
|
||||||
}
|
|
||||||
inline bool isNone() const
|
|
||||||
{
|
|
||||||
return !name && !value && !hidden && !type && !groupName && !actors;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ItemUpdateRequest
|
|
||||||
{
|
|
||||||
item_update_type_t type = ITEM_UPDATE_INVALID;
|
|
||||||
ItemData payload;
|
|
||||||
ItemFieldChanges changes;
|
|
||||||
std::vector<std::shared_ptr<Actor> > newActors;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ItemAddRequest
|
|
||||||
{
|
|
||||||
item_update_type_t type = ITEM_UPDATE_INVALID;
|
|
||||||
std::shared_ptr<Item> payload;
|
|
||||||
ItemFieldChanges changes;
|
|
||||||
inline ItemUpdateRequest updateRequest() const
|
|
||||||
{
|
|
||||||
ItemUpdateRequest update;
|
|
||||||
update.payload = *payload;
|
|
||||||
update.type = type;
|
|
||||||
update.changes = changes;
|
|
||||||
if(changes.actors)
|
|
||||||
update.newActors = payload->getActors();
|
|
||||||
return update;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ ItemLoaderSource::ItemLoaderSource(const QJsonObject& json, QObject *parent):
|
||||||
|
|
||||||
void ItemLoaderSource::refresh()
|
void ItemLoaderSource::refresh()
|
||||||
{
|
{
|
||||||
std::vector<ItemAddRequest> itemAddRequests;
|
std::vector<std::shared_ptr<Item>> items;
|
||||||
const QJsonArray itemsArray(json["Items"].toArray());
|
const QJsonArray itemsArray(json["Items"].toArray());
|
||||||
for(int i = 0; i < itemsArray.size(); ++i)
|
for(int i = 0; i < itemsArray.size(); ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -21,15 +21,11 @@ void ItemLoaderSource::refresh()
|
||||||
std::shared_ptr<Item> newItem = Item::loadItem(itemObject);
|
std::shared_ptr<Item> newItem = Item::loadItem(itemObject);
|
||||||
if(newItem)
|
if(newItem)
|
||||||
{
|
{
|
||||||
|
items.push_back(newItem);
|
||||||
qDebug()<<"Loaded item"<<newItem->getName();
|
qDebug()<<"Loaded item"<<newItem->getName();
|
||||||
ItemAddRequest request;
|
|
||||||
request.type = ITEM_UPDATE_LOADED;
|
|
||||||
request.payload = newItem;
|
|
||||||
request.changes = ItemFieldChanges(true);
|
|
||||||
itemAddRequests.push_back(request);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gotItems(itemAddRequests);
|
gotItems(items, ITEM_UPDATE_LOADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLoaderSource::updateJson(const QJsonObject& json)
|
void ItemLoaderSource::updateJson(const QJsonObject& json)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ public slots:
|
||||||
virtual void refresh() = 0;
|
virtual void refresh() = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void gotItems(std::vector<ItemAddRequest> items);
|
void gotItems(std::vector<std::shared_ptr<Item>> items, item_update_type_t updateType);
|
||||||
void requestReplaceItems(std::vector<std::shared_ptr<Item>> items);
|
void requestReplaceItems(std::vector<std::shared_ptr<Item>> items);
|
||||||
void updateItems(std::vector<ItemUpdateRequest> updates);
|
void updateItems(std::vector<ItemUpdateRequest> updates);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,38 +6,39 @@ ItemStore::ItemStore(QObject *parent): QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemStore::addItem(const ItemAddRequest& item)
|
void ItemStore::addItem(const std::shared_ptr<Item>& item, item_update_type_t updateType)
|
||||||
{
|
{
|
||||||
qDebug()<<"Item add request for"<<item.payload->getName()<<item.payload->id();
|
|
||||||
std::shared_ptr<Item> matched = nullptr;
|
std::shared_ptr<Item> matched = nullptr;
|
||||||
for(unsigned i = 0; i < items_.size(); i++ )
|
for(unsigned i = 0; i < items_.size(); i++ )
|
||||||
{
|
{
|
||||||
if(*items_[i] == *item.payload)
|
if(*items_[i] == *item)
|
||||||
{
|
{
|
||||||
matched = items_[i];
|
matched = items_[i];
|
||||||
assert(matched->id() == items_[i]->id());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!matched)
|
if(!matched)
|
||||||
{
|
{
|
||||||
items_.push_back(item.payload);
|
items_.push_back(std::shared_ptr<Item>(item));
|
||||||
connect(item.payload.get(), &Item::updated, this, &ItemStore::itemUpdateSlot);
|
connect(item.get(), &Item::updated, this, &ItemStore::itemUpdateSlot);
|
||||||
qDebug()<<"Item"<<item.payload->getName()<<"added"<<(item.payload->getLoaded() ? "from loaded" : "");
|
qDebug()<<"Item"<<item->getName()<<"added"<<(item->getLoaded() ? "from loaded" : "");
|
||||||
itemAdded(std::weak_ptr<Item>(items_.back()));
|
itemAdded(std::weak_ptr<Item>(items_.back()));
|
||||||
}
|
}
|
||||||
else if(!item.changes.isNone())
|
else
|
||||||
{
|
{
|
||||||
qDebug()<<"Item"<<item.payload->getName()<<"was matched with"<<matched->getName()<<"and has changes";
|
ItemUpdateRequest request = item->createValueUpdateRequest(item->getValue(),
|
||||||
ItemUpdateRequest request = item.updateRequest();
|
updateType,
|
||||||
|
updateType == ITEM_UPDATE_LOADED);
|
||||||
|
request.newActors = item->getActors();
|
||||||
updateItem(request);
|
updateItem(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemStore::addItems(const std::vector<ItemAddRequest>& itemIn)
|
void ItemStore::addItems(const std::vector<std::shared_ptr<Item>>& itemIn,
|
||||||
|
item_update_type_t updateType)
|
||||||
{
|
{
|
||||||
for(unsigned j = 0; j < itemIn.size(); j++)
|
for(unsigned j = 0; j < itemIn.size(); j++)
|
||||||
addItem(itemIn[j]);
|
addItem(itemIn[j], updateType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemStore::removeItem(const ItemData& item)
|
void ItemStore::removeItem(const ItemData& item)
|
||||||
|
|
@ -56,15 +57,8 @@ void ItemStore::removeItem(const ItemData& item)
|
||||||
|
|
||||||
void ItemStore::replaceItems(const std::vector<std::shared_ptr<Item>>& items)
|
void ItemStore::replaceItems(const std::vector<std::shared_ptr<Item>>& items)
|
||||||
{
|
{
|
||||||
for(const std::shared_ptr<Item>& item : items)
|
qDebug()<<__func__;
|
||||||
{
|
addItems(items, ITEM_UPDATE_LOADED);
|
||||||
ItemAddRequest request;
|
|
||||||
request.changes = ItemFieldChanges(true);
|
|
||||||
request.changes.actors = true;
|
|
||||||
request.type = ITEM_UPDATE_LOADED;
|
|
||||||
request.payload = item;
|
|
||||||
addItem(request);
|
|
||||||
}
|
|
||||||
std::vector<ItemData> deletedItems;
|
std::vector<ItemData> deletedItems;
|
||||||
for(std::shared_ptr<Item> item : items_)
|
for(std::shared_ptr<Item> item : items_)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void removeItem(const ItemData& item);
|
void removeItem(const ItemData& item);
|
||||||
void addItem(const ItemAddRequest& item);
|
void addItem(const std::shared_ptr<Item>& item, item_update_type_t updateType);
|
||||||
void addItems(const std::vector<ItemAddRequest>& itemsIn);
|
void addItems(const std::vector<std::shared_ptr<Item>>& itemsIn, item_update_type_t updateType);
|
||||||
void replaceItems(const std::vector<std::shared_ptr<Item>>& items);
|
void replaceItems(const std::vector<std::shared_ptr<Item>>& items);
|
||||||
void updateItems(const std::vector<ItemUpdateRequest>& updates);
|
void updateItems(const std::vector<ItemUpdateRequest>& updates);
|
||||||
void updateItem(const ItemUpdateRequest& update);
|
void updateItem(const ItemUpdateRequest& update);
|
||||||
|
|
|
||||||
11
src/main.cpp
11
src/main.cpp
|
|
@ -115,7 +115,12 @@ int main(int argc, char *argv[])
|
||||||
QObject::connect(&mainObject.micro, SIGNAL(textRecived(QString)), w, SLOT(changeHeaderLableText(QString)));
|
QObject::connect(&mainObject.micro, SIGNAL(textRecived(QString)), w, SLOT(changeHeaderLableText(QString)));
|
||||||
QObject::connect(w, &MainWindow::sigSetRgb, &mainObject.micro, &Microcontroller::changeRgbColor);
|
QObject::connect(w, &MainWindow::sigSetRgb, &mainObject.micro, &Microcontroller::changeRgbColor);
|
||||||
QObject::connect(w, &MainWindow::sigSave, &mainObject, [&mainObject, settingsPath](){mainObject.storeToDisk(settingsPath);});
|
QObject::connect(w, &MainWindow::sigSave, &mainObject, [&mainObject, settingsPath](){mainObject.storeToDisk(settingsPath);});
|
||||||
QObject::connect(w, &MainWindow::createdItem, &globalItems, &ItemStore::addItem);
|
QObject::connect(w,
|
||||||
|
&MainWindow::createdItem,
|
||||||
|
&globalItems,
|
||||||
|
[](std::shared_ptr<Item> item) {
|
||||||
|
globalItems.addItem(item, ITEM_UPDATE_USER);
|
||||||
|
});
|
||||||
w->show();
|
w->show();
|
||||||
}
|
}
|
||||||
retVal = a.exec();
|
retVal = a.exec();
|
||||||
|
|
@ -127,7 +132,9 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
SecondaryMainObject mainObject(parser.value(hostOption), parser.value(portOption).toInt());
|
SecondaryMainObject mainObject(parser.value(hostOption), parser.value(portOption).toInt());
|
||||||
MainWindow w(&mainObject);
|
MainWindow w(&mainObject);
|
||||||
QObject::connect(&w, &MainWindow::createdItem, &globalItems, &ItemStore::addItem);
|
QObject::connect(&w, &MainWindow::createdItem, &globalItems, [](std::shared_ptr<Item> item) {
|
||||||
|
globalItems.addItem(item, ITEM_UPDATE_USER);
|
||||||
|
});
|
||||||
QObject::connect(&w, &MainWindow::sigSave, mainObject.tcpClient, &TcpClient::sendItems);
|
QObject::connect(&w, &MainWindow::sigSave, mainObject.tcpClient, &TcpClient::sendItems);
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -157,31 +157,16 @@ void Microcontroller::processList(const QString& buffer)
|
||||||
else if(buffer.contains("EOL"))
|
else if(buffer.contains("EOL"))
|
||||||
{
|
{
|
||||||
listMode = false;
|
listMode = false;
|
||||||
std::vector<ItemAddRequest> requests;
|
gotItems(relayList, ITEM_UPDATE_BACKEND);
|
||||||
for(const std::shared_ptr<Item>& item : relayList)
|
|
||||||
{
|
|
||||||
ItemAddRequest request;
|
|
||||||
request.changes.name = true;
|
|
||||||
request.changes.value = true;
|
|
||||||
request.payload = item;
|
|
||||||
request.type = ITEM_UPDATE_BACKEND;
|
|
||||||
requests.push_back(request);
|
|
||||||
}
|
|
||||||
gotItems(requests);
|
|
||||||
relayList.clear();
|
relayList.clear();
|
||||||
}
|
}
|
||||||
else
|
else listMode = false;
|
||||||
{
|
|
||||||
listMode = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Microcontroller::processRelayState(const QString& buffer)
|
void Microcontroller::processRelayState(const QString& buffer)
|
||||||
{
|
{
|
||||||
ItemUpdateRequest update;
|
ItemUpdateRequest update;
|
||||||
update.type = ITEM_UPDATE_BACKEND;
|
update.type = ITEM_UPDATE_BACKEND;
|
||||||
update.changes.name = true;
|
|
||||||
update.changes.value = true;
|
|
||||||
update.payload = static_cast<ItemData>(*processRelayLine(buffer));
|
update.payload = static_cast<ItemData>(*processRelayLine(buffer));
|
||||||
updateItems({update});
|
updateItems({update});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ void Server::processIncomeingJson(const QByteArray& jsonbytes)
|
||||||
QJsonArray data = json["Data"].toArray();
|
QJsonArray data = json["Data"].toArray();
|
||||||
bool FullList = json["FullList"].toBool(false);
|
bool FullList = json["FullList"].toBool(false);
|
||||||
std::vector<std::shared_ptr<Item>> items;
|
std::vector<std::shared_ptr<Item>> items;
|
||||||
std::vector<ItemFieldChanges> fieldChanges;
|
|
||||||
for(QJsonValueRef itemjson : data)
|
for(QJsonValueRef itemjson : data)
|
||||||
{
|
{
|
||||||
QJsonObject jsonobject = itemjson.toObject();
|
QJsonObject jsonobject = itemjson.toObject();
|
||||||
|
|
@ -34,7 +33,6 @@ void Server::processIncomeingJson(const QByteArray& jsonbytes)
|
||||||
{
|
{
|
||||||
qDebug()<<"Server got item"<<item->getName();
|
qDebug()<<"Server got item"<<item->getName();
|
||||||
item->setLoaded(FullList);
|
item->setLoaded(FullList);
|
||||||
fieldChanges.push_back(item->loadWithChanges(jsonobject));
|
|
||||||
items.push_back(item);
|
items.push_back(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -45,16 +43,7 @@ void Server::processIncomeingJson(const QByteArray& jsonbytes)
|
||||||
}
|
}
|
||||||
else if(!items.empty())
|
else if(!items.empty())
|
||||||
{
|
{
|
||||||
std::vector<ItemUpdateRequest> updates;
|
gotItems(items, ITEM_UPDATE_REMOTE);
|
||||||
for(size_t i = 0; i < items.size(); i++)
|
|
||||||
{
|
|
||||||
ItemUpdateRequest request;
|
|
||||||
request.payload = *items[i];
|
|
||||||
request.changes = fieldChanges[i];
|
|
||||||
request.type = ITEM_UPDATE_REMOTE;
|
|
||||||
updates.push_back(request);
|
|
||||||
}
|
|
||||||
updateItems(updates);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ void Service::sendItems()
|
||||||
sendJson(json);
|
sendJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Service::processIncomeingJson(const QByteArray& jsonbytes)
|
void Service::processIncomeingJson(const QByteArray& jsonbytes)
|
||||||
{
|
{
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
|
QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
|
||||||
|
|
@ -81,6 +82,7 @@ void Service::processIncomeingJson(const QByteArray& jsonbytes)
|
||||||
else if(type == "SensorUpdate")
|
else if(type == "SensorUpdate")
|
||||||
{
|
{
|
||||||
QJsonArray data = json["Data"].toArray();
|
QJsonArray data = json["Data"].toArray();
|
||||||
|
qWarning()<<"Got sensor update with no/empty sensors array";
|
||||||
for(QJsonValueRef sensorjson : data)
|
for(QJsonValueRef sensorjson : data)
|
||||||
{
|
{
|
||||||
QJsonObject jsonobject = sensorjson.toObject();
|
QJsonObject jsonobject = sensorjson.toObject();
|
||||||
|
|
|
||||||
|
|
@ -34,40 +34,20 @@ void TcpClient::processIncomeingJson(const QByteArray& jsonbytes)
|
||||||
if(type == "ItemUpdate")
|
if(type == "ItemUpdate")
|
||||||
{
|
{
|
||||||
QJsonArray data = json["Data"].toArray();
|
QJsonArray data = json["Data"].toArray();
|
||||||
bool FullList = json["FullList"].toBool(false);
|
|
||||||
std::vector<std::shared_ptr<Item>> items;
|
std::vector<std::shared_ptr<Item>> items;
|
||||||
std::vector<ItemFieldChanges> fieldChanges;
|
|
||||||
for(QJsonValueRef itemjson : data)
|
for(QJsonValueRef itemjson : data)
|
||||||
{
|
{
|
||||||
QJsonObject jsonobject = itemjson.toObject();
|
QJsonObject jsonobject = itemjson.toObject();
|
||||||
std::shared_ptr<Item> item = Item::loadItem(jsonobject);
|
std::shared_ptr<Item> item = Item::loadItem(jsonobject);
|
||||||
if(item)
|
if(item)
|
||||||
{
|
{
|
||||||
item->setLoaded(FullList);
|
qDebug()<<"Client got item"<<item->getName();
|
||||||
fieldChanges.push_back(item->loadWithChanges(jsonobject));
|
item->setLoaded(false);
|
||||||
items.push_back(item);
|
items.push_back(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(FullList && !items.empty())
|
if(!items.empty())
|
||||||
{
|
gotItems(items, ITEM_UPDATE_REMOTE);
|
||||||
qDebug()<<"Client replaceing items";
|
|
||||||
requestReplaceItems(items);
|
|
||||||
}
|
|
||||||
else if(!items.empty())
|
|
||||||
{
|
|
||||||
std::vector<ItemAddRequest> itemAddRequests;
|
|
||||||
qDebug()<<"Client updateing items";
|
|
||||||
for(size_t i = 0; i < items.size(); i++)
|
|
||||||
{
|
|
||||||
ItemAddRequest request;
|
|
||||||
request.type = ITEM_UPDATE_REMOTE;
|
|
||||||
request.payload = items[i];
|
|
||||||
request.changes = fieldChanges[i];
|
|
||||||
itemAddRequests.push_back(request);
|
|
||||||
qDebug()<<"Payload"<<request.payload->id();
|
|
||||||
}
|
|
||||||
gotItems(itemAddRequests);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -106,11 +106,8 @@ ActorSettingsDialog::~ActorSettingsDialog()
|
||||||
|
|
||||||
void ActorSettingsDialog::editAsItem()
|
void ActorSettingsDialog::editAsItem()
|
||||||
{
|
{
|
||||||
setModal(false);
|
ItemSettingsDialog itemSettingsDiag(actor_, this);
|
||||||
ItemSettingsDialog itemSettingsDiag(actor_, false, this);
|
|
||||||
itemSettingsDiag.setModal(false);
|
|
||||||
itemSettingsDiag.exec();
|
itemSettingsDiag.exec();
|
||||||
setModal(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActorSettingsDialog::setEnabled()
|
void ActorSettingsDialog::setEnabled()
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
#include "itemscrollbox.h"
|
#include "itemscrollbox.h"
|
||||||
#include "ui_relayscrollbox.h"
|
#include "ui_relayscrollbox.h"
|
||||||
#include <QScrollArea>
|
#include "../items/auxitem.h"
|
||||||
#include <QFrame>
|
#include "../items/messageitem.h"
|
||||||
|
|
||||||
ItemScrollBox::ItemScrollBox(QWidget *parent) :
|
ItemScrollBox::ItemScrollBox(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
ui(new Ui::RelayScrollBox)
|
ui(new Ui::RelayScrollBox)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
QScroller::grabGesture(ui->scrollArea, QScroller::TouchGesture);
|
||||||
ensureTabExists("All");
|
QScroller::grabGesture(ui->scrollArea, QScroller::LeftMouseButtonGesture);
|
||||||
ui->tabWidget->setCurrentIndex(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemScrollBox::~ItemScrollBox()
|
ItemScrollBox::~ItemScrollBox()
|
||||||
|
|
@ -24,166 +23,24 @@ void ItemScrollBox::addItem(std::weak_ptr<Item> item)
|
||||||
{
|
{
|
||||||
if(workItem->isHidden())
|
if(workItem->isHidden())
|
||||||
return;
|
return;
|
||||||
|
widgets_.push_back(new ItemWidget(item));
|
||||||
// Add to "All" tab
|
ui->relayWidgetVbox->addWidget(widgets_.back());
|
||||||
widgets_["All"].push_back(new ItemWidget(item, false));
|
connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);
|
||||||
QWidget* allScrollContent = tabs_["All"].content;
|
connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem);
|
||||||
QLayout* layout = allScrollContent->layout();
|
|
||||||
layout->removeItem(tabs_["All"].spacer);
|
|
||||||
layout->addWidget(widgets_["All"].back());
|
|
||||||
layout->addItem(tabs_["All"].spacer);
|
|
||||||
connect(widgets_["All"].back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);
|
|
||||||
connect(widgets_["All"].back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem);
|
|
||||||
|
|
||||||
addItemToTabs(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemScrollBox::addItemToTabs(std::weak_ptr<Item> item)
|
|
||||||
{
|
|
||||||
if(auto workItem = item.lock())
|
|
||||||
{
|
|
||||||
if(workItem->isHidden())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString groupName = workItem->getGroupName();
|
|
||||||
if(groupName.isEmpty() || groupName != "All")
|
|
||||||
{
|
|
||||||
ensureTabExists(groupName);
|
|
||||||
ItemWidget* groupWidget = new ItemWidget(item, true);
|
|
||||||
widgets_[groupName].push_back(groupWidget);
|
|
||||||
|
|
||||||
QWidget* scrollContent = tabs_[groupName].content;
|
|
||||||
QLayout* groupLayout = scrollContent->layout();
|
|
||||||
groupLayout->removeItem(tabs_[groupName].spacer);
|
|
||||||
groupLayout->addWidget(groupWidget);
|
|
||||||
groupLayout->addItem(tabs_[groupName].spacer);
|
|
||||||
|
|
||||||
connect(groupWidget, &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);
|
|
||||||
connect(groupWidget, &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem);
|
|
||||||
|
|
||||||
connect(widgets_[groupName].back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);
|
|
||||||
connect(widgets_[groupName].back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemScrollBox::removeItem(const ItemData& item)
|
void ItemScrollBox::removeItem(const ItemData& item)
|
||||||
{
|
{
|
||||||
QString key = "All";
|
for(unsigned i = 0; i < widgets_.size(); i++)
|
||||||
std::vector<ItemWidget*>& widgets = widgets_[key];
|
|
||||||
for(unsigned i = 0; i < widgets.size(); i++)
|
|
||||||
{
|
{
|
||||||
if(widgets[i]->controles(item))
|
if(widgets_[i]->controles(item))
|
||||||
{
|
{
|
||||||
QWidget* tabContent = tabs_[key].content;
|
ui->relayWidgetVbox->removeWidget(widgets_[i]);
|
||||||
if(tabContent)
|
delete widgets_[i];
|
||||||
{
|
widgets_.erase(widgets_.begin()+i);
|
||||||
QLayout* layout = tabContent->layout();
|
|
||||||
if(layout)
|
|
||||||
layout->removeWidget(widgets[i]);
|
|
||||||
}
|
|
||||||
delete widgets[i];
|
|
||||||
widgets.erase(widgets.begin()+i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeItemFromTabs(item);
|
|
||||||
cleanupEmptyTabs();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemScrollBox::removeItemFromTabs(const ItemData& item)
|
|
||||||
{
|
|
||||||
for(const QString& key : widgets_.keys())
|
|
||||||
{
|
|
||||||
if(key == "All")
|
|
||||||
continue;
|
|
||||||
std::vector<ItemWidget*>& widgets = widgets_[key];
|
|
||||||
for(unsigned i = 0; i < widgets.size(); i++)
|
|
||||||
{
|
|
||||||
if(widgets[i]->controles(item))
|
|
||||||
{
|
|
||||||
QWidget* tabContent = tabs_[key].content;
|
|
||||||
if(tabContent)
|
|
||||||
{
|
|
||||||
QLayout* layout = tabContent->layout();
|
|
||||||
if(layout)
|
|
||||||
layout->removeWidget(widgets[i]);
|
|
||||||
}
|
|
||||||
delete widgets[i];
|
|
||||||
widgets.erase(widgets.begin()+i);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanupEmptyTabs();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ItemScrollBox::onItemUpdate(const ItemUpdateRequest& update)
|
|
||||||
{
|
|
||||||
if(!update.changes.groupName)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(ItemWidget* widget : widgets_["All"])
|
|
||||||
{
|
|
||||||
if(widget->controles(update.payload))
|
|
||||||
{
|
|
||||||
qDebug()<<"ItemUpdate with group change";
|
|
||||||
std::weak_ptr<Item> item = widget->getItem();
|
|
||||||
removeItemFromTabs(update.payload);
|
|
||||||
addItemToTabs(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemScrollBox::ensureTabExists(const QString& groupName)
|
|
||||||
{
|
|
||||||
if(!tabs_.contains(groupName))
|
|
||||||
{
|
|
||||||
Tab tab;
|
|
||||||
tab.scroller = new QScrollArea(ui->tabWidget);
|
|
||||||
tab.scroller->setWidgetResizable(true);
|
|
||||||
tab.scroller->setFrameShape(QFrame::NoFrame);
|
|
||||||
tab.scroller->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
|
|
||||||
tab.content = new QWidget(tab.scroller);
|
|
||||||
QVBoxLayout* scrollLayout = new QVBoxLayout(tab.content);
|
|
||||||
scrollLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
tab.content->setLayout(scrollLayout);
|
|
||||||
tab.content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
||||||
tab.scroller->setWidget(tab.content);
|
|
||||||
|
|
||||||
tab.spacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
|
|
||||||
scrollLayout->addSpacerItem(tab.spacer);
|
|
||||||
|
|
||||||
ui->tabWidget->addTab(tab.scroller, groupName);
|
|
||||||
tabs_[groupName] = tab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemScrollBox::cleanupEmptyTabs()
|
|
||||||
{
|
|
||||||
for(auto it = tabs_.begin(); it != tabs_.end(); ++it)
|
|
||||||
{
|
|
||||||
QString groupName = it.key();
|
|
||||||
if(groupName == "All")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
qDebug()<<__func__<<it.value().content->layout()->count();
|
|
||||||
|
|
||||||
if(it.value().content->layout()->count() <= 1)
|
|
||||||
{
|
|
||||||
int index = ui->tabWidget->indexOf(tabs_[groupName].scroller);
|
|
||||||
if(index >= 0)
|
|
||||||
ui->tabWidget->removeTab(index);
|
|
||||||
Tab tab = tabs_.take(groupName);
|
|
||||||
delete tab.content;
|
|
||||||
delete tab.scroller;
|
|
||||||
cleanupEmptyTabs();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QScrollArea>
|
#include <QScroller>
|
||||||
#include <QSpacerItem>
|
|
||||||
#include "itemwidget.h"
|
#include "itemwidget.h"
|
||||||
|
#include "../items/relay.h"
|
||||||
#include "../items/item.h"
|
#include "../items/item.h"
|
||||||
#include "../items/itemstore.h"
|
#include "../items/itemstore.h"
|
||||||
|
|
||||||
|
|
@ -20,16 +20,7 @@ class ItemScrollBox : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
struct Tab
|
std::vector< ItemWidget* > widgets_;
|
||||||
{
|
|
||||||
QScrollArea* scroller;
|
|
||||||
QWidget* content;
|
|
||||||
QSpacerItem* spacer;
|
|
||||||
};
|
|
||||||
|
|
||||||
QMap<QString, Tab> tabs_;
|
|
||||||
QMap<QString, std::vector<ItemWidget*>> widgets_;
|
|
||||||
Ui::RelayScrollBox *ui;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void deleteRequest(const ItemData& item);
|
void deleteRequest(const ItemData& item);
|
||||||
|
|
@ -45,15 +36,9 @@ public slots:
|
||||||
|
|
||||||
void addItem(std::weak_ptr<Item> item);
|
void addItem(std::weak_ptr<Item> item);
|
||||||
void removeItem(const ItemData& item);
|
void removeItem(const ItemData& item);
|
||||||
void onItemUpdate(const ItemUpdateRequest& update);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ensureTabExists(const QString& groupName);
|
Ui::RelayScrollBox *ui;
|
||||||
void cleanupEmptyTabs();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void addItemToTabs(std::weak_ptr<Item> item);
|
|
||||||
void removeItemFromTabs(const ItemData& item);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RELAYSCROLLBOX_H
|
#endif // RELAYSCROLLBOX_H
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#include "itemsettingsdialog.h"
|
#include "itemsettingsdialog.h"
|
||||||
#include "ui_itemsettingsdialog.h"
|
#include "ui_itemsettingsdialog.h"
|
||||||
#include "../items/itemstore.h"
|
|
||||||
#include "actorsettingsdialog.h"
|
#include "actorsettingsdialog.h"
|
||||||
#include "../actors/alarmtime.h"
|
#include "../actors/alarmtime.h"
|
||||||
#include "../actors/sensoractor.h"
|
#include "../actors/sensoractor.h"
|
||||||
|
|
@ -14,7 +13,7 @@
|
||||||
#include "itemsettingswidgets/relayitemsettingswidget.h"
|
#include "itemsettingswidgets/relayitemsettingswidget.h"
|
||||||
#include<memory>
|
#include<memory>
|
||||||
|
|
||||||
ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr<Item> item, bool noGroup, QWidget *parent) :
|
ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr<Item> item, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
item_(item),
|
item_(item),
|
||||||
ui(new Ui::ItemSettingsDialog)
|
ui(new Ui::ItemSettingsDialog)
|
||||||
|
|
@ -23,17 +22,9 @@ ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr<Item> item, bool noGroup,
|
||||||
|
|
||||||
setModal(false);
|
setModal(false);
|
||||||
|
|
||||||
if(noGroup)
|
|
||||||
ui->comboBox_Group->setEnabled(false);
|
|
||||||
|
|
||||||
ui->label_name->setText(item_->getName());
|
ui->label_name->setText(item_->getName());
|
||||||
ui->checkBox_Override->setChecked(item_->getOverride());
|
ui->checkBox_Override->setChecked(item_->getOverride());
|
||||||
|
|
||||||
// Setup group combobox with editable mode for creating new groups
|
|
||||||
ui->comboBox_Group->setEditable(true);
|
|
||||||
ui->comboBox_Group->addItem("All");
|
|
||||||
ui->comboBox_Group->addItems(getExistingGroups());
|
|
||||||
ui->comboBox_Group->setCurrentText(item_->getGroupName());
|
|
||||||
|
|
||||||
if(std::shared_ptr<Relay> relay = std::dynamic_pointer_cast<Relay>(item_))
|
if(std::shared_ptr<Relay> relay = std::dynamic_pointer_cast<Relay>(item_))
|
||||||
{
|
{
|
||||||
|
|
@ -57,7 +48,6 @@ ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr<Item> item, bool noGroup,
|
||||||
connect(ui->pushButton_remove, &QPushButton::clicked, this, &ItemSettingsDialog::removeActor);
|
connect(ui->pushButton_remove, &QPushButton::clicked, this, &ItemSettingsDialog::removeActor);
|
||||||
connect(ui->pushButton_edit, &QPushButton::clicked, this, &ItemSettingsDialog::editActor);
|
connect(ui->pushButton_edit, &QPushButton::clicked, this, &ItemSettingsDialog::editActor);
|
||||||
connect(ui->checkBox_Override, &QPushButton::clicked, this, &ItemSettingsDialog::changeOverride);
|
connect(ui->checkBox_Override, &QPushButton::clicked, this, &ItemSettingsDialog::changeOverride);
|
||||||
connect(ui->comboBox_Group, &QComboBox::currentTextChanged, this, &ItemSettingsDialog::changeGroup);
|
|
||||||
|
|
||||||
|
|
||||||
ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("Actor"));
|
ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("Actor"));
|
||||||
|
|
@ -71,23 +61,10 @@ ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr<Item> item, bool noGroup,
|
||||||
|
|
||||||
ItemSettingsDialog::~ItemSettingsDialog()
|
ItemSettingsDialog::~ItemSettingsDialog()
|
||||||
{
|
{
|
||||||
if(itemSpecificWidget_)
|
if(itemSpecificWidget_) delete itemSpecificWidget_;
|
||||||
delete itemSpecificWidget_;
|
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemSettingsDialog::changeGroup()
|
|
||||||
{
|
|
||||||
QString newGroup = ui->comboBox_Group->currentText();
|
|
||||||
if(newGroup != item_->getGroupName())
|
|
||||||
{
|
|
||||||
ItemUpdateRequest update = item_->createValueUpdateRequest(ITEM_UPDATE_USER);
|
|
||||||
update.payload.setGroupName(newGroup);
|
|
||||||
update.changes.groupName = true;
|
|
||||||
item_->requestUpdate(update);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemSettingsDialog::changeOverride()
|
void ItemSettingsDialog::changeOverride()
|
||||||
{
|
{
|
||||||
item_->setOverride(ui->checkBox_Override->isChecked());
|
item_->setOverride(ui->checkBox_Override->isChecked());
|
||||||
|
|
@ -189,21 +166,14 @@ void ItemSettingsDialog::editActor()
|
||||||
|
|
||||||
ActorSettingsDialog* dialog;
|
ActorSettingsDialog* dialog;
|
||||||
|
|
||||||
if(alarmTime)
|
if(alarmTime) dialog = new ActorSettingsDialog(alarmTime, this);
|
||||||
dialog = new ActorSettingsDialog(alarmTime, this);
|
else if(regulator) dialog = new ActorSettingsDialog(regulator, this);
|
||||||
else if(regulator)
|
else if(sensorActor) dialog = new ActorSettingsDialog(sensorActor, this);
|
||||||
dialog = new ActorSettingsDialog(regulator, this);
|
else if(timerActor) dialog = new ActorSettingsDialog(timerActor, this);
|
||||||
else if(sensorActor)
|
else if(polynomalActor) dialog = new ActorSettingsDialog(polynomalActor, this);
|
||||||
dialog = new ActorSettingsDialog(sensorActor, this);
|
else if(factorActor) dialog = new ActorSettingsDialog(factorActor, this);
|
||||||
else if(timerActor)
|
else dialog = new ActorSettingsDialog(actor, this);
|
||||||
dialog = new ActorSettingsDialog(timerActor, this);
|
dialog->setParent(this);
|
||||||
else if(polynomalActor)
|
|
||||||
dialog = new ActorSettingsDialog(polynomalActor, this);
|
|
||||||
else if(factorActor)
|
|
||||||
dialog = new ActorSettingsDialog(factorActor, this);
|
|
||||||
else
|
|
||||||
dialog = new ActorSettingsDialog(actor, this);
|
|
||||||
|
|
||||||
dialog->show();
|
dialog->show();
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
|
|
||||||
|
|
@ -213,19 +183,5 @@ void ItemSettingsDialog::editActor()
|
||||||
ui->tableWidget->item(i, 1)->setText(item_->getActors()[i]->actionName());
|
ui->tableWidget->item(i, 1)->setText(item_->getActors()[i]->actionName());
|
||||||
ui->tableWidget->item(i, 2)->setText(item_->getActors()[i]->isActive() ? "Y" : "N");
|
ui->tableWidget->item(i, 2)->setText(item_->getActors()[i]->isActive() ? "Y" : "N");
|
||||||
}
|
}
|
||||||
delete dialog;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ItemSettingsDialog::getExistingGroups()
|
|
||||||
{
|
|
||||||
QSet<QString> uniqueGroups;
|
|
||||||
for(const auto& item : *globalItems.getItems())
|
|
||||||
{
|
|
||||||
if(!item->getGroupName().isEmpty() && item->getGroupName() != "All")
|
|
||||||
{
|
|
||||||
uniqueGroups.insert(item->getGroupName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return uniqueGroups.values();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,9 @@ class ItemSettingsDialog : public QDialog
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadActorList();
|
void loadActorList();
|
||||||
QStringList getExistingGroups();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ItemSettingsDialog(std::shared_ptr<Item> item, bool noGroup = false, QWidget *parent = nullptr);
|
explicit ItemSettingsDialog(std::shared_ptr<Item> item, QWidget *parent = nullptr);
|
||||||
~ItemSettingsDialog();
|
~ItemSettingsDialog();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
@ -31,7 +30,6 @@ private slots:
|
||||||
void addActor();
|
void addActor();
|
||||||
void editActor();
|
void editActor();
|
||||||
void changeOverride();
|
void changeOverride();
|
||||||
void changeGroup();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ItemSettingsDialog *ui;
|
Ui::ItemSettingsDialog *ui;
|
||||||
|
|
|
||||||
|
|
@ -63,20 +63,6 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_group">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_Group">
|
|
||||||
<property name="text">
|
|
||||||
<string>Group:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="comboBox_Group"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="checkBox_Override">
|
<widget class="QCheckBox" name="checkBox_Override">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,10 @@
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include "itemsettingsdialog.h"
|
|
||||||
|
|
||||||
ItemWidget::ItemWidget(std::weak_ptr<Item> item, bool noGroupEdit, QWidget *parent) :
|
ItemWidget::ItemWidget(std::weak_ptr<Item> item, QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
item_(item),
|
item_(item),
|
||||||
noGroupEdit_(noGroupEdit),
|
|
||||||
ui(new Ui::ItemWidget)
|
ui(new Ui::ItemWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
@ -42,13 +40,12 @@ ItemWidget::ItemWidget(std::weak_ptr<Item> item, bool noGroupEdit, QWidget *pare
|
||||||
connect(ui->pushButton, &QPushButton::clicked, this, &ItemWidget::showSettingsDialog);
|
connect(ui->pushButton, &QPushButton::clicked, this, &ItemWidget::showSettingsDialog);
|
||||||
connect(workingItem.get(), &Item::updated, this, &ItemWidget::onItemUpdated);
|
connect(workingItem.get(), &Item::updated, this, &ItemWidget::onItemUpdated);
|
||||||
connect(ui->pushButton_Remove, &QPushButton::clicked, this, &ItemWidget::deleteItem);
|
connect(ui->pushButton_Remove, &QPushButton::clicked, this, &ItemWidget::deleteItem);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
disable();
|
disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemWidget::deleteItem()
|
void ItemWidget::deleteItem()
|
||||||
|
|
@ -63,9 +60,7 @@ void ItemWidget::moveToValue(int value)
|
||||||
{
|
{
|
||||||
if(auto workingItem = item_.lock())
|
if(auto workingItem = item_.lock())
|
||||||
{
|
{
|
||||||
ItemUpdateRequest request = workingItem->createValueUpdateRequest(ITEM_UPDATE_USER);
|
ItemUpdateRequest request = workingItem->createValueUpdateRequest(value, ITEM_UPDATE_USER);
|
||||||
request.payload.setValueData(value);
|
|
||||||
request.changes.value = true;
|
|
||||||
workingItem->requestUpdate(request);
|
workingItem->requestUpdate(request);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -76,7 +71,15 @@ void ItemWidget::moveToValue(int value)
|
||||||
|
|
||||||
void ItemWidget::moveToState(bool state)
|
void ItemWidget::moveToState(bool state)
|
||||||
{
|
{
|
||||||
moveToValue(state);
|
if(auto workingItem = item_.lock())
|
||||||
|
{
|
||||||
|
ItemUpdateRequest request = workingItem->createValueUpdateRequest(state, ITEM_UPDATE_USER);
|
||||||
|
workingItem->requestUpdate(request);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemWidget::disable()
|
void ItemWidget::disable()
|
||||||
|
|
@ -101,9 +104,8 @@ void ItemWidget::showSettingsDialog()
|
||||||
{
|
{
|
||||||
if(auto workingItem = item_.lock())
|
if(auto workingItem = item_.lock())
|
||||||
{
|
{
|
||||||
ItemSettingsDialog dialog(workingItem, noGroupEdit_, this);
|
ItemSettingsDialog dialog(workingItem, this);
|
||||||
dialog.exec();
|
dialog.exec();
|
||||||
|
|
||||||
}
|
}
|
||||||
else disable();
|
else disable();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "itemsettingsdialog.h"
|
||||||
#include "../items/item.h"
|
#include "../items/item.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
|
|
@ -15,7 +16,6 @@ class ItemWidget : public QWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<Item> item_;
|
std::weak_ptr<Item> item_;
|
||||||
bool noGroupEdit_;
|
|
||||||
|
|
||||||
void disable();
|
void disable();
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ private slots:
|
||||||
void deleteItem();
|
void deleteItem();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ItemWidget(std::weak_ptr<Item> item, bool noGroupEdit = false, QWidget *parent = nullptr);
|
explicit ItemWidget(std::weak_ptr<Item> item, QWidget *parent = nullptr);
|
||||||
std::weak_ptr<Item> getItem();
|
std::weak_ptr<Item> getItem();
|
||||||
bool controles(const ItemData& relay);
|
bool controles(const ItemData& relay);
|
||||||
~ItemWidget();
|
~ItemWidget();
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ MainWindow::MainWindow(MainObject * const mainObject, QWidget *parent) :
|
||||||
connect(ui->pushButton_refesh, &QPushButton::clicked, mainObject, &MainObject::refresh);
|
connect(ui->pushButton_refesh, &QPushButton::clicked, mainObject, &MainObject::refresh);
|
||||||
connect(&globalItems, &ItemStore::itemAdded, ui->relayList, &ItemScrollBox::addItem);
|
connect(&globalItems, &ItemStore::itemAdded, ui->relayList, &ItemScrollBox::addItem);
|
||||||
connect(&globalItems, &ItemStore::itemDeleted, ui->relayList, &ItemScrollBox::removeItem);
|
connect(&globalItems, &ItemStore::itemDeleted, ui->relayList, &ItemScrollBox::removeItem);
|
||||||
connect(&globalItems, &ItemStore::itemUpdated, ui->relayList, &ItemScrollBox::onItemUpdate);
|
|
||||||
|
|
||||||
for(size_t i = 0; i < globalItems.getItems()->size(); ++i)
|
for(size_t i = 0; i < globalItems.getItems()->size(); ++i)
|
||||||
ui->relayList->addItem(globalItems.getItems()->at(i));
|
ui->relayList->addItem(globalItems.getItems()->at(i));
|
||||||
|
|
@ -66,7 +65,7 @@ void MainWindow::showPowerItemDialog()
|
||||||
}
|
}
|
||||||
if(powerItem)
|
if(powerItem)
|
||||||
{
|
{
|
||||||
ItemSettingsDialog diag(std::shared_ptr<Item>(powerItem), false, this);
|
ItemSettingsDialog diag(std::shared_ptr<Item>(powerItem), this);
|
||||||
diag.show();
|
diag.show();
|
||||||
diag.exec();
|
diag.exec();
|
||||||
}
|
}
|
||||||
|
|
@ -80,13 +79,7 @@ void MainWindow::showItemCreationDialog()
|
||||||
ItemCreationDialog diag(this);
|
ItemCreationDialog diag(this);
|
||||||
diag.show();
|
diag.show();
|
||||||
if(diag.exec())
|
if(diag.exec())
|
||||||
{
|
createdItem(diag.item);
|
||||||
ItemAddRequest request;
|
|
||||||
request.type = ITEM_UPDATE_USER;
|
|
||||||
request.changes = ItemFieldChanges(true);
|
|
||||||
request.payload = diag.item;
|
|
||||||
createdItem(request);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::changeHeaderLableText(QString string)
|
void MainWindow::changeHeaderLableText(QString string)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ private:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void sigSave();
|
void sigSave();
|
||||||
void createdItem(ItemAddRequest request);
|
void createdItem(std::shared_ptr<Item> item);
|
||||||
void sigSetRgb(const QColor color);
|
void sigSetRgb(const QColor color);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>350</width>
|
<width>400</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,52 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
<property name="tabsClosable">
|
<property name="frameShape">
|
||||||
<bool>false</bool>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="movable">
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>388</width>
|
||||||
|
<height>288</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="relayWidgetVbox"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue