paint: stage fixes

This commit is contained in:
luboslenco
2026-08-22 20:08:28 +02:00
parent 7a96a6cab4
commit 13810046e1
8 changed files with 106 additions and 34 deletions
+3
View File
@@ -429,6 +429,9 @@ char *strings_graphics_api();
stage_t *tab_stages_create_stage(char *name);
stage_t *tab_stages_get_stage();
void tab_stages_apply(stage_t *stage);
void tab_stages_apply_visible(mesh_object_t *o);
bool tab_stages_is_hidden(stage_t *stage, char *name);
void tab_stages_set_hidden(stage_t *stage, char *name, bool hidden);
void tab_stages_add_object(char *name);
void tab_stages_rename_object(char *old_name, char *new_name);
void tab_stages_rename_layer(char *old_name, char *new_name);
+1 -1
View File
@@ -7,7 +7,7 @@
char *manifest_title = "ArmorPaint";
char *manifest_version = "1.0 rc2";
char *manifest_version_project = "14";
char *manifest_version_project = "15";
char *manifest_version_config = "1";
char *manifest_url = "https://armorpaint.org";
char *manifest_url_android = "https://play.google.com/store/apps/details?id=org.armorpaint";
+13 -1
View File
@@ -304,6 +304,7 @@ project_t *import_arm_from_map_to_arm(any_map_t *old) {
d->name = any_map_get(old, "name");
d->objects = any_map_get(old, "objects");
d->layers = any_map_get(old, "layers");
d->hidden = any_map_get(old, "hidden");
any_array_push(project->stages, d);
}
}
@@ -311,6 +312,16 @@ project_t *import_arm_from_map_to_arm(any_map_t *old) {
return project;
}
project_t *import_arm_from_version_14(any_map_t *old) {
any_array_t *stages = any_map_get(old, "stages");
if (stages != NULL) {
for (i32 i = 0; i < stages->length; ++i) {
any_map_set(stages->buffer[i], "hidden", NULL);
}
}
return import_arm_from_map_to_arm(old);
}
project_t *import_arm_from_version_13(any_map_t *old) {
any_array_t *lds = any_map_get(old, "layer_datas");
if (lds != NULL) {
@@ -319,7 +330,7 @@ project_t *import_arm_from_version_13(any_map_t *old) {
armpack_map_set_i32(ld, "path_text", 0);
}
}
return import_arm_from_map_to_arm(old);
return import_arm_from_version_14(old);
}
project_t *import_arm_from_version_12(any_map_t *old) {
@@ -454,6 +465,7 @@ project_t *import_arm_from_old(buffer_t *b) {
import_arm_from_version_0, import_arm_from_version_1, import_arm_from_version_2, import_arm_from_version_3, import_arm_from_version_4,
import_arm_from_version_5, import_arm_from_version_6, import_arm_from_version_7, import_arm_from_version_8, import_arm_from_version_9,
import_arm_from_version_10, import_arm_from_version_11, import_arm_from_version_12, import_arm_from_version_13,
import_arm_from_version_14,
};
for (i32 v = sizeof(fns) / sizeof(fns[0]) - 1; v >= 0; --v) {
if (import_arm_is_version(b, i32_to_string(v))) {
+1
View File
@@ -527,6 +527,7 @@ typedef struct {
char *name;
string_array_t *objects;
string_array_t *layers;
string_array_t *hidden;
} stage_t;
typedef struct {
+6 -16
View File
@@ -15,6 +15,11 @@ bool tab_meshes_search_focus = false;
ui_handle_t *tab_meshes_search_handle = NULL;
static bool tab_meshes_slot_hidden(mesh_object_t *o) {
stage_t *stage = tab_stages_get_stage();
if (stage != NULL && string_array_index_of(stage->objects, o->base->name) < 0) {
return true;
}
if (!tab_meshes_search_show || tab_meshes_search_handle == NULL) {
return false;
}
@@ -851,21 +856,6 @@ void tab_meshes_make_preview(mesh_object_t *o) {
g_context->ddirty = 0;
}
void tab_meshes_apply_visible(mesh_object_t *o) {
stage_t *stage = tab_stages_get_stage();
if (stage != NULL) {
i32 idx = string_array_index_of(stage->objects, o->base->name);
if (o->base->visible && idx < 0) {
string_array_push(stage->objects, o->base->name);
}
else if (!o->base->visible && idx >= 0) {
array_splice(stage->objects, idx, 1);
}
}
util_mesh_visibility_changed();
}
static char *tab_meshes_mesh_info(mesh_object_t *o, i32 i) {
i32 owner = util_mesh_data_owner(o->data);
if (!util_mesh_data_is_shared(o->data)) {
@@ -922,7 +912,7 @@ void tab_meshes_draw_mesh_slot(mesh_object_t *o, i32 i) {
i32 col = g_theme->HOVER_COL + 0x00282828;
if (ui_sub_image(icons, col, 18 * UI_SCALE(), r->x, r->y, r->w, r->h) == UI_STATE_RELEASED) {
o->base->visible = !o->base->visible;
tab_meshes_apply_visible(o);
tab_stages_apply_visible(o);
}
// Mesh icon
+38 -14
View File
@@ -65,7 +65,7 @@ static i32 tab_timeline_tween_tex0 = 0;
static i32 tab_timeline_tween_tex1 = 0;
static i32 tab_timeline_tween_factor = 0;
static bool tab_timeline_stage_rename_init = false;
static bool tab_timeline_stage_edit_init = false;
static void tab_timeline_copy_tex(gpu_texture_t *dst, gpu_texture_t *src) {
draw_begin(dst, true, 0x00000000);
@@ -1112,18 +1112,47 @@ void tab_timeline_draw_edit() {
}
}
void tab_timeline_stage_rename_box_draw() {
stage_t *s = tab_stages_get_stage();
void tab_timeline_stage_edit_box_draw() {
stage_t *s = tab_stages_get_stage();
if (s == NULL) {
return;
}
ui_handle_t *h = ui_handle(__ID__);
if (tab_timeline_stage_rename_init) {
if (tab_timeline_stage_edit_init) {
h->text = string_copy(s->name);
ui_start_text_edit(h, UI_ALIGN_LEFT);
tab_timeline_stage_rename_init = false;
tab_timeline_stage_edit_init = false;
}
char *name = ui_text_input(h, tr("Name"), UI_ALIGN_LEFT, true, false);
ui_end_element();
ui_text(tr("Meshes"), UI_ALIGN_LEFT, 0x00000000);
ui_handle_t *hmeshes = ui_handle(__ID__);
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
mesh_object_t *o = g_project->_->paint_objects->buffer[i];
i32 idx = string_array_index_of(s->objects, o->base->name);
ui_handle_t *hmesh = ui_nest(hmeshes, i);
hmesh->b = idx >= 0;
ui_check(hmesh, o->base->name, "");
if (hmesh->changed) {
if (hmesh->b) {
string_array_push(s->objects, o->base->name);
}
else {
array_splice(s->objects, idx, 1);
}
o->base->visible = hmesh->b;
tab_stages_set_hidden(s, o->base->name, false);
util_mesh_visibility_changed();
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2;
}
}
ui_end_element();
ui_row2();
if (ui_icon_button(tr("Cancel"), ICON_CLOSE, UI_ALIGN_CENTER)) {
ui_box_hide();
@@ -1154,9 +1183,9 @@ void tab_timeline_draw_stage_menu() {
}
g_ui->enabled = true;
if (ui_menu_button(tr("Rename"), "", ICON_EDIT)) {
tab_timeline_stage_rename_init = true;
ui_box_show_custom(&tab_timeline_stage_rename_box_draw, 400, 130, NULL, true, tr("Rename Stage"));
if (ui_menu_button(tr("Edit"), "", ICON_EDIT)) {
tab_timeline_stage_edit_init = true;
ui_box_show_custom(&tab_timeline_stage_edit_box_draw, 400, 430, NULL, true, tr("Edit Stage"));
}
}
@@ -1385,12 +1414,7 @@ void tab_timeline_draw(ui_handle_t *htab) {
bool eye_hover = !tab_timeline_scrolling && tab_timeline_input_in_rect(g_ui->_x, row_y, eye_size, strip_h);
if (eye_hover && g_ui->input_released) {
mesh->base->visible = !mesh->base->visible;
util_mesh_merge(util_mesh_get_visible());
util_uv_uvmap_cached = false;
util_uv_trianglemap_cached = false;
util_uv_dilatemap_cached = false;
g_context->ddirty = 2;
tab_stages_apply_visible(mesh);
}
rect_t *rect = resource_tile50(icons, ICON_CUBE);
+3 -1
View File
@@ -561,13 +561,15 @@ buffer_t *util_encode_project(project_t *raw) {
if (raw->stages != NULL) {
armpack_encode_array(raw->stages->length);
for (i32 i = 0; i < raw->stages->length; ++i) {
armpack_encode_map(3);
armpack_encode_map(4);
armpack_encode_string("name");
armpack_encode_string(raw->stages->buffer[i]->name);
armpack_encode_string("objects");
armpack_encode_array_string(raw->stages->buffer[i]->objects);
armpack_encode_string("layers");
armpack_encode_array_string(raw->stages->buffer[i]->layers);
armpack_encode_string("hidden");
armpack_encode_array_string(raw->stages->buffer[i]->hidden);
}
}
else {
+41 -1
View File
@@ -8,9 +8,27 @@ stage_t *tab_stages_create_stage(char *name) {
s->name = name;
s->objects = string_array_create(0);
s->layers = string_array_create(0);
s->hidden = string_array_create(0);
return s;
}
bool tab_stages_is_hidden(stage_t *stage, char *name) {
return stage->hidden != NULL && string_array_index_of(stage->hidden, name) >= 0;
}
void tab_stages_set_hidden(stage_t *stage, char *name, bool hidden) {
if (stage->hidden == NULL) {
stage->hidden = string_array_create(0);
}
i32 idx = string_array_index_of(stage->hidden, name);
if (hidden && idx < 0) {
string_array_push(stage->hidden, name);
}
else if (!hidden && idx >= 0) {
array_splice(stage->hidden, idx, 1);
}
}
stage_t *tab_stages_get_stage() {
if (g_project->stages == NULL || g_project->stages->length == 0) {
return NULL;
@@ -25,7 +43,7 @@ void tab_stages_apply(stage_t *stage) {
mesh_object_t_array_t *visibles = any_array_create_from_raw((void *[]){}, 0);
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
mesh_object_t *p = g_project->_->paint_objects->buffer[i];
p->base->visible = string_array_index_of(stage->objects, p->base->name) >= 0;
p->base->visible = string_array_index_of(stage->objects, p->base->name) >= 0 && !tab_stages_is_hidden(stage, p->base->name);
if (p->base->visible) {
any_array_push(visibles, p);
}
@@ -34,6 +52,14 @@ void tab_stages_apply(stage_t *stage) {
g_context->ddirty = 2;
}
void tab_stages_apply_visible(mesh_object_t *o) {
stage_t *stage = tab_stages_get_stage();
if (stage != NULL) {
tab_stages_set_hidden(stage, o->base->name, !o->base->visible);
}
util_mesh_visibility_changed();
}
void tab_stages_add_object(char *name) {
stage_t *stage = tab_stages_get_stage();
if (stage != NULL && string_array_index_of(stage->objects, name) < 0) {
@@ -52,6 +78,14 @@ void tab_stages_rename_object(char *old_name, char *new_name) {
s->objects->buffer[j] = string_copy(new_name);
}
}
if (s->hidden == NULL) {
continue;
}
for (i32 j = 0; j < s->hidden->length; ++j) {
if (string_equals(s->hidden->buffer[j], old_name)) {
s->hidden->buffer[j] = string_copy(new_name);
}
}
}
}
@@ -89,6 +123,12 @@ void tab_stages_prune() {
}
}
for (i32 j = s->hidden != NULL ? s->hidden->length - 1 : -1; j >= 0; --j) {
if (string_array_index_of(s->objects, s->hidden->buffer[j]) < 0) {
array_splice(s->hidden, j, 1);
}
}
for (i32 j = s->layers->length - 1; j >= 0; --j) {
bool found = false;
for (i32 k = 0; k < g_project->_->layers->length; ++k) {