editing normal nodetText
This commit is contained in:
@@ -40,6 +40,48 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
#nodes-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.node-item {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.modal {
|
||||||
|
display: none; /* Hidden by default */
|
||||||
|
position: fixed; /* Stay in place */
|
||||||
|
z-index: 1; /* Sit on top */
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%; /* Full width */
|
||||||
|
height: 100%; /* Full height */
|
||||||
|
overflow: auto; /* Enable scroll if needed */
|
||||||
|
background-color: rgb(0,0,0); /* Fallback color */
|
||||||
|
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: 15% auto; /* 15% from the top and centered */
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
width: 80%; /* Could be more or less, depending on screen size */
|
||||||
|
}
|
||||||
|
.close {
|
||||||
|
color: #aaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -53,6 +95,37 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
<div id="nodes-container">
|
||||||
|
<h2>Current Text Nodes</h2>
|
||||||
|
<div id="nodes-list"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="modify-modal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close" onclick="closeModal()">×</span>
|
||||||
|
<h3>Modify Text Node</h3>
|
||||||
|
<div class="text-input-group">
|
||||||
|
<input type="hidden" id="modifyIdInput">
|
||||||
|
<b>Node ID:</b> <span id="modifyIdDisplay"></span>
|
||||||
|
</div>
|
||||||
|
<div class="text-input-group">
|
||||||
|
<input type="text" id="modifyTextInput" placeholder="New text...">
|
||||||
|
<div class="param-explanation">New text for the node.</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-input-group">
|
||||||
|
<input type="color" id="modifyColorPicker">
|
||||||
|
<div class="param-explanation">New color for the text.</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-input-group">
|
||||||
|
<input type="number" id="modifySlownessInput" placeholder="Slowness" min="0" max="255">
|
||||||
|
<div class="param-explanation">Animation slowness (0-255).</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-buttons">
|
||||||
|
<button class="button" onclick="modifyText()">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="text-controls">
|
<div class="text-controls">
|
||||||
<h3>Add Text Node (Full Control)</h3>
|
<h3>Add Text Node (Full Control)</h3>
|
||||||
<pre><code>void addNewTextNode(char text[TEXT_MAX_LENGTH + 1], uint32_t color, bool handle_pos_via_cursor = true, short pos_x = 0, short pos_y = 0, unsigned char scroll_slowness = 1, bool is_scrolling = true, bool is_small = true, short disappear_time = -1)</code></pre>
|
<pre><code>void addNewTextNode(char text[TEXT_MAX_LENGTH + 1], uint32_t color, bool handle_pos_via_cursor = true, short pos_x = 0, short pos_y = 0, unsigned char scroll_slowness = 1, bool is_scrolling = true, bool is_small = true, short disappear_time = -1)</code></pre>
|
||||||
@@ -172,6 +245,11 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
}
|
}
|
||||||
if(fontSize) data += "&fontSize=" + fontSize;
|
if(fontSize) data += "&fontSize=" + fontSize;
|
||||||
|
|
||||||
|
xhr.onload = function() {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
fetchNodes();
|
||||||
|
}
|
||||||
|
};
|
||||||
xhr.send(data);
|
xhr.send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,8 +280,82 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
if(y) data += "&y=" + y;
|
if(y) data += "&y=" + y;
|
||||||
if(fontSize) data += "&fontSize=" + fontSize;
|
if(fontSize) data += "&fontSize=" + fontSize;
|
||||||
|
|
||||||
|
xhr.onload = function() {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
fetchNodes();
|
||||||
|
}
|
||||||
|
};
|
||||||
xhr.send(data);
|
xhr.send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function modifyText() {
|
||||||
|
const id = document.getElementById('modifyIdInput').value;
|
||||||
|
const color = document.getElementById('modifyColorPicker').value;
|
||||||
|
const text = document.getElementById('modifyTextInput').value;
|
||||||
|
const slowness = document.getElementById('modifySlownessInput').value;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
alert('Please enter a node ID.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "/modify-text", true);
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
let data = "id=" + id + "&color=" + encodeURIComponent(color) + "&text=" + encodeURIComponent(text) + "&slowness=" + slowness;
|
||||||
|
xhr.onload = function() {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
fetchNodes();
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchNodes() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", "/nodes", true);
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
var nodes = JSON.parse(this.responseText);
|
||||||
|
var nodesList = document.getElementById('nodes-list');
|
||||||
|
nodesList.innerHTML = '';
|
||||||
|
for (var i = 0; i < nodes.length; i++) {
|
||||||
|
var node = nodes[i];
|
||||||
|
var color = '#' + ('000000' + node.color.toString(16)).slice(-6);
|
||||||
|
var nodeDiv = document.createElement('div');
|
||||||
|
nodeDiv.className = 'node-item';
|
||||||
|
nodeDiv.innerHTML = '<b>ID:</b> ' + node.id + ', <b>Text:</b> ' + node.text + ', <b>Color:</b> <span style="color:' + color + '">' + color + '</span>' +
|
||||||
|
'<button style="margin-left: 10px;" onclick="populateModifyForm(' + node.id + ', \'' + color + '\', \'' + node.text + '\', ' + node.slowness + ')">Modify</button>';
|
||||||
|
nodesList.appendChild(nodeDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateModifyForm(id, color, text, slowness) {
|
||||||
|
document.getElementById('modifyIdInput').value = id;
|
||||||
|
document.getElementById('modifyIdDisplay').innerText = id;
|
||||||
|
document.getElementById('modifyColorPicker').value = color;
|
||||||
|
document.getElementById('modifyTextInput').value = text;
|
||||||
|
document.getElementById('modifySlownessInput').value = slowness;
|
||||||
|
document.getElementById('modify-modal').style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
document.getElementById('modify-modal').style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onclick = function(event) {
|
||||||
|
if (event.target == document.getElementById('modify-modal')) {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(fetchNodes, 5000);
|
||||||
|
window.onload = fetchNodes;
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ void addNewTextNode
|
|||||||
text_nodes[i].is_scrolling = is_scrolling;
|
text_nodes[i].is_scrolling = is_scrolling;
|
||||||
text_nodes[i].is_repeating = is_repeating;
|
text_nodes[i].is_repeating = is_repeating;
|
||||||
text_nodes[i].disappear_time = disappear_time;
|
text_nodes[i].disappear_time = disappear_time;
|
||||||
|
text_nodes[i].id = ever_created_text_nodes;
|
||||||
ever_created_text_nodes++;
|
ever_created_text_nodes++;
|
||||||
|
|
||||||
if (handle_pos_via_cursor)
|
if (handle_pos_via_cursor)
|
||||||
@@ -82,6 +83,21 @@ void addNewTextNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void modifyTextNodeById(unsigned char id, uint32_t new_color, char new_text[TEXT_MAX_LENGTH + 1], unsigned char new_slowness)
|
||||||
|
{
|
||||||
|
for (unsigned char i = 0; i < MAX_TEXT_NODES_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (text_nodes[i].id == id && text_nodes[i].disappear_time != 0)
|
||||||
|
{
|
||||||
|
text_nodes[i].color = new_color;
|
||||||
|
strncpy(text_nodes[i].content, new_text, TEXT_MAX_LENGTH);
|
||||||
|
text_nodes[i].character_count = strlen(new_text);
|
||||||
|
text_nodes[i].scroll_slowness = new_slowness;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void scrollAllScrollableTexts(bool split_scroll_mode = false)
|
void scrollAllScrollableTexts(bool split_scroll_mode = false)
|
||||||
{
|
{
|
||||||
for (unsigned char i = 0; i < MAX_TEXT_NODES_COUNT; i++)
|
for (unsigned char i = 0; i < MAX_TEXT_NODES_COUNT; i++)
|
||||||
@@ -187,6 +203,7 @@ void addNewMultiColor
|
|||||||
multi_color_text_node[i].is_scrolling = is_scrolling;
|
multi_color_text_node[i].is_scrolling = is_scrolling;
|
||||||
multi_color_text_node[i].is_repeating = is_repeating;
|
multi_color_text_node[i].is_repeating = is_repeating;
|
||||||
multi_color_text_node[i].disappear_time = disappear_time;
|
multi_color_text_node[i].disappear_time = disappear_time;
|
||||||
|
multi_color_text_node[i].id = ever_created_multi_color_text_nodes;
|
||||||
ever_created_multi_color_text_nodes++;
|
ever_created_multi_color_text_nodes++;
|
||||||
|
|
||||||
if (handle_pos_via_cursor)
|
if (handle_pos_via_cursor)
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ void handleMultiColorDisappearTimers();
|
|||||||
short getTextNodeY2(TextNode *node);
|
short getTextNodeY2(TextNode *node);
|
||||||
short getTextNodeX2(TextNode *node);
|
short getTextNodeX2(TextNode *node);
|
||||||
short getMultiColorTextNodeX2(MultiColorTextNode *node);
|
short getMultiColorTextNodeX2(MultiColorTextNode *node);
|
||||||
|
void modifyTextNodeById(unsigned char id, uint32_t new_color, char new_text[TEXT_MAX_LENGTH + 1], unsigned char new_slowness);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PROTOTYPES_H
|
#endif // PROTOTYPES_H
|
||||||
+66
-2
@@ -219,13 +219,75 @@ void handleMulticolorText() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleModifyText()
|
||||||
|
{
|
||||||
|
if (server.hasArg("id") && server.hasArg("color"))
|
||||||
|
{
|
||||||
|
unsigned char id = server.arg("id").toInt();
|
||||||
|
String colorStr = server.arg("color");
|
||||||
|
uint32_t color = strtol(colorStr.substring(1).c_str(), NULL, 16);
|
||||||
|
String text_str = server.arg("text");
|
||||||
|
char text[TEXT_MAX_LENGTH + 1];
|
||||||
|
text_str.toCharArray(text, TEXT_MAX_LENGTH + 1);
|
||||||
|
unsigned char slowness = server.arg("slowness").toInt();
|
||||||
|
modifyTextNodeById(id, color, text, slowness);
|
||||||
|
server.send(200, "text/plain", "OK");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server.send(400, "text/plain", "Invalid arguments for /modify-text");
|
||||||
|
}
|
||||||
|
} void handleGetNodes()
|
||||||
|
{
|
||||||
|
StaticJsonDocument<2048> jsonDoc;
|
||||||
|
JsonArray nodes = jsonDoc.to<JsonArray>();
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_TEXT_NODES_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (text_nodes[i].disappear_time != 0)
|
||||||
|
{
|
||||||
|
JsonObject node = nodes.createNestedObject();
|
||||||
|
node["id"] = text_nodes[i].id; node["text"] = text_nodes[i].content;
|
||||||
|
node["color"] = text_nodes[i].color;
|
||||||
|
node["x"] = text_nodes[i].pos_x;
|
||||||
|
node["y"] = text_nodes[i].pos_y;
|
||||||
|
node["slowness"] = text_nodes[i].scroll_slowness;
|
||||||
|
node["is_repeating"] = text_nodes[i].is_repeating;
|
||||||
|
node["type"] = "text";
|
||||||
|
node["slowness"] = text_nodes[i].scroll_slowness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < MAX_TEXT_NODES_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (multi_color_text_node[i].disappear_time != 0)
|
||||||
|
{
|
||||||
|
JsonObject node = nodes.createNestedObject();
|
||||||
|
node["id"] = multi_color_text_node[i].id; node["text"] = multi_color_text_node[i].content;
|
||||||
|
JsonArray colors = node.createNestedArray("colors");
|
||||||
|
for(int j = 0; j < multi_color_text_node[i].color_count; j++)
|
||||||
|
{
|
||||||
|
JsonObject color = colors.createNestedObject();
|
||||||
|
color["r"] = multi_color_text_node[i].colors[j].r;
|
||||||
|
color["g"] = multi_color_text_node[i].colors[j].g;
|
||||||
|
color["b"] = multi_color_text_node[i].colors[j].b;
|
||||||
|
}
|
||||||
|
node["x"] = multi_color_text_node[i].pos_x;
|
||||||
|
node["y"] = multi_color_text_node[i].pos_y;
|
||||||
|
node["slowness"] = multi_color_text_node[i].scroll_slowness;
|
||||||
|
node["is_repeating"] = multi_color_text_node[i].is_repeating;
|
||||||
|
node["type"] = "multi-color";
|
||||||
|
node["slowness"] = multi_color_text_node[i].scroll_slowness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String jsonString;
|
||||||
|
serializeJson(jsonDoc, jsonString);
|
||||||
|
server.send(200, "application/json", jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
void start_server()
|
void start_server()
|
||||||
{
|
{
|
||||||
WiFi.begin(ssid, password);
|
WiFi.begin(ssid, password);
|
||||||
while (WiFi.status() != WL_CONNECTED)
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
{
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
Serial.println("Connecting to WiFi...");
|
Serial.println("Connecting to WiFi...");
|
||||||
}
|
}
|
||||||
@@ -233,7 +295,9 @@ void start_server()
|
|||||||
Serial.println(WiFi.localIP());
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
server.on("/", handleRoot);
|
server.on("/", handleRoot);
|
||||||
|
server.on("/nodes", HTTP_GET, handleGetNodes);
|
||||||
server.on("/text", HTTP_POST, handleText);
|
server.on("/text", HTTP_POST, handleText);
|
||||||
|
server.on("/modify-text", HTTP_POST, handleModifyText);
|
||||||
server.on("/multicolor-text", HTTP_POST, handleMulticolorText);
|
server.on("/multicolor-text", HTTP_POST, handleMulticolorText);
|
||||||
server.on("/brightness", HTTP_POST, handleBrightness);
|
server.on("/brightness", HTTP_POST, handleBrightness);
|
||||||
server.on("/upload-page", HTTP_GET, handleUploadPage);
|
server.on("/upload-page", HTTP_GET, handleUploadPage);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ struct Pixel
|
|||||||
|
|
||||||
struct TextNode
|
struct TextNode
|
||||||
{
|
{
|
||||||
|
unsigned char id;
|
||||||
char content[TEXT_MAX_LENGTH];
|
char content[TEXT_MAX_LENGTH];
|
||||||
uint32_t color;
|
uint32_t color;
|
||||||
struct CharacterSize
|
struct CharacterSize
|
||||||
@@ -37,7 +38,7 @@ struct TextNode
|
|||||||
bool is_repeating;
|
bool is_repeating;
|
||||||
|
|
||||||
|
|
||||||
TextNode() : color(0), pos_x(0), pos_y(0), character_count(0), scroll_slowness(0), scroll_progress(0), characterSize({7,5}), disappear_time(0), is_scrolling(true), is_repeating(false) {}
|
TextNode() : id(0), color(0), pos_x(0), pos_y(0), character_count(0), scroll_slowness(0), scroll_progress(0), characterSize({7,5}), disappear_time(0), is_scrolling(true), is_repeating(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RGB
|
struct RGB
|
||||||
@@ -62,6 +63,7 @@ struct RGBWithIndex
|
|||||||
|
|
||||||
struct MultiColorTextNode
|
struct MultiColorTextNode
|
||||||
{
|
{
|
||||||
|
unsigned char id;
|
||||||
char content[TEXT_MAX_LENGTH];
|
char content[TEXT_MAX_LENGTH];
|
||||||
RGBWithIndex colors[4];
|
RGBWithIndex colors[4];
|
||||||
|
|
||||||
@@ -80,7 +82,7 @@ struct MultiColorTextNode
|
|||||||
bool is_scrolling;
|
bool is_scrolling;
|
||||||
bool is_repeating;
|
bool is_repeating;
|
||||||
|
|
||||||
MultiColorTextNode() : pos_x(0), pos_y(0), character_count(0), scroll_slowness(0), scroll_progress(0), characterSize({7,5}), disappear_time(0), is_scrolling(true), color_count(0), is_repeating(false) {}
|
MultiColorTextNode() : id(0), pos_x(0), pos_y(0), character_count(0), scroll_slowness(0), scroll_progress(0), characterSize({7,5}), disappear_time(0), is_scrolling(true), color_count(0), is_repeating(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Image
|
struct Image
|
||||||
|
|||||||
Reference in New Issue
Block a user