コード例 #1
0
        // FIXME: Keyboard and general mouse movement events!!
        public override bool KeyPressed(CircuitEditor editor, Gdk.EventKey eventKey)
        {
            bool consumed = false;

            var modifiers = eventKey.State & Accelerator.DefaultModMask;

            if (modifiers == Gdk.ModifierType.None)
            {
                // No modifiers are pressed
                if (eventKey.Key == Gdk.Key.Up)
                {
                    CompOrientation = Circuit.Orientation.North;
                    consumed        = true;
                }
                if (eventKey.Key == Gdk.Key.Down)
                {
                    CompOrientation = Circuit.Orientation.South;
                    consumed        = true;
                }
                if (eventKey.Key == Gdk.Key.Left)
                {
                    CompOrientation = Circuit.Orientation.West;
                    consumed        = true;
                }
                if (eventKey.Key == Gdk.Key.Right)
                {
                    CompOrientation = Circuit.Orientation.East;
                    consumed        = true;
                }
            }

            if (consumed)
            {
                editor.DrawingArea.QueueDraw();
            }
            return(consumed);
        }
コード例 #2
0
        static Gtk.Toolbar CreateToolbar(CircuitEditor editor)
        {
            Gtk.Toolbar toolbar = new Gtk.Toolbar();

            SelectTool selectTool = new SelectTool(editor, toolbar);
            WireTool   wireTool   = new WireTool(editor, toolbar);
            // FIXME: Make this be selected with a callback or something
            //editor.CurrentTool = selectTool;

            ComponentTool constantTool = new ComponentTool(ComponentType.Constant, "Constant", editor, toolbar);

            ComponentTool bufferTool = new ComponentTool(ComponentType.Buffer, "Buffer gate", editor, toolbar);
            ComponentTool notTool    = new ComponentTool(ComponentType.Not, "Not gate", editor, toolbar);

            ComponentTool andTool = new ComponentTool(ComponentType.And, "And gate", editor, toolbar);

            ComponentTool orTool = new ComponentTool(ComponentType.Or, "Or gate", editor, toolbar);

            ComponentTool xorTool = new ComponentTool(ComponentType.Xor, "Xor gate", editor, toolbar);

            SeparatorToolItem sep = new SeparatorToolItem();

            int index = 0;

            toolbar.Insert(selectTool, index++);
            toolbar.Insert(wireTool, index++);
            toolbar.Insert(sep, index++);
            toolbar.Insert(constantTool, index++);
            toolbar.Insert(bufferTool, index++);
            toolbar.Insert(notTool, index++);
            toolbar.Insert(andTool, index++);
            toolbar.Insert(orTool, index++);
            toolbar.Insert(xorTool, index++);

            return(toolbar);
        }
コード例 #3
0
 public SelectTool(
     CircuitEditor circuitEditor,
     Gtk.Toolbar toolbar
     ) : base(Util.Icon.Selector(), "Select", circuitEditor, toolbar)
 {
 }
コード例 #4
0
 public void ClearSelection(CircuitEditor editor)
 {
     SelectedWires.Clear();
     SelectedGates.Clear();
     editor.DrawingArea.QueueDraw();
 }
コード例 #5
0
ファイル: ITool.cs プロジェクト: Rickard-Martensson/logik
 public BasicTool(Image image, string name, CircuitEditor circuitEditor) : base(image, name)
 {
     CircuitEditor = circuitEditor;
     Clicked      += BasicTool_Clicked;
 }
