[Add] File saving for the fancy new text editor.
This commit is contained in:
parent
b4d985db29
commit
ebd1e222d7
@ -12,6 +12,7 @@
|
|||||||
#include "ui/desktop.h"
|
#include "ui/desktop.h"
|
||||||
#include "ui/i_window_content.h"
|
#include "ui/i_window_content.h"
|
||||||
#include "ui/ui_window.h"
|
#include "ui/ui_window.h"
|
||||||
|
#include "ui/window_action.h"
|
||||||
#include <ui/main_menu.h>
|
#include <ui/main_menu.h>
|
||||||
#include <ui/boot_sequence.h>
|
#include <ui/boot_sequence.h>
|
||||||
|
|
||||||
@ -153,6 +154,18 @@ void GameState::update(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(_desktop) {
|
if(_desktop) {
|
||||||
|
WindowAction action = _desktop->get_pending_action();
|
||||||
|
switch(action.type) {
|
||||||
|
case ActionType::WRITE_FILE: {
|
||||||
|
std::string message = "WRITEF::" + action.payload1 + "::" + action.payload2;
|
||||||
|
_network->send(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ActionType::NONE:
|
||||||
|
default:
|
||||||
|
/* Do nothing. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* TODO: These fuck'in window dimensions just need to be global at this point!!
|
* TODO: These fuck'in window dimensions just need to be global at this point!!
|
||||||
* Pass GameState by reference ?
|
* Pass GameState by reference ?
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "client_network.h"
|
#include "client_network.h"
|
||||||
#include "gfx/txt_renderer.h"
|
#include "gfx/txt_renderer.h"
|
||||||
#include "gfx/types.h"
|
#include "gfx/types.h"
|
||||||
|
#include "ui/window_action.h"
|
||||||
|
|
||||||
Terminal::Terminal(ClientNetwork* network)
|
Terminal::Terminal(ClientNetwork* network)
|
||||||
: _network(network), _should_close(false), _scroll_offset(0),
|
: _network(network), _should_close(false), _scroll_offset(0),
|
||||||
@ -44,6 +45,10 @@ void Terminal::set_prompt(const std::string& prompt) {
|
|||||||
|
|
||||||
bool Terminal::should_close(void) { return _should_close; }
|
bool Terminal::should_close(void) { return _should_close; }
|
||||||
|
|
||||||
|
WindowAction Terminal::get_pending_action(void) {
|
||||||
|
return { ActionType::NONE };
|
||||||
|
}
|
||||||
|
|
||||||
void Terminal::_on_ret_press(void) {
|
void Terminal::_on_ret_press(void) {
|
||||||
std::string command = _input_buffer.get_line(0);
|
std::string command = _input_buffer.get_line(0);
|
||||||
_input_buffer.newline(); /* Add newline to buffer for histroy. */
|
_input_buffer.newline(); /* Add newline to buffer for histroy. */
|
||||||
|
|||||||
@ -22,6 +22,7 @@ public:
|
|||||||
void add_history(const std::string& line);
|
void add_history(const std::string& line);
|
||||||
void set_prompt(const std::string& prompt);
|
void set_prompt(const std::string& prompt);
|
||||||
bool should_close(void) override;
|
bool should_close(void) override;
|
||||||
|
WindowAction get_pending_action(void) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _on_ret_press(void);
|
void _on_ret_press(void);
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include <SDL3/SDL_video.h>
|
#include <SDL3/SDL_video.h>
|
||||||
#include <ui/cursor_manager.h>
|
#include <ui/cursor_manager.h>
|
||||||
#include "ui/ui_window.h"
|
#include "ui/ui_window.h"
|
||||||
|
#include "ui/window_action.h"
|
||||||
|
|
||||||
static const std::string& get_random_snippet(const std::vector<std::string>& snippets) {
|
static const std::string& get_random_snippet(const std::vector<std::string>& snippets) {
|
||||||
if(snippets.empty()) {
|
if(snippets.empty()) {
|
||||||
@ -171,6 +172,16 @@ void Desktop::update(int screen_width, int screen_height) {
|
|||||||
_windows.end());
|
_windows.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowAction Desktop::get_pending_action(void) {
|
||||||
|
if(_focused_window) {
|
||||||
|
IWindowContent* content = _focused_window->get_content();
|
||||||
|
if(content) {
|
||||||
|
return content->get_pending_action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { ActionType::NONE };
|
||||||
|
}
|
||||||
|
|
||||||
UIWindow* Desktop::get_focused_window(void) {
|
UIWindow* Desktop::get_focused_window(void) {
|
||||||
return _focused_window;
|
return _focused_window;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include "ui/ui_window.h"
|
#include "ui/ui_window.h"
|
||||||
#include "ui/taskbar.h"
|
#include "ui/taskbar.h"
|
||||||
#include "ui/launcher.h"
|
#include "ui/launcher.h"
|
||||||
|
#include "ui/window_action.h"
|
||||||
|
|
||||||
/* Animated background stuff. */
|
/* Animated background stuff. */
|
||||||
struct ScrollingText {
|
struct ScrollingText {
|
||||||
@ -31,6 +32,7 @@ public:
|
|||||||
void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height,
|
void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height,
|
||||||
bool show_cursor);
|
bool show_cursor);
|
||||||
|
|
||||||
|
WindowAction get_pending_action(void);
|
||||||
UIWindow* get_focused_window(void);
|
UIWindow* get_focused_window(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "gfx/txt_renderer.h"
|
#include "gfx/txt_renderer.h"
|
||||||
|
#include "ui/window_action.h"
|
||||||
|
|
||||||
Editor::Editor(void) : _should_close(false) {
|
Editor::Editor(void)
|
||||||
|
: _should_close(false), _pending_action({ActionType::NONE}) {
|
||||||
_view = std::make_unique<TextView>(&_buffer, true);
|
_view = std::make_unique<TextView>(&_buffer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,8 +16,14 @@ void Editor::update(void) {
|
|||||||
|
|
||||||
void Editor::handle_input(SDL_Event* event) {
|
void Editor::handle_input(SDL_Event* event) {
|
||||||
/* We don't care about the return val here. RET is just newline. */
|
/* We don't care about the return val here. RET is just newline. */
|
||||||
|
if(event->type == SDL_EVENT_KEY_DOWN && event->key.key == SDLK_S &&
|
||||||
|
(event->key.mod & SDL_KMOD_CTRL)) {
|
||||||
|
/* C-S pressed, create a save action. */
|
||||||
|
_pending_action = { ActionType::WRITE_FILE, "test.txt", _buffer.get_text() };
|
||||||
|
} else {
|
||||||
_view->handle_event(event);
|
_view->handle_event(event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::render(TextRenderer* renderer, int x, int y, int width, int height,
|
void Editor::render(TextRenderer* renderer, int x, int y, int width, int height,
|
||||||
bool show_cursor) {
|
bool show_cursor) {
|
||||||
@ -29,3 +37,9 @@ void Editor::scroll(int amount, int content_height) {
|
|||||||
bool Editor::should_close(void) {
|
bool Editor::should_close(void) {
|
||||||
return _should_close;
|
return _should_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowAction Editor::get_pending_action(void) {
|
||||||
|
WindowAction action = _pending_action;
|
||||||
|
_pending_action.type = ActionType::NONE; /* Clear action. */
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "i_window_content.h"
|
#include "i_window_content.h"
|
||||||
#include "ui/text_buffer.h"
|
#include "ui/text_buffer.h"
|
||||||
#include "text_view.h"
|
#include "text_view.h"
|
||||||
|
#include "ui/window_action.h"
|
||||||
|
|
||||||
class Editor : public IWindowContent {
|
class Editor : public IWindowContent {
|
||||||
public:
|
public:
|
||||||
@ -18,9 +19,11 @@ public:
|
|||||||
bool show_cursor) override;
|
bool show_cursor) override;
|
||||||
void scroll(int amount, int content_height) override;
|
void scroll(int amount, int content_height) override;
|
||||||
bool should_close(void) override;
|
bool should_close(void) override;
|
||||||
|
WindowAction get_pending_action(void) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextBuffer _buffer;
|
TextBuffer _buffer;
|
||||||
std::unique_ptr<TextView> _view;
|
std::unique_ptr<TextView> _view;
|
||||||
bool _should_close;
|
bool _should_close;
|
||||||
|
WindowAction _pending_action;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
|
|
||||||
|
#include "window_action.h"
|
||||||
|
|
||||||
class TextRenderer;
|
class TextRenderer;
|
||||||
|
|
||||||
class IWindowContent {
|
class IWindowContent {
|
||||||
@ -13,4 +15,5 @@ public:
|
|||||||
bool show_cursor = 0) = 0;
|
bool show_cursor = 0) = 0;
|
||||||
virtual void scroll(int amount, int content_height) = 0;
|
virtual void scroll(int amount, int content_height) = 0;
|
||||||
virtual bool should_close(void) = 0;
|
virtual bool should_close(void) = 0;
|
||||||
|
virtual WindowAction get_pending_action() = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
14
client/src/ui/window_action.h
Normal file
14
client/src/ui/window_action.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
enum class ActionType {
|
||||||
|
NONE,
|
||||||
|
WRITE_FILE
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WindowAction {
|
||||||
|
ActionType type = ActionType::NONE;
|
||||||
|
std::string payload1; /* i.e., filename. */
|
||||||
|
std::string payload2; /* i.e., content. */
|
||||||
|
};
|
||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "command_processor.h"
|
#include "command_processor.h"
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
|
#include "lua_api.h"
|
||||||
#include "lua_processor.h"
|
#include "lua_processor.h"
|
||||||
#include "machine_manager.h"
|
#include "machine_manager.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
@ -74,6 +75,10 @@ std::string CommandProcessor::process_command(const std::string& command) {
|
|||||||
return "Unknown command: " + command_name + "\n";
|
return "Unknown command: " + command_name + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CommandProcessor::write_file(const std::string& path, const std::string& content) {
|
||||||
|
return api::write_file(*this, path, content);
|
||||||
|
}
|
||||||
|
|
||||||
/* Find a VFS node by it's absolute path. */
|
/* Find a VFS node by it's absolute path. */
|
||||||
vfs_node* find_node_by_path(vfs_node* root, const std::string& path) {
|
vfs_node* find_node_by_path(vfs_node* root, const std::string& path) {
|
||||||
if(path == "/") {
|
if(path == "/") {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ public:
|
|||||||
~CommandProcessor(void);
|
~CommandProcessor(void);
|
||||||
|
|
||||||
std::string process_command(const std::string& command);
|
std::string process_command(const std::string& command);
|
||||||
|
std::string write_file(const std::string& path, const std::string& content);
|
||||||
|
|
||||||
/* Public interface for API functions. */
|
/* Public interface for API functions. */
|
||||||
vfs_node* get_current_dir(void);
|
vfs_node* get_current_dir(void);
|
||||||
|
|||||||
@ -107,13 +107,28 @@ void NetworkManager::on_message(std::shared_ptr<net::TcpConnection> connection,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "[Player %u] Command: '%s'\n", player->id, message.c_str());
|
/* Check for "special" message prefixes. */
|
||||||
|
if(message.rfind("WRITEF::", 0) == 0) {
|
||||||
|
/* Message format: WRITEF::/path/to/file::content. */
|
||||||
|
std::string payload = message.substr(8);
|
||||||
|
size_t separator_pos = payload.find("::");
|
||||||
|
if(separator_pos != std::string::npos) {
|
||||||
|
std::string filepath = payload.substr(0, separator_pos);
|
||||||
|
std::string content = payload.substr(separator_pos+2);
|
||||||
|
|
||||||
|
fprintf(stderr, "[Player %u] Write file: \'%s\'\n", player->id, filepath.c_str());
|
||||||
|
player->cmd_processor->write_file(filepath, content);
|
||||||
|
/* Response not required for a file write. */
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no prefix, treat as normal terminal command. */
|
||||||
|
fprintf(stderr, "[Player %u] Command: '%s'\n", player->id, message.c_str());
|
||||||
std::string response = player->cmd_processor->process_command(message);
|
std::string response = player->cmd_processor->process_command(message);
|
||||||
|
|
||||||
if(response == "__CLOSE_CONNECTION__") {
|
if(response == "__CLOSE_CONNECTION__") {
|
||||||
connection->send(response);
|
connection->send(response);
|
||||||
/* Just let me close the f.cking terminal? */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user