Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New features: undo and redo historial #255

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added oregano-graphical-testing.ogv
Binary file not shown.
1 change: 1 addition & 0 deletions src/clipboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <glib.h>

#include "oregano.h"
#include "sheet.h"
#include "sheet-item.h"
#include "clipboard.h"

Expand Down
26 changes: 26 additions & 0 deletions src/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
*
* Authors:
* Bernhard Schuster <[email protected]>
* Daniel Dwek <[email protected]>
*
* Web page: https://ahoi.io/project/oregano
*
* Copyright (C) 2012-2013 Bernhard Schuster
* Copyright (C) 2022-2023 Daniel Dwek
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand Down Expand Up @@ -43,3 +45,27 @@
##__VA_ARGS__); \
} \
}

#define color_black "\033[00;30m"
#define color_red "\033[00;31m"
#define color_green "\033[00;32m"
#define color_orange "\033[00;33m"
#define color_blue "\033[00;34m"
#define color_magenta "\033[00;35m"
#define color_cyan "\033[00;36m"
#define color_lightgray "\033[00;37m"
#define color_darkgray "\033[01;30m"
#define color_lightred "\033[01;31m"
#define color_lightgreen "\033[01;32m"
#define color_yellow "\033[01;33m"
#define color_lightblue "\033[01;34m"
#define color_lightmagenta "\033[01;35m"
#define color_lightcyan "\033[01;36m"
#define color_white "\033[01;37m"

#define color_restore "\033[00m"

#define COLOR_SHEETITEM color_blue
#define COLOR_COORDS color_green
#define COLOR_CENTER color_red
#define COLOR_NORMAL color_restore
2 changes: 1 addition & 1 deletion src/engines/gnucap.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ static gboolean gnucap_generate_netlist (OreganoEngine *engine, const gchar *fil
for (iter = output.models; iter; iter = iter->next) {
gchar *model;
model = (gchar *)iter->data;
g_fprintf (file, ".include %s/%s.model\n", OREGANO_MODELDIR, model);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the OREGANO_MODEL dir guaranteed to have a trailiing backslash?

g_fprintf (file, ".include %s%s.model\n", OREGANO_MODELDIR, model);
}

// Prints template parts
Expand Down
2 changes: 0 additions & 2 deletions src/load-library.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ typedef enum { SYMBOL_OBJECT_LINE, SYMBOL_OBJECT_ARC, SYMBOL_OBJECT_TEXT } Symbo
struct _SymbolObject
{
SymbolObjectType type;

union
{
struct
Expand All @@ -79,5 +78,4 @@ struct _SymbolObject
Library *library_parse_xml_file (const gchar *filename);
LibrarySymbol *library_get_symbol (const gchar *symbol_name);
LibraryPart *library_get_part (Library *library, const gchar *part_name);

#endif
15 changes: 6 additions & 9 deletions src/load-schematic.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Marc Lorber <[email protected]>
* Bernhard Schuster <[email protected]>
* Guido Trentalancia <[email protected]>
* Daniel Dwek <[email protected]>
*
* Web page: https://ahoi.io/project/oregano
*
Expand All @@ -17,6 +18,7 @@
* Copyright (C) 2009-2012 Marc Lorber
* Copyright (C) 2013-2014 Bernhard Schuster
* Copyright (C) 2017 Guido Trentalancia
* Copyright (C) 2022-2023 Daniel Dwek
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand Down Expand Up @@ -50,6 +52,7 @@
#include "errors.h"
#include "engines/netlist-helper.h"

#include "part-private.h"
#include "debug.h"

typedef enum {
Expand Down Expand Up @@ -219,7 +222,7 @@ static void create_textbox (ParseState *state)

textbox = textbox_new (NULL);
textbox_set_text (textbox, state->textbox_text);
item_data_set_pos (ITEM_DATA (textbox), &state->pos);
item_data_set_pos (ITEM_DATA (textbox), &state->pos, EMIT_SIGNAL_CHANGED);
schematic_add_item (state->schematic, ITEM_DATA (textbox));
}

Expand All @@ -236,7 +239,7 @@ static void create_wire (ParseState *state)
wire = wire_new ();
wire_set_length (wire, &length);

item_data_set_pos (ITEM_DATA (wire), &state->wire_start);
item_data_set_pos (ITEM_DATA (wire), &state->wire_start, EMIT_SIGNAL_CHANGED);
schematic_add_item (state->schematic, ITEM_DATA (wire));
}

Expand All @@ -251,13 +254,7 @@ static void create_part (ParseState *state)
return;
}

item_data_set_pos (ITEM_DATA (part), &state->pos);
item_data_rotate (ITEM_DATA (part), state->rotation, NULL);
if (state->flip & ID_FLIP_HORIZ)
item_data_flip (ITEM_DATA (part), ID_FLIP_HORIZ, NULL);
if (state->flip & ID_FLIP_VERT)
item_data_flip (ITEM_DATA (part), ID_FLIP_VERT, NULL);

item_data_set_pos (ITEM_DATA (part), &state->pos, EMIT_SIGNAL_MOVED | EMIT_SIGNAL_CHANGED);
schematic_add_item (state->schematic, ITEM_DATA (part));
}