コード例 #6
0
        public override void GestureEnd(CircuitEditor editor, Vector2d endOffset)
        {
            // FIXME: Do l-shaped wire addition
            var diff = editor.RoundDistToGrid(endOffset);

            if (Math.Abs(diff.X) > Math.Abs(diff.Y))
            {
                // FIXME: We shouldn't rely on the constructor to flip negative diffs
                // because we are going to remove that so we should do it ourselves here.

                // Here we are drawing a horizontal line
                CurrentWire = new Wire(DragStartPos, diff.X, Circuit.Direction.Horizontal);
            }
            else
            {
                //This should be a vertical line
                CurrentWire = new Wire(DragStartPos, diff.Y, Circuit.Direction.Vertical);
            }

            DraggingWire = false;

            if (CurrentWire.Length != 0)
            {
                // Here we should figure out if we are modifying an existing wire.
                // Because adding wires handles merging wires that go in the same
                // direction, we only want to detect the case where we are shrinking
                // a wire. This is easy, because we only need to check that we grabbed
                // one end of the wire and the the other end is inside the wire we want
                // to shrink.
                Wire?modifying = null;
                bool movingEnd = false;
                foreach (var bWire in editor.Scene.Wires.WiresList)
                {
                    if (CurrentWire.Direction != bWire.Direction)
                    {
                        continue;
                    }

                    // We do 'IsPointInsideWire' because we don't want to detect the case
                    // where we are dragging a wire left from a junction to create a new wire.
                    // What would happen if we used 'IsPointOnWire' is that the start pos would
                    // be equal and at the same time 'CurrentWire.Pos' would be on the wire,
                    // making us think that we want to edit the wire while we don't want to.
                    if (DragStartPos == bWire.Pos && bWire.IsPointInsideWire(CurrentWire.EndPos))
                    {
                        modifying = bWire;
                        movingEnd = false;
                    }
                    else if (DragStartPos == bWire.EndPos && bWire.IsPointInsideWire(CurrentWire.Pos))
                    {
                        modifying = bWire;
                        movingEnd = true;
                    }
                    else if (CurrentWire == bWire)
                    {
                        // If they are the same wire we want to remove the bWire
                        modifying = bWire;
                    }
                }

                // If there there more than one endpoint at the start position
                // We don't want to modify a wire, we want to create a new one
                // If there was only one point we check that we actually want to
                // modify that wire (ie modifying is not null).
                if (modifying is Wire modify)
                {
                    // Here we are modifying an existing wire.
                    // So we should figure out how the wire should be modified.
                    // If the wire is deleted we need to check for places where we should merge
                    // other connecting wires. The creation of the remove transaction should
                    // probably be created in a Wires.CreateRemoveWireTransaction(...).

                    Wire modifiedWire = modify;
                    if (movingEnd == false)
                    {
                        // Here we are moving the start poistion of the wire.
                        diff                 = CurrentWire.EndPos - modify.Pos;
                        modifiedWire.Pos     = CurrentWire.EndPos;
                        modifiedWire.Length -= diff.ManhattanDistance;
                    }
                    else
                    {
                        // Here we only need to change the length of the wire.
                        diff = modify.EndPos - CurrentWire.Pos;
                        modifiedWire.Length -= diff.ManhattanDistance;
                    }

                    if (modifiedWire.Length > 0)
                    {
                        // FIMXE: Figure out if there are any edge-cases when modifying wires like this.
                        // One of the cases is where the modified wire should split another already
                        // existing wire.

                        WireTransaction?modifyTransaction = editor.Scene.Wires.CreateModifyWireTransaction(modify, modifiedWire);
                        if (modifyTransaction != null)
                        {
                            editor.Scene.PushTransaction(modifyTransaction);
                            //Console.WriteLine($"Modified existing wire! ({modify}) -> ({modifiedWire})\n{modifyTransaction}\n");
                        }
                    }
                    else
                    {
                        // Here we should remove the wire completely
                        var deleteTransaction = editor.Scene.Wires.CreateRemoveWireTransaction(modify);
                        editor.Scene.PushTransaction(deleteTransaction);
                        //Console.WriteLine($"Deleted wire! ({modify})\n{deleteTransaction}\n");
                    }
                }
                else
                {
                    var transaction = editor.Scene.Wires.CreateAddWireTransaction(CurrentWire);
                    if (transaction != null)
                    {
                        editor.Scene.PushTransaction(transaction);
                        //Console.WriteLine($"End wire!\n{transaction}\n");
                    }
                    else
                    {
                        //Console.WriteLine($"No wire created!\n");
                    }
                }
            }
            else
            {
                //Console.WriteLine($"Zero length wire!\n\n");
            }

            editor.DrawingArea.QueueDraw();
        }
コード例 #7
0
 public abstract void GestureStart(CircuitEditor editor, Vector2d dragStartPos);
コード例 #8
0
 public abstract void GestureEnd(CircuitEditor editor, Vector2d endOffset);
