2022-06-19 23:50:08 +02:00
|
|
|
#include "source.h"
|
|
|
|
#include "heditor.h"
|
|
|
|
|
2022-06-17 23:03:27 +02:00
|
|
|
#include <gint/display.h>
|
|
|
|
#include <gint/keyboard.h>
|
2022-06-18 19:17:31 +02:00
|
|
|
#include <gint/exc.h>
|
2022-06-17 23:03:27 +02:00
|
|
|
|
2022-06-18 19:17:31 +02:00
|
|
|
#include <justui/jscene.h>
|
|
|
|
#include <justui/jlabel.h>
|
|
|
|
#include <justui/jfkeys.h>
|
|
|
|
#include <justui/jinput.h>
|
2022-06-19 23:50:08 +02:00
|
|
|
#include <justui/jfileselect.h>
|
2022-06-18 19:17:31 +02:00
|
|
|
|
|
|
|
#include <stdio.h>
|
2022-06-20 02:51:06 +02:00
|
|
|
#include <stdlib.h>
|
2022-06-18 19:17:31 +02:00
|
|
|
#include <string.h>
|
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
static void update_status(jlabel *status, jlabel *title, source_t *s)
|
2022-06-18 19:17:31 +02:00
|
|
|
{
|
2022-06-19 23:50:08 +02:00
|
|
|
if(!s) {
|
|
|
|
jlabel_set_text(status, "-");
|
|
|
|
jlabel_set_text(title, "Hex Editor");
|
|
|
|
return;
|
2022-06-18 19:17:31 +02:00
|
|
|
}
|
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
size_t size = source_size(s);
|
2022-06-18 19:17:31 +02:00
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
if(s->origin)
|
|
|
|
jlabel_asprintf(title, "%s (%d B) - Hex Editor", s->origin, size);
|
|
|
|
else
|
|
|
|
jlabel_set_text(title, "(nil) - Hex Editor");
|
2022-06-18 19:17:31 +02:00
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
jlabel_asprintf(status, "Buffer: @%X %d/%d",
|
|
|
|
s->buf_offset, s->buf->data_size, s->buf->mem_size);
|
2022-06-18 19:17:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void hex_view(void)
|
|
|
|
{
|
2022-06-19 23:50:08 +02:00
|
|
|
source_t *s = NULL;
|
2022-06-18 19:17:31 +02:00
|
|
|
|
|
|
|
jscene *scene = jscene_create_fullscreen(NULL);
|
|
|
|
jlabel *title = jlabel_create("Hex Editor", scene);
|
|
|
|
jwidget *stack = jwidget_create(scene);
|
2022-06-19 23:50:08 +02:00
|
|
|
jfkeys *fkeys = jfkeys_create("@JUMP;@OPEN",scene);
|
2022-06-18 19:17:31 +02:00
|
|
|
|
|
|
|
if(!scene || !title || !stack || !fkeys) {
|
|
|
|
jwidget_destroy(scene);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
jwidget_set_background(title, C_BLACK);
|
|
|
|
jlabel_set_text_color(title, C_WHITE);
|
|
|
|
jwidget_set_stretch(title, 1, 0, false);
|
|
|
|
jwidget_set_padding(title, 3, 6, 3, 6);
|
|
|
|
|
|
|
|
jlayout_set_vbox(scene)->spacing = 3;
|
|
|
|
jlayout_set_stack(stack);
|
|
|
|
jwidget_set_padding(stack, 0, 6, 0, 6);
|
|
|
|
jwidget_set_stretch(stack, 1, 1, false);
|
|
|
|
|
|
|
|
// Main tab //
|
|
|
|
|
|
|
|
jwidget *tab = jwidget_create(NULL);
|
2022-06-19 23:50:08 +02:00
|
|
|
heditor *mem = heditor_create(tab); /* previously 321x153 */
|
2022-06-18 19:17:31 +02:00
|
|
|
jlabel *status = jlabel_create("", tab);
|
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
jwidget_set_margin(mem, 3, 0, 3, 0);
|
|
|
|
jwidget_set_stretch(mem, 1, 1, false);
|
2022-06-18 19:17:31 +02:00
|
|
|
|
|
|
|
jwidget_set_stretch(status, 1, 0, false);
|
|
|
|
|
2022-06-20 02:51:06 +02:00
|
|
|
jlayout_set_vbox(tab)->spacing = 3;
|
2022-06-18 19:17:31 +02:00
|
|
|
jwidget_add_child(stack, tab);
|
|
|
|
jwidget_set_stretch(tab, 1, 1, false);
|
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
update_status(status, title, s);
|
|
|
|
jscene_show_and_focus(scene, mem);
|
|
|
|
|
|
|
|
// File selection tab //
|
|
|
|
|
|
|
|
jfileselect *fileselect = jfileselect_create(stack);
|
|
|
|
jfileselect_set_show_file_size(fileselect, true);
|
|
|
|
jwidget_set_stretch(fileselect, 1, 1, false);
|
2022-06-18 19:17:31 +02:00
|
|
|
|
2022-06-20 02:51:06 +02:00
|
|
|
// Goto popup //
|
|
|
|
|
|
|
|
jwidget *popup_goto = jwidget_create(scene);
|
|
|
|
jwidget_set_floating(popup_goto, true);
|
|
|
|
jwidget_set_border(popup_goto, J_BORDER_SOLID, 2, C_BLACK);
|
|
|
|
jwidget_set_padding(popup_goto, 4, 4, 4, 4);
|
|
|
|
jwidget_set_background(popup_goto, C_WHITE);
|
|
|
|
jwidget_set_visible(popup_goto, false);
|
|
|
|
jwidget_set_fixed_size(popup_goto, DWIDTH * 3 / 4, DHEIGHT / 2);
|
|
|
|
popup_goto->x = DWIDTH / 8;
|
|
|
|
popup_goto->y = DHEIGHT / 4;
|
|
|
|
jlayout_set_vbox(popup_goto)->spacing = 3;
|
|
|
|
|
|
|
|
|
|
|
|
jinput *goto_input = jinput_create("Go to: ", 12, popup_goto);
|
|
|
|
jwidget_set_stretch(goto_input, 1, 0, false);
|
|
|
|
|
|
|
|
jlabel *goto_help = jlabel_create(
|
|
|
|
"In hexadecimal. Use [ALPHA] to type letters.\n"
|
|
|
|
"Prefix with [+] or [-] to move relative to the current position.",
|
|
|
|
popup_goto);
|
|
|
|
jlabel_set_wrap_mode(goto_help, J_WRAP_WORD);
|
|
|
|
jlabel_set_line_spacing(goto_help, 2);
|
|
|
|
jlabel_set_block_alignment(goto_help, J_ALIGN_LEFT, J_ALIGN_TOP);
|
|
|
|
jwidget_set_stretch(goto_help, 1, 1, false);
|
|
|
|
|
2022-06-18 19:17:31 +02:00
|
|
|
// Event handling //
|
|
|
|
|
|
|
|
int key = 0;
|
|
|
|
while(key != KEY_EXIT)
|
|
|
|
{
|
2022-06-20 02:51:06 +02:00
|
|
|
bool input_focus = (jscene_focused_widget(scene) == goto_input);
|
2022-06-18 19:17:31 +02:00
|
|
|
jevent e = jscene_run(scene);
|
|
|
|
|
|
|
|
if(e.type == JSCENE_PAINT) {
|
|
|
|
dclear(C_WHITE);
|
|
|
|
jscene_render(scene);
|
|
|
|
dupdate();
|
|
|
|
}
|
|
|
|
if(e.type == JINPUT_VALIDATED) {
|
|
|
|
/* Parse string into hexa */
|
2022-06-20 02:51:06 +02:00
|
|
|
char const *str = jinput_value(goto_input);
|
|
|
|
uint32_t target = strtoul(str, NULL, 16);
|
2022-06-20 02:02:52 +02:00
|
|
|
heditor_move_to(mem, target);
|
2022-06-18 19:17:31 +02:00
|
|
|
}
|
|
|
|
if(e.type == JINPUT_VALIDATED || e.type == JINPUT_CANCELED) {
|
2022-06-20 02:51:06 +02:00
|
|
|
jwidget_set_visible(popup_goto, false);
|
2022-06-19 23:50:08 +02:00
|
|
|
jscene_show_and_focus(scene, mem);
|
|
|
|
}
|
|
|
|
if(e.type == JFILESELECT_LOADED) {
|
|
|
|
char const *path = jfileselect_current_folder(fileselect);
|
|
|
|
jlabel_asprintf(title, "Browsing: %s", path ? path : "(nil)");
|
|
|
|
}
|
|
|
|
if(e.type == JFILESELECT_CANCELED || e.type == JFILESELECT_VALIDATED) {
|
|
|
|
jscene_show_and_focus(scene, mem);
|
|
|
|
|
|
|
|
if(e.type == JFILESELECT_VALIDATED) {
|
|
|
|
char const *file = jfileselect_selected_file(fileselect);
|
|
|
|
if(file) {
|
|
|
|
if(s)
|
|
|
|
source_free(s);
|
|
|
|
s = source_loaded_file_open(file);
|
|
|
|
if(s) {
|
|
|
|
source_load(s, 0, 2048);
|
|
|
|
}
|
|
|
|
heditor_set_source(mem, s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
update_status(status, title, s);
|
|
|
|
}
|
|
|
|
if(e.type == HEDITOR_CHANGED) {
|
|
|
|
update_status(status, title, s);
|
2022-06-18 19:17:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(e.type != JSCENE_KEY || e.key.type == KEYEV_UP) continue;
|
|
|
|
key = e.key.key;
|
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
if(key == KEY_F1 && stack->layout_stack.active == 0 && !input_focus) {
|
2022-06-20 02:51:06 +02:00
|
|
|
jinput_clear(goto_input);
|
|
|
|
jwidget_set_visible(popup_goto, true);
|
|
|
|
jscene_set_focused_widget(scene, goto_input);
|
2022-06-18 19:17:31 +02:00
|
|
|
}
|
2022-06-19 23:50:08 +02:00
|
|
|
if(key == KEY_F2 && !input_focus) {
|
|
|
|
jfileselect_browse(fileselect, "/");
|
|
|
|
jscene_show_and_focus(scene, fileselect);
|
|
|
|
}
|
2022-06-18 19:17:31 +02:00
|
|
|
}
|
|
|
|
jwidget_destroy(scene);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
{
|
|
|
|
hex_view();
|
|
|
|
return 1;
|
2022-06-17 23:03:27 +02:00
|
|
|
}
|