Expand Down
12 changes: 12 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
* Ricardo Markiewicz <[email protected]>
* Andres de Barbara <[email protected]>
* Marc Lorber <[email protected]>
* Daniel Dwek <[email protected]>
*
* Web page: https://ahoi.io/project/oregano
*
* Copyright (C) 1999-2001 Richard Hult
* Copyright (C) 2003,2006 Ricardo Markiewicz
* Copyright (C) 2009-2012 Marc Lorber
* Copyright (C) 2022-2023 Daniel Dwek
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand Down Expand Up @@ -40,6 +42,8 @@
#include "options.h"
#include "schematic.h"

#include "stack.h"

int main (int argc, char *argv[])
{
// keep in mind the app is a subclass of GtkApplication
Expand Down Expand Up @@ -75,6 +79,14 @@ int main (int argc, char *argv[])
// required?
gtk_init (&argc, &argv);

undo_stack = (historial_stack_t *) calloc (1, sizeof (historial_stack_t));
if (!undo_stack)
return 1;

redo_stack = (historial_stack_t *) calloc (1, sizeof (historial_stack_t));
if (!redo_stack)
return 1;

// required, as we possibly need signal
// information within oregano.c _before_ the
// first Schematic instance exists
Expand Down
85 changes: 61 additions & 24 deletions src/model/item-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
* Andres de Barbara <[email protected]>
* Marc Lorber <[email protected]>
* Bernhard Schuster <[email protected]>
* Daniel Dwek <[email protected]>
*
* Web page: https://ahoi.io/project/oregano
*
* Copyright (C) 1999-2001 Richard Hult
* Copyright (C) 2003,2006 Ricardo Markiewicz
* Copyright (C) 2009-2012 Marc Lorber
* Copyright (C) 2013 Bernhard Schuster
* Copyright (C) 2022-2023 Daniel Dwek
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand All @@ -39,7 +41,9 @@
#include "item-data.h"
#include "node-store.h"

#include "sheet.h"
#include "debug.h"
#include "stack.h"

static void item_data_class_init (ItemDataClass *klass);
static void item_data_init (ItemData *item_data);
Expand All @@ -52,10 +56,12 @@ static void item_data_copy (ItemData *dest, ItemData *src);
enum { ARG_0, ARG_STORE, ARG_POS };

enum {
CREATED,
MOVED,
ROTATED,
FLIPPED,
CHANGED, // used to notify the view to reset and recalc the transformation
DELETED,
HIGHLIGHT,
LAST_SIGNAL
};
Expand Down Expand Up @@ -132,18 +138,28 @@ static void item_data_class_init (ItemDataClass *klass)

object_class->dispose = item_data_dispose;
object_class->finalize = item_data_finalize;
item_data_signals[CREATED] =
g_signal_new ("created", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ItemDataClass, created), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);

item_data_signals[MOVED] =
g_signal_new ("moved", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ItemDataClass, moved), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);

item_data_signals[DELETED] =
g_signal_new ("deleted", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ItemDataClass, deleted), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);

item_data_signals[ROTATED] =
g_signal_new ("rotated", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, 0, NULL,
NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);

item_data_signals[FLIPPED] =
g_signal_new ("flipped", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, 0, NULL,
NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);

item_data_signals[CHANGED] =
g_signal_new ("changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, 0, NULL,
Expand All @@ -163,7 +179,9 @@ static void item_data_class_init (ItemDataClass *klass)
klass->changed = NULL;

// Signals.
klass->created = NULL;
klass->moved = NULL;
klass->deleted = NULL;
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -221,29 +239,34 @@ void item_data_get_pos (ItemData *item_data, Coords *pos)
pos->y = priv->translate.y0;
}

