np
This commit is contained in:
1 parent
1e85df5193
commit
33c70e776a
4 files changed
+265
-203
No files matched your search
@@ -130,6 +130,55 @@ action_layout_auto :: proc(controller: ^ui.App_Controller) -> string {
|
||||
return "Auto layout generated"
|
||||
}
|
||||
|
||||
action_regenerate_page_layout :: proc(controller: ^ui.App_Controller, page_num: int) -> string {
|
||||
if page_num < 0 || page_num >= len(controller.state.page_layouts) {
|
||||
return "Invalid layout page"
|
||||
}
|
||||
|
||||
layout := &controller.state.page_layouts[page_num]
|
||||
panel_count := len(layout.panels)
|
||||
if panel_count == 0 {
|
||||
return "Page has no panels"
|
||||
}
|
||||
|
||||
// For a simple visible regenerate effect, pick a random pattern that fits
|
||||
pattern_ids := []string{
|
||||
"single-splash", "grid-2x2", "grid-3x3", "dynamic-action",
|
||||
"manga-spread", "dialogue-heavy", "cinematic-widescreen",
|
||||
}
|
||||
|
||||
// Just pick the next valid pattern in the list (or wrap around)
|
||||
start_idx := 0
|
||||
for id, i in pattern_ids {
|
||||
if id == layout.pattern_id {
|
||||
start_idx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
new_pattern_id := layout.pattern_id
|
||||
for i in 1..=len(pattern_ids) {
|
||||
idx := (start_idx + i) % len(pattern_ids)
|
||||
candidate := pattern_ids[idx]
|
||||
if core.pattern_max_panels(candidate) >= panel_count {
|
||||
new_pattern_id = candidate
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
pattern := core.get_layout_pattern_by_id(new_pattern_id)
|
||||
layout.pattern_id = new_pattern_id
|
||||
for i in 0..<panel_count {
|
||||
cell_index := i
|
||||
if cell_index >= len(pattern.cells) {
|
||||
cell_index = len(pattern.cells) - 1
|
||||
}
|
||||
layout.panels[i].layout_cell = pattern.cells[cell_index]
|
||||
}
|
||||
|
||||
return "Layout page regenerated"
|
||||
}
|
||||
|
||||
export_format_name :: proc(f: core.Export_Format) -> string {
|
||||
switch f {
|
||||
case .PDF: return "PDF"
|
||||
|
||||
@@ -331,6 +331,26 @@ run_gui_app :: proc(state: ^core.Comic_State) -> shared.App_Error {
|
||||
push_status(&status_msg, &action_log, fmt.tprintf("Viewing panel %d/%d", summary_opts.panel_cursor+1, panel_count))
|
||||
}
|
||||
}
|
||||
if controller.active_screen == .Layout && button_clicked(summary_prev_btn) {
|
||||
layout_page_count := len(controller.state.page_layouts)
|
||||
if layout_page_count > 0 {
|
||||
summary_opts.layout_page_cursor -= 1
|
||||
if summary_opts.layout_page_cursor < 0 {
|
||||
summary_opts.layout_page_cursor = layout_page_count - 1
|
||||
}
|
||||
push_status(&status_msg, &action_log, fmt.tprintf("Viewing layout page %d/%d", summary_opts.layout_page_cursor+1, layout_page_count))
|
||||
}
|
||||
}
|
||||
if controller.active_screen == .Layout && button_clicked(summary_next_btn) {
|
||||
layout_page_count := len(controller.state.page_layouts)
|
||||
if layout_page_count > 0 {
|
||||
summary_opts.layout_page_cursor += 1
|
||||
if summary_opts.layout_page_cursor >= layout_page_count {
|
||||
summary_opts.layout_page_cursor = 0
|
||||
}
|
||||
push_status(&status_msg, &action_log, fmt.tprintf("Viewing layout page %d/%d", summary_opts.layout_page_cursor+1, layout_page_count))
|
||||
}
|
||||
}
|
||||
|
||||
if button_clicked(new_btn) {
|
||||
if is_dirty && !shift_down {
|
||||
@@ -519,6 +539,26 @@ run_gui_app :: proc(state: ^core.Comic_State) -> shared.App_Error {
|
||||
push_status(&status_msg, &action_log, fmt.tprintf("Viewing panel %d/%d", summary_opts.panel_cursor+1, panel_count))
|
||||
}
|
||||
}
|
||||
if controller.active_screen == .Layout && ctrl_down && rl.IsKeyPressed(.LEFT_BRACKET) {
|
||||
layout_page_count := len(controller.state.page_layouts)
|
||||
if layout_page_count > 0 {
|
||||
summary_opts.layout_page_cursor -= 1
|
||||
if summary_opts.layout_page_cursor < 0 {
|
||||
summary_opts.layout_page_cursor = layout_page_count - 1
|
||||
}
|
||||
push_status(&status_msg, &action_log, fmt.tprintf("Viewing layout page %d/%d", summary_opts.layout_page_cursor+1, layout_page_count))
|
||||
}
|
||||
}
|
||||
if controller.active_screen == .Layout && ctrl_down && rl.IsKeyPressed(.RIGHT_BRACKET) {
|
||||
layout_page_count := len(controller.state.page_layouts)
|
||||
if layout_page_count > 0 {
|
||||
summary_opts.layout_page_cursor += 1
|
||||
if summary_opts.layout_page_cursor >= layout_page_count {
|
||||
summary_opts.layout_page_cursor = 0
|
||||
}
|
||||
push_status(&status_msg, &action_log, fmt.tprintf("Viewing layout page %d/%d", summary_opts.layout_page_cursor+1, layout_page_count))
|
||||
}
|
||||
}
|
||||
if ctrl_down && rl.IsKeyPressed(.MINUS) {
|
||||
push_dirty_status(&is_dirty, &status_msg, &action_log, set_autosave_interval_text(&autosave_interval_text, autosave_secs-5))
|
||||
}
|
||||
@@ -889,12 +929,12 @@ run_gui_app :: proc(state: ^core.Comic_State) -> shared.App_Error {
|
||||
} else if controller.active_screen == .Panels {
|
||||
draw_small_button(summary_prev_btn, "< Pn")
|
||||
draw_small_button(summary_next_btn, "Pn >")
|
||||
} else if controller.active_screen == .Layout {
|
||||
draw_small_button(summary_prev_btn, "< Ly")
|
||||
draw_small_button(summary_next_btn, "Ly >")
|
||||
}
|
||||
if !compact_mode {
|
||||
hint_label := "Ctrl+[ / Ctrl+]"
|
||||
if controller.active_screen == .Script || controller.active_screen == .Layout {
|
||||
hint_label = "Ctrl+H / Ctrl+J"
|
||||
}
|
||||
draw_hint_pill(rl.Rectangle{x = f32(282 + status_w_loop - 186), y = f32(lower_y_loop + 46), width = 172, height = 20}, hint_label, false)
|
||||
}
|
||||
}
|
||||
@@ -935,6 +975,31 @@ run_gui_app :: proc(state: ^core.Comic_State) -> shared.App_Error {
|
||||
}
|
||||
|
||||
draw_text_fitted("Ctrl+[ / Ctrl+] panel nav", log_x_loop+18, lower_y_loop+8, 13, int(main_w_loop-status_w_loop-34), 7, TEXT_TERTIARY)
|
||||
} else if controller.active_screen == .Layout {
|
||||
regen, new_layout_cursor := draw_layout_detail_panel(controller, log_x_loop, lower_y_loop, main_w_loop-status_w_loop-2, 200, summary_opts.layout_page_cursor)
|
||||
layout_page_count := len(controller.state.page_layouts)
|
||||
if summary_opts.layout_page_cursor != new_layout_cursor {
|
||||
summary_opts.layout_page_cursor = new_layout_cursor
|
||||
push_status(&status_msg, &action_log, fmt.tprintf("Viewing layout page %d/%d", summary_opts.layout_page_cursor+1, layout_page_count))
|
||||
}
|
||||
if regen {
|
||||
msg := action_regenerate_page_layout(&controller, summary_opts.layout_page_cursor)
|
||||
push_status(&status_msg, &action_log, msg)
|
||||
}
|
||||
|
||||
wheel := rl.GetMouseWheelMove()
|
||||
if wheel != 0 && layout_page_count > 0 {
|
||||
summary_opts.layout_page_cursor -= int(wheel)
|
||||
if summary_opts.layout_page_cursor < 0 {
|
||||
summary_opts.layout_page_cursor = 0
|
||||
}
|
||||
if summary_opts.layout_page_cursor >= layout_page_count {
|
||||
summary_opts.layout_page_cursor = layout_page_count - 1
|
||||
}
|
||||
push_status(&status_msg, &action_log, fmt.tprintf("Viewing layout page %d/%d", summary_opts.layout_page_cursor+1, layout_page_count))
|
||||
}
|
||||
|
||||
draw_text_fitted("Ctrl+H / Ctrl+J layout nav", log_x_loop+18, lower_y_loop+8, 13, int(main_w_loop-status_w_loop-34), 7, TEXT_TERTIARY)
|
||||
} else {
|
||||
draw_card(rl.Rectangle{x = f32(log_x_loop), y = f32(lower_y_loop), width = f32(main_w_loop-status_w_loop-2), height = 200})
|
||||
draw_section_title(log_x_loop+18, lower_y_loop+6, "Action Log")
|
||||
|
||||
@@ -441,3 +441,137 @@ draw_panels_detail_panel :: proc(controller: ui.App_Controller, x, y, w, h: i32,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
clamp_layout_cursor :: proc(layout_count, cursor: int) -> int {
|
||||
if layout_count <= 0 {
|
||||
return 0
|
||||
}
|
||||
if cursor < 0 {
|
||||
return 0
|
||||
}
|
||||
if cursor >= layout_count {
|
||||
return layout_count - 1
|
||||
}
|
||||
return cursor
|
||||
}
|
||||
|
||||
draw_layout_detail_panel :: proc(controller: ui.App_Controller, x, y, w, h: i32, cursor: int) -> (regen_clicked: bool, new_cursor: int) {
|
||||
new_cursor = cursor
|
||||
regen_clicked = false
|
||||
|
||||
draw_card(rl.Rectangle{x = f32(x), y = f32(y), width = f32(w), height = f32(h)})
|
||||
draw_section_title(x+18, y+6, "Layout Detail")
|
||||
draw_subtle_strip(rl.Rectangle{x = f32(x+12), y = f32(y), width = f32(w-24), height = 34})
|
||||
layout_count := len(controller.state.page_layouts)
|
||||
if layout_count == 0 {
|
||||
draw_summary_line(x+18, y+46, "No layouts yet. Use Layout Auto after panels.", SUMMARY_HINT)
|
||||
return
|
||||
}
|
||||
idx := clamp_layout_cursor(layout_count, cursor)
|
||||
layout := controller.state.page_layouts[idx]
|
||||
|
||||
// Header line with status
|
||||
draw_summary_line(x+18, y+46, fmt.tprintf("Page %d/%d • pattern: %s • %d panels", idx+1, layout_count, layout.pattern_id, len(layout.panels)), SUMMARY_ACCENT)
|
||||
|
||||
// Regenerate button
|
||||
btn_rec := rl.Rectangle{x = f32(x + w - 100), y = f32(y+42), width = 80, height = 24}
|
||||
draw_small_button_state(btn_rec, "Regen", true)
|
||||
if button_clicked(btn_rec) {
|
||||
regen_clicked = true
|
||||
}
|
||||
|
||||
// Layout dimensions
|
||||
draw_summary_subline(x+18, y+68, fmt.tprintf("size: %d x %d", layout.width, layout.height), SUMMARY_SUBLINE)
|
||||
|
||||
// ── Mini wireframe preview ─────────────────────────────────
|
||||
preview_x := x + 18
|
||||
preview_y := y + 88
|
||||
preview_max_w: f32 = f32(w) * 0.4
|
||||
preview_max_h: f32 = f32(h - 100)
|
||||
if preview_max_h < 40 {
|
||||
preview_max_h = 40
|
||||
}
|
||||
|
||||
// Scale to fit
|
||||
lw := f32(layout.width)
|
||||
lh := f32(layout.height)
|
||||
if lw < 1 { lw = 1 }
|
||||
if lh < 1 { lh = 1 }
|
||||
scale_x := preview_max_w / lw
|
||||
scale_y := preview_max_h / lh
|
||||
scale := scale_x
|
||||
if scale_y < scale {
|
||||
scale = scale_y
|
||||
}
|
||||
pw := lw * scale
|
||||
ph := lh * scale
|
||||
|
||||
// Draw page outline
|
||||
page_rec := rl.Rectangle{x = f32(preview_x), y = f32(preview_y), width = pw, height = ph}
|
||||
rl.DrawRectangleRounded(page_rec, 0.02, 4, BG_STRIP)
|
||||
rl.DrawRectangleRoundedLinesEx(page_rec, 0.02, 4, 1.0, BORDER_CARD)
|
||||
|
||||
// Draw each panel cell
|
||||
for i in 0..<len(layout.panels) {
|
||||
cell := layout.panels[i].layout_cell
|
||||
cx := f32(preview_x) + cell.x * pw
|
||||
cy := f32(preview_y) + cell.y * ph
|
||||
cw := cell.w * pw
|
||||
ch := cell.h * ph
|
||||
// Inset slightly for gutter
|
||||
inset: f32 = 1.5
|
||||
cell_rec := rl.Rectangle{x = cx + inset, y = cy + inset, width = cw - inset*2, height = ch - inset*2}
|
||||
rl.DrawRectangleRounded(cell_rec, 0.06, 4, ACCENT_SURFACE)
|
||||
rl.DrawRectangleRoundedLinesEx(cell_rec, 0.06, 4, 1.0, ACCENT_MUTED)
|
||||
// Panel number label
|
||||
num_label := fmt.tprintf("%d", layout.panels[i].panel_number)
|
||||
label_sz: i32 = 10
|
||||
if cw > 30 && ch > 14 {
|
||||
draw_text_fitted(num_label, i32(cx + inset + 3), i32(cy + inset + 2), label_sz, int(cw - inset*2 - 4), 5, TEXT_SECONDARY)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Page list (right side) ─────────────────────────────────
|
||||
list_x := x + i32(preview_max_w) + 36
|
||||
list_y := y + 88
|
||||
list_w := w - i32(preview_max_w) - 54
|
||||
row_h: i32 = 18
|
||||
rows: i32 = (h - 100) / row_h
|
||||
if rows < 1 {
|
||||
rows = 1
|
||||
}
|
||||
start := idx - int(rows/2)
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
end := start + int(rows)
|
||||
if end > layout_count {
|
||||
end = layout_count
|
||||
start = end - int(rows)
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
}
|
||||
line: i32 = 0
|
||||
for i in start..<end {
|
||||
l := controller.state.page_layouts[i]
|
||||
mark := " "
|
||||
row_color := TEXT_TERTIARY
|
||||
if i == idx {
|
||||
mark = ">"
|
||||
row_color = TEXT_PRIMARY
|
||||
}
|
||||
|
||||
row_rec := rl.Rectangle{x = f32(list_x), y = f32(list_y + line*row_h), width = f32(list_w), height = f32(row_h)}
|
||||
if rl.CheckCollisionPointRec(rl.GetMousePosition(), row_rec) && rl.IsMouseButtonPressed(.LEFT) {
|
||||
new_cursor = i
|
||||
}
|
||||
if rl.CheckCollisionPointRec(rl.GetMousePosition(), row_rec) && row_color == TEXT_TERTIARY {
|
||||
row_color = TEXT_SECONDARY
|
||||
}
|
||||
|
||||
draw_summary_subline(list_x, list_y+line*row_h+2, fit_text_for_width(fmt.tprintf("%s %02d %s (%d)", mark, l.page_number, l.pattern_id, len(l.panels)), int(list_w), 7), row_color)
|
||||
line += 1
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in new issue
Block a user