private static void GenerateLayoutLevel(IShapeContainer container, GridLayout layout, Transaction transaction) { foreach (var sub in layout.Contents) { var item = new Item { ItemType = sub.Type, StyleType = Item.DefaultItemDisplayTypeForType(sub.Type), LineStyle = { Colour = Color.Black }, FillStyle = { Colour = Color.LightGray }, LabelText = "" }; item.SetBounds(sub.Bounds); var scriptable = new Scriptable(item); container.Contents.Add(scriptable); scriptable.Parent = container; transaction.Create(item); transaction.Create(scriptable); scriptable.SelectScript = new Script(); if (sub.Contents != null) { scriptable.SelectScript.Visit.VisitType = Script.VisitTarget.VisitTypes.Down; GenerateLayoutLevel(item, sub, transaction); } else { scriptable.SelectScript.Visit.VisitType = Script.VisitTarget.VisitTypes.Up; } } container.FinishedModifyingContents(transaction); }
public void CopyPresentationFrom(Scriptable item, bool noOverwriteExisting) { // see Item if (HighlightStyle == null) { HighlightStyle = new HighlightStyleC(); } HighlightStyle.CopyFrom(item.HighlightStyle); if (!noOverwriteExisting || Sound == null) { Sound = item.Sound?.Clone(); } if (!noOverwriteExisting || string.IsNullOrEmpty(OutputText)) { OutputText = item.OutputText; } OutputAsDisplay = item.OutputAsDisplay; if (!noOverwriteExisting || string.IsNullOrEmpty(SpeechText)) { SpeechText = item.SpeechText; } SpeechAsDisplay = item.SpeechAsDisplay; if (!noOverwriteExisting || string.IsNullOrEmpty(PromptText)) { PromptText = item.PromptText; } }
protected override bool IdenticalToShape(Shape other) { if (!base.IdenticalToShape(other)) { return(false); } if (!Element.IdenticalTo(other)) { return(false); } Scriptable scriptable = (Scriptable)other; if (Popup != scriptable.Popup || Shown != scriptable.Shown) { return(false); } for (int i = 0; i < Scripts.Length; i++) { if (Scripts[i] != null && scriptable.Scripts[i] != null && !Scripts[i].IdenticalTo(scriptable.Scripts[i])) { return(false); } } return(true); }
/// <summary>Display the given scriptable object for editing. Use isDefault when editing one of the set defaults</summary> public void Edit(Scriptable item, bool isDefault = false) { m_Scriptable = item; chkRepeats.Visible = !isDefault; m_IsDefault = isDefault; FillUI(); }
/// <summary>Use overloaded version (Scriptable, which) normally. This version is intended for the default scripts, and will not support calling thru to default</summary> public void Edit(Script script, Page page) { m_Scriptable = null; m_Script = script; m_Page = page; m_DefaultScript = null; FillUI(); }
/// <summary>Display the given script for editing.</summary> public void Edit(Scriptable scriptable, int which) { m_Scriptable = scriptable; m_Script = scriptable.Scripts[which]; m_Page = scriptable.FindPage(); m_DefaultScript = m_Scriptable.GetDefaultScript((Scriptable.ScriptTypes)which, Globals.Root.CurrentDocument); FillUI(); }
private void StopCustomRepeat() { if (m_RepeatItem != null) // just in case. Both protects vs null and from running it twice { InvokeScript(m_RepeatItem, Scriptable.ScriptTypes.PostRepeat, true, m_RepeatItem); } m_RepeatItem = null; m_RepeatTimer.Enabled = false; }
public ExecutionContext(Scriptable target, RunView view, Page page, Document doc, Switches.Engine scanEngine, Scriptable.ScriptTypes scriptType) { TargetItem = target; View = view; Page = page; Document = doc; ScanEngine = scanEngine; ScriptType = scriptType; }
/// <summary>Causes the given command to capture all further scan output until StopContinuous</summary> public void StartContinuous(IContinuousCommand command) { if (m_Continuous == command) { return; // so it doesn't have stop called } m_Continuous?.Stop(); m_Continuous = command; m_RepeatItem = null; }
/// <summary>Run one of the scripts on the item. If noVisit then the VisitItem is not used (but explicit Visit scripts would still run) /// The item which acts as the context can be provided, but is the Current/selected item normally (NOT the item on which the script is invoked - exec commands still /// run in the context of the pressed button)</summary> public void InvokeScript(Scriptable item, Scriptable.ScriptTypes which, bool noVisit = false, Scriptable contextItem = null) { //Debug.WriteLine("Invoke script " + which + " on " + item.Description); Script script = item.GetScript(which); if (contextItem == null) { contextItem = m_Current; } // find defaults first, if needed (unlike SAW6 this is possible even if there are genuine scripts) Script def = null; if (script?.RunDefault ?? true) // if object missing entirely(?!?) default is used { def = item.GetDefaultScript(which, m_Document); } Scriptable originalCurrent = m_Current; // used below to detect if a custom visit script changed the selection Command.ExecutionContext context = new Command.ExecutionContext(contextItem, this, m_Page, m_Document, m_Engine, which); if (def != null) { InvokeScriptCommands(def, context); } if ((script?.CommandList?.Count ?? 0) != 0) // either null object, or no commands (only latter possible?) either counts the same { InvokeScriptCommands(script, context); } if (noVisit || context.Terminate) { return; } // however the default visit is done after any custom commands Scriptable target = null; if (script != null) { target = ResolveVisitTarget(script.Visit, contextItem); // 8.0.4 changed to context from Item - } if (target == null && def != null) // default is only used if self is set to None: { target = ResolveVisitTarget(def.Visit, contextItem); } if (target == null && which == Scriptable.ScriptTypes.Next && originalCurrent == m_Current) { target = item; // a Next script which references nothing useful should re-select the same item // but only if a custom script didn't make a selection } if (target != null) { SelectItem(target, false); } }
private void m_Engine_EndSelect() { // switch which was repeat selecting released. Ensure no repeats (although trigger shouldn't be called anyway!) if (m_RepeatItem?.HasRepeatingScript ?? false) { // custom repeating scripts, this would usually stop // but first check if this actually ends, or if they are in the alternate mode: if (CurrentConfig.ReadBoolean(Config.Repeat_PressStop)) { return; // this doesn't actually stop until clicked again. The switch up does nothing } StopCustomRepeat(); } else { m_RepeatItem = null; } }
/// <summary>Highlights the item, calling the Visit script. directSelect=true IFF this is a request from the mouse input</summary> public void SelectItem(Scriptable item, bool directSelect) { if (m_MouseInput && !directSelect) { return; // ignore all other changes when using mouse input } Debug.Assert(item == null || !item.NotVisited); if (m_Current != null && directSelect) // these may be unnecessary now with above? { // can't clear m_Current before call (would help avoid infinite loops) since m_Current is always the execution context InvokeScript(m_Current, Scriptable.ScriptTypes.Next, true); // SAW was changed to include the next script in direct selection modes // originally it only did manual deselection // and it still manually unhighlights } m_Current = item; // must be before script - which might re-assign it if (item != null) { InvokeScript(item, Scriptable.ScriptTypes.Visit); } }
/// <summary>Returns the item which is referenced by the visit object, or null if nothing found (which usually has same effect as "Me")</summary> public Scriptable ResolveVisitTarget(Script.VisitTarget visit, Scriptable source) { //Debug.WriteLine("Resolve: " + visit.GetDescription() + " from " + (source?.SAWID.ToString() ?? "null")); List <Scriptable> items; if (source != null) { items = (source.Parent as IShapeContainer).Contents.OfType <Scriptable>().Where(i => i.Shown && !i.NotVisited).ToList(); } else { items = new List <Scriptable>(); } int currentIndex = items.IndexOf(source); switch (visit.VisitType) { case Script.VisitTarget.VisitTypes.None: return(null); case Script.VisitTarget.VisitTypes.Me: return(source); case Script.VisitTarget.VisitTypes.First: return(items.FirstOrDefault()); case Script.VisitTarget.VisitTypes.Last: return(items.LastOrDefault()); case Script.VisitTarget.VisitTypes.Previous: Debug.Assert(currentIndex >= 0); currentIndex -= 1; if (currentIndex < 0) { currentIndex = items.Count - 1; } return(items[currentIndex]); case Script.VisitTarget.VisitTypes.Next: Debug.Assert(currentIndex >= 0); currentIndex += 1; if (currentIndex >= items.Count) { currentIndex = 0; } return(items[currentIndex]); case Script.VisitTarget.VisitTypes.Down: return(((source.Element as IShapeContainer)?.Contents.OfType <Scriptable>()).FirstOrDefault(i => i.Shown && !i.NotVisited)); case Script.VisitTarget.VisitTypes.Up: return((source.Parent as Shape)?.Parent as Scriptable); // will return null if not within an element within a Scriptable case Script.VisitTarget.VisitTypes.Item: return(m_Page.FindScriptableByID(visit.ItemID)); default: OnError("Unknown visit type: " + visit.VisitType); return(null); } }
private void m_Engine_Trigger(bool isRepeat) { if (m_frmReport != null) { m_frmReport.SwitchActivated(); return; } if (m_RepeatItem?.HasRepeatingScript ?? false) { // currently doing custom repeats scripts if (CurrentConfig.ReadBoolean(Config.Repeat_PressStop) && !isRepeat) { StopCustomRepeat(); } // either way no further action is taken on this - the separate timer activates this return; } if (m_Continuous != null) { // a command has captured the output to make a selection if (!m_Continuous.Trigger(isRepeat)) { m_Continuous?.Stop(); // ? needed in case the command removed itself already m_Continuous = null; } return; } var item = isRepeat ? m_RepeatItem : m_Current; if (item == null) // usually this will be because repeating is not enabled on the last item, but also covers the case where nothing was selected for a genuine switch activation { return; } if (CurrentConfig.ReadBoolean(Config.Use_Swap_Switch)) { LogicalSwapper.Swap = !LogicalSwapper.Swap && !item.ResetSwap; } // if item has ResetSwap then the state is forced to false // when repeating we explicitly use the remembered item -it may have selected something else as "current" //Debug.WriteLine("Trigger"); var current = m_Current; if (isRepeat && item.HasRepeatingScript) { InvokeScript(item, Scriptable.ScriptTypes.Repeat, true, item); } else { InvokeScript(m_Current, Scriptable.ScriptTypes.Select); } if (!isRepeat) // for first activation, set up repeating if needed. { // if item is not AutoRepeat, failing to set this will ensure the repeat triggers are ignored if (current.HasRepeatingScript) { // start up the timer for custom repeat scripts m_RepeatItem = current; InvokeScript(m_RepeatItem, Scriptable.ScriptTypes.PreRepeat, true, m_RepeatItem); // this one fires immediately. m_RepeatTimer.Interval = m_Engine.ConfiguredTiming(Switches.Engine.Timings.FirstRepeat); m_RepeatTimer.Enabled = true; } else if (current.AutoRepeat) { m_RepeatItem = current; } } }
/// <summary>Changes the highlight state of the item. Doesn't need to be the current one</summary> public void SetItemState(Scriptable item, ButtonShape.States state) { //Debug.WriteLine("SetItemState " + item.Description + " = " + state); item.State = state; m_Page.NotifyIndirectChange(item, ChangeAffects.RepaintNeeded, item.RefreshBounds()); }
public override void CopyFrom(Datum other, CopyDepth depth, Mapping mapID) { // this is slightly flaky for Undo still, in that the scriptable must be put into the transaction FIRST // (otherwise it will refernce differing copies of the contained element) base.CopyFrom(other, depth, mapID); Scriptable scriptable = (Scriptable)other; if (depth > CopyDepth.Transform) { CopyPresentationFrom(scriptable, false); } //Debug.WriteLine("Scriptable.CopyFrom, depth=" + depth + " ID=" + scriptable.SAWID); // contained element. Works like ShapeStack containment - Element is tightly bound within this if (depth == CopyDepth.Transform && Element != null) { // first time must copy reference, below if (Element != scriptable.Element) { Element?.CopyFrom(scriptable.Element, depth, mapID); } } else // if (depth == CopyDepth.Duplicate) { if (mapID?.ContainsKey(scriptable.Element.ID) ?? false) { Element = (Shape)mapID[scriptable.Element.ID]; } else { Element = (Shape)scriptable.Element.Clone(mapID ?? new Mapping()); // use actual mapID if there is one, otherwise need a real one as Container aspects of Item don't like Ignore } Element.Parent = this; } //else //{ // Element = scriptable.Element; //} ////else if (depth == CopyDepth.Duplicate) ////{ //// if (mapID == null) //// mapID = Mapping.Ignore; //// Element = (Shape)scriptable.Element.Clone(mapID); //// Element.Parent = this; ////} //else //{ // // undo requires all shapes are copied, because they could later be edited by styling changes // //Element = Shape.CreateShape(scriptable.Element.ShapeCode); // <- this is inadequate as it doesn't clone contents of the items which leaves some reference problems // //Element.CopyFrom(scriptable.Element, depth, null); // Element = (Shape)scriptable.Element.Clone(mapID ?? new Mapping()); // use actual mapID if there is one, otherwise need a real one as Container aspects of Item don't like Ignore // Element.Parent = this; //} // other fields: if (depth > CopyDepth.Transform) { SAWID = scriptable.SAWID; Popup = scriptable.Popup; Shown = scriptable.Shown; AutoRepeat = scriptable.AutoRepeat; RepeatTimeout = scriptable.RepeatTimeout; for (int i = 0; i < Scripts.Length; i++) { Scripts[i] = scriptable.Scripts[i]?.Clone(); } } m_Bounds = RectangleF.Empty; // because content may have moved - especially on Undo }