コード例 #9
0
ファイル: Program.cs プロジェクト: axel-kaliff/logik
        // VERY IMPORTANT!!!!!!!!!!!!
        // After the call to Application.Init() NullReferenceExceptions
        // will no longer be thrown. This is an active bug in GtkSharp
        // and can be tracked here https://github.com/GtkSharp/GtkSharp/issues/155
        // Hopefully this can be fixed sooner rather than later...
        static void Main()
        {
            Backend = Logic.Init();

            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

            Value a = new Value(0b00_00_00_00_01_01_01_01_10_10_10_10_11_11_11_11, 16);
            Value b = new Value(0b00_01_10_11_00_01_10_11_00_01_10_11_00_01_10_11, 16);

            Console.WriteLine($"Resolve: {Value.Resolve(a, b)}");
            Console.WriteLine($"And: {Value.And(a, b)}");
            Console.WriteLine($"Or: {Value.Or(a, b)}");
            Console.WriteLine($"Not: {Value.Not(a)}");

            Application.Init();

            GLib.ExceptionManager.UnhandledException += ExceptionManager_UnhandledException;

            Window wnd = new Window("Logik");

            wnd.Resize(1600, 800);

            Notebook nbook         = new Notebook();
            var      circuitEditor = new CircuitEditor();

            nbook.AppendPage(circuitEditor.DrawingArea, new Label("Circuit editor"));
            nbook.AppendPage(new Label("TODO: Package editor"), new Label("Package editor"));

            Notebook sideBar    = new Notebook();
            var      components = new ComponentView(new List <ComponentFolder> {
                new ComponentFolder("Test folder 1", new List <Component.Component>()
                {
                    new Component.Component("Test comp 1", "x-office-document"),
                    new Component.Component("Test comp 2", "x-office-document"),
                    new Component.Component("Test comp 3", "x-office-document"),
                }),
                new ComponentFolder("Test folder 2", new List <Component.Component>()
                {
                    new Component.Component("Another test comp 1", "x-office-document"),
                    new Component.Component("Another test comp 2", "x-office-document"),
                    new Component.Component("Another test comp 3", "x-office-document"),
                }),
            });

            sideBar.AppendPage(components.TreeView, new Label("Components"));
            var hierarchy = new HierarchyView(new HierarchyComponent("Top comp", "x-office-document", new List <HierarchyComponent>()
            {
                new HierarchyComponent("Test Comp 1", "x-office-document", new List <HierarchyComponent>()
                {
                    new HierarchyComponent("Test Nested Comp 1", "x-office-document", new List <HierarchyComponent>()),
                }),
                new HierarchyComponent("Test Comp 2", "x-office-document", new List <HierarchyComponent>()
                {
                    new HierarchyComponent("Test Nested Comp 1", "x-office-document", new List <HierarchyComponent>()),
                    new HierarchyComponent("Test Nested Comp 2", "x-office-document", new List <HierarchyComponent>()),
                }),
                new HierarchyComponent("Test Comp 3", "x-office-document", new List <HierarchyComponent>()),
            }));

            sideBar.AppendPage(hierarchy.TreeView, new Label("Hierarchy"));

            HPaned hPaned = new HPaned();

            hPaned.Pack1(sideBar, false, false);
            hPaned.Pack2(nbook, true, false);

            //Add the label to the form
            VBox box = new VBox(false, 0);

            box.PackStart(CreateMenuBar(wnd), false, false, 0);
            box.PackStart(CreateToolbar(circuitEditor), false, false, 0);
            box.PackEnd(hPaned, true, true, 0);
            box.Expand = true;
            wnd.Add(box);

            wnd.Destroyed += Wnd_Destroyed;

            wnd.ShowAll();
            Application.Run();
        }
コード例 #10
0
 public SelectTool(CircuitEditor circuitEditor) : base(Icon.Selector(), "Select", circuitEditor)
 {
 }
コード例 #11
0
 public override void GestureUpdate(CircuitEditor editor, Vector2d offset)
 {
     SelectionSize = editor.RoundDistToGrid(offset);
     editor.DrawingArea.QueueDraw();
 }