void item_data_set_pos (ItemData *item_data, Coords *pos)
void item_data_set_pos (ItemData *item_data, Coords *pos, guint signals)
{
ItemDataPriv *priv;
gboolean handler_connected;

g_return_if_fail (pos);
g_return_if_fail (item_data);
g_return_if_fail (item_data != NULL);
g_return_if_fail (IS_ITEM_DATA (item_data));
g_return_if_fail (pos != NULL);

priv = item_data->priv;

cairo_matrix_init_translate (&(priv->translate), pos->x, pos->y);

handler_connected =
g_signal_handler_is_connected (G_OBJECT (item_data), item_data->moved_handler_id);
if (handler_connected) {
g_signal_emit_by_name (G_OBJECT (item_data), "moved", pos);
}
handler_connected =
g_signal_handler_is_connected (G_OBJECT (item_data), item_data->changed_handler_id);
if (handler_connected) {
g_signal_emit_by_name (G_OBJECT (item_data), "changed");
}
if (signals & EMIT_SIGNAL_CREATED)
if (g_signal_handler_is_connected (G_OBJECT (item_data), item_data->created_handler_id))
g_signal_emit_by_name (G_OBJECT (item_data), "created", pos);
if (signals & EMIT_SIGNAL_MOVED)
if (g_signal_handler_is_connected (G_OBJECT (item_data), item_data->moved_handler_id))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to check if the signal handler is connected?

g_signal_emit_by_name (G_OBJECT (item_data), "moved", pos);
if (signals & EMIT_SIGNAL_ROTATED)
if (g_signal_handler_is_connected (G_OBJECT (item_data), item_data->rotated_handler_id))
g_signal_emit_by_name (G_OBJECT (item_data), "rotated", NULL);
if (signals & EMIT_SIGNAL_DELETED)
if (g_signal_handler_is_connected (G_OBJECT (item_data), item_data->deleted_handler_id))
g_signal_emit_by_name (G_OBJECT (item_data), "deleted", pos);
if (signals & EMIT_SIGNAL_CHANGED)
if (g_signal_handler_is_connected (G_OBJECT (item_data), item_data->changed_handler_id))
g_signal_emit_by_name (G_OBJECT (item_data), "changed");
if (signals & EMIT_SIGNAL_NONE)
return;
}

void item_data_move (ItemData *item_data, const Coords *delta)
Expand Down Expand Up @@ -381,30 +404,44 @@ void item_data_list_get_absolute_bbox (GList *item_data_list, Coords *p1, Coords
}
}

void item_data_rotate (ItemData *data, int angle, Coords *center)
void item_data_create (ItemData *data)
{
ItemDataClass *id_class;

g_return_if_fail (data != NULL);
g_return_if_fail (IS_ITEM_DATA (data));

id_class = ITEM_DATA_CLASS (G_OBJECT_GET_CLASS (data));
if (id_class->rotate) {
id_class->rotate (data, angle, center);
}
if (id_class->create)
id_class->create (data);
}

void item_data_flip (ItemData *data, IDFlip direction, Coords *center)
void item_data_rotate (ItemData *data, int angle, Coords *center, Coords *b1, Coords *b2, const char *caller_fn)
{
ItemDataClass *id_class;

g_return_if_fail (data != NULL);
g_return_if_fail (IS_ITEM_DATA (data));
g_return_if_fail (center != NULL);
g_return_if_fail (b1 != NULL);
g_return_if_fail (b2 != NULL);
g_return_if_fail (caller_fn != NULL);

id_class = ITEM_DATA_CLASS (G_OBJECT_GET_CLASS (data));
if (id_class->flip) {
if (id_class->rotate)
id_class->rotate (data, angle, center, b1, b2, caller_fn);
}

void item_data_flip (ItemData *data, SheetItem *item, Coords *center, IDFlip direction)
{
ItemDataClass *id_class;

g_return_if_fail (data != NULL);
g_return_if_fail (IS_ITEM_DATA (data));

id_class = ITEM_DATA_CLASS (G_OBJECT_GET_CLASS (data));
if (id_class->flip)
id_class->flip (data, direction, center);
}
}

void item_data_unregister (ItemData *data)
Expand Down
Loading