[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/i_window_content.h"
 | 
			
		||||
#include "ui/ui_window.h"
 | 
			
		||||
#include "ui/window_action.h"
 | 
			
		||||
#include <ui/main_menu.h>
 | 
			
		||||
#include <ui/boot_sequence.h>
 | 
			
		||||
 | 
			
		||||
@ -153,6 +154,18 @@ void GameState::update(void) {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      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!!
 | 
			
		||||
         * Pass GameState by reference ?
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@
 | 
			
		||||
#include "client_network.h"
 | 
			
		||||
#include "gfx/txt_renderer.h"
 | 
			
		||||
#include "gfx/types.h"
 | 
			
		||||
#include "ui/window_action.h"
 | 
			
		||||
 | 
			
		||||
Terminal::Terminal(ClientNetwork* network)
 | 
			
		||||
    : _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; }
 | 
			
		||||
 | 
			
		||||
WindowAction Terminal::get_pending_action(void) {
 | 
			
		||||
  return { ActionType::NONE };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Terminal::_on_ret_press(void) {
 | 
			
		||||
  std::string command = _input_buffer.get_line(0);
 | 
			
		||||
  _input_buffer.newline(); /* Add newline to buffer for histroy. */
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ public:
 | 
			
		||||
  void add_history(const std::string& line);
 | 
			
		||||
  void set_prompt(const std::string& prompt);
 | 
			
		||||
  bool should_close(void) override;
 | 
			
		||||
  WindowAction get_pending_action(void) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  void _on_ret_press(void);
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@
 | 
			
		||||
#include <SDL3/SDL_video.h>
 | 
			
		||||
#include <ui/cursor_manager.h>
 | 
			
		||||
#include "ui/ui_window.h"
 | 
			
		||||
#include "ui/window_action.h"
 | 
			
		||||
 | 
			
		||||
static const std::string& get_random_snippet(const std::vector<std::string>& snippets) {
 | 
			
		||||
  if(snippets.empty()) {
 | 
			
		||||
@ -171,6 +172,16 @@ void Desktop::update(int screen_width, int screen_height) {
 | 
			
		||||
                 _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) {
 | 
			
		||||
  return _focused_window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@
 | 
			
		||||
#include "ui/ui_window.h"
 | 
			
		||||
#include "ui/taskbar.h"
 | 
			
		||||
#include "ui/launcher.h"
 | 
			
		||||
#include "ui/window_action.h"
 | 
			
		||||
 | 
			
		||||
/* Animated background stuff. */
 | 
			
		||||
struct ScrollingText {
 | 
			
		||||
@ -31,6 +32,7 @@ public:
 | 
			
		||||
  void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height,
 | 
			
		||||
              bool show_cursor);
 | 
			
		||||
 | 
			
		||||
  WindowAction get_pending_action(void);
 | 
			
		||||
  UIWindow* get_focused_window(void);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,10 @@
 | 
			
		||||
#include "editor.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,7 +16,13 @@ void Editor::update(void) {
 | 
			
		||||
 | 
			
		||||
void Editor::handle_input(SDL_Event* event) {
 | 
			
		||||
  /* 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);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Editor::render(TextRenderer* renderer, int x, int y, int width, int height,
 | 
			
		||||
@ -29,3 +37,9 @@ void Editor::scroll(int amount, int content_height) {
 | 
			
		||||
bool Editor::should_close(void) {
 | 
			
		||||
  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 "ui/text_buffer.h"
 | 
			
		||||
#include "text_view.h"
 | 
			
		||||
#include "ui/window_action.h"
 | 
			
		||||
 | 
			
		||||
class Editor : public IWindowContent {
 | 
			
		||||
public:
 | 
			
		||||
@ -18,9 +19,11 @@ public:
 | 
			
		||||
              bool show_cursor) override;
 | 
			
		||||
  void scroll(int amount, int content_height) override;
 | 
			
		||||
  bool should_close(void) override;
 | 
			
		||||
  WindowAction get_pending_action(void) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  TextBuffer _buffer;
 | 
			
		||||
  std::unique_ptr<TextView> _view;
 | 
			
		||||
  bool _should_close;
 | 
			
		||||
  WindowAction _pending_action;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
 | 
			
		||||
#include <SDL3/SDL_events.h>
 | 
			
		||||
 | 
			
		||||
#include "window_action.h"
 | 
			
		||||
 | 
			
		||||
class TextRenderer;
 | 
			
		||||
 | 
			
		||||
class IWindowContent {
 | 
			
		||||
@ -13,4 +15,5 @@ public:
 | 
			
		||||
                      bool show_cursor = 0) = 0;
 | 
			
		||||
  virtual void scroll(int amount, int content_height) = 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 "vfs.h"
 | 
			
		||||
#include "lua_api.h"
 | 
			
		||||
#include "lua_processor.h"
 | 
			
		||||
#include "machine_manager.h"
 | 
			
		||||
#include "machine.h"
 | 
			
		||||
@ -74,6 +75,10 @@ std::string CommandProcessor::process_command(const std::string& command) {
 | 
			
		||||
  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. */
 | 
			
		||||
vfs_node* find_node_by_path(vfs_node* root, const std::string& path) {
 | 
			
		||||
  if(path == "/") {
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ public:
 | 
			
		||||
  ~CommandProcessor(void);
 | 
			
		||||
 | 
			
		||||
  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. */
 | 
			
		||||
  vfs_node* get_current_dir(void);
 | 
			
		||||
 | 
			
		||||
@ -107,13 +107,28 @@ void NetworkManager::on_message(std::shared_ptr<net::TcpConnection> connection,
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
  if(response == "__CLOSE_CONNECTION__") {
 | 
			
		||||
    connection->send(response);
 | 
			
		||||
    /* Just let me close the f.cking terminal? */
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user