From cc5f83e191813a61ee97f34f55cc212399e97450 Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Thu, 5 May 2022 07:38:02 -0700 Subject: [PATCH] Add 'Arbitrary Move' command and dialog to the Modify menu. --- src/mainframe.cpp | 2 + src/select.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++++ src/select.h | 1 + 3 files changed, 142 insertions(+) diff --git a/src/mainframe.cpp b/src/mainframe.cpp index 915b1ba..ef4f2c4 100644 --- a/src/mainframe.cpp +++ b/src/mainframe.cpp @@ -2160,6 +2160,7 @@ ui::MenuItem create_selection_menu() create_menu_item_with_mnemonic(menu_in_menu, "Flip _Z", "MirrorSelectionZ"); } menu_separator(menu); + create_menu_item_with_mnemonic(menu, "Arbitrary move...", "ArbitraryMove"); create_menu_item_with_mnemonic(menu, "Arbitrary rotation...", "ArbitraryRotation"); create_menu_item_with_mnemonic(menu, "Arbitrary scale...", "ArbitraryScale"); create_menu_item_with_mnemonic(menu, "Find brush...", "FindBrush"); @@ -3207,6 +3208,7 @@ void MainFrame_Construct() GlobalCommands_insert("MirrorSelectionZ", makeCallbackF(Selection_Flipz)); GlobalCommands_insert("RotateSelectionZ", makeCallbackF(Selection_Rotatez)); + GlobalCommands_insert("ArbitraryMove", makeCallbackF(DoMoveDlg)); GlobalCommands_insert("ArbitraryRotation", makeCallbackF(DoRotateDlg)); GlobalCommands_insert("ArbitraryScale", makeCallbackF(DoScaleDlg)); diff --git a/src/select.cpp b/src/select.cpp index d2d3bb5..ddeb791 100644 --- a/src/select.cpp +++ b/src/select.cpp @@ -1280,3 +1280,142 @@ void DoScaleDlg() g_scale_dialog.window.show(); } + +/* NEW: Artbirary Move */ + +struct MoveDialog { + ui::Entry x{ui::null}; + ui::Entry y{ui::null}; + ui::Entry z{ui::null}; + ui::Window window{ui::null}; +}; + +static gboolean movedlg_apply(ui::Widget widget, MoveDialog *moveDialog) +{ + float sx, sy, sz; + + sx = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->x)))); + sy = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->y)))); + sz = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->z)))); + + StringOutputStream command; + command << "nudgeSelected -axis x " << sx; + command << "nudgeSelected -axis y " << sy; + command << "nudgeSelected -axis z " << sz; + UndoableCommand undo(command.c_str()); + + Nudge(0, sx); + Nudge(1, sy); + Nudge(2, sz); + return TRUE; +} + +static gboolean movedlg_cancel(ui::Widget widget, MoveDialog *moveDialog) +{ + moveDialog->window.hide(); + + moveDialog->x.text("0.0"); + moveDialog->y.text("0.0"); + moveDialog->z.text("0.0"); + + return TRUE; +} + +static gboolean movedlg_ok(ui::Widget widget, MoveDialog *moveDialog) +{ + movedlg_apply(widget, moveDialog); + moveDialog->window.hide(); + return TRUE; +} + +static gboolean movedlg_delete(ui::Widget widget, GdkEventAny *event, MoveDialog *moveDialog) +{ + movedlg_cancel(widget, moveDialog); + return TRUE; +} + +MoveDialog g_move_dialog; + +void DoMoveDlg() +{ + if (!g_move_dialog.window) { + g_move_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary scale", + G_CALLBACK(movedlg_delete), + &g_move_dialog); + + auto accel = ui::AccelGroup(ui::New); + g_move_dialog.window.add_accel_group(accel); + + { + auto hbox = create_dialog_hbox(4, 4); + g_move_dialog.window.add(hbox); + { + auto table = create_dialog_table(3, 2, 4, 4); + hbox.pack_start(table, TRUE, TRUE, 0); + { + ui::Widget label = ui::Label(" X "); + label.show(); + table.attach(label, {0, 1, 0, 1}, {0, 0}); + } + { + ui::Widget label = ui::Label(" Y "); + label.show(); + table.attach(label, {0, 1, 1, 2}, {0, 0}); + } + { + ui::Widget label = ui::Label(" Z "); + label.show(); + table.attach(label, {0, 1, 2, 3}, {0, 0}); + } + { + auto entry = ui::Entry(ui::New); + entry.text("0.0"); + entry.show(); + table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); + + g_move_dialog.x = entry; + } + { + auto entry = ui::Entry(ui::New); + entry.text("0.0"); + entry.show(); + table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); + + g_move_dialog.y = entry; + } + { + auto entry = ui::Entry(ui::New); + entry.text("0.0"); + entry.show(); + table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); + + g_move_dialog.z = entry; + } + } + { + auto vbox = create_dialog_vbox(4); + hbox.pack_start(vbox, TRUE, TRUE, 0); + { + auto button = create_dialog_button("OK", G_CALLBACK(movedlg_ok), &g_move_dialog); + vbox.pack_start(button, FALSE, FALSE, 0); + widget_make_default(button); + gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, + (GtkAccelFlags) 0); + } + { + auto button = create_dialog_button("Cancel", G_CALLBACK(movedlg_cancel), &g_move_dialog); + vbox.pack_start(button, FALSE, FALSE, 0); + gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, + (GtkAccelFlags) 0); + } + { + auto button = create_dialog_button("Apply", G_CALLBACK(movedlg_apply), &g_move_dialog); + vbox.pack_start(button, FALSE, FALSE, 0); + } + } + } + } + + g_move_dialog.window.show(); +} + diff --git a/src/select.h b/src/select.h index 643c240..6a4e3f2 100644 --- a/src/select.h +++ b/src/select.h @@ -63,6 +63,7 @@ void DoRotateDlg(); void DoScaleDlg(); +void DoMoveDlg(); void Select_SetShader(const char *shader);