public ConnectedWire(Gates.AbstractGate originGate, Gate.TerminalID origin, Gates.AbstractGate destGate, Gate.TerminalID dest) :base() { if (origin.isInput || !dest.isInput) { throw new ArgumentException("Can only connect output (origin) to input (dest)"); } Value = false; this.originGate = originGate; this.destGate = destGate; this.origin = origin; this.dest = dest; //originGate.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(originGate_PropertyChanged); originGate.PropertyChanged += EventDispatcher.CreateBatchDispatchedHandler(originGate, originGate_PropertyChanged); Connect(); }
public void circuitInkCanvas_PreviewMouseDown(object sender, MouseButtonEventArgs e) { // only come here if the uigate doesn't handle it ClearSelection(); Point mp2 = e.GetPosition(circuitInkCanvas); sp = new Point(mp2.X, mp2.Y); ReadyToSelect = true; onGateStroke = false; foreach (UIElement gate in circuitInkCanvas.Children) { if (gate is Gate) { Gate g = gate as Gate; Rect grect = new Rect(g.Margin.Left - 10, g.Margin.Top - 10, g.Width + 10, g.Height + 10); bool condition = false; condition = grect.Contains(mp2); if (condition) { onGateStroke = true; uigate_MouseDown(g, e); if (dragging == DragState.MOVE) { if (g is UIGates.UserInput) { UIGates.UserInput temp = g as UIGates.UserInput; temp.r_MouseDown(this, e); } } break; } } } if (sender is ConnectedWire) { onWireStroke = true; //Debug.WriteLine("HitTest Wire start at " + mp2.ToString()); ConnectedWire myWire = sender as ConnectedWire; Gate.TerminalID tid = myWire.OriginTerminalID; // ok, so are we connecting to or from // is this an input or output? if (tid.isInput) { // can only connect from an input // if there is no other connection here //if (wires.ContainsKey(new Gates.Terminal(tid.ID, tid.abgate))) dragging = DragState.CONNECT_TO; dragWire.Value = false; // highlight all terminals which provide output foreach (Gates.AbstractGate ag in gates.Keys) { for (int i = 0; i < ag.Output.Length; i++) { gates[ag].FindTerminal(false, i).t.Highlight = true; } } } else { dragging = DragState.CONNECT_FROM; // TODO: if the value of the output changes // while being dragged, this won't update dragWire.Value = tid.abgate.Output[tid.ID]; // highlight all terminals which accept input // note this is all inputs NOT already connected foreach (Gates.AbstractGate ag in gates.Keys) { for (int i = 0; i < ag.NumberOfInputs; i++) { if (c.GetSource(new Gates.Terminal(i, ag)) == null) gates[ag].FindTerminal(true, i).t.Highlight = true; } } } beginTID = tid; dragWire.Destination = tid.t.TranslatePoint(new Point(5, 5), circuitInkCanvas); dragWire.Origin = tid.t.TranslatePoint(new Point(5, 5), circuitInkCanvas); //if (dragging == DragState.MOVE) //{ // if (g is UIGates.UserInput) // { // UIGates.UserInput temp = g as UIGates.UserInput; // temp.r_MouseDown(this, e); // } //} //break; } e.Handled = true; }
/* void circuitInkCanvas_StylusMove(object sender, StylusEventArgs e) { if (IsReadOnly) return; TimeSpan ts = _stopWatch.Elapsed; if (ts.TotalSeconds - _lastElapsedSecs> 2) { _stopWatch.Stop(); _stopWatch = Stopwatch.StartNew(); MessageBox.Show("Popup"); } Point mp2 = e.GetPosition(circuitInkCanvas); circuitInkCanvas.BringIntoView(new Rect(new Point(mp2.X - 10, mp2.Y - 10), new Point(mp2.X + 10, mp2.Y + 10))); switch (dragging) { case DragState.CONNECT_FROM: dragWire.Destination = mp2; break; case DragState.CONNECT_TO: dragWire.Origin = mp2; break; case DragState.MOVE: #region DragState is Move foreach (Gate g in selected) { //g.RenderTransform = new TranslateTransform(mp2.X, mp2.Y); //Direct Move double dx = mp2.X - mp.X; double dy = mp2.Y - mp.Y; ((GateLocation)g.Tag).x = ((GateLocation)g.Tag).x + dx; ((GateLocation)g.Tag).y = ((GateLocation)g.Tag).y + dy; double cx = ((GateLocation)g.Tag).x % GRID_SIZE; double cy = ((GateLocation)g.Tag).y % GRID_SIZE; Point op = new Point(g.Margin.Left, g.Margin.Top); if ((Math.Abs(cx) < DELTA_SNAP || Math.Abs(GRID_SIZE - cx) < DELTA_SNAP) && (Math.Abs(cy) < DELTA_SNAP || Math.Abs(GRID_SIZE - cy) < DELTA_SNAP)) { g.Margin = new Thickness(Math.Round(g.Margin.Left / GRID_SIZE) * GRID_SIZE, Math.Round(g.Margin.Top / GRID_SIZE) * GRID_SIZE, 0, 0); } else { g.Margin = new Thickness(((GateLocation)g.Tag).x, ((GateLocation)g.Tag).y, 0, 0); } Point np = new Point(g.Margin.Left, g.Margin.Top); if (op != np) moves.Add(new UndoRedo.MoveGate(g, this, op, np)); SizeCanvas(); g.BringIntoView(); // still needed because gate larger than 20px block } UpdateWireConnections(); break; #endregion case DragState.NONE: #region Drag State is None // not dragging // creating a selection rectangle if (ReadyToSelect) { double x1 = Math.Min(mp2.X, sp.X); double width = Math.Abs(mp2.X - sp.X); double y1 = Math.Min(mp2.Y, sp.Y); double height = Math.Abs(mp2.Y - sp.Y); dragSelect.Margin = new Thickness(x1, y1, 0, 0); dragSelect.Width = width; dragSelect.Height = height; dragSelect.Visibility = Visibility.Visible; // select any gates inside the rectangle Rect select = new Rect(x1, y1, width, height); foreach (Gate g in gates.Values) { Rect grect = new Rect(g.Margin.Left, g.Margin.Top, g.Width, g.Height); if (select.IntersectsWith(grect) && !g.Selected) { g.Selected = true; selected.Add(g); } // this is not the same as just "not" or else the above if (!select.IntersectsWith(grect) && g.Selected) { g.Selected = false; selected.Remove(g); } } } break; #endregion } mp = mp2; } * * */ /* void circuitInkCanvas_MouseMove(object sender, MouseEventArgs e) { if (IsReadOnly) return; TimeSpan ts = _stopWatch.Elapsed; if (ts.TotalSeconds - _lastElapsedSecs > 2) { MessageBox.Show("Popup"); } Point mp2 = e.GetPosition(circuitInkCanvas); circuitInkCanvas.BringIntoView(new Rect(new Point(mp2.X - 10, mp2.Y - 10), new Point(mp2.X + 10, mp2.Y + 10))); switch (dragging) { case DragState.CONNECT_FROM: dragWire.Destination = mp2; break; case DragState.CONNECT_TO: dragWire.Origin = mp2; break; case DragState.MOVE: #region DragState is Move foreach (Gate g in selected) { //g.RenderTransform = new TranslateTransform(mp2.X, mp2.Y); //Direct Move if (e.LeftButton == MouseButtonState.Pressed) { double dx = mp2.X - mp.X; double dy = mp2.Y - mp.Y; ((GateLocation)g.Tag).x = ((GateLocation)g.Tag).x + dx; ((GateLocation)g.Tag).y = ((GateLocation)g.Tag).y + dy; double cx = ((GateLocation)g.Tag).x % GRID_SIZE; double cy = ((GateLocation)g.Tag).y % GRID_SIZE; Point op = new Point(g.Margin.Left, g.Margin.Top); if ((Math.Abs(cx) < DELTA_SNAP || Math.Abs(GRID_SIZE - cx) < DELTA_SNAP) && (Math.Abs(cy) < DELTA_SNAP || Math.Abs(GRID_SIZE - cy) < DELTA_SNAP)) { g.Margin = new Thickness(Math.Round(g.Margin.Left / GRID_SIZE) * GRID_SIZE, Math.Round(g.Margin.Top / GRID_SIZE) * GRID_SIZE, 0, 0); } else { g.Margin = new Thickness(((GateLocation)g.Tag).x, ((GateLocation)g.Tag).y, 0, 0); } Point np = new Point(g.Margin.Left, g.Margin.Top); if (op != np) moves.Add(new UndoRedo.MoveGate(g, this, op, np)); SizeCanvas(); g.BringIntoView(); // still needed because gate larger than 20px block } } UpdateWireConnections(); break; #endregion case DragState.NONE: #region Drag State is None // not dragging // creating a selection rectangle if (ReadyToSelect) { double x1 = Math.Min(mp2.X, sp.X); double width = Math.Abs(mp2.X - sp.X); double y1 = Math.Min(mp2.Y, sp.Y); double height = Math.Abs(mp2.Y - sp.Y); dragSelect.Margin = new Thickness(x1, y1, 0, 0); dragSelect.Width = width; dragSelect.Height = height; dragSelect.Visibility = Visibility.Visible; // select any gates inside the rectangle Rect select = new Rect(x1, y1, width, height); foreach (Gate g in gates.Values) { Rect grect = new Rect(g.Margin.Left, g.Margin.Top, g.Width, g.Height); if (select.IntersectsWith(grect) && !g.Selected) { g.Selected = true; selected.Add(g); } // this is not the same as just "not" or else the above if (!select.IntersectsWith(grect) && g.Selected) { g.Selected = false; selected.Remove(g); } } } break; #endregion } mp = mp2; } * */ /* void circuitInkCanvas_PreviewStylusDown(object sender, StylusDownEventArgs e) { if (EditingMode.currentEditingMode != EditingMode.EditingModeType.SketchLogicGate) { MessageBox.Show("Please Check Sketch Logic Diagram Radio Button", "TIP"); return; } _lastElapsedSecs = _stopWatch.Elapsed.TotalSeconds; // only come here if the uigate doesn't handle it ClearSelection(); Point mp2 = e.GetPosition(circuitInkCanvas); sp = new Point(mp2.X, mp2.Y); ReadyToSelect = true; onGateStroke = false; foreach (UIElement gate in circuitInkCanvas.Children) { if (gate is Gate) { Gate g = gate as Gate; Rect grect = new Rect(g.Margin.Left, g.Margin.Top, g.Width, g.Height); if (mp2.X >= grect.Left && mp2.X <= grect.Right && mp2.Y >= grect.Top && mp2.Y <= grect.Bottom) { onGateStroke = true; uigate_MouseDown(g, e); if (dragging == DragState.MOVE) { if (g is UIGates.UserInput) { UIGates.UserInput temp = g as UIGates.UserInput; temp.r_MouseDown(this, e); } } break; } } } e.Handled = true; } */ #endregion public void circuitInkCanvas_PreviewStylusMove(object sender, StylusEventArgs e) { if (IsReadOnly) return; Point mp2 = e.GetPosition(circuitInkCanvas); if (sender is ConnectedWire) { #region connectedWire Object onWireMoveStroke = true; ConnectedWire myWire = sender as ConnectedWire; Gate.TerminalID tid = myWire.OriginTerminalID; // ok, so are we connecting to or from // is this an input or output? if (tid.isInput) { // can only connect from an input // if there is no other connection here //if (wires.ContainsKey(new Gates.Terminal(tid.ID, tid.abgate))) dragging = DragState.CONNECT_TO; dragWire.Value = false; // highlight all terminals which provide output foreach (Gates.AbstractGate ag in gates.Keys) { for (int i = 0; i < ag.Output.Length; i++) { gates[ag].FindTerminal(false, i).t.Highlight = true; } } } else { dragging = DragState.CONNECT_FROM; // TODO: if the value of the output changes // while being dragged, this won't update dragWire.Value = tid.abgate.Output[tid.ID]; // highlight all terminals which accept input // note this is all inputs NOT already connected foreach (Gates.AbstractGate ag in gates.Keys) { for (int i = 0; i < ag.NumberOfInputs; i++) { if (c.GetSource(new Gates.Terminal(i, ag)) == null) gates[ag].FindTerminal(true, i).t.Highlight = true; } } } beginTID = tid; dragWire.Destination = tid.t.TranslatePoint(new Point(5, 5), circuitInkCanvas); dragWire.Origin = tid.t.TranslatePoint(new Point(5, 5), circuitInkCanvas); //if (dragging == DragState.MOVE) //{ // if (g is UIGates.UserInput) // { // UIGates.UserInput temp = g as UIGates.UserInput; // temp.r_MouseDown(this, e); // } //} //break; return; #endregion } circuitInkCanvas.BringIntoView(new Rect(new Point(mp2.X - 10, mp2.Y - 10), new Point(mp2.X + 10, mp2.Y + 10))); switch (dragging) { case DragState.CONNECT_FROM: foreach (UIElement gate in circuitInkCanvas.Children) { if (gate is Gate) { Gate g = gate as Gate; foreach (Gate.TerminalID tid in g) { tid.t.Background = Brushes.Transparent; } } } // gate termination indication foreach (UIElement gate in circuitInkCanvas.Children) { if (gate is Gate) { Gate g = gate as Gate; Rect grect = new Rect(g.Margin.Left - 10, g.Margin.Top - 10, g.Width + 10, g.Height + 10); bool condition = false; condition = grect.Contains(mp2); if (condition) { Rect gRect = new Rect(g.Margin.Left, g.Margin.Top, g.Width, g.Height); foreach (Gate.TerminalID tid in g) { Rect tRect = GetTerminalBounds(g, grect, tid); condition = tRect.Contains(mp2); if (condition) { tid.t.Background = Brushes.Yellow; }else { tid.t.Background = Brushes.Transparent; } } } } } dragWire.Destination = mp2; break; case DragState.CONNECT_TO: foreach (UIElement gate in circuitInkCanvas.Children) { if (gate is Gate) { Gate g = gate as Gate; foreach (Gate.TerminalID tid in g) { tid.t.Background = Brushes.Transparent; } } } // gate termination indication foreach (UIElement gate in circuitInkCanvas.Children) { if (gate is Gate) { Gate g = gate as Gate; Rect grect = new Rect(g.Margin.Left - 10, g.Margin.Top - 10, g.Width + 10, g.Height + 10); bool condition = false; condition = grect.Contains(mp2); if (condition) { Rect gRect = new Rect(g.Margin.Left, g.Margin.Top, g.Width, g.Height); foreach (Gate.TerminalID tid in g) { Rect tRect = GetTerminalBounds(g, grect, tid); condition = tRect.Contains(mp2); if (condition) { tid.t.Background = Brushes.Yellow; }else { tid.t.Background = Brushes.Transparent; } } } } } dragWire.Origin = mp2; break; case DragState.MOVE: #region DragState is Move foreach (Gate g in selected) { //g.RenderTransform = new TranslateTransform(mp2.X, mp2.Y); //Direct Move double dx = mp2.X - mp.X; double dy = mp2.Y - mp.Y; ((GateLocation)g.Tag).x = ((GateLocation)g.Tag).x + dx; ((GateLocation)g.Tag).y = ((GateLocation)g.Tag).y + dy; double cx = ((GateLocation)g.Tag).x % GRID_SIZE; double cy = ((GateLocation)g.Tag).y % GRID_SIZE; Point op = new Point(g.Margin.Left, g.Margin.Top); if ((Math.Abs(cx) < DELTA_SNAP || Math.Abs(GRID_SIZE - cx) < DELTA_SNAP) && (Math.Abs(cy) < DELTA_SNAP || Math.Abs(GRID_SIZE - cy) < DELTA_SNAP)) { g.Margin = new Thickness(Math.Round(g.Margin.Left / GRID_SIZE) * GRID_SIZE, Math.Round(g.Margin.Top / GRID_SIZE) * GRID_SIZE, 0, 0); } else { g.Margin = new Thickness(((GateLocation)g.Tag).x, ((GateLocation)g.Tag).y, 0, 0); } Point np = new Point(g.Margin.Left, g.Margin.Top); if (op != np) moves.Add(new UndoRedo.MoveGate(g, this, op, np)); SizeCanvas(); g.BringIntoView(); // still needed because gate larger than 20px block } UpdateWireConnections(); break; #endregion case DragState.NONE: #region Drag State is None // not dragging // creating a selection rectangle if (ReadyToSelect) { double x1 = Math.Min(mp2.X, sp.X); double width = Math.Abs(mp2.X - sp.X); double y1 = Math.Min(mp2.Y, sp.Y); double height = Math.Abs(mp2.Y - sp.Y); //dragSelect.Margin = new Thickness(x1, y1, 0, 0); //dragSelect.Width = width; //dragSelect.Height = height; //dragSelect.Visibility = Visibility.Visible; // select any gates inside the rectangle Rect select = new Rect(x1, y1, width, height); foreach (Gate g in gates.Values) { Rect grect = new Rect(g.Margin.Left, g.Margin.Top, g.Width, g.Height); if (select.IntersectsWith(grect) && !g.Selected) { g.Selected = true; selected.Add(g); } // this is not the same as just "not" or else the above if (!select.IntersectsWith(grect) && g.Selected) { g.Selected = false; selected.Remove(g); } } } break; #endregion } mp = mp2; }
void uigate_MouseDown(object sender, MouseButtonEventArgs e) { Point mp2 = e.GetPosition(circuitInkCanvas); if (IsReadOnly) return; Gate tg = (Gate)sender; // to avoid sticking on other gates, move this one to the top circuitInkCanvas.Children.Remove(tg); circuitInkCanvas.Children.Add(tg); if (!tg.Selected) { selected.Add(tg); ((GateLocation)tg.Tag).x = tg.Margin.Left; ((GateLocation)tg.Tag).y = tg.Margin.Top; tg.Selected = true; } Rect gRect = new Rect(tg.Margin.Left, tg.Margin.Top, tg.Width, tg.Height); foreach (Gate.TerminalID tid in tg) { Rect tRect = GetTerminalBounds(tg, gRect, tid); bool condition = tRect.Contains(mp2); // if (tid.t.IsMouseOver) //if (mp2.X >= tRect.Value.Left - 10 && mp2.X <= tRect.Value.Right + 10 // && mp2.Y >= tRect.Value.Top - 10 && mp2.Y <= tRect.Value.Bottom + 10) if(condition) { // ok, so are we connecting to or from // is this an input or output? if (tid.isInput) { // can only connect from an input // if there is no other connection here if (wires.ContainsKey(new Gates.Terminal(tid.ID, tid.abgate))) continue; dragging = DragState.CONNECT_TO; dragWire.Value = false; // highlight all terminals which provide output foreach (Gates.AbstractGate ag in gates.Keys) { for (int i = 0; i < ag.Output.Length; i++) { gates[ag].FindTerminal(false, i).t.Highlight = true; } } } else { dragging = DragState.CONNECT_FROM; // TODO: if the value of the output changes // while being dragged, this won't update dragWire.Value = tid.abgate.Output[tid.ID]; // highlight all terminals which accept input // note this is all inputs NOT already connected foreach (Gates.AbstractGate ag in gates.Keys) { for (int i = 0; i < ag.NumberOfInputs; i++) { if (c.GetSource(new Gates.Terminal(i, ag)) == null) gates[ag].FindTerminal(true, i).t.Highlight = true; } } } beginTID = tid; dragWire.Destination = tid.t.TranslatePoint(new Point(5, 5), circuitInkCanvas); dragWire.Origin = tid.t.TranslatePoint(new Point(5, 5), circuitInkCanvas); e.Handled = true; return; } } dragging = DragState.MOVE; moves = new UndoRedo.Transaction( (e.LeftButton == MouseButtonState.Pressed ? "Move" : "Rotate") + " " + (selected.Count == 1 ? "Gate" : selected.Count.ToString() + " Gates")); e.Handled = true; }
private void uigate_MouseDown(object sender, MouseButtonEventArgs e) { if (IsReadOnly) return; Gate tg = (Gate)sender; // to avoid sticking on other gates, move this one to the top GC.Children.Remove(tg); GC.Children.Add(tg); if (!tg.Selected) { // can use ctrl or alt to multi-select if (Keyboard.Modifiers == ModifierKeys.None) ClearSelection(); selected.Add(tg); ((GateLocation)tg.Tag).x = tg.Margin.Left; ((GateLocation)tg.Tag).y = tg.Margin.Top; tg.Selected = true; } foreach (Gate.TerminalID tid in tg) { if (tid.t.IsMouseOver) { // ok, so are we connecting to or from // is this an input or output? if (tid.isInput) { // can only connect from an input // if there is no other connection here if (wires.ContainsKey(new Gates.Terminal(tid.ID, tid.abgate))) continue; dragging = DragState.CONNECT_TO; dragWire.Value = false; // highlight all terminals which provide output foreach (Gates.AbstractGate ag in gates.Keys) { for (int i = 0; i < ag.Output.Length; i++) { gates[ag].FindTerminal(false, i).t.Highlight = true; } } } else { dragging = DragState.CONNECT_FROM; // TODO: if the value of the output changes // while being dragged, this won't update dragWire.Value = tid.abgate.Output[tid.ID]; // highlight all terminals which accept input // note this is all inputs NOT already connected foreach (Gates.AbstractGate ag in gates.Keys) { for (int i = 0; i < ag.NumberOfInputs; i++) { if (c.GetSource(new Gates.Terminal(i, ag)) == null) gates[ag].FindTerminal(true, i).t.Highlight = true; } } } beginTID = tid; dragWire.Destination = tid.t.TranslatePoint(new Point(5, 5), GC); dragWire.Origin = tid.t.TranslatePoint(new Point(5, 5), GC); e.Handled = true; return; } } dragging = DragState.MOVE; moves = new UndoRedo.Transaction( (e.LeftButton == MouseButtonState.Pressed ? "Move" : "Rotate") + " " + (selected.Count == 1 ? "Gate" : selected.Count.ToString() + " Gates")); e.Handled = true; }