mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2024-12-24 00:54:43 +00:00
170 lines
4.3 KiB
C++
170 lines
4.3 KiB
C++
|
/*
|
||
|
* Copyright (C) 2023 Kyle Reed
|
||
|
*
|
||
|
* This file is part of PortaPack.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||
|
* any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; see the file COPYING. If not, write to
|
||
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#ifndef __UI_TEXT_EDITOR_H__
|
||
|
#define __UI_TEXT_EDITOR_H__
|
||
|
|
||
|
#include "ui.hpp"
|
||
|
#include "ui_font_fixed_5x8.hpp"
|
||
|
#include "ui_navigation.hpp"
|
||
|
#include "ui_painter.hpp"
|
||
|
#include "ui_widget.hpp"
|
||
|
//#include "ui_textentry.hpp"
|
||
|
|
||
|
#include "file.hpp"
|
||
|
#include "log_file.hpp"
|
||
|
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
|
||
|
namespace ui {
|
||
|
|
||
|
enum class LineEnding : uint8_t {
|
||
|
LF,
|
||
|
CRLF
|
||
|
};
|
||
|
|
||
|
enum class ScrollDirection : uint8_t {
|
||
|
Vertical,
|
||
|
Horizontal
|
||
|
};
|
||
|
|
||
|
// TODO: RAM is _very_ limited. Need to
|
||
|
// rework this to not store every line.
|
||
|
// Should be able to get away with only
|
||
|
// abount one screen of lines so long as
|
||
|
// you can't scroll more than one screen
|
||
|
// at a time.
|
||
|
struct FileInfo {
|
||
|
/* Offsets of newlines. */
|
||
|
std::vector<uint32_t> newlines;
|
||
|
LineEnding line_ending;
|
||
|
File::Size size;
|
||
|
bool truncated;
|
||
|
|
||
|
uint32_t line_count() const {
|
||
|
return newlines.size();
|
||
|
}
|
||
|
|
||
|
uint32_t line_start(uint32_t line) const {
|
||
|
return line == 0 ? 0 : (newlines[line - 1] + 1);
|
||
|
}
|
||
|
|
||
|
uint16_t line_length(uint32_t line) const {
|
||
|
if (line >= line_count())
|
||
|
return 0;
|
||
|
|
||
|
auto start = line_start(line);
|
||
|
auto end = newlines[line];
|
||
|
return end - start;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/*class TextViewer : public Widget {
|
||
|
};*/
|
||
|
|
||
|
class TextEditorView : public View {
|
||
|
public:
|
||
|
TextEditorView(NavigationView& nav);
|
||
|
// TextEditorView(NavigationView& nav, const std::filesystem::path& path);
|
||
|
|
||
|
std::string title() const override {
|
||
|
return "Notepad";
|
||
|
};
|
||
|
|
||
|
void on_focus() override;
|
||
|
void paint(Painter& painter) override;
|
||
|
bool on_key(KeyEvent delta) override;
|
||
|
bool on_encoder(EncoderEvent delta) override;
|
||
|
|
||
|
private:
|
||
|
static constexpr uint8_t max_line = 32;
|
||
|
static constexpr uint8_t max_col = 48;
|
||
|
static constexpr int8_t char_width = 5;
|
||
|
static constexpr int8_t char_height = 8;
|
||
|
|
||
|
// TODO: should these be common somewhere?
|
||
|
static constexpr Style style_default{
|
||
|
.font = font::fixed_5x8,
|
||
|
.background = Color::black(),
|
||
|
.foreground = Color::white(),
|
||
|
};
|
||
|
|
||
|
/* Returns true if the cursor was updated. */
|
||
|
bool apply_scrolling_constraints(
|
||
|
int16_t delta_line,
|
||
|
int16_t delta_col);
|
||
|
|
||
|
void refresh_ui();
|
||
|
void refresh_file_info();
|
||
|
void open_file(const std::filesystem::path& path);
|
||
|
std::string read(uint32_t offset, uint32_t length = 30);
|
||
|
|
||
|
void paint_text(Painter& painter, uint32_t line, uint16_t col);
|
||
|
void paint_cursor(Painter& painter);
|
||
|
|
||
|
// Gets the length of the current line.
|
||
|
uint16_t line_length() const;
|
||
|
|
||
|
NavigationView& nav_;
|
||
|
|
||
|
File file_{};
|
||
|
FileInfo info_{};
|
||
|
// LogFile log_{ };
|
||
|
|
||
|
struct {
|
||
|
// Previous cursor state.
|
||
|
uint32_t line{};
|
||
|
uint16_t col{};
|
||
|
|
||
|
// Previous draw state.
|
||
|
uint32_t first_line{};
|
||
|
uint16_t first_col{};
|
||
|
bool redraw_text{true};
|
||
|
bool has_file{false};
|
||
|
} paint_state_{};
|
||
|
|
||
|
struct {
|
||
|
uint32_t line{};
|
||
|
uint16_t col{};
|
||
|
ScrollDirection dir{ScrollDirection::Vertical};
|
||
|
} cursor_{};
|
||
|
|
||
|
/* 8px grid is 30 wide, 38 tall. */
|
||
|
/* 16px font height or 19 rows. */
|
||
|
/* Titlebar is 16px tall, so 18 rows left. */
|
||
|
/* 240 x 320, (304 with titlebar) */
|
||
|
|
||
|
// TODO: The scrollable view should be its own widget
|
||
|
// otherwise control navigation doesn't work.
|
||
|
|
||
|
Button button_open{
|
||
|
{24 * 8, 34 * 8, 6 * 8, 4 * 8},
|
||
|
"Open"};
|
||
|
|
||
|
Text text_position{
|
||
|
{0 * 8, 36 * 8, 24 * 8, 2 * 8},
|
||
|
""};
|
||
|
};
|
||
|
|
||
|
} // namespace ui
|
||
|
|
||
|
#endif // __UI_TEXT_EDITOR_H__
|