コード例 #12
0
        public override void GestureEnd(CircuitEditor editor, Vector2d endOffset)
        {
            SelectionSize = editor.RoundDistToGrid(endOffset);
            Selecting     = false;

            // Make sure we don't have a negitive size

            if (SelectionSize.X < 0)
            {
                SelectionSize.X   = -SelectionSize.X;
                SelectionStart.X -= SelectionSize.X;
            }

            if (SelectionSize.Y < 0)
            {
                SelectionSize.Y   = -SelectionSize.Y;
                SelectionStart.Y -= SelectionSize.Y;
            }

            if (Poking)
            {
                Poking = false;
                LogikUI.Simulation.ReleaseComponent(SelectedGates[0].ID);
            }

            // FIXME: Do the selecting
            var wires = editor.Scene.Wires;

            // If the size is zero we want to check if we clicked a wire or gate
            if (SelectionSize == Vector2i.Zero)
            {
                ClearSelection(editor);

                bool foundGate = false;
                var  pos       = editor.FromGridToWorld(SelectionStart);
                foreach (var instance in editor.Scene.Gates.Instances)
                {
                    Rect r = editor.Scene.Gates.GetBounds(instance);
                    r = r.Rotate(instance.Position * CircuitEditor.DotSpacing, instance.Orientation);

                    if (r.Contains(pos))
                    {
                        SelectedGates.Add(instance);
                        break;
                    }
                }

                if (foundGate == false)
                {
                    foreach (var wire in wires.WiresList)
                    {
                        if (wire.IsPointOnWire(SelectionStart))
                        {
                            SelectedWires.Add(wire);
                            foundGate = true;
                            break;
                        }
                    }
                }
            }
            else
            {
                ClearSelection(editor);

                // Here we should loop through all wires and see if they are contained in the area
                Recti selectionRect = new Recti(SelectionStart, SelectionSize);

                foreach (var wire in wires.WiresList)
                {
                    if (selectionRect.Contains(wire.Pos) &&
                        selectionRect.Contains(wire.EndPos))
                    {
                        SelectedWires.Add(wire);
                        Console.WriteLine($"Selected wire: {wire}");
                    }
                }

                Rect worldRect = editor.FromGridToWorld(selectionRect);
                foreach (var instance in editor.Scene.Gates.Instances)
                {
                    Rect r = editor.Scene.Gates.GetBounds(instance);
                    r = r.Rotate(instance.Position * CircuitEditor.DotSpacing, instance.Orientation);

                    if (worldRect.Contains(r))
                    {
                        SelectedGates.Add(instance);
                    }
                }
            }

            editor.DrawingArea.QueueDraw();
        }
コード例 #13
0
ファイル: WireTool.cs プロジェクト: Rickard-Martensson/logik
 public override void DeSelect(CircuitEditor editor)
 {
 }
コード例 #14
0
ファイル: WireTool.cs プロジェクト: Rickard-Martensson/logik
 public WireTool(CircuitEditor circuitEditor) : base(Icon.Wire(), "Wire", circuitEditor)
 {
 }
コード例 #15
0
 // Use this for initialization
 void Start()
 {
     Application.targetFrameRate = -1;
     QualitySettings.vSyncCount  = 0;
     circuitEditor = new CircuitEditor(notGateTex, bufferGateTex, wireTex, emptyTex, outputPlane);
 }
コード例 #16
0
 public override void GestureUpdate(CircuitEditor editor, Vector2d offset)
 {
     SelectionSize = editor.RoundDistToGrid(offset);
     //Console.WriteLine($"Size: {SelectionSize}");
     editor.DrawingArea.QueueDraw();
 }
コード例 #17
0
 public virtual bool KeyPressed(CircuitEditor editor, EventKey eventKey) => false;
