#include "../muscles.h"
#include "../ui.h"
#include "dialog.h"
void View_Object::update_ui(Camera& camera) {
reposition_box_buttons(cross, maxm, box.w, cross_size);
float title_w = 200;
float title_x = (cross.pos.x - title_w) / 2;
if (title_x < border) {
title_x = border;
title_w = cross.pos.x - title_x - 2*border;
}
title_edit.pos = {
title_x,
2,
title_w,
title_edit.font->render.text_height() * 1.4f / camera.scale
};
float meta_y = title_edit.pos.h + 4*border;
hide_meta.pos = {
cross.pos.x + (cross.pos.w - meta_btn_width),
meta_y,
meta_btn_width,
meta_btn_height
};
float label_x = 2*border;
float y = meta_y;
if (!meta_hidden) {
float label_h = struct_label.font->render.text_height() * 1.2f / camera.scale;
float edit_h = get_edit_height(camera.scale);
float edit_gap = edit_h + border;
float edit_y = meta_y - (edit_h - label_h) / 2;
struct_label.pos = {
label_x,
y,
80,
label_h
};
y += edit_gap;
source_label.pos = {
label_x,
y,
80,
label_h
};
y += edit_gap;
addr_label.pos = {
label_x,
y,
100,
label_h
};
y = edit_y;
struct_edit.pos = {
label_x + struct_label.pos.w + border,
y,
160,
edit_h
};
y += edit_gap;
source_edit.pos = {
label_x + source_label.pos.w + border,
y,
160,
edit_h
};
y += edit_gap;
addr_edit.pos = {
label_x + addr_label.pos.w + border,
y,
140,
edit_h
};
y += edit_gap + border;
}
else
y += meta_btn_height + 2*border;
float scroll_w = 14;
float view_w = box.w - 2*label_x - scroll_w - border;
float view_h = box.h - y - scroll_w - all_btn.height - 4*border;
vscroll.pos = {
label_x + view_w + border,
y,
scroll_w,
view_h
};
hscroll.pos = {
label_x,
y + view_h + border,
view_w,
scroll_w
};
object.pos = {
label_x,
y,
view_w,
view_h
};
all_btn.pos = {
label_x,
box.h - 2*border - all_btn.height,
all_btn.width,
all_btn.height
};
sel_btn.pos = {
all_btn.pos.x + all_btn.pos.w,
all_btn.pos.y,
sel_btn.width,
sel_btn.height
};
}
float View_Object::get_edit_height(float scale) {
return struct_edit.font->render.text_height() * 1.4f / scale;
}
void View_Object::update_hide_meta_button(float scale) {
float pad = hide_meta.padding;
int meta_w = 0.5 + (meta_btn_width - 2*pad) * scale;
int meta_h = 0.5 + (meta_btn_height - 2*pad) * scale;
sdl_destroy_texture(&hide_meta.icon);
hide_meta.icon = make_triangle(hide_meta.default_color, meta_w, meta_h, !meta_hidden);
}
void View_Object::select_view_type(bool all) {
all = all;
auto theme_all = all ? &theme_on : &theme_off;
auto theme_sel = all ? &theme_off : &theme_on;
all_btn.active_theme = *theme_all;
all_btn.inactive_theme = *theme_all;
sel_btn.active_theme = *theme_sel;
sel_btn.inactive_theme = *theme_sel;
object.condition_col = all ? -1 : 0;
object.needs_redraw = true;
}
void struct_edit_handler(Edit_Box *edit, Input& input) {
auto ui = dynamic_cast<View_Object*>(edit->parent);
Workspace *ws = edit->parent->parent;
populate_object_table<View_Object>(ui, ws->structs, ws->name_vector);
}
void source_edit_handler(Edit_Box *edit, Input& input) {
auto ui = dynamic_cast<View_Object*>(edit->parent);
Source *src = nullptr;
if (edit->editor.text.size() > 0) {
Workspace& ws = *edit->parent->parent;
for (auto& s : ws.sources) {
if (s->name == edit->editor.text) {
src = s;
break;
}
}
}
if (src != ui->source || !src) {
if (ui->source && ui->span_idx >= 0)
ui->source->deactivate_span(ui->span_idx);
ui->source = src;
ui->span_idx = src ? src->request_span() : -1;
}
ui->object.needs_redraw = true;
}
void view_handler(UI_Element *elem, Camera& view, bool dbl_click) {
auto table = dynamic_cast<Data_View*>(elem);
table->sel_row = table->hl_row;
}
void View_Object::refresh(Point *cursor) {
Workspace& ws = *parent;
int n_sources = ws.sources.size();
source_dd.content.resize(n_sources);
for (int i = 0; i < n_sources; i++)
source_dd.content[i] = (char*)ws.sources[i]->name.c_str();
struct_dd.external = &ws.struct_names;
if (!record || !source)
return;
Span& span = source->spans[span_idx];
span.address = strtoull(addr_edit.editor.text.c_str(), nullptr, 16);
span.size = (record->total_size + 7) / 8;
field_vec.clear();
int idx = -1;
for (auto& row : object.data->columns[1]) {
idx++;
if (idx >= record->fields.n_fields)
break;
Field& field = record->fields.data[idx];
int name_idx = get_full_field_name(field, ws.name_vector, field_vec);
char *name = &field_vec.pool[name_idx];
Bucket& buck = field_fmt.insert(name);
Value_Format fmt = {};
if (buck.flags & FLAG_NEW) {
if (field.flags & FLAG_FLOAT)
fmt.floatfmt = FloatAuto;
buck.value = format.size();
format.push_back(fmt);
}
else
fmt = format[buck.value];
format_field_value(field, fmt, span, (char*&)object.data->columns[2][idx], object.data->headers[2].count_per_cell);
}
}
void View_Object::handle_zoom(Workspace& ws, float new_scale) {
cross.img = ws.cross;
maxm.img = ws.maxm;
update_hide_meta_button(new_scale);
float height = get_edit_height(new_scale);
struct_edit.update_icon(IconTriangle, height, new_scale);
source_edit.update_icon(IconTriangle, height, new_scale);
}
void View_Object::on_close() {
source->deactivate_span(span_idx);
}
View_Object::View_Object(Workspace& ws, MenuType mtype) {
float scale = get_default_camera().scale;
cross.action = get_delete_box();
cross.img = ws.cross;
ui.push_back(&cross);
maxm.action = get_maximize_box();
maxm.img = ws.maxm;
ui.push_back(&maxm);
title_edit.placeholder = "Instance";
title_edit.ph_font = ws.make_font(12, ws.colors.ph_text, scale);
title_edit.font = ws.default_font;
title_edit.caret = ws.colors.caret;
title_edit.caret.a = 0.6;
title_edit.default_color = ws.colors.dark;
ui.push_back(&title_edit);
hide_meta.padding = 0;
hide_meta.action = [](UI_Element *elem, Camera& view, bool dbl_click) {
auto ui = dynamic_cast<View_Object*>(elem->parent);
ui->meta_hidden = !ui->meta_hidden;
ui->struct_label.visible = ui->struct_edit.visible = !ui->meta_hidden;
ui->source_label.visible = ui->source_edit.visible = !ui->meta_hidden;
ui->addr_label.visible = ui->addr_edit.visible = !ui->meta_hidden;
ui->update_hide_meta_button(view.scale);
};
hide_meta.active_theme = {
ws.colors.light,
ws.colors.light_hl,
ws.colors.light_hl,
nullptr
};
hide_meta.inactive_theme = hide_meta.active_theme;
hide_meta.default_color = ws.colors.text;
hide_meta.default_color.a = 0.8;
ui.push_back(&hide_meta);
hscroll.back_color = ws.colors.scroll_back;
hscroll.default_color = ws.colors.scroll;
hscroll.hl_color = ws.colors.scroll_hl;
hscroll.sel_color = ws.colors.scroll_sel;
hscroll.vertical = false;
ui.push_back(&hscroll);
vscroll.back_color = ws.colors.scroll_back;
vscroll.default_color = ws.colors.scroll;
vscroll.hl_color = ws.colors.scroll_hl;
vscroll.sel_color = ws.colors.scroll_sel;
ui.push_back(&vscroll);
object.font = ws.default_font;
object.default_color = ws.colors.dark;
object.hl_color = ws.colors.hl;
object.sel_color = ws.colors.light;
object.action = view_handler;
object.use_sf_cache = false;
object.hscroll = &hscroll;
object.hscroll->content = &object;
object.vscroll = &vscroll;
object.vscroll->content = &object;
Column cols[] = {
{ColumnCheckbox, 0, 0.05, 1.0, 1.0, ""},
{ColumnString, 0, 0.5, 0, 0, "Name"},
{ColumnString, 20, 0.45, 0, 0, "Value"}
};
Arena *arena = &ws.object_arena;
arena->set_rewind_point();
table.init(cols, arena, nullptr, nullptr, 3, 0);
object.data = &table;
ui.push_back(&object);
struct_label.font = ws.make_font(11, ws.colors.text, scale);
struct_label.text = "Struct:";
struct_label.padding = 0;
ui.push_back(&struct_label);
source_label.font = struct_label.font;
source_label.text = "Source:";
source_label.padding = 0;
ui.push_back(&source_label);
addr_label.font = struct_label.font;
addr_label.text = "Address:";
addr_label.padding = 0;
ui.push_back(&addr_label);
auto mm = ws.first_box_of_type<Main_Menu>();
RGBA icon_color = ws.colors.text;
icon_color.a = 0.7;
addr_edit.font = addr_label.font;
addr_edit.caret = ws.colors.caret;
addr_edit.default_color = ws.colors.dark;
ui.push_back(&addr_edit);
source_dd.edit_elem = &source_edit;
source_dd.font = source_label.font;
source_dd.default_color = ws.colors.back;
source_dd.hl_color = ws.colors.hl;
source_dd.sel_color = ws.colors.active;
source_dd.width = 250;
ui.push_back(&source_dd);
source_edit.font = source_label.font;
source_edit.caret = ws.colors.caret;
source_edit.default_color = ws.colors.dark;
source_edit.icon_color = icon_color;
source_edit.icon_right = true;
source_edit.dropdown = &source_dd;
source_edit.key_action = source_edit_handler;
ui.push_back(&source_edit);
struct_dd.edit_elem = &struct_edit;
struct_dd.font = struct_label.font;
struct_dd.default_color = ws.colors.back;
struct_dd.hl_color = ws.colors.hl;
struct_dd.sel_color = ws.colors.active;
struct_dd.width = 250;
ui.push_back(&struct_dd);
struct_edit.font = struct_label.font;
struct_edit.caret = ws.colors.caret;
struct_edit.default_color = ws.colors.dark;
struct_edit.icon_color = icon_color;
struct_edit.icon_right = true;
struct_edit.dropdown = &struct_dd;
struct_edit.key_action = struct_edit_handler;
ui.push_back(&struct_edit);
theme_on = {
ws.colors.dark,
ws.colors.light,
ws.colors.light,
ws.make_font(10, ws.colors.text, scale)
};
theme_off = {
ws.colors.back,
ws.colors.light,
ws.colors.light,
theme_on.font
};
all_btn.padding = 0;
all_btn.text = "All";
all_btn.active_theme = theme_on;
all_btn.inactive_theme = theme_on;
all_btn.update_size(scale);
all_btn.action = [](UI_Element *elem, Camera&, bool dbl_click) { dynamic_cast<View_Object*>(elem->parent)->select_view_type(true); };
ui.push_back(&all_btn);
sel_btn.padding = 0;
sel_btn.text = "Selected";
sel_btn.active_theme = theme_off;
sel_btn.inactive_theme = theme_off;
sel_btn.update_size(scale);
sel_btn.action = [](UI_Element *elem, Camera&, bool dbl_click) { dynamic_cast<View_Object*>(elem->parent)->select_view_type(false); };
ui.push_back(&sel_btn);
refresh_every = 1;
initial_width = 400;
initial_height = 450;
min_width = 300;
min_height = 200;
expungeable = true;
}