コード例 #18
0
ファイル: LogikUI.cs プロジェクト: NogginBops/logik
        static MenuBar CreateMenuBar(Window parent, CircuitEditor editor)
        {
            MenuItem open = new MenuItem("Open...");

            open.Activated += (object?sender, EventArgs e) =>
            {
                FileChooserDialog fcd = new FileChooserDialog("Open Project", parent, FileChooserAction.Open,
                                                              Stock.Open, ResponseType.Ok,
                                                              Stock.Cancel, ResponseType.Cancel);
                fcd.SelectMultiple = false;
                AddFilters(fcd);

                if (fcd.Run() == (int)ResponseType.Ok)
                {
                    try
                    {
                        FileManager.Load(fcd.Filename);

                        Console.WriteLine($"Successfully read and parsed project file { fcd.Filename }.");
                        Console.WriteLine($"- wires: { FileManager.Wires }");
                        Console.WriteLine($"- components: { FileManager.Components }");
                        Console.WriteLine($"- labels: { FileManager.Labels }");

                        var lables = new TextLabels(FileManager.Labels.ToArray());
                        var gates  = new Gates();
                        gates.Instances = FileManager.Components;
                        var wires = new Wires(gates, FileManager.Wires.ToArray());

                        editor.Scene = new Scene(wires, gates, lables);
                    }
                    catch (Exception err)
                    {
                        // FIXME: Do something if parse fails?

                        Output.WriteError($"Failed to read and parse project file { fcd.Filename }.", err);
                    }
                }

                fcd.Dispose();
            };

            MenuItem saveAs = new MenuItem("Save As...");

            saveAs.Activated += (object?sender, EventArgs e) =>
            {
                FileChooserDialog fcd = new FileChooserDialog("Save Project", parent, FileChooserAction.Save,
                                                              Stock.Save, ResponseType.Ok,
                                                              Stock.Cancel, ResponseType.Cancel);
                AddFilters(fcd);

                if (fcd.Run() == (int)ResponseType.Ok)
                {
                    try
                    {
                        FileManager.Labels     = new List <TextLabel>(editor.Scene.Labels.Labels);
                        FileManager.Wires      = editor.Scene.Wires.WiresList;
                        FileManager.Components = editor.Scene.Gates.Instances;

                        FileManager.Save(fcd.Filename);

                        Console.WriteLine($"Successfully saved and parsed project file { fcd.Filename }.");
                        Console.WriteLine($"- wires: { FileManager.Wires }");
                        Console.WriteLine($"- components: { FileManager.Components }");
                        Console.WriteLine($"- labels: { FileManager.Labels }");
                    }
                    catch (Exception err)
                    {
                        // FIXME: Do something if parse fails?

                        Output.WriteError($"Failed to write and parse project file { fcd.Filename }.", err);
                    }
                }

                fcd.Dispose();
            };

            MenuItem save = new MenuItem("Save...");

            save.Activated += (object?sender, EventArgs e) =>
            {
                if (FileManager.IsNew)
                {
                    saveAs.Activate();
                }
                else
                {
                    FileManager.Save();
                }
            };

            Menu fileMenu = new Menu();

            fileMenu.Append(open);
            fileMenu.Append(save);
            fileMenu.Append(saveAs);

            MenuItem file = new MenuItem("File");

            file.AddEvents((int)Gdk.EventMask.AllEventsMask);
            file.Submenu = fileMenu;

            // FIXME: Hook up callbacks

            // FIXME: On windows (and Mac) there should be no delay
            // on the ability to close the menu when you've opened it.
            // Atm there is a delay after opening the menu and when
            // you can close it...

            MenuBar bar = new MenuBar();

            bar.Append(file);

            return(bar);
        }
コード例 #19
0
ファイル: ITool.cs プロジェクト: Rickard-Martensson/logik
 public abstract void DeSelect(CircuitEditor editor);
コード例 #20
0
 public virtual void DeSelect(CircuitEditor editor)
 {
 }
コード例 #21
0
        public override void GestureUpdate(CircuitEditor editor, Vector2d offset)
        {
            VisualPosition = StartPosition + editor.RoundDistToGrid(offset);

            editor.DrawingArea.QueueDraw();
        }
コード例 #22
0
 public virtual void MouseMoved(CircuitEditor editor, Vector2d mousePos)
 {
 }
コード例 #23
0
 public override void DeSelect(CircuitEditor editor)
 {
     PlacingComponent = false;
     editor.DrawingArea.QueueDraw();
 }
コード例 #24
0
 public abstract void GestureUpdate(CircuitEditor editor, Vector2d offset);
コード例 #25
0
 public WireTool(
     CircuitEditor circuitEditor,
     Gtk.Toolbar toolbar
     ) : base(Icon.Wire(), "Wire", circuitEditor, toolbar)
 {
 }
コード例 #26
0
 public abstract void Draw(CircuitEditor editor, Cairo.Context cr);
コード例 #27
0
 public ComponentTool(T exampleInstance, CircuitEditor circuitEditor) : base(Icon.AndGate(), exampleInstance.Name, circuitEditor)
 {
     BaseComponent = exampleInstance;
 }