OPEN BUG: - Presentation-based Show/Hide with Fading that occurs during a tight-looped arrow translation kills GSP on ProcessTick() re-entrancy :-(. True all the way back to 3028.

2025.01.02 [BUGFIX] Fixed toolbox re-entrancy problem when "click-release-mouse-waving" over a popup tool submenu

2025.01.02 [COSMETIC IMPROVEMENT] Popup tool submenus now visibly track a "waved" mouse (just like they now again do a "dragged" mouse), in the situation where a tool submenu has been popped up by click/hold/releasing rather than by press&dragging.

2025.01.02 [BUGFIX] Toolbox positioning is more deterministic on multiple-monitor setups, and new sketch documents do a better job of avoiding appearing "just under" the right edge of the toolbox.

2025.01.02 [COSMETIC IMPROVEMENT] Adjusted font-size on Calculator's keypad buttons to reflect new sizing of Sequoia/Tahoe system fonts.

2025.12.27 [BUGFIX] Using Document Options to remove a page from the active document no longer fails to enable the Save command if the document is otherwise unchanged since it was last opened. (Present since Forever, reported by Daniel "Multi-page sketch bug" 12/2025)

2025.11.24 Fixed a bug in which MacOS could crash after the "Missing Assumed Objects" dialog was dismissed, and along the way clarified documentation in common code about the ownership policy around MFS that common code passes to the platform in MFSDisplayControls.

[BUGFIX] In a new sketch, two points and apply-as-command the Custom Tool "Inverse Tools -> Inverse of a Circle". One correctly receives a "Missing ASsumed Objects" dialog, after which you previously had a high risk of  crashing. No more!

2025.11.23 Fixed new (Sequoia era) MacOS regression in handling event key modifiers.

BUGFIX (11/22/25 found in 3058). Segment tool, place first endpoint, mouse to random location for second endpoint but don't yet place it, press the Command or the Shift key. 2nd endpoint zooms off to (0,0) until you move the mouse again.
    
2025.11.23 [BUGFIX] Fatal assertion "ExpandMetaLabelInPlace() string logic is bogus" or runtime crash applying a custom tool (such as the three-way AND tool in Daniel's 11/2025 "GSPBug.gsp") that has parameter labels designed to generate a specific variable label in their productions but in which the expansion of the destination label table, given the actual labels of the component objects referenced by that template, would generate a string longer than the maximum legal length of an object label (255 characters). In the fix, the component object label that would cause the produced template to overflow its legal length is truncated to the maximum amount of room available in the string, which has the effect that non-component portions of the template are ALWAYS preserved in the destination but object labels that are dynamically instantiated components of the produced template may be shortened.

2025.11.23 Fixed residual issues with Custom Tools Tool's  non-standard handling of mouseActions.

[BUGFIX] (Logged 11/22/25 found in 3058). Make a trivial custom tool of e.g. a triangle and preselect the necessary points to apply this custom tool "as a command." Switch to the Polygon Tool so Toolplay modality is active. Then command-click the Custom Tools icon and apply the custom tool as a command to your selections. The triangle correctly appears. However, afterwards, polygon-toolplay starts back up, but the toolbox displays the Custom Tool as the "active tool".  It should instead revert to the Arrow tool. Note this only happens if the "previous tool" is itself an object-constructing (toolplay modality) tool (polygon, segment, point, compass); the toolbox correctly revert to the Arrow after custom-tool-command application if the on-entry tool is Object Info, Text, or Marker. (Internal problem is the ToolboxController code checks if toolplay modality exists post-menu and
    if so doesn't revert to Arrow tool, under the incorrect assumption that it was the menu choice that
    fired up toolplay rather than some other action.

2025.11.22: Redesigned MacOS Toolbox button mouse-tracking logic to compensate for Apple's broken NSTrackingAreas in Ventura and later.

[BUGFIX] Click-and-dragging the mouse on a Toolbox with a potential submenu correctly showed the submenu, but drag-releasing over one of this submenu's subtools did not successfully activate the subtool. (New in MacOS Ventura)
[BUGFIX] Dragging the mouse over subtools in a Toolbox subpalette did not correctly "track the mouse" with tentative tool highlighting. (New in MacOS Ventura.)
[BUGFIX] Pressing on a non-active root Toolbox tool#1 (e.g. Compass tool) correctly
temporarily hilit that tool, and subsequently stillDown-dragging off tool#1 to dead space correctly dehilit #1 and rehilit previously chosen tool#0, but subsequent stillDown-dragging on to and off of #1 no longer rehilit/dehilit it; instead tool#0 remained hilit regardless of mouse location until mouseUp (at which point "the correct tool" was chosen). Now, dragging the mouse off and on a just-pressed
icon correctly dehighlights/rehighlights the potential new tool choice until you "make your decision" by releasing the mouse (newish in MacOS Ventura.
[BUGFIX] Pressing on an already active root Toolbox tool (e.g. a previouosly active Compass tool), and then stillDown-dragging off it, dehilit that icon, "plausibly correctly," but then letting go of the mouse (while off that tool) left the toolbox with no visible hilit icon.  From the status bar one or by sketch-clicking one can see that the previously active tool is still active, but it did not appear active in the toolbox until the next toolbox mouse-interaction or tool-changing event. Now repressing the already-active tool in the Toolbox has no effect on its icon highlight: that tool was active before you pressed and will be after you release, no matter what.
     
2025.11.22: Started up beta-development on 3059, heading to an eventual new release of
    GSP 5.11.
===============================================================================

2024.08.15 *** BUILDING A RELEASE CANDIDATE UPDATE **

Around the 3058 release, XCode 15.2 began generating cryptic error messages about app-entitlements being incorrect when attempting to Validate release builds under com.kcptech.Sketchpad, our historic bundleID. Sleuthing was not definitive but some of the evidence suggested that the fact that the bundleID did not somehow match the TeamID of McGraw-Hill was an issue; or that there was no app record matching that bundle ID if I attempted to build as tean Roman Nicholas Jackiw. Looking at previous successful Release builds in the my Organizer's archive of past builds, I see "Ready to Distribute" apps built under both these Teams in the past, so suspect something has changed either in XCode's handling or in McGraw-Hill's management of its Dev Team assets on the Developer portal.

On August 15, I switched the bundle to com.scratchconsortium.gsp, which I'd used in the past in experimental builds under team Roman Nicholas Jackiw, and discovered I got further in Validation, which now claimed I needed App Sandboxing and certain modern 512x512 ICNS to clear validation. I looked briefly at App Sandboxing, which seemed feasible if tedious (i.e. real work, especially for semi-permanent access to a custom-location for the Script Tool Folder), before discovering that Direct Distribution apps (instead of App Store apps) don't require that mandatory phase. From this I concluded Validation always assumes App Store release, and instead switched directly to Distribution, which --- succeeded!  Choosing "Distribute App" from a freshly-archived build lets you choose how to distribute it -- App Store is an option, but so is Direct Distribution, which is what we're using for the field test -- and then code-signs and notarizes the app successfully. One can build, run, and privately distribute the resulting app.

[TO DO] So, takeaway TO DO if we ever want to App Store release this, is (1) figure out if we can restore com.kcptech.Sketchpad as the BundleID, presumably with MH's Dev Account generating a new AppIdentifier for this ID which they manage; and (2) implement app_sandbox conformance, granting Sketchpad access to Files with Standard User Interactions (e.g. Open/Save dialogs) and with a persistent securityScopeAllowOnlyReadAccess URL bookmark to the Script Tool Folder.


2024.08.26: [FEATURE ADDED] "Export as HTML..." with impacts to File Menu and platform-specific UI.  UI is: File Menu contains this new menu command, which leads to a Save As document allowing export in either HTML or JSON.  "JSON" choice leads simply to the raw output of our existing WSP export logic, and "HTML" choice is secret code for "save a parametrically-instantiated copy of the bundled-resource auxilliary file, "web_sketch_export_template.html", using a parameter-instantiation grammar that includes sketch-specific JSON, export version#, export date, etc.

Along the way, we add a minor bugfix to WSP Export so it can function in DEBUG builds on Macintosh, where gMem allocations are intentionally NOT C pointer blocks, and we fix RDB browsing import, which was screwed up by changes to our GSPDocument-bundle semantics.

[WINDOWS INTEGRATION] Since Mac GSP's File menu is no longer generated by Charade common code, the change to the File Menu does not appear in common code. Windows will have to add its own specific widgetry -- ideally a File Menu command -- for initiating export.  That platform-specific code should present a file export dialog with a choice between HTML and JSON export, ideally targetting a filename that corresponds to the current gBook's document title with *.html or *.json output extensions, and then output the appropriate file (see below). Finally, a "Preview in Browser" checkbox in the export dialog, enabled only when the export choice is "HTML," should control whether a successful textfile-export is followed by a shell launch of that file in a local browser.  Mac-specific ExportHTML_ViewController.onSave[] is the corresponding Mac implementation of all of this UI logic.

In terms of determining the contents of the file to export, Book_SaveAsWSP () is the appropriate (new) worker function. In addition to an output stream, it takes a parameter which is either NULL (for raw JSON export), or which points to an 8-bit template string (the "HTML export template") in which the specific JSON, current export version, current date and time, etc., will all be instantiated based on hardcoded formal parameters (e.g. {{WSP_EXPORT_DATE}}) in the template.  Mac-specific code contains logic to fetch this string from the file web_sketch_export_template.html in the application bundle, or to fall back to a hardcoded HTML template based in localizable cross-platform strings. For reference, GSPDocument.dataOfType is the Mac-specific method which generates the exported text based on a prepared template (see particularly the logic handling com.kcptech.wspHTML and public.json NSDocument "data types").

[/END WINDOWS INTEGRATION]

- [ADDED] GSP/sketch/web_sketch_export_template.html: new cross-platform template for "Save As HTML" output instantiation
- [ADDED] Mac/Classes/ExportHTML_ViewController.*: new UI logic for Mac's "Save as HTML..."
- [ADDED] Charade/streams/streamout_string_template.*: new parameter instantiater for 8-bit strings to Stream-based output
- misc_st.*: new formnal parameters for HTML template grammar
- skwebgsp.*: cleanup, bugfixing, renaming to support better export of modern JSON or Json-embedded-in-HTML
- mnuset_m.c, UICMenuItem, MainMenu: new "Save as HTML" menu item, bugfixing
- GSPDocument.*, GSPDocumentController.m: "Save as HTML" destination-file choosing logic, also some compliance implementation of Cocoa horseshit around "how an NSDocument should export different document types"

2024.08.xx Fixed issues on code "Built for Sonoma." These relate to NSView changes introduced in any app built against Sonoma SDK (https://developer.apple.com/documentation/macos-release-notes/appkit-release-notes-for-macos-14#NSView), in which an app can now draw outside its view frame and is passed a dirtyRect larger than that frame!
- apple_mfsCursorView.m:
So for blinking MFS Cursors ("Text Tool" in Sketch; "input line" in Calculator) rather than blink the apple_MfsCursorView's dirtyRect, we simply blink its frame, and hope that clipping does the rest!
- ScrollViewWithSidePanel.swift: Document window frame side-Panel now clipsToBounds, so page tabs don't overdraw righthand scrollbar
- CalcInputView.swift: calc input pane now clipsToBounds, so its background-white-preclearing does not obliterate button bar

2024.05.22
- BUGFIX: "Doc Options" is no longer enabled when no document is
    open. Problem was UIC is enabling/disabling a disconnected local
    affordance -- a temporary UIC-specific File menu that Mac
    abandons by harvesting some items (Doc Options) into clones
    in its pre-existing File menu. Fix was to wrap the dispatch
    mechanism for such clones in a GSPDocument-specific action
    so that Cocoa knows to disable them when No Document.

2023.08.04 REV'D TO High Sierra Minimum

2023.08.04 [SUPPRESSED COMPILER WARNINGS] added explicit (void) parameters to argumentless functions for modern C conformance
- *.*: numerous .c files

2023.08.04 [IMPROVEMENT] Dragging a fully-entailed rotation-by-marked-angle-measure no longer drags the angle measure as well if that is not part of the pre-image/image geometry.
- constran.c: RotateByMarkedAngleMarker_C edge type improvement

2023.02.14 [IMPROVEMENT] Sample Sketches & Tools are now fetched from scratchconsortium.com,
rather than dynamicgeometry.com, and therefore have the "new 5.1 samples" rather than the "old 5.0 samples"
- AppDelegate.m: revised the default URL for _helpMenu_samplesSketches_item

2023.02.14 [BUGFIX] Intermittent crash after closing a sketch with a script showing in Script View
- scrvieew.c: ScriptView_AboutToDisposeTool() now releases gScriptViewScript_OwningBook.

2023.02.14 [BUGFIX] Drag-n-drop of Givens in Script View was not working smoothly; a dragged Given would at most move up or down by one position, rather than to the actual drop-target.
- scrview.*: added new routine to permit dropping beyond one-position "away"
- ScriptViewController.swift: called ScriptView_DropRearrangeDraggedGiven

2022.08.11 - 3056 RELEASED

2022.08.11 [NEW] With a single selected free point, Shift+Edit Menu displays a new command: "Allow Dragging to Merge." By default this is checked for all free points; choosing it toggles it from checked to unchecked and back. When unchecked, drag-merging does not "begin" when you drag the point over a mergeable target. Use this to permanently disable drag merging for specific control points in your sketch whose intended use consistently triggers unintended merge operations. This setting is saved in, files created in 3056 or later (and only respected by builds 3056 or later). (For a lighterweight disabling of drag merging, just tap SHIFT when you see the merge highlighters, as discussed below 2022.05.14.)
2022.08.11 [NEW] With a single selected free point, Shift+Edit Menu displays a new command: "Allow Dragging to Merge." By default this is checked for all free points; choosing it toggles it from checked to unchecked and back. When unchecked, drag-merging does not "begin" when you drag the point over a mergeable target. Use this to permanently disable drag merging for specific control points in your sketch whose intended use consistently triggers unintended merge operations. This setting is saved in, files created in 3056 or later (and only respected by builds 3056 or later). (For a lighterweight disabling of drag merging, just tap SHIFT when you see the merge highlighters, as discussed below 2022.05.14.)
2022.08.11 [NEW] With a single selected free point, Shift+Edit Menu displays a new command: "Allow Dragging to Merge." By default this is checked for all free points; choosing it toggles it from checked to unchecked and back. When unchecked, drag-merging does not "begin" when you drag the point over a mergeable target. Use this to permanently disable drag merging for specific control points in your sketch whose intended use consistently triggers unintended merge operations. This setting is saved in, files created in 3056 or later (and only respected by builds 3056 or later). (For a lighterweight disabling of drag merging, just tap SHIFT when you see the merge highlighters, as discussed below 2022.05.14.)
- triples.h: new optional GObj Triple for points in files, marking them as NOT drag-merge allowable
- skfile.c: reading/writing new optional triple
- gpoints.*, gobjkind.*: new gPoint flag for dragMergePermissibility; new postAllocInit proc for initializing that property
- uic_enum.*, merge_ui.*: new action proc for toggling DragMergePermissibility, which we now also respect when evaluating drags as candidate drag-merges
- uic_appr.c, uic_st.*: SplitMerge appearance proc now queues up new actionProc on suitable Shift+Selections



2022.08.11 [BUGFIX] Print jobs now inherit variant Page Setup settings / page sizes (reported by Peter Blaskiewicz). Problem was we were creating our ondemand custom PrintView using the global "shared" printInfo (page settings), rather than the one stored in the corresponding GSPDocument and therefore targetted by prior Page Setting operations.

- GSPDocument.m: create the PrintView's print operation using the GSPDocument's printInfo

2022.05.14 Shift-Key Cancels "Merge Dragging" for remainder of this drag
- [NEW] [DOCUMENTATION IMPACT] Tapping Shift while Sketchpad is proposing a mergeable destination for that drag cancels that potential merge and any others for the duration of the drag.
Commentary: Designwise, This is problematic in several senses:
        1) ShiftKey potentially conflicts semantically with "15° alignment dragging".
        User may want to snap-merge an aligned drag, or to stop-snapping without
        temporarily swapping in alignment. Neither are categorical disasters, just
        inconveniences, compared to re-writing the API to take another modifier and/or
        bitfield of modifier requests.
     
        2) A point that is inappropriately being targeted as "drag mergeable" in a given
        drag context has a good probability of being re-targeted, equally inappropriately,
        the next time it's dragged, and the time after that, etc. It would be nice to
        have a more permanent state (isDragMergeable) associated with each point, and
        have the modifier key here dynamically retoggle that state and potential terminate
        or initiate a mergeDragging operation based on the retoggle.
        
        3) While permitting merge-cancellation only during an active targetting avoids the
        problem of "I didn't even know I was merge-cancelling while shift-constraining the
        drag earlier, and now my drag won't merge!", it does mean that there's no way to
        avoid SEEING the inappropriate-target-highlighting on every drag you wish to cancel.
        So e.g. if you were demoing a cool sketch that's drag-merge incompatible you are
        going to have unwelcome blinking arrows popping up even on drags in which you intend
        to cancel them.
        
        So, all round, imperfect.
     
        For now, 5/2022, late GSP 5.1, we accept these limitations in the name of
        minimal code movement, provisional API, and diminishing returns, and simply give
        power users this one-tap ability to abort an unfortunately-scoped potential
        merge.

2022.03.09 RDB Dialog & Help Menu
- [NEW] RDB Browser complete
There was a tricky bug here in which the NSTableView at the heart of RDB Dialog displayed corrupt appearances when we requested custom row heights to display MFS items. Turns out descending from GSPDialogController inherits a partial NSTableViewDelegate implementation that services common-code-dialogs, and this partial implementation was conflicting with the partial Delegate implementation we were providing for the RDB resource table. Solution was to isolate the RDB delegate implementation in its own NSObject, inheriting from no one, and instantiating that, rather than the browser's Controller, as the table's delegate.
- [NEW] [DOCUMENTATION IMPACT] Help Menu changes.
    Learning Guide, Reference Center, Sample Sketches & Scripts, and Picture Gallery all return to the Help menu.
    


2022.01.22 RDB/RDL Core Functionality
Got RDB and RDL working at the web-transport/file-open level (RDB browser still bust). Our main approach for sketch-loading here is to customize GSP's NSDocument handling to support http-stream loading of documents rather than just local-file loading, and then implement Charade's RDL/RDB protocols to send RDL-located files to the AppDelegate for loading. This involves customizations of the GSPDocumentController (to diagnose "this URL points to a Sketch document; therefore GSPDocument is the appropriate opener"), as well as to GSPDocument (to permit sourcing a new-document's data from an HTTP:/HTTPS: URLs rather than just from file:// URLs).

    There is some confusion and some anomaly in the previous implementation of things. Despite www.dynamicgeometry.com
    still serving rdb files at their proper locations, GSP 5.06 claims "That URL cannot be accessed" suggesting the
    code has broken somehow, rather than the server.

- [NEW] rdbbrowse_dlg.nib: RDB Browser dialog nib imported from GSP 5.0
- mac_rdbrowse.*: Cocoa-based Controller for previous dialog
- GSPDocumentController.*: new subclass, whose typeForContentsOfURL is capable of informing MacOS that candidate remote-documents (URLs) are actually Sketchpad documents (and therefore should create new GSPDocuments)
- AppDelegate.m: register then subclassed DocumentController as the app's singleton
- GSPDocument.*: refactored readFromData[] so it can be shared with new readFromURL[] override to support http/https-based document loading. Also implemented an "alternate window title" mechanism to help install the optional "preferred document title" that RDB defines in an attempt to allow people to give RDB-hosted documents meaningful local names that are not as restricted as the URLs at which they are stored.
- BookWindowController.m: new windowTitleForDocumentDisplayName override
- 



2022.01.11
- Moved to 3053
- [Mirek] Newly transformed polygon interiors are now created with their perimeter frame visible iff their pre-image parent is displaying its frame at the moment they are created, rather than based on the setting of Preferences | Tools | Frame New Polygon Perimeter (which now only applies to polygons constructed by their vertices using the Polygon Tools or the Construct | Polygon Interior command).
- Help menu "Sketchpad Help" command now correctly launches the Help system, if it is installed.
- Eliminated a variety of diagnostic information inadvertently printed to the console.


2021.10.28
- Build 3050
- Build 3052 FC#1 - Build

2021.10.27
- Wrote a scrolling about box, expanded About Box credits based on GSP 5.0's

2021.10.25
- Moved to 3049

[BUGFIX] Crash on quit if Script View has never been shown.
- scriptviewcontroller.swift: check for range is non-empty before executing

[CLEANUP] Rewrote code to avoid compiler warnings on appropriate ptr->short int casts.
- various

[BUGFIX] Prevented Calculator from taking up useless full-screen (or blacking out the screen background) when entered from a Full Screen'd sketch (a state which also prevented the Calculator from allowing any back-clicked data entry)
- CalculatorWindowController.xib: changed the window collectionBehavior from Inferred to FullScreenAuxiliary

2021.06.14 RELEASE 3048

2021.06.14 Calculator BUGFIXes
[BUGFIX] Prior Calculations inserted into a new expression when defining a new Calculation or Function now appear with in the Calculator Input Pane gray background, indicating they are atomic elements in the new (child) expression, rather than a sequence of tokens. This helps converge the user's sense of an expression's "order of operations" between its separate appearances in the Preview pane (where subexpression precedence is properly indicated by parentheses or geographically-distinct placement within the laid-out expression) and the Input Pane (where each visible element corresponds to a selectable, typable "token" in the expression).

[BUGFIX] Maximizing the Calculator window no longer complete obliterates any access to the Sketch window behind it.

- CalculatorWindowController.xib: added some fairly arbitrary MaxContentDimensions to the calculator to prevent it automatically full-screening on Maximize
- calc_edit_m.m: OS_Calc_RenderAtomicInputToken() now pre-renders the background of unselected atomic tokens in either

2021.06.14
[BUGFIX] Shift+Ctrl+Z and Shift+Ctrl+R now properly trigger Undo All and Redo All, and appear correctly in the Menu Bar as well. Behind the scenes, this requires cooperation behind Mac's UICMenuItem behavior and Mac's menu set builder mnuset_m.c to defeat a Cocoa/Charade menu conventions mismatch in GSP 5.1. Cocoa has case-sensitive keyboard equivalents for menu items, and only one per item, which means UIC_Commands that are modifier-sensitive (e.g. shift sensitive, like UIC_Undo which under Shift becomes Undo All) cannot be accessed by their "primary" (unshifted) command key since Cocoa only dispatches it when Shift is NOT down. SO...mnuset_m.c now works around this by hardcoding a list of such UIC_Commands, and for each of them, wherever they are added to a menu, we add an "alternate" menu item to the same menu, registered to the same UIC Command, with a capitalized version of the keyboard equivalent. Cocoa's "alternate NSMenuItems" only show when their required keyboard modifiers are held down, so this second item -- WITH THE PROPER EQUIVALENT -- appears as an alternate to the first in the menu bar whenver Shift is down, and gets properly dispatched when the Shifted keyEquiv is pressed.

- UICMenuItem.swift: defines "alternate" items that have the Shifted key-equiv but same UIC behavior as some base command
- mnuset_m.m: add "alternate" items wherever we add UIC_Commands that (a) are shift-sensitive and (b) have alphabetic command keys. Currently this list is just UndoAll and RedoAll.

2021.05.25
- Rev'd to 3047
- Modernized lots of code to avoid compiler warnings to the effect that ptr-to-int conversions can now overflow when GSP fetches its stashed (traditionally 32-bit) int values from (now 64-bit) void* pointers.
- BUGFIX: Translating selected objects with the Arrow Key held down over time no longer posts a long stream of "empty" Undo action. Now a single Undo/Redo action summarizes the entire arrow-key-based translation.
(Behind the scenes, we flush pending auto-key repeat events at the end of a tightlooped arrow key translation.)
- Cosmetic. Moving objects with the Arrow Key now temporarily hides the mouse pointer.
- BUGFIX: (José Sala) "SPANISH KEYBOARD" Calculator option+i (which should generate ^) crashes


2021.04.29 RELEASE 3046

2021.04.29 Bugfix: Text Style Menu

[BUGFIX] The Text Style menu's style commands are no longer inappropriately enabled before you have ever selected your first piece of stylable text, and GSP no longer crashes with an "Sketch_MFS_ApplyStyle() called with no frontmost sketch" if you choose from that menu (or choose a text-styling keyboard shortcut, like cmd-I) because it is inappropriately enabled.

- MainMenu.xib: UICommand-managed menus, including those bridged to pre-existing platform-native affordances like these rather than built from a cross-platform menuset, need to be DISABLED by default (with UIC then managing their selective ENABLING).

2021.04.29 New Page Tabs: More Progress (Semi:B); also Minimum Sketch Document Size

[BUGFIX] The page tab panel now occupies 50% of the window width. While there is still no means to adjust this ratio, at least the ratio itself is dynamically preserved as the window resizes.

[BUGFIX] While here, we peg the minimum document window size at 150 x 150 pixels; the previous minimum was "1 old-style tab-width x 0 pixels" which was not a very useful minimum size.

- BookPageTabController.swift
- BookWindowController.xib
- ScrollViewWithSidePanel.swift

2021.04.29 New Page Tabs: More Progress (C. Layout Bug bugfix)

BUGFIX from earlier [2021.04.29] checkin:
> C. Known Bug: 1. New Sketch 2. Resize window narrow and taller than default. 3. Doc Options: Add Page. BUG: Page Tabs appear temporarily misplaced (in the "middle" of the document until the document is next resized.

We refactor so that we now retile the ScrollViewWithSidePanel--fixing the scroll bar and panel sizes to current window geometry---whenever we show or hide the sidepanel.

2021.04.29 New Page Tabs: Progress

BUGFIX from earlier [2021.04.29] checkin:
> A. Old Page Tab Controller still exists and should eventually be removed

Old Page Tabs no longer exist.

- [removed] PageTabController.xib: prototype cell no longer useful
- [removed] PageTabController.swift: old controller no longer useful
- BookWindowController.xib: got rid of CustomView for old page tabs and stackView which managed it
- BookWindowController.m: ditto, as well as API for communicating with the old PageTabController
- BookPageTabController.swift: captured a few notes about resizing for future work


2021.04.29 First Checkin of New Page Tabs

We introduce a new page tab implementation for switching between a document's pages, based largely on the UX of GSP5.0, and fixing several problems with current (5.1-era) design:

* page tabs no longer shrink to unreadability when the number of pages in a document grows beyond a window width's worth of tabs
* page tabs no longer take up vertical space in the document, decreasing the available height of sketch content
* page tabs no "compete for reader's attention" as the top-left contents of newly-opened documents
* page tabs no longer appear for single-page documents

[DOCUMENTATION IMPACT] New Page Tab controllers, very different from early GSP 5.1, somewhat different (specifically wrt Scrolling) from GSP 5.0.

Beneath the hood,  First we subclass NSScrollView to create a ScrollViewWithSidePanel, capable of supporting some other NSView to the left of the horizontal scrollbar. Then we further subclass that with a ScrollViewWithSidePanel, based on a new BookPageTabController that provides GSP5.0-UX access to tabs, augmented by some new-fangled auto-scroll dynamics to eliminate page-tab-scrollers and to keep the current tab "in view"". This new view controller's design is clean and straightforward, but because it is now part of the NSScrollView, it interacts with the outside environment through a different point of connection -- the GSPCanvas rather than the BookWindow. This requires opening up some additional minor API to bridge book-level traffic in document page switching and layout with Canvas-level control of the visual tab display.

As of this checkin, there are still some known defects which we defer to later checkins.

A. Old Page Tab Controller still exists and should eventually be removed
B. There is no interface yet to change the width of a window's tab panel, and if the window is not as wide as the fixed-width tab panel, no room is left for the horizontal scroll bar.
C. Known Bug: 1. New Sketch 2. Resize window narrow and taller than default. 3. Doc Options: Add Page. BUG: Page Tabs appear temporarily misplaced (in the "middle" of the document until the document is next resized.

- BookWindowController.m, GSPCanvas.*: canvas now uses a ScrollViewWithSidePanel, and both Canvas and Book controllers coordinate to make sure canvas-hosted page tabs get updates about common-code-driven page-switching and new-layout activity.

- [NEW] BookPageTabController.swift: the new tab panel
- [NEW] ScrollViewWithSidePanel.swift: the new scrollview, hosting the new tab panel to the left of the horizontal scrollbar

- bookfile.*: Added Book_ShowingTabs() as convenience API for non-C clients (Swift!!) who can't dereference Charade gMem PTRs themselves
- DialogDocOptionsController.swift: Now that Page Tabs can be actually hidden, we "readopt" the GSP5.00 of never displaying page tabs for single page documents, and therefore of DISABLING Doc Options: Show Page Tabs when the document has only a single page.



2021.04.28 Fixed Big Sur Intermittent Crash in CGPatternDrawInContextDelegate()

Sketch drawing uses a CGPattern whose callback needs to access gSketch colors to determine the color to draw. Up to Big Sur, this has always worked problemlessly, because the pattern is created at the beginning of frame-drawing and destroyed at the end of it, meaning the lifetime of the pattern was guaranteeably shorter than the lifetime of the gSketch. Oh, Apple! Now the GPU pipeline is prone to still execute CoreGraphics rendering long after the client requesting them has shutdown, meaning a CATransaction's downstream committal may render a pattern requesting gSketch access even after the gSketch and the NSWindow containing it have both been disposed. (Of course that rendering will never make it to the screen, but that's the nature of delayed and/or speculative operations.) The symptom is a set of recently-reported crashes whose stacklog prominently features CGPatternDrawInContextDelegate() deep within a callchain stemming from some sort of deferred rendering operation initiated by the CFRunLoop rather than by Sketchpad code.

The fix is to revise our pattern renderer to cache its own copy of the color it needs, rather than ask gSketch for that color, and to then dispose the color when it gets its own renderer-specific kiss-of-death, rather than when its owning sketch's renderProc decides rendering is done. This permits CoreGraphics to Retain a copy of the pattern past the end of sketch for whatever purposes it needs them for, without risking having the renderer access de-allocated memory in the event the gSketch has disappeared.

- draw_apple.*: revised Apple_DrawInteriorSelectionPattern() to use a cached copy of the gSketch.selectionColor, rather than reference gSketch; and added a parallel Apple_ReleaseInteriorSelectionPatternState callback to dispose of that cached state when the pattern is given its OS-triggered kiss-of-death.

2021.04.21 Debugging undisposed MFS Text at program quit

For Charade running in the modern era (2020s), any MFS_TextNode allocation has UTF16 storage, so our 8-byte "ascii preview" of an allocations shows us only the first four characters ... not enough to be very helpful. So we manually diagnose MFS_TextNode contents (by callerCharID signature) and print out up the first 1024 UNICODE characters associated with them to console for extra debugging help.

- gmem_a.c: CHARADE_CLIENT_SKETCHPAD-time enhanced debug output for undisposed MFS_TextNodes()

2021.04.21 ScriptView shutdown

**BUGFIX** Assert at Quit on gMem overallocation after any session that involves a script.

The problem here is lazy-shutdown of WindowControllers at program quit; we have to manually dealloc MFS from the ScriptViewController singleton before our gMem "all allocations are disposed" debug-time warning, because MacOS--knowing it's heading toward quit---is "too lazy" to deallocate it itself.

- AppDelegate.m: invoke new ScriptViewController.shutdown
- ScriptViewController.swift: manually dispose MFS from scriptview when shutting down


2021.04.21 Build 3045

- Rev'd to 3045

2021.04.16 Build 3044
- Added support for Build | GSP (Any Mac) & archiving



2021.02.18 Drawing/Scrolling Improvements

**BUGFIX** Scrolling to new regions of the sketch plane no longer risks showing partial "stale" contents, e.g. parts of selection markers along objects that are no selected, etc.

**BUGFIX** Scrolling to new regions of the sketch plane no longer fails to show dotted or dashed axes newly revealed in those parts of the plane.

In general, both of these fixes involve reducing Mac-rendering's reliance on SketchRect as an effective clipping frame for visible content. NSScrollView's speculative draw mechanisms ("responsive scrolling") means the view, and therefore drawing, can be temporarily expanded outside of the window-visible portion of the view (i.e. SketchRect).

- draw_apple.m: OS_Draw_UpdateViewFromDirtyRect() now passes the entire primal dirtyRect on to NSView-dirtification. This is subtle because we still want to make sure we're going to manually update the scrollbars if nothing needs to be drawn as a result of our dirtying, and NSScrollView is not frank about what it will need to redraw. So we conservatively manually update the scrollbar unless we are GUARANTEEABLY going to redraw (i.e. dirtying actual, onscreen/in-sketchRect, content NOW).

- render_apple.c: AxisKind_RenderProc() no longer alternates between drawing to the clipRect or the sketchRect to provide stability to dashed-line origins; instead it always passes the clipRect on to lower-level primitives and expects them to draw correctly

- render_axis.c: renderVerticalAxis() and renderHorizonalAxis() now render non-solid axes to the edge of the integer plane, in order to maintain stable dash-patterns on them regardless of clip domain. This is technically a Quartz-specific "enhancement" entering common code; if we ever instead ever want to factor it out, then the renderXXXAxis() prims should take take separate lineDrawBounds and dashTickNumberingClipBounds arguments rather than the single lineClipBounds argument it takes now. In that case, Mac/Quartz/render_apple.c:AxisKind_RenderProc() could go back to passing clipBounds for both, for solid-or-gExported cases, or planeBounds&clipBounds separately, for dashed/non-Exported cases.




2021.02.16 SR-39 Bugfixing: MFS Overbar Color

BUGFIX (SR-39) Overbars (from measurements and captions) exported to PDF (copy/paste or print) no longer occasionally inherit an inappropriate color setting from nearby objects.

- mfs_overbar.c: adopted MFS_OS_RenderCOlor() and _ClearColor() protocols to guarantee OS pen-color is consistent for overbars with intended rendering context, rather than with last-rendering-context used.
- mfs_platform_apple.m: conditionalized NSLog() to GSP_DEBUG

2021.01.29 First-ever APPLE SILICON build (M1)

- added a new XCode Build Scheme, "Release!!!", that builds universal release code (turning off GSP_DEBUG in our source as well as lots of system-level debugging enabled by our previous scheme, which I've renamed "Debug on this machine (intel or arm64)")
- cleaned up compiler warnings for unused-except-at-DEBUG-time variables, using the preferred C/C++/ObjC idiom
        (void) varName; // "use it" to suppress unused variable warnings in non-DEBUG builds
- fixed a variety of Swift concerns and errors with debug
- conditionalized align_debug.c explicitly to only appear in DEBUG builds, as per design, using a Target GSP/Build Settings/Build Options/Excluded Source File Names to remove it, conditionally on RELEASE, from the master list (Build Phase/Compile Sources) of files to compile which, itself, cannot be conditionalized on RELEASE vs. DEBUG




2021.01.14 URL Link Properties enabling fix

[BUGFIX] The URL field in Properties:Link is no longer permanently disabled when first creating a new URL Link Action Button in a multi-page document.

- build.h, project.pbxproj - moved to 3043
- projects_link.nib: warning cleanup: rev'd to Current Deployment Target
- mac_propsheets.m: explicitly recompute URL edittext enabling on dialog change


2021.01.05 Build 3042
- build.h
- project.pbxproj

2021.01.05 Printing!

[NEW FEATURES] GSP 5.0's Print Preview has been replaced by a "Sketchpad panel" in the standard Print dialog box, which offers choice of scaled vs. unscaled printing, convenient access to Orientation, and the ability to choose between the area visible in the current window, or the area of all objects (trimmed of extended lengths), or the area of all objects including extended lengths (if there are any such objects). The most notable differences here from old functionality are:
1) the settings are dynamically determined on every Print invocation to choose the best possible single-page printout for your current work.
2) the "current window view" option gives you an easier/better way to control arbitrary clipping than Print Preview did, and also naturally corresponds to the view you most likely want to clip to, if you want to clip (since many sketches are "laid out" to include their interesting contents directly in their window view).
While this interface does NOT directly include GSP5.0's ability to set an arbitrarily-scaled print area larger than a window view, technically this is still accessible through GSP5.1's window-view-rescaling (pinch gesture zooming) followed by window-view-printing. That doesn't sound very workable ... but nor ever was GSP 5.0 Print Preview's mechanism!

- PrintPanelAccessoryView.xib, PrintPanelAccessoryViewController.swift: : our custom "Sketchpad panel" in the Print dialog box
- SketchpadPrintSetupProtocol.h
- GSPCanvas.*: PrintableView now subclasses InternalCanvas, so it can use basic GSP rendering
- GSPDocument.m: print menu dispatch

2021.01.04 First Metal Implementation of Custom Picture Transforms

CHANGE: Sampled Transformed Pictures now render using Apple's Metal graphics architecture, and so benefit from GPU acceleration. This returns them to nearly the speed they had during OpenGL days, and opens the way to (considerable) further pipeline improvements in graphics rendering speed.

- ftr_chrd.h: PLATFORM_MAC now SUPPORTS_ACCELERATED_GRAPHICS again, but no longer SUPPORTS_OPENGL

- apple_drawingcontext.h, apple_offscreen.h, render_apple.c: updated comments to describe new graphics architecture
- [NEW] AppleCore/graphics/metal/shader_definitions.h, apple_metal_metapixelrender.swift, shaders.metal, apple_offscreenrender.m: Metal-based replacement for the old OpenGL implementation of apple_offscreenrender.h.
- render_apple.c: fixed bug in which code did not dynamically fail from accelerated to non-accelerated rendering when the accelerator was not up to the task
- about_st.c: removed OpenGL

- project.pbxproj: removed former Accelerated Graphics renderer and numerous OpenGL support files, headers, and frameworks

- mac_advancedprefs.m: fixed GSP5.1-dev-era bug in which Advanced Prefs/System/Accelerated Graphics stopped working
- advanced_prefs.nib: changed "OpenGL graphics acceleration" to "Accelerated graphics (Metal)"
- GSP-Bridging-Header.h: swift eats more C

2021.01.04 Memory Leak Cleanup

Fixed a few memory leaks in custom tool loading and error reporting.

- DialogGetCustomToolNameController.swift
- DialogDocOptionsController.swift
- DirectoryScanner.swift
- SwiftUtils.swift
- ScriptViewController.swift


2020.12.30 Custom Tools menu alphabetization

We now present files in alphabetical order in the Custom Tools menu, although -- as in GSP5.0 -- subdirectories' tools now appear as "alphabetical inserts" in their superdirectory's alphabeticization. This is not quite ideal; it would work best if we had a hierarchical tool menu rather than a flat one.

- DirectoryScanner.swift: sort scanned directory's paths before touring them!


2020.12.16 Toolplay Point-On-Object Failures
 
First we fix the BZ474 fix, which introduced a regression in which toolplay'd points-on-objects always jumped to "zero position" on their path when a tentatively-matched ancestor (not necessarily the path) was, as a result of actual click-confirmation, late-matched to a pre-existing object. This manifest in a variety of reports:

- Poincaré Disk:Hyperbolic Angle tool failed when VERTEX of three-point given angle was a pre-existing object.
- Nick's BF_PCD_ToolplayBug.gsp test sketch, a slimmed down replicable.
- Scott's 506_Random Point Bug.gsp.

From code comments,
         Revised 16-Dec-20 (GSP3042). The previous iteration of this bugfix tested
         isToolplayTentativeMatch, which definitely randomized authentic points-on-objects
         created during tooling, but failed to randomize them in the case we were re-allocating
         productions and pre-existing given that had been confirmed in place of a tentative one.
         In that case, the allocated production descendents were NOT tentative toolplay matches,
         and so we failed to randomize. This is Brad Findell's 5.05/5.06 Poincaré Disk bug, among
         others.

Then we separately fix another instance of "hopping of random points" on completion of toolplay, which manifests in the same set of test cases. When a produced point-on-object is first randomized as a tentative allocation, its path is very likely non-existing (all tentative objs are first allocated as non-existing). But when the same point-on-object is REPRODUCED in the late-confirmation production chain of a tentative given replaced by a pre-existing given, the parental path may well exist (may potentially even pre-exist). But non-existing paths lead to different randomization behaviors than existing paths, even for identical randomization seeds, so our careful attempt to randomize the "late replacement" point-on-object IDENTICALLY to the earlier tentative point-on-object fails...and the result "hops."

We fix this by the potentially-risky act of momentarily switching the path to non-existing, regardless of its sketch status, before randomization, to guarantee an identical code path of random decisions through anyPath.setRandomPosition() and therefore to guarantee an identically-produced random result. (We switch the path "back" to its former existence immediately after.) This means now late-confirmation remapped points-on-path never take into account how their path intersects the viewRect, which means points-on-lines, -rays, and -infinite loci are more likely to wind up outside of the view. Our rationale for doing that is that we ALREADY ignored that for the point-on-object when it was still a tentative match; and only heeded it in the case the path existed during a hop-calculation. So by uniformly eliminating last-minute hops we eliminate, in some much less frequent cases, a hop to "a more visible location."

- toolplay.c: improved BZ474 (fixing Hyperbolic Angle); also eliminated a point-on-object toolplay hop in late-matching to a pre-existing Given

2020.06.04 Build 3040

2020.05.03 Assert & Crash-Fixing: InsetRect_UTIL() and UIC_ExecuteCommand()

First we fix a 3038-introduced problem which is the frequent Assertion

    InsetRect_UTIL() overflowed INT_Coord
    
in numerous situations opening and dragging sketches, and a variety of crashes in which this assertion does not appear but that relate to the difficulty Cocoa has showing assertion dialog boxes in certain circumstances.

The new scrolling logic of 3038 "inflates" the maximal bounds of a sketch by a small fraction to guarantee "theoretically thin but practically thick" contents are fully-scrollable, but for some classes of objects (e.g. certain function plots), the maximal bounds of a sketch will be "as big as you can get" so the attempt to further inflate will fail, which asserts, which often crashes.  The fix is to only inflate bounds smaller than the theoretical maximum; after that, sketch content (e.g. those function plots, which continue to infinity) is theoretically unreachable.

BUGS FIXED:
- InsetRect_UTIL() overflowed INT_Coord
- (SS) "Crash pasting bitmap from the Preview window"
- (DS) "Dragging unit point in ExploringPolynomials.gsp crashes"

Then we fix an problem which has appeared in a variety of guises since GSP 5.1 began, but which has shown in several user reports recently under most common symptom:

    UIC_ExecuteCommand[] being called to execute a disabled static command
    
However, there are a broad number of other asserts and crash conditions possible from the underlying defect, which is that GSP 5.1 cannot, under Cocoa's architecture, verify that the menus are entirely up to date with ever changing dynamic sketch commands immediately prior to the user's choice of menu command or command-key-dispatch. Instead these happen in two independent processes. Because the menu re-enabling happens quickly after sketch conditions change, usually the menus are up to date when you choose from them, but in bogged-down conditions, it is possible to dispatch menu commands based on out of date menu appearances. Thus if you Cmd-L and Cmd-M in fast repeated sequence a sketch of hundreds of selecting animating points, eventually you may see ParentGenusTemplate violation assertions coming from commands "fielded" by the UI when the menus were enabled but "dispatched" to common code those commands are logically disabled.

Mac GSP5.0 fit UIC design without this problem because it "owned" the fielding of menu-clicks and command-keys and could pre-validate the UI just before permitting these events.  In GSP5.1, Cocoa owns the UI so validation happens asynchronously. To fix the bug, therefore, we post-validate, which is to say after receiving a UIC-dispatch request for Cocoa we make sure that command is up-to-date in its theoretically validity before actually giving it to common code to execute. This requires access to some unexposed UIC state and therefore we add a helper utility to uicommand() rather than dig around in its internals at the Mac layer.

BUGS FIXED:
- (DS) "In the attached sketch (3038_ExploringPolynomials.gsp), dragging the unit point back and forth causes the sketch to lock up. Not sure why—the sketch seems, on the surface, to be pretty mundane."
- (RP) "Pasting a graphic seems to cause this [assert] sporadically"
- (SR-27) "Assert deleting Polygon Interior with Cmd-X"
- (JN) "UIC_ExecuteCommand[] being called to execute a disabled static command (xx).


- build.h: moved to 3039
- uicommand.*: added UIC_SafeExecuteCommand
- UICMenuItem.swift: called UIC_SafeExecuteCommand() instead of UIC_ExecuteCommand()
- GSPCanvas.m: called SafeInsetRect_UTIL() rather than InsetRect_UTIL() when inflating documentBounds


2020.04.06 Build 3038
- build.h, etc.

2020.04.06 Infinite Trackpad Scrollability & Trace-Drawing Speedup

CHANGE: Two-fingered scrolling on the trackpad now scrolls "off into space" beyond the farthest scroll-bar-reachable geometry, equally in both horizontal and vertical "directions."

Also, we track down a tremendous slow-down in our tracing strategy compared to 5.0x created by modern build's approach to Retina screens. On Retina, depending on the size of the (accumulated) traces and the size of the per-frame changes to foreground moving geometry during an animation, the individual cost of rendering a single traced frame could be up to 40x slower than in GSP 5.0x, resulting in a net animation slowdown more on the order of 1.1 - 1.5x ... still slow enough to be noticeable. The fact that this slowdown was highly dependent on two semi-independent parameters, both of which evolve over the course of animation, also meant that certain "moire patterns" would occur in the biparametric phase space of these parameters' dynamic evolution, resulting in the appearance of contracting/stuttering "now-we-slow-down / now-we-speed-up" effects on animations. All this is fixed and tracing returns to GSP 5.0x speeds.


BUGFIX: Stuttering Animation.gsp "dissolves into a dotted trace" and seems "very slow compared to what I recall from my past experience."

BUGFIX: Hyperbola Trace.gsp's (traced) animation seems considerably more sluggish on 3036 compared to 5.06

- apple_paintlayer.m: in our lowest level tracebitmap blitter, we turn off interpolation in the receiving context, which keeps retina displays from trying to synthesize bits we never captured in the first place. This seems cosmetically unnoticeable (since for example our trace bitmaps don't contain small-font-size text, or other appearances where retina-grade resolution seems highly consequential) and eliminates an up to 40x slowdown in the actual blit!

- GSPCanvas.m: Changed our scrollBars elasticity from None to Allowed, which permits them to scroll off the end of the plane.

2020.04.06 Misc Fixes

- Dark Mode: Fixed Color Menu checkmark's poor appearance in Light Mode since last build

- BUGFIX: Various asserts on opening unobjectionable sketch (DiscretePoints2.gsp): "LoadSketchOrScript() called with nil gBuffer" and/or "CircleParamToArcParam tCircle param logic error"

- BUGFIX: (SR-26) Crash exiting Doc Options after deleting the active sketch page, when Doc Options was originally invoked by Document Context menu right-click rather than File Menu

- arc.c: Quieted a CircleParamToArcParam() assertion which overloudly identifies a rounding-error situation anticipated and rectified by downstream code. (The sketch provoking this does so in the context of arc-locus intersections, a relatively undertested configuration involving heavy linear approximations and therefore heavier potentials for round-off error than the arc-parameter code originally anticipated it would encounter.)

- ColorMenuItemView.swift: Changed Color Menu checkmark from SelectedTextColor (which is good in Dark but bad in Light) to just Text Color (good in both)

- GSPCanvas.m: gspMouseDown now abandons save/restore of gSketch around SketchMousePress/SketchMouseDoubleClick() since these can, in theory, restore a gSketch which no longer exists (if press invokes DocContext which closes or DocOption:Deletes the prev gSketch). We now target gFrontmost on entry and don't retarget anything after SketchMouseXX.

- UICMenuItem.swift: UICItem.dispatchCommand() now abandons save/restore of gSketch around UIC_ExecuteCommand() since this can, in theory, restore a gSketch which no longer exists (if comment involves Close, or DocOption:DeletePage, etc., of the prev gSketch). We now target gFrontmost on entry and don't retarget anything after command Execution.



2020.04.05 Dark Mode

This checkin adds better support for Dark Mode on Mojave and later versions of Mac OS, including explicit changes to:
- About Sketchpad/Copyright&Beta Warning Text
- Preferences/"Apply To" text
- Properties/Animate Panel/Background color of list of animated Points & Parameters
- [KCPMFSField] Plot Value, Plot Curve, Transforms, Properties/Object Panel/Object Description, Calculator Expression Preview Pane, and multiple other dialogs: text color and the pink background used to indicate a dialog-box input field which can be populated by a backclicked Object (and/or a number value),
- Iterate: "Mappings" field
- Color menu (Display Menu, Text Style Palette) checkmarks for active color choice
- Object Info balloon hyperlinks
- Properties/Object Panel/Object Description Text hyperlinks
- Toolbox / appearances of large and small tool icons. Toolbox appearances could use more work, e.g. customization of the individual tool icons by a graphic artist rather than just background recoloration, but at least are "darker" than they have been in previous builds.
Please log cosmetic bugs against other parts of the user interface that you find objectionable or illegible in Dark Mode!

BUGFIX: Dark Mode: It's difficult to read the [Calculator Expression Display] Panel b/c of the dark grey background
BUGFIX: Some text renders with incorrect colors for macOS Dark Mode. Examples are the Calculate dialog (black-on-black), About dialog (white-on-white).

BUGFIX: Fixed a minor coloration bug in which colored text was rendered theoretically incorrectly (R, G, B values all about .4% off)

- mfs_platform_apple.m: fixed platform calculation of effective (RGB) from MFS_Style-encoding
- mac_dialogutils.m: fixed a minor platform miscalculation of MFSStyle from RGBColor in Mac_DialogUtil_SetMFSStyleColorFromNSColor()
- hypermfs.c, balloon_mfs.c: default hyper link text is now more midtone, legible against both dark and light backgrounds
- iter_ui.h: OS_IterateUI_PredrawGObjField() is now documented as able to modify the renderContext provided it maintains metric stability of that context's prior measurements
- iter_ui_m.m: Mac's OS_IterateUI_PredrawGObjField() now leaves the pen in ControlTextColor, rather than Black, so that the DrawnGObjField's content is legible against the current Appearance background
- [new] toolbox.xcassets: moved toolbox icon background images (big/small vs. up/down) into an asset catalog, added Dark Mode versions of them which use Affinity Photo's Levels to reduce "Output White Level: 50%"
- colors.xcassets/BackclickableMFSField_ActiveBackColor.colorset: added DarkMode appearance to KCPMFSField backclickable items
- properties_animate.nib: changed Anim Panel background color to TextBackgroundColor from White
- splash.xib: changed text from ControlTextColor to BlackColor so it always stands off white backdrop
- mac_prefs.m: "Apply To" statText enabling/disabling now switches to ControlTextColor rather than BlackColor for enabled
- KCPMFSField.h, KCPMFSField.m: KCPMFSFields now expose a new member, recolorBaseStyleToSystemControlTextColor, which controls (default: true) if the MFS they draw gets drawn in the baseStyle as set by the caller, or in a baseStyle which is dynamically-recolored to controlTextColor (which the system dynamically updates on Light/Dark Mode appearance change)
- ToolButton.swift: now implements updateLayer(), which is documented as called on Light/Dark Mode change, to refretch a button's BackgroundImage from the new toolbox asset file (which will dynamically retarget the new mode's specific image)
- ColorMenuItemView.swift: checkmarks in Color Menu now drawn in selectedMenuItemTextColor rather than in default CGContext color (Black)

- GSPCanvas.m: removed a debugging assert inadvertently checked in recently



2020.04.01 Picture Pasting Improvements

BUGFIX: Pasting a Cut or Copied clipboard "clipping" that includes more than one object at least one of which is a Picture no longer fails after a string of error messages.

Internally, this has been broken since the dawn of GSP5+, under an evolving list of failures. Historically (back to GSP5.00), picturesGObj on clipboards differentiate into the "single picture gobj", which is exported to clip simply as a raw picture (no GObj) for supremacy of pasting, and "pictureGObj-within-sketch-stream" formats. The latter format, in which the bug occurs, has historically differed from saved sketches, where all pictureGObjs-in-stream store their pictureimages as a simple index into a separately-exported, document-wide master table of pictures. Clippings pictureGObjs-in-streams, by contrast, store their picture images as supplemental triples directly following the pictureGObj stream info. So far so good. Now we move to GSP5+ era. SPiOS has no clipboard, so old code for handling "pictureData as supplemental triple in stream," and the corresponding platform callout, is never modernized. In GSP3011, we discover that we can't handle old-style MacPICTs coming from GSP4-era documents, and implement a fix for that which involves the same platform callout. However, a bug in that fix causes us to assume that all code reaching it is MacPICT, rather than more modern formats. Now we come to this bug, which feeds that callout modern PNGs that are coming from supplemental-triples-mid-clipStream rather than supplemental-triples-from-old-GSP4-documents. Amazingly, the code works, because the lowest-level MacOS PICT importer turns out to parse PNGs well too! BUT: where PICTS are always even in byte size, PNGS can be odd-byte-size, and a separate bug in our platform callout fails to advance the stream by physical (even) size, only by logical (potentially odd) size, as it consumes the triple. So the net result is the bug: if we feed our old PICT-importing callout new PNG data, which we only do in the event of clipboard fragments containing a PictureGObj along with other gobjs, it correctly reconstructs the image but then mistracks the stream, leading to cascading failure of the entire PasteOp.

The fix is easier than the diagnosis. Update the platform callout to properly diagnose both PICTS and PNGS as formats it can handle, rejecting other formats (e.g. GSP4 WindowsMetaFile), and make sure that it advances the stream by the physical triple size rather than the logical size.

- picturegobj_apple.m: fixed OS_Picture_ReadOneImageDataTriple() to track stream properly and to correctly diagnose MacPICT (from GSP4) vs. PNG (from GSP5 multi-gobj clipboard fragments) vs. Unsupported Formats (e.g. from GSP4 WindowsMetaFile pictures).

2020.03.30 Touchpad Scrolling Improvements

We fix at least two bugs with touchpad two-finger scrolling, as well potentially as with a variety of other inut devices (scrollwheels and scroll buttons of various sorts on various mouse peripherals):

BUGFIX: Horizontal scrolling no longer fails on touchpads in situations where vertical scrolling succeeds.
BUGFIX: Two-fingered scroll-bar scrolling no longer "judders and trembles" tremendously when you arrive at the edge of the scrollable region.

The cost of these improvements is that trackpad scrolling no longer allows you to scroll "off the edge" of the scrollable area into infinite blank space. If you want to reach into blank space "beyond" the extent of the most extremely-distant object in any direction, you will have to option-drag to yourself further into the void. See "Drag-Scrolling" at sketchhelp://Reference%20Center/index.html?shortcuts_specialkeys.htm for more information.

On the bright side, this now permits mouse-drags to properly survive trackpad-scrolling. So you can continue dragging objects, or creating objects with tools, "off the edge" of the visible canvas using two-finger-trackpad-scrolling without having to "put down your tool" first.

As well,

MINOR BUGFIX: Sketchpad no longer cuts off the "very edges" of the appearance of certain finite objects (like big circles or long segments) at the extreme edge of the scrollable region, especially when these objects are thick and/or selected in their display. Now any finite object visible in the sketch can be scrolled "fully"" into view.

Internally, we change the Elasticity setting of both scroll-bars to match (eliminating the first bug), and add a scrollWheel handler to InternalCanvas, which both defeats 10.9's new "responsive scrolling" -- which causes no end of rendering problems and canvas inconsistencies at the border -- and permits Sketchpad's mouse-actions

- GSPCanvas.m: turn off elasticity,
- GSPCanvas.swift: override scrollWheel() to defeat Responsive Scrolling & track drag-in-progress across scroll

2020.03.26 Text Input Improvements

* Dead keys work during caption editing to permit accented characters, like GSP 5.0
* (NEW) Dead keys now preview diacritics -- e.g. option+tilde followed by "e" first shows the back-accent then shows é
* (NEW) Enhanced input palettes for non-Roman characters / alphabets now work at least somewhat during caption editing -- best US keyboard example is long-press "e" now shows pop-up palette of diacritical variants é, è, ë, ê, etc.
* (NEW) Apple's Keyboard Dictation now works during caption-editing: start editing a caption, then choose Edit | Start Dictation or use the shortcut key to start listening; then dictate freely and Sketchpad transcribes your thoughts poorly :-). You can improve things with System Preferences | Keyboard | Dictation | Use Enhanced Dictation.

BUGFIX: Can no longer type composed character/character accepts into MFS Captions. Try typing Nadège using either long-press-e (which didn't work in 5.0x) or option-tilde-e (which did). This probably has dire consequences for international users who use composed characters a lot more (e.g. Chinese input).

BUGFIX: The only problem that I have is that for some reason I am not able to write in Portuguese, with our accents… ã, á and so on…

Beneath the hood, we revise our Cocoa text handling. Previously InternalCanvas, a private subview of GSPCanvas, handled our keyboard traffic entirely through keyDown:, which has no dead-key support. Now we revise InternalCanvas to be a full-fledged implementor of the NSTextInputClient protocol, which is the "thermonuclear option" of Apple's designated levels of app-support for multilingual text. (The lower levels delegate more authority to MacOS than Sketchpad is prepared to give, since Sketchpad's caption-editor is fundamentally a math-text editor--our proprietary MFS technology---with good captioning support rather than a generic Mac text-entry box with excellent text-support but zero math-layout support). Unfortunately this level of buy-in has three fundamental problems. The API is inadequately documented (most documents are obsolete or transitional); the Apple-side of the API contract is  demonstrably buggy (in Apple's apps as well as our own); and full app support for the mandatory API would require changes deep inside the cross-platform MFS editing engine which we are unwilling/unable to make for 5.1. So rather than "embrace" the NSTextInputClient API, we attempt a fairly minimal adoption, following some online precedent of other app instances---e.g. OpenGL games---that want international keyboard input but are unwilling to hand over their entire text handling to Apple's NSTextView widgetry. The first two problems are typical problems dealing with Cocoa -- which is junk --- anytime, but the latter is a problem of deploying a common-code architecture on an advanced platform like MacOS, so we give it some airtime here:

Architecturally, Apple's NSTextInputContext (which I think of as some sort of language-and-keyboard-specific behavior, logic, and UI model provided by the OS) wants to talk to an NSTextInputClient (in this case, Sketchpad), through a virtual text model in which text is a linear indexed sequence of Unicode codepoints that the NSTextInputContext can arbitrarily select, "mark," delete, and replace in, where "marking" is some sort of provisional visual indication of text-actively-being-input-whose-final-form-is-not-entirely-determined". MFS in theory could conform to that requirement, since it maintains a linear sequence of token positions (not always unicode characters), and supports (most of the time) selection, deletion, and replacement within them, as well as the ability to perform syntactic highlighting of the form other NSTextInputClients often associated with "marked text" (underlining, coloring, etc.), but it would be a major chore, for several reasons. First, at the moment of caption editing, the platform is far removed from MFS internals: platform talks to Charade (Key_HandleTextKey), which talks to the Sketch (SketchMFS), which talks to MFS_Edit, which talks to MFS. Only in the last of these conversations is anyone paying attention to MFS's token-sequencing. Additionally, SketchMFS and MFS_Edit both want to think of MFS's entire gamut of style capabilities as within the users' control rather than any procedural caller's, which is incompatible with the idea of purposing some of those capabilities toward depicting "marked text" separate from user-formatted stylistic variations. (For instance, trivially, "marked text's" color or underlining would appear in the Text Style Palette as a user-set, and worse: user-unsettable!, formatting "option" rather than a fundamental attribute of the text-editing process.)

So rather than attempt this graft, we keep the platform far removed from MFS's internals, and instead implement NSTextInputClient as if its marked text requirements all always took place immediately around the most-recently entered text in a linear sequence of text. In this simplified model, insertions happen always and only at the current insertion point, and deletions always happen "just before" the insertion point. So where the TextInputContext says "delete a provisional accent one-character wide at location #X and then insert an accented vowel at location #Y where #X happens to equal #Y", GSP interprets these commands as "delete one character at the current insertion point, then insert an accented vowel at the current insertion point." It's like we're paying attention only to the first derivative, relocating all edits, and all requests to show or position pop-up palettes, outside of the global text address space spoken by the OS to the current MFS insertion point, wherever that may be" Fortunately, this works shockingly well for English and I suspect for most other Western keyboard/language combinations--and as a result, this checkin provides better performance in English & French than GSP 5.0 ever did, and arguably better performance than current versions of XCode, Mail, or Word do on Mojave. I suspect its inadequacies surface quickly under the more advanced requirements that NSTextInputContext's API virtualizes, like Japanese Katakana or Chinese Cangie, but don't have the linguistic knowledge to test these or, necessarily, the ability to address them without better documentation and without violating my (self-imposed) decision to NOT refactor MFS and all of its onion levels to accommodate Mac text input at its lowest-level. So the hope is, if we set the 5.1 goal as "at least as functional as 5.0," we have not only met but surpassed that, and broadened access to multi-national text considerably, while (like GSP 5.0 and all earlier) fundamentally recognizing we don't support all the world's languages and Apple's preferred ways of inputting them.




2020.03.22 Properties Bugfixes

BUGFIX: 1) If you create a Presentation button that presents actions sequentially, you cannot enter the # of seconds to pause between actions.
BUGFIX: 2) If you create a Presentation button that presents actions simultaneously and choose “elapsed time,” you cannot enter the desired elapsed time.

This dialog is classic examples of the operational inefficiency that the postSyncUpdating pattern was introduced in early GSP 5.1 to address: Properties previously flushed all data from all pages from Charade cache to platform controls on every platform-instigated control interaction, all to monitor the possibility that the user had changed from Simultaneous to Sequential (or vice versa) and therefore needed to refresh some control visibility.  The postSyncUpdating pattern allows a specific dialog to report this requirement if it is too lazy to handle post-sync updating outside of CopyControlsToDate(); we know have Properties declare this pattern for its Presentation Button panel.
    
BUGFIX: Enter Obj Properties; press and hold a blue hyperlink, and press ESC while holding it. You will crash shortly thereafter.

This is more sinister. Normally hyperlink-tracking is shutdown by the Object Description Text control when it is deallocated, but Cocoa is choosing not to deallocate this control as part of dialog-shutdown, and instead holds it until a later drainage of some autorelease-pool that happens back in the main run loop long after gSketch---and therefore the ability to shutdown BackTracking---has gone out of scope. So we expose a 'manual shutdown' API for hyperlinks in KCPMFSField, and call it when deallocating the Properties dialog (which DOES happen at the correct moment as soon as runModal() exits, when gSketch is still in scope).  Cocoa cocoa cocoa -- who could ever right a real app in you?

- build.h: rev'd to 3037
- mac_propsheets.m: PresentationButton panel now requiresPostSyncUpdatingAfterEvenSelfOriginDataChanges(), in order to manage visibility of subsidiary platform controls

- KCPMFSField.m, KCPMFSField.h: added and exposed shutdownHyperlinkTracking
- mac_properties.m: Properties:Object panel's Object Description Text now shuts down hyperlink tracking on dialog-dealloc



2020.03.10 Build 3036

2020.03.10 Memory Leak on ink

BUGFIX: gMem overallocation assert determined by any successful use of Ink tool. Problem is OS_Ink_HandleEvent()'s call to PictureGObj_ImportPlatformPicture() fails to consume or own the original bits from PaintLayer_Create32BitBitmap(), unlike in GSP5.00, so those get orphaned. Problem is either there or in building the NSImage (an unintentional data copy?).

Problem was an undisposed CGBitmap() used as a temporary bit buffer in a long series of bit <-> cgImage <-> nsImage <-> bitmap <-> Blob transformations. CGBitmaps() are not autoreleased objects; they're manually allocated and disposed.

- ink_m.m: added unconditional CGBitmap_Dispose() to ink finalization



2020.03.10 Sketch dirtification post-RelabelMultiple dialog

BUGFIX: Open a saved sketch with labeled objects visible. Select multiple labeled objects and choose Edit | Relabel. Relabel them using this dialog. Close sketch. Sketchpad fails to ask you if you want to save.

This bug, sleuthed thanks to hard work by Scott, dates back to the dawn of the multirelabel dialog, and the difficult fix, accomplished by Nick, unequivocally establishes GSP 5.1 as the most superior product ever released in the history of time. The superiorest.

- dlg_multilabel.c: added Book_MarkModified_UTIL()

2020.03.10 BUGFIX: RGB Value Preservation

BUGFIX:"In the attached sketch, I’ve been trying to color the three points with R, G, B values of 0, 161, 187 (MHE’s official blue for Illustrative Math). But the values don’t stick when I make the change. They revert to 0, 176, 199."

To preserve round-trip RGB value fidelity from the Color Chooser dialog box,  we switch locally to genericRGB colorSpace profiles rather than deviceRGB ones, despite deviceRGB being historically used throughout. Longer source comments discuss history and potential consequences of new decision, which introduces asymmetry in colorSpace assumptions but at a semantic level-switch rather than within a single component application (e.g. within drawing).

- NSColor+GSP.swift: switched from deviceRGB to genericRGB


2020.03.06 Mouse Problems Pressing HyperLinks in Properties:Objects

BUGFIX: In Properties:Object Panel, the blue links hover properly but occasionally clicking on them fail to work as links.

This bug became very pronounced in 3035 (in fact, first was reliably diagnosed there) but is latent and occasionally visible in earlier builds dating back to 5.06. Properties' Object Info link tracking relies on BackTracking to simulate "mouse move" events and does so buggily, inadvertently clearing the tracking-cycle mid-press in a way that cancels mouseUps from being interpreted as "link clicks." The recently revised dialog event traffic changes made the bug much more pronounced.

- KCPMFSField.m: BackTrackMouseMoved() now knows whether the hyperlinks are being tracked in mouseDown or mouseUp states, and simulates mouseDragged instead of mouseMoved where appropriate.


2020.03.06 Crash on Cancelling Doc Options

BUGFIX: SR-22. In Doc Options, did a new blank page. Gave it a name. Then changed my mind and hit CANCEL and Sketchpad crashed.

Problem was introduced in 2/10 checkin ("BUGFIX: If a single document includes both light-backgroudn and dark-background sketches..."), where Mac OS_Book_pageHasSwitched() mistakenly assumed that a switched page was a valid SketchRef in the document and therefore a dereferenceable gSketch. As it turns out DocOptions occasionally and temporarily switches to a MemNil page while shuffling pages in a document, and passes this on (perhaps incorrectly, but historically) all the way to OS_Book_PageHasSwitched() visibility. So now we guard against nil-gSketch-dereference there before proceeding with the earlier fix.

2020.02.28 Better Termination "Special Sketch Activity"

This checkin revises our whole distributed and fairly buggy (/insufficient) approach to the handling of Caption Editing, Ink Drawing, and Object Info Ballon Displaying, especially where those ongoing "modal activities" in the front sketch get interrupted by other actions instead of being "gracefully terminated" by the user. Examples of interrupting actions are dispatching certain menu commands, displaying most dialog boxes, switching active documents, switching out of Sketchpad into another app, and closing the active document (either with Close or Cmd-W or the Close Box; or by quitting Sketchpad either by Quit or by Finder | Shutdown).  Almost all of these events could be buggy under certain user patterns of interaction; and this checkin addresses almost all of the known cases of such bugs through a multi-pronged approach:

1)  The Cocoa app follows very different paths when users close a single document as opposed to when they try to quit the app -- quitting auto-closes any window Cocoa thinks needs no saving without giving that window or its corresponding NSDocument any specific "going away" tickles. This is problematic if the window has an ongoing activity that has not yet dirtied the sketch, but will on termination! So we intercept these earlier (at App:terminate) and make sure our Cocoa documents are properly dirtied by then..

2) Separately, we diagnose the most strategic place to intercept NSWindow/NSDocument "going away" cases for the Close (as opposed to Quit) code-paths, and centralize our effort to guarantee dirtiness-is-accurate there, removing a variety of half-assed efforts strewn through other Cocoa windowMightClose() and documentShouldGoAway()-style callbacks.

3) We extend the same logic used in both these cases to applicationWillResignActive(), so that we no longer blink caption-editing cursors or continue to accept ink-paint or show ObjInfo balloons when we have been switched to the background.


Along the way, we fix a long standing bug in common code that could prevent a screen update from happening if termination of a user-activity like caption editing or ink-drawing also resulted in a change of the activeSketch. This showed up in GSP 5.1 but not in 5.0 because 5.0 was over-aggressive in redrawing its windows on certain activities compared to common-code's parsimonious maintenance of minimally accurate dirtyRect notifications.


BUGFIX (believed, though never replicable for me): Cmd-W Closing Doc threw "Failed Assertion: TextKind_preDispose() finds MFSMapCells ostensibly taregted." The error seems to be reproducible, but in a strange way. It has something to do with dirtying the document, but for only certain types of dirty. If I move a text box or some other object and then close (clicking Don't Save), I consistently don't get the error. However I do get the error if I click hypertext that is linked to a hide/show button. I didn't go further into the investigation.

BUGFIX: If you close a sketch (e.g. Cmd-W) while mid-ink, you crash. If you switch from one sketch to another mid-ink, ink survives, but selection behavior is not the same as in GSP5.0. (I believe the old sketch is still "ink hungry" until you return to it, which suggests deeper internal bugs might happen since inkAPI is not generally multistroke-capable.) Both of these seem to have to do with inadequate activation/deactivation logic under Cocoa. Somewhere GSP5.0 is getting to terminateModalStates() in a context where GSP5.1 is not; and we should track that down and make sure GSP5.1 conforms to it generally (not just to ink -- script-step-Play and other modalities are probably similarly buggy in such transitions).

BUGFIX: SR-3: Losing text in actively-edited Caption. Start a caption edit (new or different). Make changes. Quit Sketchpad with session active. Say "YES" to "Save Changes?" Sketch gets saved with pre-edit caption contents super-hidden and new changed contents abandoned.

BUGFIX: Open Sketchpad, scribble with the Marker tool. Quit Sketchpad. Sketchpad quits unexpectedly without asking if you wish to save your sketch.

- modal.c: post dirtyRect notification to gFrontmostSketch if its going away post modality cleanup; we tried to do this previously but a clear codebug shows we failed.
- AppDelegate.h, AppDelegate.m: added terminateModalUserActionsAffectingDocContents and terminateModalUserActionsUnfriendlyToMenuAccess; called the first from applicationResignActive (case #3) and the second from menuWillDisplay (revising prior code that accomplished the same thing without a helper routine). Cleaned up applicationWillTerminate: with better documentation of its position in the shutdown sequence.

- BookWindowController.m: shouldCloseDocument() now  terminatesModalUserActionsAffectingDocContents, handling all of the File/Close paths (case #2).
- GSPApplication.swift: NSApp.terminate() now terminatesModalUserActionsAffectingDocContents, handling all of the App/Quit paths (case #1).
- GSP-Bridging-Header.h: Swift eats more C


2020.02.27 Define Function From Drawing bugfix

BUGFIX: Sketchpad asserts "UIC_NewDataFunction_actionProc() cant' store UINT32 in cells" on Number | Define function From Drawing, and then crashes.

- uic_actn.c: UIC_NewDataFunctionFromPicture_actionProc() has an overaggressive assert in it policing its assumptions about DataThreads for DataDefinedFunctions. Our general approach in GSP5+ is to keep dataThreadCells as 32-bit values but store them in 64-bit, rather than 32-bit, cell structures, for processor memory alignment convenience. We can do that here, since sizeof(cell)≥sizeof(data) even if sizeof(cell)≠sizeof(data), which triggered the (now erroneous) assertion.


2020.02.27 Dialog Fixes

We revisit some very old code -- the first Cocoa to enter GSP5, back in the 5.00 dev days -- and fix a profound problem with the core event loop for all dialogs that has surfaced in that code once it runs on top of Cocoa, rather than Carbon, event loops. The nature of the bug is described in KCPDialog:runModal as follows:
 
// Now loop until the modality quits on us, giving some time as we loop
// to OTHER processes beyond our modal window (which limitDateForMode
// for mode does, running the currentRunLoop once before calculating
// how long until it needs to be run again), and also delaying while
// there is no further system activity, since otherwise we are pegging
// the processor clock at 100%. Finally, all of this is done in an
// autorelease pool since autoreleased allocations made here -- notably
// the NSDate time returned by NSRunLoop:limitDateForMode -- won't otherwise
// get deallocated on their own til we escape back to the main event
// loop, which won't happen til the dialog (or rather the nested stack of
// dialogs) is done.  This fixes two bugs in 3034, both of which date back
// to the dawn of Carbonization:
//      100% CPU time on all KCPDialogs, regardless of activity
//      slowly memory pressure during all (most?) dialogs, as a result
//          of never draining the autoreleasePool into which the limitDateForModes
//          were accumulating in our fast-burning pooling loop.

// The main purpose of all of this, just for the record, in contrast to
// a simple call to runModalForWindow, is that we need backtracking --
// which is watching the currentRunLoop -- to get some time, which
// runModalForWindow[] prevents, since it ignores all UI traffic to
// windows other than the frontmost.

While here, we revisit some portion of our recent changes trying to prevent
NSFormatters from being overretained by KCPDialogs, which in turn caused Advanced Prefs
and Properties to crash in some cases. In particular, rather than immediately [release]
our previously unreleased formatters, we now autorelease the ones we allocate ourself.
This lets them survive long enough to be useful!

BUGFIX: CPU processor no longer goes to 100% when most Sketchpad dialogs are active, and overall app memory requirements no longer grow at ~1MB/sec when dialog boxes are foremost (since dawn of GSP5.1).

BUGFIX: Advanced Preferences no longer crashes (since 3034)

BUGFIX: Choosing Properties on some objects no longer immediately crashes ().

- mac_dialogdatamap.m: switch from [release] to [autorelease]-on-init
- mac_cocoadlog.m: sleep the thread an appropriate amount of time during our blocking modal loop to not block the CPU; and also @autorelease things we collect once per loop since we are not yielding back up to our main run().


2020.02.10 Build 3034

- build.h: rev'd version numbers

2020.02.10 Calculator UI Enablement

Fixed a bug in which mouse-clicking or dragging within the Calculator's expression failed to correctly update UI controls to enable elements of the expression logically-inputtable at the post-drag cursor location (or overwriting the post-drag subexpression selection).

BUGFIX: SR-17. Sometimes when you select a term in the Calculator's expression with the mouse and then back-click on a replacement value, the term does not always get replaced.

BUGFIX: In the Calculator, cannot insert a logically-eligible symbol shortly after mouse-click-repositioning the cursor at the left or right edge of the expression

- CalculatorWindowController.swift: improved mouse-tracking loop's accuracy, and added an explicit call to refresh the UI's enablement based on common-code's computed enablement post-mouse-dragging.


2020.02.10 More Dialog Cleanup

We are still tracking down overly-retained elements of GSP5.00 Cocoa dialogs that are preventing suitable deallocation in GSP5.1+.  At this point, Preferences and Properties seem clean, but Transform dialogs still have some problems we have not diagnosed. This checkin is routine cleanup but also clocks a bug technically fixed in an earlier checkin:

BUGFIX: Crash after "BackFlash_IndicateGObj() to deactivate a GObj in a sketch which is no longer itself active." This occured attempting to target-highlight an object (e.g. visit it in Properties) on page #x after having switched from page#y where a prior Properties session had inadvertently left an object target-highlit on exit.  That was the source of the bug, and in turn was caused by 3030's (and earlier's) failure to properly deallocate the Properties dialog (and therefore, to properly clean up that early instance's left-over target highlighting).

- mac_plotvalue.m, mac_prefs.m, mac_propsheets.m, mac_plotpoints.m, mac_dialogdatamap.m: we now release formatters after installing them in EditFields, attempting to prevent over-retentions...

- GSPDocument.h: backout an incorrect assertion of _nullability trying to placate modern compiler warnings, since such assertion turns out to be source-incompatible with source-modules implementing this header (which previously survived unrecompiled thanks to XCode's sloppy dependency tracking!)

2020.02.10 "File | Revert" bugfixing

"Revert" was seriously buggy -- MacGSP5+ was structured for "open" ""so that the BookFile was loaded before the window was created, and was ill-prepared internall for the reverse to happen, which is how Cocoa drives the NSDocument architecture. (i.e. The window persists, but its bookfile content gets "reloaded" by Revert operations.) We refactor so that book can load before window or window before book, as the case may be.

Along the way, we investigate the failure of "Save" to properly toggle between "Save..." and "Save" and "Save(disabled)". It turns out we are not using Charade's Save File affordance, but rather OS X's, which comes with the NSDocument. Unfortunately, this affordance has no style variations to speak of. We remove the ellipis from the menu item (so we are now "Save" 100% instead of "Save...", so we are now wrong only 1/n times rather than (1-n)/n), and we implement a manual override to Disable SAVE (and REVERT) when no changes exist in the current document. This is as good as we'll aim for GSP5+.

BUGFIX: "File->Revert to Saved" Locks up the current document. Create a sketch, save, make a change, revert to saved. You can no longer interact with the sketch until you do something like put the app in the background, then forground.

BUGFIX: After choosing Save and giving a file a name, the File menu still displays the save option as “Save…” rather than just “Save.”

BUGFIX: If a single document includes both light-backgroudn and dark-background sketches, Sketchpad fails to properly adjust the "contrast color" (e.g. the black rim around point objects, action buttons, etc.) when switching back & forth between pages. Contrast colors appear to be per-document (incorrect) rather than per-page (correct).

BUGFIX: Possible crash when changing pages in a reverted document when the pre-reverted document  a document was showing the status line

- draw_apple.m: Removed background-color updating (which is sketch dependent) from Apple_CreateDrawingContext() (which creates a window-property, and therefore may precede availability of suitable sketches)

- BookWindowController.h, BookWindow.Controller.m:  fixed a stale reference to gBookOwningStatusMsg on book-disposal; refactored windowDidLoad() to do  most of the work in launchNewBookInWindow(), which can now also be called by (old-window-retaining) Revert as well as (new-window-creating) Open. Also OS_Book_PageHasSwitched() now handles background/target-color recalculation for page changes.

- GSPDocument.h, GSPDocument.m: added NSDocument customization of validateUserInterfaceItem: handler to disable SAVE and REVERT when there are no GSP-level changes, and revertToContentsOfURL: handler for Revert File operations,  correctly reinscribing newly-reloaded BookFile in old window, preserving its frontmost status and convincing GSP to redraw its contents.

- MainMenu.xib: removed "..." from File | Save...

- PageTabController.swift: page tabs no longer try to load themselves from the active Book when the tab controller is first created; we defer this til book pages declare themselves  available (which may not happen til later in load sequence).

2020.01.22 Bugfix: kcpTextFieldEditor Memory Leak

BUGFIX: kcpTextFieldEditor leaked in some dialogs (e.g. Preferences) with non-standard mappings of platform:commonCode controls

- mac_gspcocoadlog.m: we now dispose of kcpTextFieldEditors identically to how we handle gspTextFieldEditors and other gspXXXFieldEditors


2020.01.22 Bugfix: Backtracking Memory Leak

Fixed a once-per-backtracking-dialog-box memory leak of the SketchpadCanvasCoverLayer

MacBacktrack.m: we now remove the window-resizing observer in close() rather than dealloc() since a registered observer prevents deallocation


2020.01.21 Bugfix: Unintentional Retain of All KCPTDialogs

This goes back to at least Jon's code, maybe Kirk's: an internal backClick handling block of all KCPTDialogs (whether backclickable or not) was "retaining self," meaning the dialogController would never be deallocated, leading to massive leaks of all dialog-related structures for every GSPDialogController invoked
     in a run of GSP. Oops!

BUGFIX: Large-scale memory leak (leaked WindowController and all subordinate structures) on every instance of a KCPTDialog (virtually all of the "content substantive" dialogs in Sketchpad) no longer happens.

- mac_gspcocoadlog.m: we switch to a __block syntax for block-captured variables, which has the effect of weak-linking self back-references, along the lines of a convention now common in our self-capturing Swift closures to which this Obj-C block is a predecessor.
  
2020.01.21 Calculator Keypad: Fixed updating of function's independent variable

BUGFIX: In the New/Edit Function Calculator, the keypad "independent variable" key gets out of sync (lags one change "behind") changes to the active Equation's axial projection).

BUGFIX: Memory leak of PageTabs when closing doc window
BUGFIX: Memory leak of Strings when viewing or changing page tabs in Doc Options

Bug caused by 01.19's fix that delayed execution of CalcPopupMenu actions until later in the game than our previous keypad-exception-handler.

- CalculatorWindowController.swift: Rewrote EquationMenuButton() to update Keypad:independentVarKey after handling the menu choice in menuDidClose rather than in menuItemClicked since that is now where we actually "do the action" that our exception needs to post-process

- DialogDocOptionsController.swift: manually deallocated UnsafeMutablePointer allocations; ARC doesn't track these

- PageTabController.swift: made back-pointer a weak reference in observer closure 

2020.01.21 Made "Big Dot" bigger

BUGFIX: [SR-6a] In Text Style Palette:Insert Other Symbol menu, we make the "big dot" operator appear larger to better distinguish from the "small dot" operator. This only affects the appearance in the menu; in actual Captions, the appearance of these two operators is dependent on the font and size of the user's overall styling.

Problem is that at font 16, the default for InsertableMFSItemView, they appear virtually the same size, just at different baselines (hard to see in separate buttons). So we add an optional property to InsertableMFSItemView, the customFontSize, which one can set in Interface Builder to request a larger or smaller appearance size than "default;" and we change the BigDot operator to use a customFontSize of 20.

- TextStylePaletteController.swift: InsertableMFSItemView now prefers customFontSize to default of 16, if present (non-zero) in nib
- TextStylePalette.xib: BigDot operators declares customFontSize:20

2020.01.21 Rev'd to 3033

- build.h, etc: rev'd build numbers

2020.01.19 Build & Release 3032

- build.h, etc: rev'd build numbers

2020.01.19 Calculator: Fixing the persisting "New Parameter" menu item

BUGFIX: (Cosmetic) Calculator: Values: New Parameter... shows the New Param dialog beneath the Values menu, which still appears as dropped down through the whole life of New Parameter subdialog. Better to close the menu first.

From code comments:

In CalculatorWindowController, we implement a delayed-execution scheme to work around a Cocoa bug or unpleasant design consequence. Traditionally our MFSMenuItemView fire their actionProc at mouseUp, after having cancel[ed]tracking in the menu. Up until GSP 3032 we used to dispatch through menuItemClick directly to CalcEdit_DoAction(), which happil did  the action. However, for Value | New Parameter, which is an action launching a subdialog, the Value menu returned FROM BEYOND THE GRAVE (since it was already explicitly cancelled before subdialog launch) and persisted during the entire life of the subdialog, floating on a window layer that positioned it OVER the subdialog rather than under (as part of the Calculator, where, if it really needs to come back from the dead, is its proper sepulchral home). This is an unpleasant cosmetic bug.

We find no stackoverflow of how to deal with this scenario, and suspect that in the middle of the menu's dispatched menu item's mouseUp routine is an insufficiently robust time to conduct a whole modal dialog. So we adopt a different execution scheme. As of 3032, mouseUp still triggers the menu item's actionProc, which is menuItemClicked() in this class, but there we buffer the clicked menu item until we see the menuDidClose() notification we receive as MenuDelegate. This is our sign we really, truly have closed the menu, and can now go ahead and execute the action (forwarding as previously to CalcEdit_DoAction(), just later in the handling of the menu-closing-mouse-up sequence). As long as our common code menu resources remain stable across this interval, we're safe -- and they do, since we don't tear down the menu til later on in menuDidClose().  Voila! End of bug.

- CalculatorWindowController.swift: per above

2020.01.19 Calculator Menu Improvements

We add backflashing to the Calculator Values & Functions menu, so

BUGFIX: When tracking through items in the Calculator's Values & Functions submenus that correspond to value or function objects in the sketch, those objects now temporarily highlight to provide a visual cross-reference to the names that appear in the Calculator submenus.

While we're Pimpin The Calc, we also

BUGFIX: Calculator now remembers its most-recent size and position across invocations (and indeed across Sketchpad launches).

- CalculatorWindowController.swift: CalculatorPopupMenuButtons now use BackFlash() API to target-highlight browsed items
- CalculatorWindowcontroller.xib: changed "Equation" menu back into a pulldown; also finally correctly configured Restorable&AutoSave to preserve window location

- GSP-Bridging-Header.h: Swift eats more C (backflashing)

2020.01.19 Calculator Menu Reimplementation

We introduce a new NSPopupMenuButton subclass for the calculator menu buttons, which both allows us to
lift a lot of redundant code into a shared class but also to change the building and disposal of these
menus items, changing them from once-per-Calc-invocation to once-per-menu-invocation. That in turn
permits:

BUGFIX: Calculator's Values and Functions menu now dynamically gain any values or functions that were previously unselected but back-clicked on in the sketch. In other words, if you click on a Value (or a Function) in your sketch behind the calculator window to add it to your calculation, it will guaranteeably thereafter be available through the Functions or Values calculator submenus (even if it wasn't previously in those menus).

- CalculatorWindowController.swift: refactored window controller to use a subclass, CalculatorMenuPopupButton, for its menu buttons; switched these from per-Calculation updating to per-menu-browse updating. This also allows us to avoid building any menu that the user never browses.
- CalculatorWindowController.xib: remapped NSPopupMenuButtons to CalculatorMenuPopupButtons and EquationMenuPopupButton (subsubclass)


2020.01.17 Text Style Submenu Renaming

FEATURE CHANGE: Renamed "Display | Text Style" submenu to "Display | Text", both because it already has a command in it named "Text Style..." (leading to the unmellifluous full name "Display | Text Style | Text Style...") and for conformance to GSP5.0.

BUGFIX: I’d prefer not to document a Display | Text Style | Text Style submenu command, since the duplicated use of “Text Style” might be confusing. Can we return to the original Display | Text wording of the main menu command, so that “Text Style” is a command that appears in only one place, as Display | Text | Text Style?

- MainMenu.xib: renamed custom MacTextStyleMenu that MacGSP swaps in and manages as a substitute for TextStyle_UIC in menusets.

2020.01.17 More Calculator Improvements

Fixed some closures which were creating strong references to the Calculator even after it quit, causing orphaned memory as well as potential later crashes. We hypothesize this fixes SR-15 as well, for which we do not have a reliable replicable.

BUGFIX: "gMem allocations outstanding" at Quit no longer fires after any run that invokes the Calculator.

BUGFIX (believed): Hard crash reported in CalcEdit_RenderNow() long after having left the Calculator (SR-15). We do not have a firm replicable on this defect nor a firm understanding of its cause so this is a conjectured fix; i.e. the fix made here >could< be causing this bug. PLEASE BRING ANY CRASHES IN CALCEDIT_RENDERNOW() IMMEDIATELY TO MY ATTENTION!

BUGFIX (believed): Intermittent repro in 3012 and  3014:
o        New Parameter t = 0.5
o        Edit Parameter definition to Show Calculator, immediately press OK
o        Double-click Parameter to edit it
o        Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
o        0   com.kcptech.GSP                       0x000000010c41235b CalcEdit_Render + 139
o        1   com.kcptech.GSP                       0x000000010c44be51 closure #1 in CalcInputView.draw(_:) + 513
o        2   com.kcptech.GSP                       0x000000010c44bed5 partial apply for closure #1 in CalcInputView.draw(_:) + 37
o        3   com.kcptech.GSP                       0x000000010c4852b2 NSView.saveGState(_:) + 210
o        4   com.kcptech.GSP                       0x000000010c44bc27 CalcInputView.draw(_:) + 199
o        5   com.kcptech.GSP                       0x000000010c44bf3f @objc CalcInputView.draw(_:) + 95
o       6   com.apple.AppKit                      0x00007fff35ed1a6e _NSViewDrawRect + 66
o        7   com.apple.AppKit                      0x00007fff35ed02fc -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inContext:shouldChangeFontReferenceColor:stopAtLayerBackedViews:] + 1627
o        8   com.apple.AppKit                      0x00007fff35ecfc8f __46-[NSView(NSLayerKitGlue) drawLayer:inContext:]_block_invoke + 192

BUGFIX (believed): CalcEdit_Render crash in closure when she double-clicks on a text box. See bug email for Crash Log.

- mfs_platform_apple: changed NSLog() message to better describe symptom
- CalculatorWindowController.swift: added explicit weak/unowned capture closes to cached closures that captured self

2020.01.17 Advanced Preference, Default Text, and Calculator Improvements

This checkin gets the Calculator Preview using the default measurement font. But in order to reset the default measurement font to system defaults requires Advanced Preferences:Reset All Preferences, which it turns out was doubly-broken.  First, new-preference default font size initialization was deeply broken as never having worked with post-ATSUI font managers (SPiOS and later); and then another time since, like all other Advanced Preferences, it never actually "took effect" since the assert you get about OS_TextEncodings trying to exit Advanced Preferences functionally cancelled the Pref session. To eliminate that assert requires getting GSP4 Text Encodings working again properly, which we do as well. So:

BUGFIX: GSP4 documents in a variety of native character encodings now open properly according to the now-settable "GSP3/GSP4 Language Override" setting in Advanced Preferences:System. This also eliminates the assertion on OS_Text Encodings that formerly appeared when entering Advanced Preferences or when attempting to Reset All Preferences.

BUGFIX: Advanced Preferences:System:Reset All Preferences now works.

BUGFIX: Default preferences (for new or Reset installations) for the text styles for different types of objects are now reasonably varied between Serif and Sans-Serif options, rather than all defaulting to Geneva.

COSMETIC CHANGE: The Calculator's Preview panel is

- CalculatorWindowController.xib, CalculatorWindowController.swift: Changed font appearance in Calculator's Preview Panel
- mac_advancedprefs.m: Got BuildEncodingMenu working again
- misc_st.c: changed "Times" as default Mac font for many formats to "Times New Roman," which has superior MFS metrics under recent OS X
- text_apple.m: modernized OSText_GetDefaultTextStyleInfo() and GSP4 TextEncoding menu
- apple_FontRegistry.*: added FontRegistry_PreferredSystemSerifFont() to accompany _PreferredSystemFont(); this is used only in rare font-initialization failures.

2020.01.15 Calculator Appearance Improvements

- BUGFIX: Improved the Calculator appearance and resizing behavior to no longer truncate elements. Now the "Insert" menus are grouped separately from the (functions-only) Equation menu; the keypad sticks to the right edge of a widened window; minimum window width is preserved during resizing; and a few visual containers are added to better organize layout.

- CalculatorWindowController.xib: revised layouts for IB items
- CalculatorWindowController.swift: revised layout for procedural items

2020.01.14 OS_RenderPrim() Export fix

We fix a bug in which OS_RenderPrim, a common-code/platform bridge used to render some MFS_Symbols and in-sketch edit boxes for editable parameters, failed on PDF export. We needed to apply the same hack for detecting rendering-gSketch-to-PDF-export rather than active-drawRect:-drawing-to-screen that cgContextFromMFSCtx (which manages the MFS_OS_ rendering bridge, which is similar to OS_RenderPrim) gained earlier in GSP5+.

BUGFIX: SR-2: Clipboard-copied special MFS symbols (Circle & Triangle, e.g., but not Congruence) fail to export to PDF.
BUGFIX: Copy/Paste or Printed "editable parameters" do not display their in-sketch edit box in the exported image.

- render_prim_m.c: if a view's currentContext is NIL when OS_RenderPrim is called, we look to see whether we're gExporting to PDF, and if so, use gSketch's quartzFrame rather than the view's.


2020.01.13 Calculator Update Improvements

We fix a number of (variously-reported) screen-refresh bugs in which the Calculator input pane fails to update after typing, using the keypad, or using the Values, Units, and Functions menus.

- BUGFIX: In the calculator, choose a function to insert from the drop-down menu. The cursor moves to the right, indicating that something happened, but no text appears. In the case of typing cos(x), the text does not appear until I type the x.
- BUGFIX: SR-5a: Temporarily missing symbols in Calculator input pane after Values menu use.
- BUGFIX: SR-5b: Failure to remove symbols in Calculator sometimes after Delete key is pressed.
- BUGFIX: This is a screen shot of the calculator after I chose Sin from the Functions menu. The cursor shifts as if the function is entered, but it’s not visible.

- CalcInputView.swift: removed command-line diagnostic output
- CalculatorWindowController.swift: added a new routine to force a redraw of the input pane; called it explicit after keyboard, keypad, and menu operations.


2020.01.13 Insert Other Symbol improvements

BUGFIX: [SR-6] The duplicate "not-equals" symbol has been removed from Text Style Palette:Insert Other Symbol menu.

FEATURE ADDITION:  Text Style Palette:Insert Other Symbol menu has gained some new symbols for logic and mapping (is-element ∈, union ∪, intersection ∩, empty set ∅, goes-to → , double-goes-to ⇒}

Along the way, we discover a GSP 5.0x-era bug in the MFS_Symbol to Unicode mapping tables, in which Union and Intersection get reversed. Thus what GSP thinks is MFSSymbol_Intersection appears on screen as the Union symbol. Since GSP logic does not actual use either of these symbols, this has never been of consequence, but its possible that GSP 5.0-era sketches have been created in which unicode characters presumably intended by the user are stored internally as MFS_Symbols of the wrong meaning. Thus they are typographically correct but semantically wrong in old files. Rather than correct the
    error at the MFS_Symbol - to - Unicode mapping, which would invert the typographic meaning but not the semantic one (making old files now wrong in BOTH),
    we invert the two choices in the raw MFS_Symbol enum, which is supposed to be "onto" the old Windows Symbol Font. I can no longer find an on-line
    character map of that font's symbols; and the closest I can find (a non-numeric ordering that may be onto the underlying high-ASCII codes) suggests
    that we may have mistook its ordering originally, in which case this fix is all round an improvement. Worst case we are no longer "onto" the Symbol
    font, but I think this is without symptom, since GSP5.0 and later has fully adopted Unicode, rather than Symbol-font, for MFS_Symbol rendering.
    It's unclear to me what version of Sketchpad produced Venn.gsp in the first place, since neither commercial GSP5.0 or GSP4.0 appear to have Union
    and Intersection in their MFS Symbol palettes!
    
- TextStylePalette.xib: new and revised symbols in Insert Other Symbol palette
- mfs_symbols.h: revised core enum to flip order of Union and Intersection, bringing semantics into alignment with character assignments in mfs_symbol_unicode.c.


- build.h, info.plist: new build#

2019.12.17 Build#3030

- build.h, info.plist: new build#

2019.12.17 Ink!

This checkin re-introduces "ink" functionality to the Marker tool, using pure Cocoa tablet API.

We abandon Carbon Event Handlers and instead key entirely off pressure information in mouse events, letting the OS do the hardware work for us. This means stepping away from GSP 5.0's reliance on "mouse proximity events," which appear in old Cocoa documentation but do not seem to be delivered by any Wacom and HUION tablet with which I can test. That means in turn that we cannot statically analyze one's pointing device for pressure-sensitive operation. Instead we rely on the simple expedient that "if the thing behaves like it's got pressure (by reporting non-binary pressure differences), then it's pressure sensitive!" This requires some logic switch, but also allows inking to be more straightforward. I believe the GSP5.0 architecture anticipated, but never actually delivered, coherent support for multiple pen-strokes simultaneously. Every pen (in GSP5.0) knows that it is different from every other pen (i.e. each action is coded by deviceID), but that information is nowhere used in stroke discrimination -- all pens contribute ink equally to the single global stroke. We keep that global stroke in GSP5.1, while noting deviceID is directly available from mouse events (therefore: no proximity events needed!), if we ever want to extend the implementation to target ink from different pens to different strokes simultaneously. This will of course require a (not yet existing) multistroke architecture, but could be cool on whiteboards.

Along the way, we fix a broken cursor (used for the INK eraser -- shift+ink tool erases, don't forget!), and add additional architecture to our pictureGObj-from-miscellaneous-image routine for generating pictureGObjs for freeform ink.

BUGFIX: Implement Ink.
BUGFIX: "Clicking the Marker Tool in white space in the sketch causes an assert about OS_Ink."

- picturegobj.c: PictureGObj_ImportPlatformPicture() know assigns Drawing_Genus to all pictures made with InkPicture_DestinationSemantics. GSP5.0 did this differently, and used an intermediate struct to permit callers to pass the Genus in a way that GSP5.1 seems to have evolved differently.
- ink_util.h: we reduce the radius of the ink eraser to more closely match the erasure cursor
- kInkEraser_ResourceID_8_8.png, assets/cursor_assets/Contents.json, tool_m.m: added a hot spot to the InkEraser cursor, and renamed its resource according to name-by-hotspot conventions
- AppDelegate.m: introduced deconditionalized code for handling applicationwide tabletProximity events ... which we don't seem to receive from our tablets, at least not at the appDelegate! Fortunately GSP5.1 now survives without proximity-session-tracking.
- GSPCanvas.m: sketch canvas mouseDragged handlers now intercept ink-targeted events (the way carbonEventHandlers used to), and funnel them off to an API capable of taking higher-precision mouse geometry as well as pressure-sensitivity information (unlike sketchMouse, which traditionally handles mouseDragged events). Some minor nuance here because not all events coming in to mouseDragged are mouse events (since we feed modifier-key-changes back through mouse handling to keep the mouse fresh to mod-key activity)
- ink_m.h [NEW], ink_m.m [RENAMED from ink_m.c]: modernized event flow removing carbonEventHandlers and deconditionalizing proximityEvent responders, and therefore, device-trackers, from flow. The ink API turns out to contradict a number of general Charade API assumptions (OS_xxx are not calls from cc-to-platform, etc.), and so can require some work to wrap one's head around, but it is remarkably bug free and that reason, as well as for general expedience, I have preserved that API where it wasn't in conflict with Cocoa.
- stubs/ink_i.c [DELETED]: removed stub ink from project

[BUG TO ADD: If you close a sketch (e.g. Cmd-W) while mid-ink, you crash. If you switch from one sketch to another mid-ink, ink survives, but selection behavior is not the same as in GSP5.0. (I believe the old sketch is still "ink hungry" until you return to it, which suggests deeper internal bugs might happen since inkAPI is not generally multistroke-capable.) Both of these seem to have to do with inadequate activation/deactivation logic under Cocoa. Somewhere GSP5.0 is getting to terminateModalStates() in a context where GSP5.1 is not; and we should track that down and make sure GSP5.1 conforms to it generally (not just to ink -- script-step-Play and other modalities are probably similarly buggy in such transitions).]


""2019.12.14 Preference & Text Style Menu Additions

This checkin adds a duplicate Preferences command to the app's Sketchpad menu (where Mac users are accustomed to finding it, along with its Mac-traditional shortcut key), and expands the Display | Text Style item into a submenu of relatively worthless commands (all of which are also available in the Text Style Palette) that have the virtue of having menu shortcut keys associated with them -- thereby restoring our quick keyboard access to Bold, Italic, and Underline, as well--finally---as to "Increase/Decrease Font Size" commands and key shortcuts.
 
Beneath the hood, both involve remapping canonical UIC_MenuCommands to Mac-specific "enhanced" UI at menuSet-building-time.  For Preferences_UIC, we intervene to duplicate the UIC command (which toggles between Pref & Advanced Pref) at the location of a nib-based placeHolder item in one of the Mac-specific menus (Sketchpad menu). For TextStyleDialogOrSubmenu_UIC, we replace the canonical item with a nib-based submenu of special MFS-styling commands, whose appearance (enabling & checking) we drive off the special embellishment associated with TextStyleDialogOrSubmenu_UIC's appearance manufacture. (This means we have to retain the actual TextStyleDialogOrSubmenu_UIC command -- i.e. the one that pops up the useless Text Style dialog --- in the bottom of the submenu.)

BUGFIX: Preferences should appear under Apple menu as well as / instead of Edit.
BUGFIX: I get a little "error bump" sound from my computer when I try to change the style of a text box using cmd-B, cmd-I, or cmd-U. Also for the re-sizing keyboard shortcuts, cmd-< and cmd->
BUGFIX: "cmd+, doesn't work to bring up Preferences; Preferences is also missing from the Sketchpad menu.

- mnuset_m.c: MenuSet parser now builds Mac-specific UI for TextStyleDialogOrSubmenu_UIC and Preferences_UIC when consuming menuSet
- uicom_m.m: OS_UpdateCommandAffordance()'s PlatformTextStyle_Embellishment handler now sets up and tears down special appearances for the Mac Text Style submenu
- AppDelegate.h, AppDelegate.m: Sketchpad app now owns IBOutlets for various placeholders and submenu items associated with Mac-specific Pref and Text Style menu UI, and offers an actionProc for the MFS-styling menu commands of the Text Style submenu
- MainMenu.xib: nib now contains a free-floating Mac Text Style submenu, which menuset parser substitutes for TextStyleDialogOrSubmenu_UIC; and a placeholder PreferenceItem, to which menuset parser duplicates Preferences_UIC on first encounter.

2019.12.10 BUGFIX: Drag-n-drop picture size

BUGFIX: Drag-n-drop of image files that are not at screen resolution, e.g. BigBlueSquare.png, import at 1:1 pixel dimensions (changing their size) rather than (as in GSP5.0) being rescanned to preserve size

On some occasions, dragging a Picture into Sketchpad results in a picture sized differently when the same file is dragged into GSP5.0. There is no certain bug here, just a change in behaviors. As it turns out, many picture files contain contradictory information about how big the picture is, and diverse applications interpret the same file differently. Dragging images from web browser windows is especially haphazard, since browsers impose a number of size constraints and transformations on the pictures they show that they do not impose on the pictures when they export them.  But in this case, we clearly have a contrast with GSP5.0 behavior, so choose to respect the logical size rather than the pixel size of the dropped image. This means higher-than-screen-resolution pictures often import smaller than previously, and lose actual pixel detail at the moment of import, while supporting enough pixel resolution to appear "life size" in Sketchpad. Conversely, less-than-screen-resolution pictures (if such things exist) will appear LARGER than previously, and will take up more storage space (if not actually gaining greater pixel detail) at the moment of import.

Note that this change means that Daniel's BigBlueSquare.gsp, to which GSP5+ now behaves exactly like GSP 5.0x, shows these inconsistencies itself. Drag-n-dropped from Finder it declares it is 116 @ 144 dpi, or 58 @ screen (Sketchpad) dpi.  So drag-n-drop creates a "small" Picture. (Previous GSP5+'s created a bigger Picture, leading to Daniel's bug.)
But copy-and-paste of its contents from Preview delivers a bitmap which is 116 with no DPI information visibly associated with it, so the same file now pasts a "big" Picture. This is the same as in GSP 5.0x; it's just an example of how hard it is to know what to do!

- clip_m.m: we know HeedMetaPixelDimensions for raw [NSImages] that come to us from drag-n-drop or the pasteBoard, not just from images that come to us packaged in NSData.


2019.12.09 BUGFIX: Picture Vector export

BUGFIX: Cutting or Copying an iterated or locus image of a Picture no longer issues an assertion ("Contrary to assumption, void PictureVector_renderClipVectorSamples(...) was callled") and no longer fails to export the image to the clipboard's PDF.

Beneath the hood, GSP5+ was inheriting SPiOS configuration in which there was no clipboard export, so functionality here was stubbed with ASSERT_NOT_CALLED. Restoring GSP5.0x implementations restored PictureVector clip-rendering.

- render_apple.c: reimplemented PictureVector_renderClipVectorSamples()

- render_picture_apple.c: removed from build, deleted from repo


2019.12.09 Object Properties Color Menu bugfix

BUGFIX: Choosing a colorswatch from the Object Properties context menu with either a right-mouse-click (click-n-click) or a right-mouse-release (press-n-drag-release corresponding to the right-mouse-click that summoned the menu) no longer has no effect.

Under the hood, our ColorMenuItemView was responding to left-mouse-ups only; but since ColorMenus can live both in the main menu and/or top-level popups (Display menu, Text Style Palette) which are LEFT-mouse dispatched OR in Context menus (Object Properties) which are RIGHT-mouse-dispatched, they have to respond to both mouse "buttons."

- colormenuitem.swift: added rightMouseUp() synonym to mouseUp()

2019.12.09 Build 3029

- build.h, info.plist: new build#

2019.11.12 Build 3028

- build.h, info.plist: new build#

2019.11.12 Pop-up menu font size consistency

Replaced various pop-up font size hard-coded constants with a single catchall value, kOS_MiscPopupMenuFontSize (currently 12). I believe the only visible change is in the Object Info popup menu, new in this build.

- apple_platform.h: new symbol defined
- miscui_m.m, ToolboxController.swift, StyledRegisteredFontNameMenuItem.swift, ScriptViewContextMenu.m, contextmenu.swift: adopted new symbol


2019.11.12 Object Info popup menu

BUGFIX: Object Info popup context menu now works.

We implement a pop-up menu for the Object Info context API.  Since this is a bit of a pattern (Hot Text popup, etc.), we write a GenericPopupMenuHandler which maps NSMenuItem into OS_Menu-capable popup behavior, in sketch.  However we don't take advantage of the opportunity to refactor other popups to this API yet...someday!

objinfo_apple.c: removed the asserting KLOOGE API from SPiOS days
miscui_m.m: added ObjInfo-specific popup API that uses new GenericPopupMenuHandler to drive an NSMenu/OS_Menu-based popup.


2019.11.12 Window Size & Drawing Improvements

First, we address the fact that saving a sketch and reopening resets its window dimensions to defaults. So old (GSP5.0 and earlier) sketches opened with correct window sizes, but sketches saved in 5.1 did not. It turns out we were never updating the internal notion of a window dimension to track user changes to window size, so were writing out a potentially stale size to files.

Second, we address the variety of redrawing artifacts seen when scrolling contents in to the screen from offscreen, particularly content of "large" objects (coordinate systems, infinite lines, loci, large captions). It turns out these bugs are subtle.

In Cocoa's architecture, the window's "scroll view" (traditionally, our sketchRect) owns a larger NSView "document view" which corresponds to our sketch's entire primal plane (traditionally, curPrimalSubRect) ... which might be vast. Our traditional rendering strategy has been to post dirtyRect notices against altered content in this entire primal plane, and then at render-time clip the area of redraw to the active window (sketchRect). This fails in 5.1 because Cocoa redraws using a tiling strategy, presumably to limit the memory bandwidth of data it pushes about, and positions its "document view" tiles on aligned boundaries that can be exceed the actual "scroll view" by up to one tile's width or height. It then caches this redrawn state and, if it is never invalidated further by the app, happily uses it in some distant future in which the user scrolls it into view. This conflicts with our traditional decision to clip to only sketchRect at render time.  Cocoa thinks we've rendered "outside the window" and can use that for future scrolls, whereas we've intentionally limited content regeneration to "inside the window" so that area, once scrolled in, is unpopulated and we see appearance bugs.

While overdrawing out-of-bounds content can be wasteful if user's never going to scroll it in bounds, rather than attempt to further gild the lily and reconcile these two conflicting optimization schemes, we bow into Cocoa's demands and abandon our "clip to sketchRect at render time." This risks in theory leading to giant primal plane redraws on every frame (if some sort of global animation e.g. of the coordSys is happening), but in observed practice, Cocoa (of course) avoids that, and limits drawing at most times to the sketchRect or even to limited areas inside the sketchRect, preserving the intent and (almost) all of the impact) of our dirtyRect design.

This closes some BETA defects:

BUGFIX: Save and reopen a sketch does not preserve its window dimensions and/or scroll offset, even at 100% size. This is critical for production!

BUGFIX: Scrolling refresh glitches. (Several supports such as: "Graphically speaking, the application does not seem to render the entire document into memory at once. Instead, it seems to render the document in chunks as they are scrolled to or accessed. This glitches on my machine and causes unrendered portions to simply remain unrendered (black) until I interact with them such as by clicking on them with the mouse or dragging. This also occurs with some objects, such as segments, text, and buttons, which appear invisible until they are clicked or otherwise accessed")


- draw_m.m: API namechange in a comment
- bookWindowController.m: we now dynamically measure the scrollbars (whose metric impact on window realestate changes based on OS settings) when sizing a new window to match a Sketchpad document's saved primal canvas size
- GSPCanvas.m: we now adjust the sketch's internal windowSize (...what gets saved to files...) when users resize the OS X window from its initial size.  Also we change our frame-drawing strategy to draw everything the OS asks, neither more nor less, and count on dirtyRectification to "work" in telling the OS what parts it needs to send back to us.
- GSPCanvas.h: API name change for clarity. Also added canvasSizeFromDesiredPrimalSize(), which currently factors in dynamic scroll bar dimensions (and maybe in the future, dynamic Page Tab dimensions?).


2019.11.11 Toolbox Submenu Improvements

This checkin introduces a number of improvements to the Toolbox's handling of submenus, i.e. for Selection Arrow, Straightedge, and Polygon tools.

a) The delay after pressing on one such tool in the main toolbox before the submenu of alternatives appears is slightly longer, decreasing the number of false-positive "submenu appearances" when you are simply trying to click-activate an existing tool choice.

b) Tools from the submenu can be chosen on the same click/release cycle as initially displays the submenu. Thus you don't have to click-and-release twice (once to show the submenu, a second time to choose from the submenu).

c) If in your initial click-release cycle that displays the submenu you do NOT choose a tool, the submenu will vanish on release UNLESS your cursor remains over the initial tool. In other words, if you drift off the initially-chosen tool to the submenu while holding the initial mouse-down still down, but then choose to choose no tool from it, the submenu will disappear.

Collectively, this means you can either CLICK-AND-DRAG to either choose a tool from the submenu or put away the submenu; or you can CLICK-AND-RELEASE to display the submenu for a subsequent click-and-release toolchoice. So, in breakdown,

BUGFIX: Toolbox pullout menus no longer appear prematurely when you "just click" (rather than "press") a tool with a pullout menu.
BUGFIX: Toolbox pullout menu items can now be chosen on the same mouse click/release cycle as initially displayed the submenu, rather than requiring a separate mouseDown/mouseUp to choose (although that mode of operation "still works" too).

Separate:
BUGFIX: ESC key and other keyboard or event sequences that change the active tool now always closes an open Toolbox palette, rather than leave the palette lingering open even while reverting to the Arrow tool.

WE STILL HAVE THE FOLLOWING BUGS FROM 3026:
* Click-release so submenu appears. Now click subtool#1 but drag over to subtool#2 and release. Behavior is poor; you are "tracking" but not yet confirmed on anything. 3027, unlike 3028, shows you #2 as your more likely tool rather than none.

- ToolboxSubmenuController.swift: preprocess ESC to >always< dismiss popovers; submenu tools now support click-and-drag off initial release and can find their "last chosen" subtool
- ToolButton.swift: revised button API so optional longPressMouseDown handler can now specify an optional longPressMouseUp handler to field the eventual return. Also, longPress is now 0.25 sec rather than 0.15 sec.
- ToolboxController.swift:  refreshForNewActiveTool() now cleans out stale popups (in addition to stale button highlights)  when common code changes the tool behind the Toolbox's back; GroupButtons now use new button API to track click-hold-popup-and-choose cycles and click-hold-popup-and-dismiss cycles.

2019.11.8 Arc Interior

BUGFIX: "Arc Interior" menu item incorrectly displays a shortcut (cmd-P) and if you choose "Arc Interior" it displays an assert and quits the program. While the Arc Interior submenu is showing, "Arc Interior" should act as a submenu title (no command key, and no particular "action" if you chose it).

- ArcInteriorState.swift: we now cache/restore the menu shortcut key and the menu action selector around presentations of the submenu
- build.h: rev'd to 3027


2019.11.4 RELEASE 3026

- build.h

2019.11.4 BUGFIXING: Toolbox

BUGFIX: Switch to Rotate Arrow. Drag (you rotate). Hit ESC. Toolbox cursor does not change back to Translate Arrow, but if you drag, you Translate.

BUGFIX: Set Arrow Tool to non-Translate. Press ESC. You have reverted to Translate Arrow in terms of tool functionality, but the Toolbox still shows your previous icon. (This is a duplicate of a bug above.)

BUGFIX: Shift-rightArrow and Shift-leftArrow appear to logically change the Arrow, Straightedge, or Polygon tools to the next (or previous) variant tool in the sequence in terms of how the tool functions in the sketch, but do not update the toolbox appearance to show the changed tool.  So you can be drawing with the RAY tool e.g. while the Straightedge icon is still showing the SEGMENT tool.

- ToolboxController.swift: Behind the scenes, all of these reflect our Swift ToolboxController's lack of anticipation that group tools can change setting by any means other than active user manipulation of their popup submenu.  We change the ToolboxController responder to OS_ActiveToolHasChanged() to refresh top-level group tools from the most recently chosen tool in their subgroup.


2019.11.1 BUGFIXING: Property Label editing

BUGFIX: Make a measurement. Go to Properties | Label and change its label, OK. Its appearance now changes from "Current Calculation" to "Current Label," like GSP5.0x, rather than stays stuck on "Original Prefix."

BUGFIX: Make a measurement. Go to Properties | Value and change it to "Display with: No Name (Value Only)". Then switch to Properties | Label and give it a new label, or change its existing label. Its appearance now changes to "Display with: Current Label" like GSP 5.0x, rather than stay stuck on "No Name."

- dlg_prop.c: added explicit Common Code signals to Platform that property panels were changing after CC changes the Measure panel's Data, so that Platform is not in danger of ignoring these data changes in preference for its (cached) platform-specific Control Values.  Unfortunately the GSP5.0x code path that assured this worked properly is no longer available (since XCode can no longer run GSP 5.0x).

2019.10.30 BUGFIX: Hot text back-clicking a reference to an image into a text component shows an empty box

Now when you back-click on a Picture while editing a Caption, Sketchpad's Hot Text reference to the picture is no longer blank but is instead, correctly, a miniature icon of that Picture.

Behind the scenes, Mac PictureMFS code was using SPiOS-style "MFSRenderContext -> CGContextRef" translation rather than new GSP5+-style.

- pictures_apple.m: fixed "MFSRenderContext -> CGContextRef" conversion in OS_PictureMFS_RenderPictureBlob()

2019.10.30 Replaced/Improved Shift-Key Handling in Menus

Shift-menu appearances depend on knowing whether the Shift key is up or down, but our current
mechanism (3024 and earlier) was an GSPApp:sendEvent() listener patch which only got fired before
menus were shown, not during dynamic tracking. This meant you had to hold down Option BEFORE
opening the Edit menu in order to "Undo All", etc. "We replace this with a GSPIdle timer which polls
the modifier directly -- and as a result now get dynamically updating menus and the ability to choose
between "Undo All" and its Shift-opposite "Undo last step" (etc.) even when the menus are actively
displayed.

* BUGFIX: Try replacing GSPApp:sendEvent() with some sort of timer patch that polls +[NSEvent modifiers] (new in 10.6)
* BUGFIX: Edit | Action Button | Hide/Show does not reliably become Hide&Show reliably when Shift key is pressed while menu is open.

- GSPApplication.swift: removed sendEvent() patch to pass shift-key changes on to common code
- GSPIdler.swift: added Idle timer to pass shift-key changes on to common code



2019.10.29 WINDOW POSITIONING & minor bugfixing

* Ported to XCode 11.1
* Enabled "Hardened Runtime" for greater app security
* BUGFIX: If you (re)launch after having set Preferences/Tools to LARGE toolbox icons, GSP 3026 no longer incorrectly shows you small toolbox icons (even while showing you a Preferences panel claiming they're still large).
* BUGFIX: Toolbox and sketch windows are now reasonably placed at startup (BUG: "The toolbox has a tendency to hide itself at the bottom of the screen when Sketchpad is opened.").

Also fixed a bug introduced in the last checkin, where a yellow (!) StatusMsg of the single word "Label"" could appear frozen in background sketches when many sketches are opened simultaneously (e.g. at launch or as a result of multiple-selections in the File Open dialog).

- ToolboxController.swift: Disabled auto-saving/restoring of Toolbox's position, per following code comment:
    // DECONDITIONALIZED GSP5+ attempt to preserve toolbox location
    // in files beyond first-launch initial (nib-based) positioning in top-left.
    // As of Mojave, this isn't working, with a symptom that on each subsequent relaunch
    // the window is moved down by its full content height. This MAY be an interaction between
    // the underdocumented autosaving mechanism, Cocoa's upside down coordinate system, and ToolboxController's desire to begin at
    // 0-content height and then grow the window repeatedly for each added tool, but the net is awash in
    // people's bugs and problems with Cocoa's window-position Autosave (varying over different OS X versions)
    // so we simply abandon the attempt and always put the Toolbox in the top-left of the screen.
    
- ToolboxController.xib: - Turned off "restorable" Toolbox window; set initialPosition based on default size
- AppDelegate.m: - let Toolbox know startup-Prefs version of "biggish tools"
- BookWindowController.m: Sketch windows now identify where their default positions (e.g. from NIB) collide on the left edge with the current Toolbox, and scoot over a bit to the right of that to have a better default appearance.
- BookWindowController.xib: turned off "restorable" Sketch window; set initialPositioning logic to be better; removed default statusMsg text ("Label")" so it does visibly appear in sketches that have not yet had a chance to manufacture a (replacement) frontmost status of their own.

""2019.10.22 REV TO BUILD 3025 & Status Msg

BUGFIX:
* Sketch Status Text is Missing (When I used a Custom Tool, I didn't get the little pink text prompts in the lower-right-hand corner of the screen for what objects I was supposed to click.)
* Sketch Status Text is Missing (Prompt e.g. "Selected: 1 point" that used to show up in the lower right corner doesn't show up. Maybe unimplemented, maybe just not worth it? I've a hazy memory of this being discussed, but can't recall the details.)

- build.h: new build#
- colorui_apple.c:
- BookWindowController.h, BookWindowController.m, BookWindowController.xib: BookWindows now have a per-window status bar, which floats above the scrollView when there is a statusMsg. We maintain a global tracking which window owns that most recent statusMsg, so we can quiet it when a new one generates its own.
- status_m.m: bridge from C StatusMgr to BookWindowController
- apple_colorui.h: new Mac-specific API for alerting statusMsg to changes in sketch color, since these changes happen less frequently than once per status message.


2019.10.05 REV TO BUILD 3024

*  rev to BUILD 3024
*  added "gsp@scratchconsortium.com" to splash page.
*  added two Help items for coordination with GSP 5.1 BETA TEST

- build.h, splash.xib: Build 3024, gsp@scratchconsortium.com
- AppDelegate.m, AppDelegate.h: new Help menu methods, hard-coded URLs
- MainMenu.xib: new Help menu items


2019.10.02 BUGFIX: MFS Edit Cursor blinking

BUGFIX: Editing a caption no longer occasionally leaves a rogue cursor visible where it shouldn't be (at a previous blink location, even once the selection has changed to multicharacter and therefore allegedely cursorless).

CODE IMPROVEMENT: We revise MFS's whole cursor locating API -- which both finds a cursor given an insertion index, and which finds an insertion index given a cursor --- to rely on MFS_MeasurementContexts and Measuring actions, rather than on MFS_RenderingContexts and Rendering actions. I believe the prior implementation was either a design error -- nothing in the code path actually relies on Rendering --- or a migration of font-realization from Rendering to Measuring (where it obvilously belongs, but where it may not have initially been located at the time the cursor-location API was designed). Either way, weaning cursors from their dependency on Rendering eliminates some of the NSLOG-level asserts in our new MFS_Context->CGContext API, improving our confidence that that assert (and the new logic) is actually robust. 

- apple_MfsCursorView.m: improved the degree to which our non-invertible blink logic parallels the behavior of the truely-invertible (XOR) platform implementation imagined by Charade
- mfs_platform.h, mfs_platform_apple.m, mfs.c, mfs.h: changed API for cursor-location to use MFS_MeasureContexts rather than MFS_RenderContexts.
- mfs_node_catalog.h, mfs_bracenode.*, mfx_expnode.*, mfs_fractnode.*, mfs_generic.*, mfs_horizontalnode.*, mfs_KLOOGEnode.*,mfs_stacknode.*, mfs_textnode.*: revised cursor-locating nodal methods to conform to new top-level API change

**INTEGRATION** Windows will need to change its MFS_OS_FindTextCaretFromPixel() to rely only on a measuring context rather than a rendering context to adopt revised API. I suspect this is a non-issue given the prior requirements of the call.

2019.10.02 SPLASH & TEXT STYLE PALETTE COLOR SWATCH BUGFIXING

- revised splash page to automatically include the Version# defined in .plist, rather than hard-code it
- rewrote Text Style Palette's "color swatch" to
    * no longer leave an orphaned Color Picker open post-edit, with downstream easy crashes
    * show a "mixed color" swatch for mixed-color selections
    * enable/disable properly
    * show a pop-up menu when clicked of Color Menu choices, including "Other..." for non-standard colors
    * present the color choice modally
    
- color_apple.c: formalized kEmptyStyleColorSentinel to support API OS_ColorIsEmptyStyleColorSentinel() API
- textstyle.xcassets: added ColorSwatch_multipleColors and ColorSwatch_menuIndicator .pngs
- TextStylePalette.xib: replaced Cocoa ColorWell with our own custom TextStylePaletteColorWell
- MotionController.xib: changed "GSP" to "Sketchpad" in custom modules
- splash.xib: changed hard-coded version to {$VERSION}
- SplashWindowController.xib: added parameteric substitution of CFShortBundleVersionString for {$VERSION} in Splash static text
- TextStylePaletteController.xib: rewrote color handling, including new TextStylePaletteColorWell with menu, modal picker, and multi-color swatch


2019.10.02 REV TO BUILD 3023

- build.h, splash.xib

2019.09.30: BUGFIXING TO BUILD 3022

BUGFIX: Eliminated "Backtrack callback finds nil controller!" on occasion when exiting many dialogs
BUGFIX: Centered Translate/FromDistance edit box in dialog. ("Daniel: Just curious how difficult it would be to vertically align the two edit boxes in the TRANSLATE Polar/Fixed Distance/Fixed Angle.")
BUGFIX: Added Splash Page.

- translate.xib: centered edits
- build.h: 3022
- pfm_chrd.h: trying to fix XCode paths bug, unsuccessfully
- ToolboxController.swift, ToolboxController.xib: experimenting with attempts to get better default placement
- splash.xib [new]: Basic Splash Page template; current text is hard-coded.
- SplashWindowController.swift: the Splash handler
- AppDelegate.m: launch SplashPage at startup, after a sufficient delay that we field odoc/oapp
- MainMenu.xib: rewire "About Sketchpad" to our own About method
- GSPApplication.swift: new About method, shows our custom SplashPage
- MacBacktrack.m: silenced acceptable alert


2019.09.30: Bugfixing re palette visibility

BUGFIX (former TODO 10-Feb-19):** Implement OS_ShowHideNotationPalette.
BUGFIX: "Show/Hide Toolbox" menu command no longer becomes confused if you hide the toolbox via its Close button.
BUGFIX: "Show/Hide Motion Controller" menu command no longer becomes confused if you hide the Motion Controller via its Close button.

- sketch_mfs_m.m:  finished OS_ShowHideNotationPalette()
- tool_m.m: removed isShowing property of ToolboxController, in favor of querying the actual window
- toolboxcontroller.swift: removed isShowing property of ToolboxController, in favor of querying the actual window; also defined close semantics on the Window rather than the WindowController since the latter is unreliable via close box.
- toolboxcontroller.xib: new custom window class so we can intercept close
- mot_ctrl_m.swift: defined close semantics on the Window rather than the WindowController since the latter is unreliable via close box.

2019.09.26: T026. Arrow-key dragging works again

OS_GetContinuousArrowKeyDirection() now yields to the processor in a way that permits background updates using OS_YieldTime(), which is superior to OS_UserInterrupt() since it doesn't remove other keypress events from the event queue.

- keypress_i.c: OS_GetContinuousArrowKeyDirection() now calls OS_YieldTime(), fixing the bug. 
- mfs_platform_apple.m: added comment to NSLog(), should probably remove NSLog statement
- time_apple.m: rewrote OS_YieldTime() to not rely on OS_UserInterrupt()
- draw_apple.m: add note to OS_Draw_UpdateViewFromDirtyRect() about new forced-updating strategy


2019.09.12: T011. SketchPDF Finalization

Rev'd to Build 3021 after Release 3020, which I forgot to checkin. Also:

BUGFIX (TODO: Fix broken PDF export) Text now exports properly with Copy/Paste. Closing "Daniel: I'm sure this is a known issue, but I can't copy and paste images from Sketchpad into other programs."
BUGFIX (TODO: Fix broken non-white colored-sketch-background export) Non-white backgrounds now export opaquely on Copy/Paste.
BUGFIX (TODO:  Remove "Bitmap Only" export option from Advanced Prefs.) Advanced Prefs:Export no longer has controls relating to Bitmap export. Clipboard export is now PDF-only in Mac GSP5+.

- build.h: Version 3021
- mac_advancedprefs.m, mac_advancedprefs.h, advanced-prefs.nib: removed or deconditionalized Export Prefs relating to Bitmap Clipboard Export
- clip_m.m: resurrect RenderBackgroundForExport()

2019.09.03: SketchPDF Work -> Preliminary

Objects but not text now successfully copy/paste exports as PDF to other documents.

(DONE 2019.09.12) TODO: Fix broken PDF export
(DONE 2019.09.12) TODO: Fix broken non-white colored-sketch-background export.
(DONE 2019.09.12) TODO: Remove "Bitmap Only" export option from Advanced Prefs.

skprint_m.m [NEW], skprint_i.c: replaced stubs for OS_ClipRenderGObjStarting(), OS_ClipRenderGObjFinished() with final versions
clip_m.m: OS_ClipboardCopySketch() now exports to PDF, removing long KLOOGEs
render_apple.c: restored some export rendering support utils



2019.08.26: T023, T024, T025 & MISC BUGFIXING

BUGFIX [T023]: OS_HyperUI_CheckboxWidgetRender now works, so Object Info balloons for hidden objects now properly display their visibility checkboxes.

BUGFIX [T024]: Implemented OS_GetHelpPrefix.

BUGFIX [T025]: Implemented OS_UserInterrupt.

Therefore,

BUGFIX: "Undo All / Redo All" now (a) executes visibly in a step-by-step fashion, rather than opaquely, transporting you to the All Done or All Undone state instantly; and (b) interruptable anywhere during its step-by-step unfolding by pressing the ESC key.

BUGFIX: Merge Points animation now visibly appears, rather than instantly transport you to the Fully Merged state.

Also implemented OS_YieldTime() to use the same event-loop spinning mechanism as OS_UserInterrupt, and added OS_YieldTime() callout to Color_FadeGObjs(), so

BUGFIX: "Hide GObjs" (and all its variants: Display | Hide or Display | Show All Hidden command, Hide/Show action buttons, and hide/show Object Info checkmarks) now properly fade objects into or out of visibility, rather than instantly transport you to the All Visible or All Hidden state.

- ui_hypermfs_a.c [NEWLY ADDED], ui_hypermfs_i.c [REMOVED]: imported cross-platform checkbox renderer for Object Info balloons
- time_apple.m: OS_YieldTime() now calls OS_UserInterrupt() to spin event loop
- colorui.c: Hiding GObjs now yields time during the fade tight-loop
- user_m.m [NEW]: OS_UserInterrupt() for Cocoa event loops
- user_i.c [REMOVED]: eliminated stubbed version of above
- sketch_url_m.m: added correct Cocoa def of OS_GetHelpPrefix()
- sketch_url_m.c: removed #ifdef 0'd stale Carbon version of OS_GetHelpPrefix(), and cleaned up headers
- help_i.c: #ifdef 0'd stubbed OS_GetHelpPrefix() since we now define it for Cocoa but still need the stubs library for other TBD funcs

2019.08.26: SKETCHAPP:// and SKETCHDOC://

IMPLEMENTED: SketchApp:// and SketchDoc:// schemes now work in action buttons. In [CHANGED FUNCTIONALITY], both now hand the URL to the operating system rather than attempt to open it directly themselves.  This works better for links to non-GSP files, and is the "correct" if not always the desired response in installations with multiple Sketchpads installed. (URLs should open in the preferred Sketchpad.)

- GSPDocument.m, GSPDocument.h: added getDocFromOwningBook() utility
- sketch_url_m.m: added support for SketchDoc & SketchApp


2019.08.26: URL launching: initial work

BUGFIX: The right button on two-button mice (or the configured right-click on Apple's Magic Mouse) now operates context menus correctly and more generally behaves like Ctrl+Click in all contexts.

IMPLEMENTED: We now successfully launch general URLs (http:, https:, mailto:) from inside Sketchpad (primarily from link buttons), as well as help:// URLs (link buttons and/or Help Buttons in GSP).  RDB, SketchApp, and SketchDoc do not yet work.

BUGFIX: [CHANGED FUNCTIONALITY] Sketchpad now only finds help systems ("Sketchpad Help" folders) stored in one of two locations:
- Inside the bundle's Contents/Resources subfolder. This will be the default installation location, although for now we don't bother shipping help there as it makes beta ZIP files humongous.
- Next to the application itself. You can put your GSP5.00 help next to a build (3020 or later) and it should work.

This means we no longer support the location "inside the bundle, but not inside Contents/Resources". Putting arbitrary contents inside there post-build will block the app from working under MacOS modern security rules, so we now outlaw that location. This in turn means we need some future [PRERELEASE ACTION] to decide where and how to permanently install Sketchpad Help.

- GSPCanvas.m: mapped rightMouse to ctrl+click
- NSString+GSP.h, NSString+GSP.m: added "const" param specifiers where appropriate
- sketch_url_m.m [NEW], sketch_url_m.c: removed MacURL callouts for pure C to new Obj-C module so they can call Cocoa

2019.08.15: Drag-n-Drop Bugfixing

BUGFIX: "* Drag-n-drop has some target-registration issues in scrolled sketches, and doesn't work at all in highly scrolled viewports"

We now primalize the viewport correctly.

BUG CLOSED/UNFIXED: * it is possible to drag a URL that then fails on drop as non-image-containing.  Example: the "App Store" badge icon on  https://people.well.com/user/smoke/ App Store badge. Presumably shouldAllowDrag should test not just whether it can get URLs  but whether those URLs contain actual graphics. Or doesn't filteringoptions do this?

Actually, this link contains an SVG file masquerading as an NSImage, which is something of a rogue format. and subverts many applications. GSP5.00 for instance hard-crashes on drop. GSP5+ simply refuses to drop, which seems reasonable in the circumstances. Different browsers put different contents out for drag-n-drop, as well as for Clipboard, so while Safari won't export the image usably, Chrome will (by copy/paste, not drag-n-drop).

BUGFIX: * it is possible to drag a picture from a server that supports only HTTP transactions, and these fail on drop because of ATS security violations. http://www.dynamicgeometry.com/General_Resources/101_Project_Ideas.html contains sample images that GSP5.00 could drop acceptably. We can override ATS security in info.plist (NSAllowsArbitraryLoads) but if we go down this path we should read and prepare a counter-argument for Apple's dire warning at https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity/nsallowsarbitraryloads.

As it turns out, these fragments also include an image as well as a URL, and rewriting our sequential handler to still prefer the URL-load over the local-image but to nonetheless revert to local-image on URL-load failure successfully revives these links.

- build.h, info.plist: new build# (3019)
- GSPCanvas.swift: drag-n-drop improvements (primalization, multiple drop-clip format error recovery)



2019.08.08: GSP 3018 build and release

- build.h: new build#
- [NEW] gsp_app.icns: GSP5.0's icon returns for 5.1 per Daniel
- proj.xcodeproj: new plist icon settings, build#, etc.
- mainmenu.xib: converted "GSP Help" to "Sketchpad Help"

2019.08.08: Drag-n-drop of pictures from outside Sketchpad now works, albeit buggily

Known Bugs:

* Drag-n-drop has some target-registration issues in scrolled sketches, and doesn't work at all in highly scrolled viewports
* it is possible to drag a URL that then fails on drop as non-image-containing.  Example: the "App Store" badge icon on  https://people.well.com/user/smoke/ App Store badge. Presumably shouldAllowDrag should test not just whether it can get URLs  but whether those URLs contain actual graphics. Or doesn't filteringoptions do this?
* it is possible to drag a picture from a server that supports only HTTP transactions, and these fail on drop because of ATS security violations. http://www.dynamicgeometry.com/General_Resources/101_Project_Ideas.html contains sample images that GSP5.00 could drop acceptably. We can override ATS security in info.plist (NSAllowsArbitraryLoads) but if we go down this path we should read and prepare a counter-argument for Apple's dire warning at https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity/nsallowsarbitraryloads.

- clip_m.m: extended OS_GrabPictureFromExternalSource() to work with non-pasteboard-hosted pictureGObjs
- GSPCanvas.h, GSPCanvas.m, GSPCanvas.h: Canvas now conforms to NSDroppingProtocol, and coordinates with Common Code's dragndrop.h and clipboard mechanisms to track and dispatch dragged/dropped pictures appropriately
- GSP-Bridging-Header.h: Swift eats more C


2019.08.06: Restored traditional Keyboard Shortcuts, App Menu + menu items changed from "GSP" to "Sketchpad"

We restore the name "Sketchpad" (rather than "GSP" to the app menu) and eliminate the offensive system-wide shortcuts for Hide App (cmd-H), Hide Other Apps (cmd-shift-H), and Print (cmd-P), allowing Sketchpad's Hide Objects, Show All Hidden, Polygon Interior, and New Parameter dialogs to resume their traditional (GSP5.00-era) keyboard shortcuts. At the same time, we add cmd-UpArrow and cmd-DownArrow as short-cuts for Select Parents and Select Children.

Internally, changing the App menu name means extensive renaming of project support files (which are related to the Target).

- GSPTypes.swift: renamed GSP.Bool to Sketchpad.Bool since GSP is not a recognized class after $PRODUCT_NAME change
- many, many files: changed GSP-Swift.h to Sketchpad-Swift.h, changed GSP.Bool to GSPBool (typedef'd Sketchpad.Bool)
- MainMenu.xib: removed canonical key shortcuts from App menu
- UICMenuItem.swift: added common-code shortcut postprocessor to handle non-Ascii shortcuts (Unicode uparrow/downarrow), Mac-specifically

2019.07.28: T022. ITERATION!

- mfs_platform_apple.h, mfs_platform_apple.m: exposed cgContextFromMFSCtx() which now both Calculator and Iteration use to hand-draw MFS
-  iter_ui.c, iter_ui.h: added IterateUI_TabCommandWillCycle(), to support platform's integration of Iteration mapping fields in a dialog-global tab order
- GSPCanvas.swift, [NEW] NSViewUtils.swift: promoted SpecialKeyCode() to its own NSViewUtil extension, out of GSPCanvas-specific
- iterate.xib: layout changes
- DialogIterationController.swift
- [NEW] iter_ui_m.m: Mac-specific implementations of OS_IterateUI_PredrawGObjField(), OS_IterateUI_PostdrawGObjField()

2019.07.22: First ITERATE checkin

We've got the basic dialog box, with no pre-image->iterated-image mapping, but otherwise entirely functional (Display menu, Structure menu, and very carefully-ordered backclicking to blind match your mappings).

Let the MFS rendering hijinx begin.

- [NEW] iterate.xib: ye old dialog box
- [NEW] DialogIterateController.swift: and controller
- build.h: moved to 3017
- GSPDialogRotateController.swift, DialogMultiLabelController.swift, SwiftUtils.swift: moved general-purpose dialogData utils from specific dialogs to SwiftUtils
- DialogPlotTableDataController.swift: unused code cleanup
- GSP-Bridging-Header.h: Swift eats more C
- dialog_i.c, mac_dialoghelpers.m, mac_dialoghelpers.h: C -> C++, C++ -> Swift new dialog dispatchers


2019.06.11 T021: PLOT TABLE DIALOG & BUGFIXING

We are tracking down memory leaks which seem to relate to unintentional strong-reference retention cycles in Kirk's old GSPDialog code as it has migrated into ARC. This checkin gives us the ability to make profiled builds.

At the same time we merge in PLOT TABLE DIALOG branch containing a functional (though still memory-leaking) PLOT TABLE DIALOG.

2019.05.23 T021: TRANSLATE

This is a reference checkin for the Translate dialog, which is now working again on a whole new foundation. Some auto-layout bugs still exist but I believe the dialog fully functional.

[NEW FEATURES] The Translate dialog has some navigational improvements. As in the Rotate dialog box, you can now largely ignore the "fixed" vs. "marked" checkboxes; the edit boxes should allow you to type (fixed-values) into them, back-click (marked objects) into them, and delete current objects or values just as if objects were text. The checkboxes remain as more explicit though now more optional UI. In addition, backclicking is somewhat smarter in the "Rectangular Vector" panel. Now, if you are currently "focused" on either the dialog's HORIZONTAL or VERTICAL edit field, when you backclick a (markeable) distance measurement it populates the field which currently has focus and changes only that field, rather than (as in GSP5.0) always changing both fields by "scrolling new values through" VERTICAL and HORIZONTAL fields. Finally, like the new Rotate and Dilate dialog boxes, you can now back-click an already-marked object which is already marked as a short-cut to switch back to a panel in which that mark is used, or to switch back to the use of a marked value in preference to a corresponding "fixed" value. In other words, the only case where a Transform dialog now disables you from marking an already-marked object is to signal to you that there's no further effect to be gained by re-marking that value.

This one impacts some common code. We fix some obscure bugs and documentation bugs there, but we also add new functionality, in terms of better back-clicking behavior (we accept re-markings now where they will switch a Translation panel or switch a value from Fixed back to Marked) and in terms of "field-targettable" back-clicking, which applies only to the Rectangular Vector panel. This introduces new x-platform API, OS_TranslateDialog_GetBestMarkedDistanceBehavior(), to dynamically diagnose which platform field is active; Mac implementation is complete with this checkin and code-comments describe the minimal (1-line) Windows implementation for future integration. Also, we have to revise Roles() handling of marks, which used to assume that marking a distance always triggered "scroll-through" impact on the collateral mark. Now, "Marked Distance X" and "Marked Distance Y" params refer >only< to those specific marks, and a new sentinelValue can be passed by marking UI requesting the fuzzy scroll-through semantics of collateral marking from GSP5.00. (The "Transform | Mark Distance" menu command still works this way.)

- translate.xib, DialogTranslateController.swift, mac_dialoghelpers.h, mac_dialoghelpers.m, dialog_i.c: the epic new dialog and its dispatchers

- dlg_tran.h: declared and documented OS_TranslateDialog_GetBestMarkedDistanceBehavior()
- dlg_tran.c: TransformDlg_Eligible() is now more generous in allowing re-marking of an already-marked object, and TransformDlg_ConfirmBackClick() now uses new platform targetted-field API to target Marked Distance backclicks;
- roles.h, roles.c: introduced new kRoleSentinel_MarkDistanceXandYUsingNewDistance to capture old "scroll-through" marking semantics; reverting MarkedDistanceY marking to >only< marking that (one) parameter; updated documentation for accuracy
- trans_ui.c, uic_sel.dat: UIC_MarkTransformParam_actionProc() and the menu command action dispatcher now honor the new kRoleSentinel_MarkDistanceXandYUsingNewDistance
- SimpleValueOfMFSView.swift: added setOrClearMfsSelectingIfSwitched() for client convenience
- swift_ui_gsp_helper_utils.m: OS_TranslateDialog_GetBestMarkedDistanceBehavior() implementation that forwards C -> Obj C -> Swift -> DialogTranslateController.swift.
- GSPDialogRotateController.swift: pulled shortAngleUnits() utility out of RotateDialog-specific class and into (an extension to) GSPDialog

2019.05.20  Minor Dialog Box cleanup

Fixed some grot in nib files:

[CHANGE] In New Parameter, cmd-G rather than cmd-A is now the shortcut for "Angle" (think an-GULL), since cmd-A generally means "Select All".

- rotate.xib: deleted an unnecessary NSView
- newparameter.xib: changed cmd-key for "Angle" since cmd-A was getting selectively swallowed



2019.05.17  DILATE command is now functional!

[NEW FEATURE] During Dilate, you can backclicking a previously marked scale factor as a way to switch from Fixed Ratio back to Marked Ratio (paralleling change to Rotate wrt Marked Angles).

* Also fixed an unlogged crash when closing gSketch at a time when the mouse is in a mouseTracking zone.

- dlg_tran.c: permitted "Mark Scale Factor" backtracking/clicking even when pointed object is already marked IFF the Dilate dialog is currently displaying "Fixed Ratio."
- dilate.xib [NEW]: new Dialog box
- DialogDilateController.swift [NEW]: new Dialog box handler
- mac_dialoghelpers.h, mac_dialoghelpers.m, dialog_i.c: new dialog dispatchers
- GSPDialogRotateController.swift: code cleanup and minor refactoring
- GSPCanvas.m: mouseExited() called even after a trackin zone's window goes away

2019.05.16 Updated to Swift 5.0, and more bugfixing

BUGFIX reactivating a previously-chosen Script Tool. "Choose a script from Custom Tool Menu. Switch to other tool. Switch back to Custom Tool icon. Move cursor into sketch. Aiee whoa is me. We are getting CustomTools_Tool set rather than Script_Tool .. is that what we expect?"

Also bugfixed various failures to revert from Custom Tool icon in Toolbox to Arrow Tool.

- GSPDialogColorizationController.swift, GSPDialogRotateController.swift, DialogMultiLabelController.swift, PageTabeController.swift, SynthesizedRadioGroupFromExample.swift: Swift 5.0 edits
- ToolboxController.swift, GSP-Bridging-Header.swift: We now reactivate a previously chosen custom tool when choosing Custom Tool icon without menu; and we now revert to Arrow if either Custom Tool activation or Menu Command leaves us >not< idling a tool. (This also successfully handles "revert from tool" in cases where a fully-automatched-tool completely plays as a result of being chosen, with no further activation necessary.)


2019.05.16 Script View: Replaced "Next Step"/"All Steps" with single "Next Step(s)" button

[NEW FEATURE] In Script View, press "Next Step(s)" once to perform the next step in the script. Press and hold "Next Step(s)" to perform multiple steps in a row.

BUGFIX: "Script View:All Steps blocks interaction and completes instantaneously, rather than show us the gradual-execution à la GSP5."

Now we see the results step by step.

- ScriptView.xib: reduced number of Step buttons by one :-)
- ScriptViewController.swift: implemented a continuous action response handler for "Next Step[s]"

2019.05.10 Bugfixing: Warning Cleanup & Floating Palette Style Consistency Pass

1) The floating palettes -- Toolbox, Motion Controller, Text Style Palette, Script View, and Calculator -- all now share the same basic appearance properties:

* White background
* 12-point-font-size popup menus (NOT on black)
* Close button only for the non-resizable palettes (Toolbox, Motion Controller, Text Style Palette)

2) BUGFIX: Calculator now has correct window title

3) Internal code-cleanup addressing the following compiler warnings:

* x2 complaints on "almost matches"
* hasEqualSpacing deprecated
* insertText deprecated

- mac_gspcocoadlog.h, mac_gspcocoadlog.m: deployed "nullable" to bring our implementations in line with Swift's optionalities. Also adopted NSTextInputClient so we could avoid the deprecated insertText:.
- DialogMultiLabelController.swift, GSPDialogRotateController.swift: conforming with mac_gspcocoadlog.h's new optionalities

- ToolboxController.swift, mot_ctrl_m.swift, TextStylePaletteController.swift: hid extra Title Bar buttons
- ToolboxSubmenuController.swift, ToolboxController.xib: got rid of HUD Display style, modernized toolbox.isEqualSpacing to distribution.equalSpacing
- CalculatorWindowController.swift, dlg_calc_m.m: added logic for caching and eventually displaying Calculator's common code Window Title

- contextmenu.swift: said farewell to DarkAqua appearance

2019.05.10 WIP: Custom Transform rendering

This is a work-in-progress implementing "accelerated graphics" for Mac. First, we turn off accelerated graphics in the UI .. it was broken. This forces us (and GSP3014, which was built with this code even though it wasn't checked in) into software-ony rendering, which is slo-o-o-o-w but functional. Then we implement the old OpenGL code ... only to discover it doesn't work :-(.

When you return to this work, if you get OpenGL working, be sure to take apple_offscreenrenderer out of /stubs.

- ftr_chrd.h: #undef SUPPORTS_ACCELERATED_GRAPHICS
- mac_advancedprefs.m: disconnected UI to accelerated graphics when it's unsupported
- apple_offscreenrender.c: imported old openGL implementation from GSP5.00 -- but now deprecated :-(

2019.05.10 Bugfixing

BUGFIX: "Forget Tool Folder" is improperly acknowledged with the New Tools Folder message (which reports "no new tools"). Instead, Forget Tool Folder should silently empty the Custom Tools menu of any registered tool folder.

musicui_m.m: revised OS_LoadCustomToolsFolder() to not fire up recursive directory crawl of an empty URL, and instead to fail silently before then.

2019.05.10 Bugfixing

BUGFIX: ""New Parameter" dialog does not show appropriate unit for DISTANCE or ANGLE params."

Hard to tell if this was newly-introduced by GSP5+ Rotate base-class changes related to synchronization, or if this is a long-standing bug from the original 2015 port to the GSP5+ project. At any rate, we now explicitly synchronize the tertiary UI (unit label) to secondary-control-UI (radio buttons) by (a) asking radio buttons to synchronize on fire; and (b) subclassing copyControlsToDialogData to handle our tertiary update.

At the same time, we clean up some old grot left-over from a mistaken early implementation belief that New Parameter's radio buttons should be labeled with current units (Degrees, cm) , rather than dimensional names (Angle, Distance).

newparam_dlog.nib: radio buttons now synchronizeControlsConfirmingEdits
mac_params.h, mac_params.m: copyControlsToDialogData override refreshes tertiary UI; removed setUnitsRadioLabelsFromPrefs


2019.05.09 Bugfixing

BUGFIX: "Launch 3014. Open a sketch with a script. With a different sketch frontmost, choose Shift+TOOL FROM BACKSKETCH. In Script View, edit properties of some non-Given step and change a label. Crash: Thread 0 Crashed:: Dispatch queue: com.apple.main-thread"

Problem here was common code using a UINT32 to store a pointer for ScriptTables; in 64-bit this is insufficient storage space. Revised to a void*.

- Info.plist, build.h: rev'd build# to 3015
- toolmenu.c, bookfile.c, scrtable.c, scrtable.h: revised ScriptTable_ReferenceConstant clients and services to use void* instead of UINT32


2019.05.06   BUILD 3014

- build.h: new build#

2019.05.06 SPiOS Integration Checkin

Keepin' the SPiOS alive!  This corrects SPiOS-specific impacts to shared code in the 3014 dev cycle; should have no impact on Mac.

- mfs_platform_apple.m
- picturegobj_apple.m
- ios_ColorPicker.m


2019.05.06 Redefine Action Buttons

* [NEW FEATURE] "You can now change the set of objects hidden or shown by a Hide or Show Action Button after that button has been created, or change the set of buttons presented by a Presentation action button after that presentation has been created. Redefining the set of objects affected by a button can help when revising complicated sketches. To revise the set of objects affected by such a button, select the new set of objects (*) you want the button to affect; then select (last) the button itself. Then choose Edit | Redefine Action Button (which replaces "Edit Definition" for this selection). (* When redefining a presentation button, ensure your selected objects include only presentable action buttons, followed by the presentation button to redefine."

BUGFIX: "[FR] Implement "Reparent Action Buttons" for Hide/Show Buttons"
"
This feature reimplements a long-standing GSP5.0x internal prototype, to support Undo/Redo as well as to include better error checking and reporting.

- features.h: #define SUPPORTS_ACTION_BUTTON_REPARENTING
- uic_appr.h, uic_appr.c, uic_actn.h, uic_enum.j, uic_enum.c, uic_sel.dat, uic_st.c, uic_st.h: new strings, and actionProc and appearanceProc support for "Redefine Action Button" appearing as a suitably-enabled variation of Edit Definition in the  Edit menu
- action.h, action.c: new business logic for Redefine Action Buttons

- gsperrs.h, softerr.c, err_st.h, err_st.c: new error & error messages for circular redefinition case (kErrCircleDefinitionInRedefineActionButton)

2019.05.03 Script View: Cursors and cursors more generally
BUGFIX: "Implement Script View."

This finishes all known issues with the Script View panel UI. We gain an instructional picture for when no Script View is loaded, and bespoke cursors when the mouse is over draggable givens.

[BUGFIX] Cleared up a general issue with cursor contention that lead to incorrect and flickering cursors when the mouse was outside of the sketch window.

- scrview.c, scrview.h: Added ScriptView_GetStatementInfo() to expose general UI information in a more convenient fashion than the existing utilities
- ScriptView.xib: added NoToolPromptLabel instructional text
- ScriptViewController.swift: hide/show noToolPromptLabel as tool is loaded/dismissed from Script View; implemented cursor tracking and highlighting, adopting new and more efficient ScriptView_XXX API; general code cleanup
- GSPIdler.swift: only force Idle cursor updates when we're tracking the frontmost sketch.



2019.05.03 Script View more work: Context Menu & Printing

* Script View now "opens" with a zoom-out animation from the Custom Tools icon
* During step-by-step play, Script View now target-highlights matching GObjs in the sketch when their matched (gray) statement is pressed in Script View.
* Script View Context Menu now fully functional, including printing

- apple_colorui.h, apple_colorui.m: refactored Color Menu code for the 3rd and hopefully last time, exposing a utility that should be able to service pop-up requests such as might come from Text Style Palette (if we want to add a color menu there!), Object Context Menu (if we want to refactor that), and any place else one might come up "in the future :-)"
- ScriptViewContextMenu.h, ScriptViewContextMenu.m: [NEW] NSMenu-subclass capable of configuring a NIB-based default menu into the proper Context Menu for a given script statement. (ObjC because needs direct interaction with GObj structures.)
- ScriptView.xib: added a ScriptViewContextMenu to the Object List; fixed minor layout problems
- scrview_m.m: OS_ShowScriptView() now zooms out new views from the Toolbox's "Custom Tools" icon, rather than just have them magically appear
- ToolboxController.swift: added utility method to find the Custom Tools Icon in global screen space (for Script View zooming)
- ScriptViewController.swift: added mouse-capture and tracking protocol for Step-Press; Double-Click dispatch to preferences; custom PageSetup/Print handlers so that Script View maintains its own "Page Layout" preferences (NSPrintInfo) separate from the global-app prefs inherited by new Sketchpad documents; and pop-up menu preprocessor for Context Menu.
- contextmenu.swift: modernized BS logic to darkMode the back of the sketch popup menu; alas not sharable by ScriptView because we're forced to use NSTable's autoAppKitmagic ContextMenu presentation technology rather than our own, since its basic mouseEvent handling is so messed up (mouseDowns with no mouseUps, no rightMouseDowns, etc.) we dare not risk second-guessing how it wants us to handle a Context Menu on its own!
- GSP-Bridging-Header.swift: Swift eats more C

2019.05.01 Script View: Drag-n-drop relocation of Givens

- ScriptView.xib
- ScriptViewController.swift

2019.05.01 Script View: Statements!

* Proper display of statements ... with MFS, scrolling, "matched and "next" highlighting.
* The "Statements" panel now has a minimum size when drag-resizing the division between it and "Comments." You can no longer collapse it entirely (unlike Comments).
* Cursor properly cues resizability of window when pointed to window periphery.
* Disabled selection. Clicking a script statement, Given object, or divider bar no longer inappropriately highlights it in system selection color.
* [NEW FEATURE] Pinch-zoom Script View's Object List to increase or decrease its text size.
* Custom Tool Menu | Hide Script View now works
* New Script View help button now "works" (though Help Launching in general is broken)


- help.h, help.st: Added ScriptView_HelpState_StringID to common code
- scrview.c: ScriptView_PressStepButton() now targets gSketch to gFrontmostSketch, so platform doesn't have to
- scrview_m.m: implemented OS_ScriptViewIsVisible()
- SimpleMFSView.m, SimpleMFSView.h: exposed renderContext as a read-only property
- ScriptView.xib, ScriptViewController.swift: changes supporting Statements in MFS and Object List

2019.04.30 Script View: Initial Checkin

Very preliminary Script View functionality. The window and controls works except the display of statements and any interaction with them (targetting, highlighting, bolding, and popup menus).

- ScriptView.xib: basic layout
- ScriptViewController.swift: layout manipulation
- scrview_i.m: (renamed/relocated from stubs/scrview_i.c): bridge between C Common Code and Swift


2019.04.19 Doc Options: Finishing Up

* Adding a page now leaves the new page not only selected, but activated as well (ready for RETURN to edit).
* Show/Hide Tabs button now works (subject to the limitations of the current GSP5+ sketchbook window layout).
* Show/Hide Script View now works (subject to the absent Script View implementation!)
* Page Tabs now resize correctly after additions/removals; they no longer require the sketch window to be resized to refresh their dimensions properly.
* CMD-RETURN is once again the shortcut for "Okay".
* Adding a page or a tool now confirms any edit-in-progress before showing a menu that may contain the name of the currently-edited page/tool.

- DialogDocOptionsController.swift, doc_options.xib: per above
- swift_ui_gsp_helper_utils.h, swift_ui_gsp_helper_utils.m: added MacDocOptions_ToggleFrontmostBookTabVisibility()
- BookWindowController.m: pagesHaveChangedIdentity() now handles page-tab visibility too
- PageTabController.swift: reinitializeTabsFromBookPages() now performs re-layout() too, causing tabs to return to equal size for their overall window-width subdivision

2019.04.19 Bugfix: PICT File Opening Support

BUGFIX: "Launch and try to open "Beyond_the_Plane.gsp" from Daniel. You get a "Supplemental Data Ignored" warning that does not occur in GSP5.0x, and  "Part Three"'s picture of Euclid is replaced by a red X."

The bug here was that GSP5+ (and SPiOS) did not support pre-OS X "PICT"-based pictures. Now we do, though they'll be upgraded to PNG bitmaps if you resave the sketch. Other GSP4-era picture formats, notably the terrible KcptBitmap format, remain unreadable by GSP5+.

- picturegobj_apple.m: special-cased k3PictureImageData_MacPICT_MissingDataTriple, and redirected it to NSImage's PICT-loading abilty!

2019.04.14 Doc Options: improvements and bugfixes

• We re-establish the descriptive text explaining tool creation ("This document contains no tools ...") where it's appropriate.
• Doc Options now tracks changes to the active page that occur not of its own initiative, e.g. in the sketch!
• DRAG N DROP now post-selects the correct list elements after drop, or restores the pre-drag selection if drop is aborted.
• Empty or tool names are no longer allowed; we revert to previous name if user leaves an edit empty.
• Switching out of an active edit by a variety of means (clicking the Page/Tools radio button; adding a page by menu; etc.) now successfully terminates the edit first.
• Buggy two-fingered pinchzoom is no longer supported in the List View. There's no need for zooming here to begin with.
• Restored double-click edit/renaming, which has been broken in Table View (perhaps since dawn of GSP5+ Doc Options).
• Eliminated crash when clicking the same radio button as already clicked halfway through a row-name edit.

- misc_st.c: new text for menu items
- doc_options.xib: numerous per above
- dialogDocOptionsController.swift: ditto
- BookWindowController.m, BookWindowController.h: We now issue a kSketchpadPageFlipNotification on page change, to allow for lazy coupling with Doc Options dialog
- GSP-Bridging-Header.h: Swift Eats More C


2019.04.12 Doc Options: Multiple Selection & Bugfixing

[NEW FEATURE] Multiple pages or tools can be selected simultaneously in Document Options, and then drag-rearranged (within the order of pages and tools), or deleted (from the document) as a unit.

- dlg_doc.c: continued improvement of where common code signals OS_Doc_PageTabSettingsHaveChanged vs. OS_Doc_PageHasChanged(). Platforms are no longer asked to change to a page of whose existence they have not been previously appraised.
- DialogDocOptionsController.swift, doc_options.xib: support for multiple selection. Also conditionalized awakeFromNib() initialization to a once-only singleton, since awakeFromNib() is called many times during the life of a single ViewController
    (especially when making views for tableRows!)

2019.04.11 Doc Options: Drag & Drop Reordering of Pages and Tools

Now works for single-selection only.

[NEW FEATURE] Along the way, added Cmd-P and Cmd-T as (invisible) keyboard shortcuts for TOOLS and PAGES.

- doc_options.xib: command-key shortcuts
- DialogDocOptionsController.swift: single-selection drag-n-drop

2019.04.11 Doc Options/Add Tool Button

- toolmenu.c: cleaned up incorrectly-worded asserts
- DialogDocOptionsController.swift: added Tool menu-building, tracking, and dispatch
- swift_ui_gsp_helper_utils.m: bugfix, we know let BookController know page count has changed before attempting to switch to new page

2019.04.11 Doc Options/Add Page Button

Doc Options:Add Page is now functional, with the exception of an ununderstood situation in which the Blank Page option does not fire (on the internal To Do list).

- build.h: moving to 3013
- bookfile.h, bookfile.c: added Book_NumSketchPages()
- dlg_doc.c: fixed sloppy use of document OS_api, where we were signalling the platform's book its pages had changed contents in a situation where they had only changed names, and vice versa.
- doc_options.xib: added a standalone menu as the stub for Add Page's new drop-down menu
- swift_ui_gsp_helper_utils.h: added MacDocOptions_DuplicateContentsPageActiveSketch(), main worker func for page duplication
- DialogDocOptionsController.swift: adopted PushActionButtonActionProviderProtocol for AddButton
- BookWindowController.h, BookWindowController.m: added pagesHaveChangedIdentity(), separated now from pageHasChangedName(), dispatcher to pageTabs
- PageTabController.swift: separated pages-changing-identy from pages-changing-name and fixed design flaws in original PageTabController that meant it could not change the number of pages in a document. This implementation may still not be good -- I think scrolling tabs make more sense than shrunken fixed ones, when you have many! --- but its API is now robust enough to handle diverse implementations.
- GSPCanvas.h: exposed utility for managing SketchOS_Ptr when new pages are added
- SwiftUtils.swift: added stripFileExtension() and getPageName() utils
- PushActionButton.swift: a lightweight NSButton subclass that intercepts mouseClicks and passes them back to a delegate. Doc Options uses this to show drop-down menus on item-click for certain pushbuttons (whose style we vastly prefer to NSPullDownButtons and NSPopupButtons).


2019.04.08  BUILD 3012

build.h: new build#
swift_ui_gsp_helper_utils.*: stub for Add Page Button
doc_options.xib: stub for Add Page button

2019.04.08 Misc Bugfixing

BUGFIX (logged 2019.03.19): MFS Parentheses over highly vertical content appear to mismeasure or misrender the parenthesis, esp. the close parenthesis, in such a way that content that should be outside appears inside (try (a/b)^2 in a number of big font sizes)

Problems were rife in OS_MFS_BraceNode utilities, which we inherit from SPiOS.  Either there is a quantifiable difference with SPiOS rendering -- which is possible; the UIView may have different origin and direction than the SketchView --- or SPiOS had bad parenthesization bugs. We fix all of these, conditionalized for OS_MAC, with #warnings added to older (now-IPHONE-only) code to double-check it specifically if and when we rebuild for-SPiOS.

Also, unrelated, Doc Options now gets its "RETURN" key shortcut for OK restored when editing a page or toolname is complete. (Minor convenience feature.) And cleaned-up a nib warning.

- DialogDocController.swift: removed TableViewCell, not actually a legal @IBOutlet since these are multiply-manufactured by makeView() and therefore not solely instantiable; added timer-based reassertion of the RETURN = OK shortcut, post-editing, that we suspended when editing commenced.

- doc_options.xib: unwired prototype TableViewCell

- mfs_platform_apple.m: revised BraceNodes for OS_MAC


2019.04.04: Prelim: Document Options

A baseline for the new Document Options dialog. Still lots of work to come. But the basic display, switching active pages, and renaming and deleting pages and tools, now work.

- doc_options.xib: [NEW] new dialog
- DialogDocOptionsController.swift: and its master
- dialog_i.c, mac_dialoghelpers.*: C to Obj C dialog dispatch, Obj C to Swift dialog dispatch
- BookWindowController.h, BookWindowController.m, PageTabeController.swift: OS_Book_UpdatePageName() and its support at the BookController's pageTabs level
- swift_ui_gsp_helpers_util.h, swift_ui_gsp_helper_utils.m: [NEW] misc utils for getting info out of common code that Swift can't handle gracefully because of PTR()-style struct dereferences.
- GSP-Bridging-Header.h: Swift eats more C
- dlg_doc_i.c: De-escalated OS_Doc_PageTabSettingsHaveChanged() warning for dialog usability. Page tabs still semi-screwed up.

Lots to do, still noted in Header Comments to DialogDocOptionsController.swift.

2019.03.21: T019. Text Style Dialog

This checkin
* implements the broken "font pop-up" menu inside the Preferences: Text: Change Individual Styles dialog.
* finishes the Text Style Dialog that Jon introduced in lieu of a Text Style menu. Really, this dialog is just about completely redundant with the Text Style Palette .. we should get rid of it, either entirely, or in favor of a return to the Text Style submenu.

BUGFIX: Actual Prefs:Text Styles:Font menu still stubbed out and pending more global Font Reform.

Beneath the hood, we discover that GSPTextPrefsTextStyleController is a superset of what we need, so we refactor that into an abstract base class (MetaFontStyleController) and two concrete descendents, GSPTextPrefsTextStyleController and GSPSingleFontStyleController, which we then hook up to the as-yet unimplemented Font Style dialog.

- [NEW/RENAMED] FontStyleDialogControllers.*, formerly GSPTextPrefsStyleController.*, contains the new class hierarchy for KCPDialog controllers relating to Font or Text Style management (outside the Text Style Palette, which is not dialog based)
- [NEW/RENAMED] StyledRegisteredFontMenuItem.swift, formerly MFSFontMenuItem: renamed, documents, and revised utilities for building Font Menus supporting the Font_Registry's global list of available fonts
- fontstyle_dlog.nib: new single-font dialog
- preferences_textstyles.nib: cosmetic edits to support new class hierarchy
- mac_prefs.m: #include file name change
- mac_dialoghelpers.m. mac_dialoghelpers.h, dialog_i.c: C and Objective C dialog dispatchers
- TextStylePaletteController.swift: adopted new utilities for working with Font Menus


2019.03.21: "Other Color..." dialog & Tentative Recoloration

The "Other Color" dialog now attempts to recolor selections dynamically, reflecting changing choices in the platform color
API *before* user presses OK/Cancel. The wrinkle in the ointment is that not all GObj colors are easily cached and restored.
Particularly:

-captions (and in theory, though not practice, all other TextGObjs) can store MFS containing arbitrary amounts of color
information which is permanently destroyed (by text-node integration) by recoloring them to a monochrome.

-drawing_Genus pictureGObjs store their color inside their bit-image, and require an expensive recoloration operation
that also has the effect of potentially recoloring other transformed images or preimages of the same pictureGObj. The
presence of varying degrees of alpha attached to this color make this another "polychome" object, even though in this
case the color change >is< reversible (again at comparatively high cost).

While we could make the change (to monochrome) dynamically at preview time with no less loss to the user than
the GSP5.00 user who hits "OK" having chosen a color in the dialog they decide subsequently isn't "the right one,"
the fact that we offer a CANCEL button means we really have to be able to go back to the original (potentially
polychrome) appearance.

In the current implementation, we accept these limitations---during dynamic preview of color-choice, not all GObjs
will respond to the tentative color, and maybe pressing "OK" applies FURTHER color changes in the sketch than the ones
you've previewed (specifically: captions & pictures will fully recolor). Users will complain, and admittedly, this sucks.
PLEASE EVALUATE WHETHER WE LIKE IT WELL ENOUGH TO SHIP; OTHERWISE WE CAN DISABLE IT simply by nulling-out the callback
parameter to OS_Color_GetEditedColor().

An eventual much better implementation would be to elevate color change to full Undo/Redo support, using an extension
of the logic here ... a PastOp holding buffered singleton "old" colors for simpleGObjs, and holding a full MFSTree for
TextGObjs. At that point, this implementation simplifies into an application of Undo technology...we build the pastOp
before presenting the dialog, present and "live" recolor willy-nilly; OK simply involves filing the pre-built PastOp
onto the top of the Undo stack whereas Cancel involves executing the PastOp (to "undo" our transient recoloration) and
then discarding it rather than filing it in permanent History. Someday! Or...never :-(

BUGFIX: "Other Color..." needs to be rethought given the problems of the Cocoa color picker


- color_apple.c: removed OS_Color_GetEditedColor() stub from here; new implementation is Mac-specific not Apple-wide
- apple_colorui.m: OS_Color_GetEditedColor() implementation, including modal color dialog and adoption of new callback context. This should eventually be further refactored for other color-picking contexts!
- color_o.h: revised OS_Color_GetEditedColor API to include an optional callback platforms can make to preview "transient color choices" that user might visit in their color-picking UI before OK/Cancel-confirmation of a final new color choice. Minimal Windows integration (can simply adopt the new method signature and ignore the optional new args).
- colorui.c: UIC_OtherColor_actionProc() exploits the expanded OS_Color_GetEditedColor() API to provide a callback that can preview >some< (but unfortunately not all) tentative color choices.
- NSColor+GSP.swift: added some convenience utilities for converting between NSColor and various MacGSP color-specs
- TextStylePaletteController.swift: adopted new convenience NSColor utilities

2019.03.19: Text Style Palette bugfix and cleanup

BUGFIX: "thingamajig" sketch crashes on open, if set to auto-open, as does any other sketch with selected text saved in, because TextStylePalette is not prepared to field updates until its window has been loaded and current "update style" notifications do not force window loading.

BUGFIX: Launch. Choose Display | Show Text Style Palette before selecting any GObj with text apperance attributes. The TSP is entirely enabled, and showing bogus color and font information!

- TextStylePaletteController.swift: force load the Palette window on first reference; pre-initialize controls to disabled/off appearance and make the conservative (high-cost) updating of current FontName and Color more robust to long-term tracking of previous appearances in the UI; dead-code removal.

2019.03.19 Hot Text: Insert Variant Text popup-menu

DONE: Platform Stub: OS_MergeText_TrackTextVariantsPopupMenu() not implemented

- MFSMenuItemView.swift: resurrected an @objc convenience utility for manufacturing these
- miscui_m.c: OS_MergeText_TrackTextVariantsPopupMenu(): added TrackTextVariantsPopupMenu class to build and track an NSMenu of MFSMenuItemViews built by common code

2019.03.18b Motion Controller: Target Pane popup-menu

The Target Pane regains its Pop-up Menu of target roots, browsing this menu target-highlights the roots, and choosing from it selects the corresponding root if it remains showing and existing at the moment it is chosen.

Beneath the hood, this is our first MFSMenu which is capable of backtracking; we may want to generalize it either to implement the missing Hot Text:Insert Appearance Variant menu or the subfunctional (at least with respect to backtracking) Calculator:Insert Value or Insert Function menus. For now though, this is MC Target Pane specific, and spread across Objective C and Swift implementations based on whether it needs access to common code or not:

The Swift MotionControllerTargetPane intercepts mouseDowns and builds an Obj-C MacMotionController_TargetMfsMenu, which in turn handles backtracking and actually processing a menu item's action; but the menu items themselves are back to Swift, TargetPaneMenuItemViews, which are simply MFSMenuViewItems capable of holding onto a GObjRef (for backtracking).

- balloon_mfs.c, balloon_mfs.h, mot_ctrl.c: removed Parent parameter from GetIndexedLabelOrNameAsMFS (rather than figure out how to deal with kROOT_NODE_PARENT from Swift!)
- MotionController.xib: improved precision of clickable pane for pop-up menu
- mot_ctrl_m.h, mot_ctrl_m.m, mot_ctrl_m.swift: object C and Swift Target Pane logic (MacMotionController_TargetMfsMenu, MotionControllerTargetPane, etc.
- MFSMenuItemView.swift: clarified CALLER's continued ownership of MFS in MFSMenuItemViews (and their descendents)

2019.03.18  Motion Controller: Target Pane title

The "Target Pane" title, which names the currently targeted object, now appears correctly -- in fact, is better than GSP5.00, in that objects with mathematical formatting in their labels (italicization, subscripts, etc.) now appear properly formatted rather than stripped of notation.

- project.pbxproj: BUGFIX: rebuilt Signing authority to eliminate "File is damaged; please move to trash" warnings when executed in a quarantined app context.
- build.h, info.plist: moved to 3011

- mot_ctrl.*: Added a new MotionController_getCurrentTargetDescriptionString() utility, replacing old CarbonMac-specific logic for generating the TargetDescriptionString, and for preserving MFS-formatting rather than degrading to plainText where possible
- misc_st.*: transferred MotionControllerTargetPrefix_StringID from MacStringTable into common code, to serve new common code utilities
- dlgm_st.*: transferred Mac_MC_TargetPrefix_StringID from MacStringTable to common code
- balloon_mfs.*: exposed GetIndexedLabelOrNameAsMFS() for shared use with Motion Controller. Could someday migrate to GObj_MFs or some such.
- AppDelegate.m: we now explicitly shutdown the Motion Controller at app quit, to prevent deferred-deallocation-on-Quit from orphaning some gMem holdings and thereby tripping false misallocation reports
- MotionController.xib: new layout of Target Pane
- mot_ctrl_m.swift:  introduced MotionControllerTargetPane, a lightweight container pane for both the targetMFS field and the disclosure triangle indicating a submenu next to it, that intercepts clicks on any of its contents to drive the eventual MotionControllerTargetMenu; added manual shutdown logic to overcome deferred-deallocation-on-Quit's problems; implemented nameSelectionsAsTargetMFS() using new common code utility; revised MotionController IB connections to eliminate standalone "Target:" label.

2019.03.15 RELEASE 3010

2019.03.15 Motion Controller: Insert Other Symbol menu

Implemented Insert Other Symbol as a custom menu so that we can do better than list format ("standard" menus) or thoughtless grid format (GSP5 Insert Other Symbol menu) in our symbol layout. We do this with a set of four proprietary objects, some of which we may be able to reuse later.  A PulloutMenuButton displays a menu when clicked; it's different from an NSPopupButton or an NSPulldownButton primarily in terms of not displaying a default item or the "double-arrowhead-popup-chooser." For TSP, this houses a single item with a single view, which permits better locality of mouse-tracking for our custom layout than treating each "Insertable Symbol" as its own NSMenuItem.  Then InsertableMFSMenuView() corresponds to custom view filled with, and capable of mouse-tracking, individual InsertableMFSItemViews, each of can be positioned and sized in Interface Builder and assigned there a piece of MFS (in stream-representation) which appears both as the "item title" and as the MFS that will be inserted into any MFS_EditSession when that item is chosen.

- sketch_mfs.h, sketch_mfs.c: added SketchMFS_MidEdit_HandleMFS() for symmetry to _HandleText and _HandleKey
- TextStylePalette.xib: designed new InsertOtherSymbol menu, grouping symbols by mathematical purpose
- SimpleMFSView.h, SimpleMFSView.m: added support for changing font size of SimpleMFSView displays
- AppDelegate.m: we now manually shutdown the Text Style Palette, to prevent NSView's deferred-dealloc-on-quit from causing Charade to report orphaned gMem allocations at quit
- NSString+GSP.h, NSString+GSP.m: now you can go from NSString to UTF16FixedString in Object-C as well as in Swift!
- mfsstyle_utils.h, mfsstyle_utils.m: Added an Obj-C bridge utility to dispatch insertable MFS to gFrontmostSketch; also a stray needed by the TSP to convert a fixed (parameter-less) MFS_Stream-rep source string into live MFS
- GSP-Bridging-Header.h: Swift eats more C
- TextStylePaletteController.swift: Insert Other Symbol logic, built out of PulloutMenuButton showing an InsertableMFSMenuView filled with InsertableMFSItemViews.


2019.03.14 MC Tweaking

* "Speed" and "Target" labels now go gray when not enabled.
* When Speed is showing a range (e.g. "1.0 .. 4.5") and you double-click to edit, the edit field now empties (so you are typing a new value, rather than editing a piece of text which in turn is a syntax error from the perspective of single-speed-values.)
* Key-entry into Speed value is now restricted to legal math keys (0-9, +/*-(), π, etc.), and 'p' is remapped to 'π'
* Fixed a historical bug, at least 5 years old but possibly back to GSP5.0, in which Sketchpad's internal expression compiler could crash on bad expressions
* Fixed issue in which speed text could remain selected in Motion Controller even after editing had stopped, and that selected text would then block future speed updates arriving from non-keystroke-edit means (e.g. speed steppers, Increase/Decrease Speed, or sketch selection of different motion targets.) Now we consistently keep Speed text deselected except during active, key-focused edit sessions.

- [NEW] mot_ctrl_m.h, mot_ctrl_m.m: added  MacMotionController_ApplySpeedToSelections() as an Obj C utility, since it talks extensively to C structs and objects; and exposed it to Swift
- calc_expr.c: fixed a lack of dereference when the exprcompiler cleans up after expression syntax errors
- MotionController.xib: targeted MotionControllerController as the MC NSWindowDelegate
- mot_ctrl_m.swift: changes per above
- mfsstyle_utils.h, mfsstyle_utils.m, TextStylePaletteController.swift: migrated MacTextStylePalette_RetargetSketchAsKeyWindow to generic MacFloatingEditControllers_RetargetFrontmostSketchAsKeyWindow(), now shared with Motion Controller
- GSP-Bridging-Header.h: Swift eats more C


2019.03.07 Motion Controller debut

We get our first Motion Controller [MC] in this waypoint checkin, adopting many of the techniques of the recent Text Style Palette implementation. More detail to follow.

- apple_drawingcontext.h: #deconditionalized Carbon-era SketchpadWindowEnum in preparation for removal.
- [NEW] motioncontroller.xcassets: ENABLED and ENABLED/PRESSED button captures from GSP5.0 resources
- [NEW] MotionController.xib: MC floating palette and control layout
- [NEW] mot_ctrl_m.m: Objective-C dispatches to Swift
- [NEW] mot_ctrl_m.swift: Swift implementation of the MC Window & WindowController
- dlgm_st.h, dlgm_st.c: retired MotionControllerWindowTitle_MacStringID and MotionControllerMixedSpeeds_MacStringID, which are now supplanted by .xib-localizable strings
- GSP-Bridging-Header.h: Swift eats more C

2019.03.05 TSP: Proper Floating Window semantics

Text Style Palette no longer grabs key focus away from the sketch (deactivating the sketch window) when we drag its title bar or click in white space.

- TextStylePaletteController.swift: The problem here was I don't understand the implications of a Swift property initializer override I was borrowing from elsewhere in the code; setting the (inherited) property ("becomeKeyOnlyIfNeeded") manually during the panel's init sequence solves the problem.

2019.03.04 TSP: Symbol Notation Palette open/close

Fixed two bugs:
- TSP:Font Size combobox should be typable, and ideally menu should show scroll bar.
- TSP: Text Palette should be floatable, draggable, and closable by window widgets

And implemented opening/closing of Symbol Notation Palette per GSP5.0 rules. Coming down the home stretch!

Still having problems with the proper IB settings and NSPanel behavior to give me a floating window that accepts key input into the combo box and doesn't become key otherwise. This one wants to become key after any widget interaction, and after things like dragging the title bar. We intercept most of those and manually reassign key to the sketch, but I'm still trying to find the magic formula in which becomesKeyOnlyIfNeeded actually works.

- textstyle.xcassets: added PNGs for "Insert Other Symbol" and "Symbol Notation Palette"
- TextStylePalette.xib: ditto, plus fooled with NSPanel settings and layout
- BookWindowController.m: suppressed modalityTerminations when a sketch becomes Key AFTER it's already gFrontmostSketch (e.g. when transition from TSP back to Sketch)
- TextStylePaletteController.swift: we know track close events that come through the title bar and sync them to the menu state; we improve our floatability and try to limit our ability to become keyWindow to interactions with the fontSize comboBox; and we wire the "Symbol Notation Palette" button to some animations showing and hiding the lower pane, while tracking whether it was previously hidden in circumstances when we are not editing an MFS caption. This in turn requires implementation of a lightweight Mac-specific sessionEdit synchronization between Sketch_MFS_Mac and MacTextStylePalette. (GSP5.0 had the same thing, but in C rather than Obj C/Swift.)
- mfsstyle_utils.*: random location for a new utility to MacTextStylePalette_RetargetSketchAsKeyWindow()
- sketch_mfs_m.*: we now delegate MFS start up/shut down to TSP


2019.03.03 TSP: Font Menu & First-Stab Font Size and Color menus

TSP Font Menu now works, and displays fonts in native style.
TSP Font Size and Font Color picker both "sort of work," but adding new defects:

2019.03.03            TSP:Font Size combobox should be typable, and ideally menu should show scroll bar.
2019.03.03            TSP: Text Palette should be floatable, draggable, and closable by window widgets
2019.03.03            TSP: Text Color needs a functional Color Picker. If the modeless OS X color picker can be made to work, great. Also still needs design around color menu -- are we going to implement GSP Colors, just use OS X Color Picker, or combo (use OS X Color Picker but add a "GSP Color panel")

For the last issue, we need some good design thinking so that any ColorPicker solution here works well with Menus | Color | Other Color as well (which is currently broken).

- apple_FontRegistry.*: exposed a count of available fonts in the global registry, so OS_Clients can iterate font names for building their own Font-choice affordances
- TextStylePalette.xib: added "on" button appearances for Overbar styles; improved layouts
- TextStylePaletteController.swift: font, font size, and color prelim support
- GSP-Bridging-Header.h: Swift eats more C


2019.02.22 Initial Text Style Palette

We get the basic Text Style palette wired up, with only MFS_Style and MFS_Symbol buttons currently operational.

- mfs_edit.h: Revised SpecialKey enumeration, without revising semantics, to explicitly code constant values now used in TextStylePalette NSButton tags (in .xib)
- sketch_mfs.c: Sketch_MFS_ApplyStyle() blurred semantics between targetting gFrontmostSketch and gSketch (which platform is "supposed" to keep the same, but Cocoa Mac often fails to do, since Cocoa rather than MacSketchpad code directs top-level call-ins). Altered code while preserving GSP5.00 semantics so this routine only targets gFrontmostSketch.

- NEW/textstyle.xcassets: a whole bunch PNGs copy/pasted from GSP5.0 graphics
- NEW/TextStylePalette.xib: first layout of GSP5+ Text Style Palette
- NEW/TextStylePaletteController.swift: ditto
- NEW/mfsstyle_utils.*: Some Objective C helpers for working with MFS_Styles, which Swift imports terribly

- uicom_m.c: PlatformTextStyle_Embellishment now once again passes selected style info on to the Text Style Palette, which can be thought of as an elaborate "custom appearance" for UIC_style commands
- sketch_mfs_m.m: OS_TextStylePaletteIsVisible() and OS_ShowHideTextStylePalette() now operational
- GSP-Bridging-Header.h: Swift eats more C


2019.02.15 Lots of Bugfixing

For the first time in GSP5+ era, document Close and application Quit trigger file-saving prompts (including the modern "Do you want to review 10 docs with unsaved changes?", which gives you an option for Fast-quit), and documents are purged of all gMem allocations appropriately when they are closed so from now "gMem allocations remain at quit" is a legitimate and reportable bug rather than status-quo. This required a fair amount of work, as GSP5+ grafts GSP5.0's document and file model onto Cocoa's "document-oriented app" model (of NSDocuments and NSDocumentController), which of course follows its own rules not compatible with Sketchpad's (such as "on quit, all open documents and windows gets orphaned in memory, rather than closed"). A particular difficulty comes in synchronizing Common Code's notion of whether a document is "dirty" or not with Cocoa's, since GSP5+ by-passes Sketchpad's UIC_Close and UIC_Quit commands in favor of Cocoa's, which are outside of common-code's appearance-manufacture scope. So at present, we (1) maintain synchronization of Cocoa UI with common code's internal state (Book.isDirty) by a periodic timer; (2) then at Close and Quit time make sure that that sync is current regardless of the timer before deciding whether to ask user to save the document; and (3) manually close and dealloc document-related gMem around quit so that the final termination "monitor" can continue to report orphans that result from code errors rather than just from Cocoa's haste to quit.

Part of the "Cocoa rush to quit" we unpack in this checkin is the fact that [dealloc] may not be called on objects that have genuinely been released during that rush. This presents a special problem: if any Objective C object owns gMem allocations that don't get cleaned until [dealloc], these MAY survive to the point that gMem-termination complains they are orphaned (even when, if we could return to the top-level autorelease pool, they would likely get disposed). This falls into the rubric of what Apple calls "scarce resources" in explicit doc warnings to "not hold scarce resources until [dealloc] time." So we rewrite GSPCanvas to dispose its PaintDrawingLayers (gMem allocations) manually when someone attempts to release it, rather than downstream when it actually gets [dealloc'd]. Big pain in ass; would be so much nicer if modern memory management gave us the ability to mark things that really should be dealloc'd, by the time they need to be.

- ** Bugfix: "Cleanup OS_MessageBox: autolayout problems persist" [2019.01.23 **TODO**]"
- ** Bugfix: "Cleaned up OS_MessageBox: hard-coded button names persist" [fix in 2019.01.23 **TODO:**]
- ** Bugfix: [12/12/18 **TODO**]: "There's some sort of system-wide problem with double-click handling, which means we are often left in a drag post-double-click. For Caption Editing, this can be problematic, since it leaves you both typing and selecting at the same time, so you are constantly overtyping a selection (symptom: all of your typed caption-edits appear one character after the other, with each character replacing the list rather than following it). Same bug appears elsewhere (e.g. following double-click-Mark-Center, you are usually dragging the Center)."

- DialogGeneralMessageController.swift: softcoded hard strings
- general_message_dlog.xib: fixed auto-layout and auto-resizing issues
- general_message_dlog.xib: tweaked layout
- AppDelegate.m: rewrote applicationShouldTerminate() to coordinate with common code, and perform a last-minute file-sync if our idle timer failed to sync before user chose Quit.
- BookWindowController.m: Close/Quit coordination, and fairly brittle code around releasing Canvas resources BEFORE dealloc time
- GSPCanvas.*: fixed double-click issue; plus Close/Quit coordination, and fairly brittle code around releasing Canvas resources BEFORE dealloc time
- GSPDocument.*: document syncing between AppKit:Document-Enabled App and Charade/Common Code
- GSPIdler.swift: document syncing between AppKit:Document-Enabled App and Charade/Common Code
- toolmenu.c: moved debugging code outside of an inner loop where it became O(n^2) to the number of script tools, bogging down menu-choice from a LARGE custom tools menu

2019.01.23 Release 3008 & Release Bugfixing

* Added a new OS_MessageBox facility, so e.g. Custom Tools folder retargeting message now appears non-blank.

* Bugfix: Properly disposed of script tools on quit, reducing gMem orphans on quit.

* Partial Bugfix: OS_LoadToolFolder() no longer crashes if the platform has not provided a valid Script Tool folder from prefs before calling.

- build.h: rev'd version#
- missing_assumed_objects.xib: minor cleanup
- general_message_dlog.xib: [NEW] OS_MessageDialogBox, OS_SoftErrror, etc.
- DialogGeneralMessageController.swift: [NEW] ditto
- miscui_m.c: implemented OS_SoftError(), OS_MessageDialog(), OS_OS_StringMessageDialog(); OS_LoadToolFolder() bugfix
- AppDelegate.m: bugfix - tool folder is now disposed on quit

**TODO/DONE 02.15.19:**: Cleanup OS_MessageBox: autolayout problems persist,
**TODO/DONE 01.28.19:** OS_MessageBox: hard-coded button names persist.
**TODO:** Figure out why High Sierra hits OS_LoadScriptToolFolder() with no pref tool folder (default or otherwise), whereas Mojave hits it with prefs properly instantiated.

2019.01.14 Misc Bugfixing: Cursors, Tools, Assert() dialog.

- boss_m.c, AppDelegate.m, GSPIdler.swift: Turned off idler behind Assert() dialog; less likely to cause re-entrancy problems.
- skmouse.c:  Fixed SPiOS-era bug in SkMouse's revised Cursor Handling, so TOOLING now works.


2018.12.17 T018. Implemented "Missing Assumed Objects" dialog

This MFS view causes us to add some preliminary support for fixed-width line wrapping. From (revised) SimpleMFSView.h:

    If you want to size an arbitrary amount of MFS text to a fixed line width,
    you can use [setMFS:wrappedToFixedWidth:]), in which case it is good to (a) make
    sure the height of the SimpleMFSView is free to vary via autolayout and that
    (b) the width is fixed (to something >= pixel margin) via autolayout. You
    can use [setMFS:theMfs wrappedToFixedWidth:theView.bounds.width] in awakeFromNib()
    here, assuming you've first added an autolayout constraint on the width of the view
    to a reasonable quantity.

- missing_assumed_objects.xib: [new] dialog
- DialogMissingAssumedObjectsController.swift: new controller, per above
- SimpleMFSView.m, SimpleMFSView.h: support for fixed width, per above

And the tedius translators:

- dialog_i.c: C to [objective C] dispatcher
- mac_dialoghelpers.m, mac_dialoghelps.h: [objective C] to Swift dispatcher
- GSP-Bridging-Header.h: Swift to C roundtripper


2018.12.13 Implemented MFS in-session Copy/Paste

- clip_m.m: (moved from Mac/stubs to Mac/GSPCore). Got PASTE-text working through modern Pasteboard conniptions; redirected OS_ClipboardCopyText() to OS_ClipboardCopySketch() which was already set up to handle its needs.

2018.12.12 *** SPIOS COMPATIBILITY CHECKIN ***

This file's location suggests its Mac's checkin history, but let's note here some checkins that get SPiOS working again. This consisted of
- moving some mis-located recent new files into AppleCore, so SPiOS can see them too,
- adopting some very minor new changes to common-code API,
- replacing SPiOS's former ios_MfsCursorView with the new AppleCore apple_MfsCursorView
- minimal changes to project file for buildability.

More SPiOS build-project work is needed, and we are currently running with a fake (Nick-specific) Bundle ID, among other things. The previous Info.plist had conditional directives in it to allow product-specific initialization; these were being rejected by XCode 10.  More sleuthing and cleanup is necessary here.

**TODO:** [SPiOS] Sleuth and fixup SPiOS Info.plist and KLOOGE hardcoded Project Bundle ID in SketchExplorer-DEBUG Project Build Settings.

2018.12.12 T016.  MFS Edit Sessions & (MFS) Cursors

You can now edit captions. Technically, we implement OS_SketchMFS_SessionManagement and OS_MFS_Cursors, borrowing an approach from SPiOS (which had a blinking cursor for its edit-param-value in-sketch-edit box), and then refactoring it for use in multiple windows and the Calculator dialog. Finally, we add a bunch more SpecialKey recognizers, so that you can now align captions left/right/center (option-arrow), and move the cursor by word rather than character boudnaries (ctrl-arrow). This also gives us TAB-key handling in-sketch (i.e. changing selected-object).

- apple_MfsCursorView.h, apple_MfsCursorView.m: NEW FILES. refactored former SPiOS-only ios_MfsCursorView to no longer be a global singleton, but to be targeted by a global (class) API rather than a per-instance API for the convenience of MFS_OS_ implementations.

- mf_platform_apple.m: replaced MFS_OS_StrobeCaretCursor()'s Calculator-specific cursor implementation with a simpler apple_MfsCursorView callout

- draw_m.m: OS_ScrollWindow() now keeps any cursor synced to its caption during scrolling. This may not be necessary, since Mac embeds its cursorView instead a docView whose internal coordinatization I believe is unchanged by scrolling, but it follows SPiOS practice and seems judicious.

- CalculatorWindowController.swift: mfsInputView now gets an mfsCursorView at initialization time.

- BookWindowController.m, BookWindowController.h: Sketchbooks now have an optional book-wide cursor, initialized on first time any sketch in that book requires cursing and retained thereafter. Also a method for conveniently activating this cursor (initializing it if necessary) at the start of blinkage.

- sketch_mfs_m.m: disabled several Asserts() relating to Text Palette activation, etc., that were getting in the way of caption-testing experience (see TO DOs). Implemented OS_SketchMFS_Session{Starting/Ending}() and deployed new MfsCursorView logic to SketchMFS sessions.

- GSPCanvas.swift: added Tab_, WordLeft_, TextAlignLeft_, WordRight_, TextAlignRight_, TextAlignUp_, TextAlignDown_, and PageUp_, PageDown_ key recognition.

- GSP-Bridging-Header.h: swift eats more C

**TODO/DONE [30-Sep-19]:** Implement OS_ShowHideNotationPalette.
**TODO/DONE [30-Sep-19]:** Implement OS_ShowHideTextStylePalette, and readd deconditionalized textStylePalette support in OS_SketchMFS_SessionStarting/OS_SketchMFS_SessionEnding.

**BUG/FIXED 10-FEB-19:** There's some sort of system-wide problem with double-click handling, which means we are often left in a drag post-double-click. For Caption Editing, this can be problematic, since it leaves you both typing and selecting at the same time, so you are constantly overtyping a selection (symptom: all of your typed caption-edits appear one character after the other, with each character replacing the list rather than following it). Same bug appears elsewhere (e.g. following double-click-Mark-Center, you are usually dragging the Center).

**BUG/OPEN:** Switch to Rotate Arrow. Drag (you rotate). Hit ESC. Toolbox cursor does not change back to Translate Arrow, but if you drag, you Translate.

2018.12.11 Bugfix: Hot Text actionProc

- sketch_mfs.c: Fixed a common-code bug in which the Hot Text Click animation proc relied on ambient gSketch activation rather than specifically target the sketch in which the Hot Text Click commenced.


2018.12.11 OS_IterateObscuringViews()

Implemented this stub function using modern CGWindowMgr

- draw_m.m: implemented OS_IterateObscuringViews
- win_i.c: removed (final stub in this file) from project

2018.12.07 T015. OS_SoundPlay and cleanup

We add the clicking sound to flickrementation and snap-merging. Then we get rid of a bunch of low-hanging warnings added from our switch to OS X 10.11 floor.

- miscui_m.c: OS_SoundPlay() 
- others: adopted renamed OS constants, added length: guards to getBytes: routines for security against buffer overflow

2018.12.06 T014. Cursors!

Here we get in-sketch cursors for all Sketchpad actions. First I wrote a data exporter to get CURS resources from GSP5.00 into PNG files, which are now in an GSP5+ AssetCatalog. Then I revised skmouse API to allow our idler to idle the mouse to permit cursor changes in response to "drifting geometry" and other ambient changes. (This is only optional new API in skmouse; previous platforms have idled from an event handler that had convenient access to mouse state so could idle with current mouse info and leave it up to skmouse to determine if that info was new. GSP5+'s idle timer doesn't conveniently receive mouse state so prefers to explicit tell skmouse nothing's changed from the platform's side.) Finally, we fix a GSP5+- bug in which the menu command dispatcher failed to mark the mouse as stale post UIC_execution.

- skmouse.*: new optional API for mouse idling; also removed an unused/unnecessary param from SketchMouseAt (WINDOWS INTEGRATION impact)
- cursors.xcassets: new file in build. Cursors are PNG images of filename {oldResourceSymbolicID}_{hotSpotY}_{hotSpotX}.png. Putting them in an asset file means we can conceivably design and substitute dark-mode equivalents, or higher-resolution cursors. Someday!
- tool_m.m: OS_SetCursor() and code for creating NSCursors from PNG assets
- GSPCanvas.m, GSPCanvas.h: Mouse handlers now track whether mouse is inside active sketch or outside, and
- GSPIdler.swift: idler now updates mouse (with common code, to check for ambient sketch changes) and refreshes cursor to last common-code verity
- UICMenuItem.swift: bugfix: UIC_commands systematically invalidate previous mouse/sketch interpretation
- GSP-Bridging-Header.h: swift eats more C

- **TODO**: Implement or remove WAIT CURSORS. (Cursors PNGs are in code, but not yet accessed by anyone.)
- **TODO**: Implement Vertical Rescale cursor for Script View Givens. (Cursor PNG are in code and in OS_SetCursor(), but nobody calls it.)


2018.12.03 T013. Multilabel Dialog

This checkin reimplements Multilabel Dialog, in Swift, using new SimpleMFS and autolayout. Along the way, extended earlier handling of midEdit "live date reporting" controls to handle non-float edit text controls as well as our float controls. Premature validation could screw up dynamics of edit session here too, even though unlike floats validation did not necessarily change the contents of the field. (But it could change firstResponder, etc.) Multilabel uses a live-data-reporting non-float editText to report "first label" keystrokes to common code so it can update the MFS used in the "example: label1, label2, label..." DialogMFS field.

- multilabel_dlog.xib: [new] dialog box
- DialogMultiLabelController.swift: [new] dialog box view controller
- dialog_i.c, mac_dialoghelpers.h, mac_dialoghelpers.m: new dialog box dispatch routines C -> Objective C -> Swift
- GSP-Bridging-Header.h: new C in Swift

- mac_gspcocoadlog.h, mac_gspcocoadlog.m: added a non-float midEdit synchronization facility paralleling editFloatText midEdit sync introduced November 9, 2018.

2018.12.03 T012 Rotate - Calling it a day!

This checkin brings the Rotate dialog under autolayout to an, I believe, shippable version. We still have an issue where when the MFS field (Marked Angle) grows to a large height and is then reset either to shorter MFS or to plain (Fixed Angle) text, the dialog box does not return to its original height but instead has vertical whitespace, but I have not been able to tweak the semantics ("Vertical Content Hugging Priority Layout Constraints") properly to overcome this despite lots of thrashing, and do not think procedural code is involved.

Elsewhere:
* You can now back-click the existing Marked Angle (measure or marker) if your dialog has, meanwhile, been switched back to Fixed Angle. So backclicking becomes a convenience shortcut for choosing "By ... Marked Angle" in the context of a previously-marked angle.

Behind the scenes, this checkin also introduces SimpleValueOrMFSView, an NSStackView subclass that manages any stack containing exactly one SimpleMFSNode and one NSTextNode-or-descendant as an either/or display controller that is compatible with autolayout. Thus it is similar to GSP5.0's MFSOrValueField, with which it coexists in current code. Comparing the two, SimpleValueOrMFSView (currently only appearing in Rotate dialog) is lightweight, free of numerous minor cosmetic glitches (in alignment, filling, activation behavior, etc.) and of dependence on lots of supplemental machinery (key loops, responders, NSTextFieldCells, etc.). Most importantly, SimpleValueOrMFSView reports changes in MFS content size by broadcasting changes to its reported intrinsicContentSize, and does not alter its frame but instead allows some listening superview to alter its frame in response to such broadcasts. MFSOrValueField, on the other hand, despite its various minor bugs, has feature-rich subclasses that supports things like hyperlinks in Object Description text, and reports its size changes directly through manipulation of its NSView frame (which is NOT compatible with a whole-superview-considering autolayout mechanism). The difference in size reporting means that dialogs containing SimpleValueOrMFSView can use autolayout whereas clients of the older view, such as Plot Points dialog, have to do all of their dynamic layout (in response to changed size of MFS contents and therefore MFS fields), and Plot Points code itself demonstrates what a burden that requirement is (likely unportable to dialogs of Translate or Iterate complexity). At this point I suggest long-term trajectory should be to grow SimpleValueOrMFSView and add no new clients to MFSOrValueField.

SimpleValueOrMFSView.swift header contains recipe documentation for setting up new instances of the view.

- SimpleMFSView.m, SimpleMFSView.h: code cleanup and simplification, further Mojave rendering, and added CoreGraphics shrink-to-max-50% display of MFS which exceeds maximum autolayout frame dimensions
- SimpleValueOrMFSView.swift: new NSView, like MFSOrValueField on auto-layout
- dlg_tran.c: TransformDlg_Eligible() now permits back-clicking an existing marked angle if the dialog box is currently showing FIXED ANGLE
- rotate.xib: autolayed-out version of rotate_dlog, adoping SimpleValueOrMFSView
- GSPDialogRotateController.swift: adopted new SimpleValueOrMFSView, removed lots of stale code/comments about manual-resizing-requirements post-MFS content changes (autolayout now does all this)


2018.11.26 SimpleMFSView refinements (contents now edit/selectable/deletable)

Added new API to SimpleMFSView to support selection (so now roughly equivalent to
GObjMfsView, but without hyperlink-support); worked around apparent drawing bugs in
NSTextFieldCell.drawWithFrame(); made MFS appearance more Mojave-friendly

- colors.xcassets: (new) named assets for OS X 10.13-and-later
- apple_utils.m, apple_utils.h: cleaned up #include guards
- mfs_styles.h: numbered MFS_Style attributes in comments to help with horrible Swift tuple-imported MFS_Style code
- KCPMFSField.*, SwiftUtils.swift: removed backClickableMFSFieldBackgroundColor from KCPMFSField, added it to SwifUtils as an NSPanel extension
- mac_gobjvaluefield.m: adopted new backClickableMFSFieldBackgroundColor
- mac_cocoadlog.h: header cleanup
- mac_dialogutils.h, mac_dialogutils.m: (new) Mac_DialogUtil_GetDefaultMFSStyleForDialogBoxes() and Mac_DialogUtil_SetMFSStyleColorFromNSColor()
- SimpleMFSView.h, SimpleMFSView.m: added API for editability, abandoned attempt to draw frame&fill with a NSTextFieldCell and instead handdraw; adopted some dynamic colors to better serve Mojave DarkMode


2018.11.26 Rotate WIP: New SimpleMFSView

Introduced a new SimpleMFSView control that attempts to cooperate with autolayout
requirements. Deployed as a replacement for "By Marked Angle ..." text in Rotate
to immediate improvement of the autolayout_rabbithole. Trying to climb out of rabbit
hole through further work in this direction...

Sticking in Objective C for MFS work since Swift makes such a hash of importing MFS structs.

- SimpleMFSView.h, SimpleMFSView.m: new NSView, which broadcasts (MFS-proper) intrinsicContentSize
for autolayout. Currently only supports static (non-editable) MFS displays.
- GSPDialogRotateController.swift, rotate.xib: switched MARKED_CENTER to SimpleMFS, adjusted autolayout constraints
- GSP-Bridging-Header.h: new C for Swift

2018.11.21 BackClick: eliminating the beep

Backtracking is still using the "event listener" (per earlier checkin today) but here
gains an intermediate SketchCanvasCoverLayer, a transparent window between the sketch
canvas and the dialog that "absorbs clicks" without beeping (since clicks there are now
NOT clicks on a modal-suppressed backwindow, which is what the modalEventLoop gets angry at).
This has a downside of suppressing OTHER mouse traffic that formerly worked to the actual sketchRect,
specifically track-pad zoom gestures (for some reason track-pad scroll gestures never worked there),
but that seems like a regrettably-acceptable price to pay for beep suppression. (No prior GSP5's
ever let you scroll behind dialogs, so no spec-functionality is lost...)

- macbacktrack.m: backTrack now adds a SketchCanvasCoverLayer immediately on top of the sketch
it's tracking, and keeps it synchronized with that sketch if and when that sketch moves during
the dialog. 

2018.11.21 Mojave: BackClick no longer fails

MacOS mojave: We had to change CGEventTapCreate() from requesting an active filter,
kCGEventTapOptionListenOnly, to passive listener (kCGEventTapOptionListenOnly),
in order to work around Mojave's new security rules, which insist that any
active listeners be directly user-authorized in System Prefs|Security|Privacy|Accessibility.
(CGEventTapCreate() returns NULL when not user-authorized.)

By switching to a listener, we can silently continue without user-intervention,
but we lose the ability to FILTER events, which we formerly took advantage of
only in the context of suppressing a successful backclick mousedown from being passed
on to the modalEventLoop, which would SysBeep() when fielded by AppKit since targeted outside the
modal window. So now backclicking beeps even when successful :-(.

Alternatives are uncertain. I have tried addLocalMonitorForEventsMatchingMask, but
it does not receive background events from the modal runLoop, only dialog-specific
events. (This approach is available at SUPPORTS_mojaveEventTapBypass_WIP.)

I have NOT tried writing our own event loop, which simulates the "main"
loop in ignoring most event traffic for non-dialog windows but which happens to
know, and manage, the specifics of back-tracking & back-clicking. That might
have promise but is relatively uncharted terrain in terms of official documentation and
stackOverflow helpers.

Beyond that, I think, we are forced toward strategies that try to enlist the main event loop's
support for backtracking and end the technical modality of our current dialog box situation.

macbacktrack.m's comment that begins with the above paragraphs goes on (many more paragraphs :-)
to outline how this approach could be achieved, what the risks are, etc.

- MacBacktrack.h, MacBacktrack.m: changed to a passive eventTap; also marked up code with
- **TODO**: Try replacing GSPApp:sendEvent() with some sort of timer patch that polls +[NSEvent modifiers] (new in 10.6), or --better?---override [NSResponder flagsChanged:()]?.

2018.11.20 CHECKIN: Mark <<Quantity>> Animations

We rewrite Mac's Mark Center, Mark Mirror, et al., animations in CoreGraphics rather than Quartz, and reimplement them as non-blocking of, rather than blocking, the event loop. (This requires adding some GObjListeners to deal with the case that User deletes or undoes a marked GObj while it is still being animated.)

- drawfx_apple.m: non-blocking, CoreGraphics Mark XXX animations

**TODO:** [Someday.] Implement a nicer Mark Vector and Mark Angle animation which use evolving directed arrows, rather than just swoosh-marks, to indicate the direction of slide or turn.

2018.11.15 Rotate WIP: AutoLayout first attempt

Looking to replace GSP5.0's manual layout algorithms for procedurally resizing all views when a KCPMFSField changes contents (and therefore content size), this checkin experiments with redoing ROTATE using OS X autolayout, and particularly StackViews, which behave almost identically to MFS_StackNodes in providing flexible layout semantics. Unfortunately, this has two bad consequences:

a) We have to advance to OS X 10.11 as our distribution target. This is where a lot of the autolayout stuff matures. Not so bad on its own.
b) It doesn't work full yet. Particularly, a stack view that contains custom views (e.g. KCPMFSField) grows bigger as those views are enhanced with (width, height) constraints indicating they should grow bigger, but does not then shrink back when those individual views shrink back. This is a bit of a drag, since it leaves our dialog oversized after you backclick to, and then backclick away, from big labels. It could very well be that the fault is mine, either in my misunderstanding of autolayout and how to orchestrate the various "content hugging" priorities involved, or in the way of layered autolayout-interoperability on top of GSPMFSorValueField as a client of KCPMFSField. There is some evidence to support the first such argument: https://stackoverflow.com/questions/18625226/in-autolayout-how-to-make-nswindow-resize-back-to-smallest-size-after-removing. But the second (how GSPMFSorValueField interacts with autolayout) is of legitimate concern too; in the present implementation, that field orchestrates its own dimensions by setting both lengthConstraints (on the composite) and frameSizes (on the two subviews). An alternate approach might be to try to really embrace autolayout in this control, and have it manage a horizontal stack {KCPMFSField, KCPTextField}, keeping only one visible, managing content size in relation to init()-provided MIN and MAX dimensions, and reporting both intrinsicSize() and invalidateIntrinsicSize() dynamically for use by layout clients rather than attempting to participate to assert constraints in the global autolayout constraint graph.

Here are some additional notes for future reference:
- Note that autolayout clearly knows GSPMFSorValueFieldhorizontal is "the right size" when switching back to Fixed Angle (since we can see its width bracketed by two stat-text items), even though the dialog remains overlarge at that point, suggesting the overlargeness is NOT a result of us somehow leaving this node too wide. Instead its a hangover in the stack nodes. This mediates against a ground-up GSPMFSorValueField rewrite that tries to do well with intrinsicSize, etc...GSPMFSorValueField is just not the problem.
- On the other hand, if you take out the calls to setFrameSize's in GSPMFSorValueField and leave it ALL up to the allegedly equivalent assertion in GSPMFSorValueField of width & height constraints, you get misplaced internal contents. So we are still setting frames where in theory we shouldn't need to (and where autolayout wants to own our frame dimensions). This could just be some sort of hangover of the KCPMFSView text layout engine, which uses frame sizing to determine render origins, but we aren't in KCPMFSView, we're in GSPMFSorValueField. So maybe there IS some problem here.
- A test app built with a generic resizing custom view inside a stackViews using intrinsicSize makes it seem like views DO cache some metrics from previous invocations (same initial conditions do not lead to same outputs), but that sufficient contentHuggingPriority on the stack node can cause it to minimally hug contents that include shown/hidden and dynamically-size-changing (intrinsicContentSize) customViews.

Meanwhile, banking work-in-progress in this checkin. We preserve the old (pre-autolayout) dialog which functions with the same code in case we need to go back to it, but it doesn't do any resizing based on backclicked elements.

- rotate_dlog.nib: content put into autolayout stacks, autolayout turned on, auto-resizing removed
- mac_gobjvaluefield.h, GSPMfsOrValueField.m: GSPMFSorValueField now includes API for a caller to pass horizontalConstraint and verticalConstraints describing its size, which it will "manage" whenever it resizes itself.
- GSPDialogRotateController.swift: Rotate Dialog now passes IB outlets for its autolayout-constraints on to GSPMfsOrValueField
- rotate_dlog_preautolayout.nib [NIB]: a backup for posterity


- BUG/OPEN: (GSP5.06 and earlier) Create a REALLY LONG calculation, and try to Graph | Plot Value on some axis. At sufficient widths, the entire plotting panel (value + "as" + axis) of the dialog disappears, and you are left with a mostly blank dialog. By contrast, Plot Points works perfectly with the same MFS, expanding first to a maximum width, then trying various smaller fonts, and finally, clipping on the right edge of the edit frame as strategies for making Oversize Fit.

2018.11.13 CHECKIN: Rotate WIP

In which we get the alternating "edit box" for Fixed Angles (e.g. "45.00°") and "static text" for Marked Angles (e.g. "Angle <ABC") unified into a single, backclickable, typable edit box, capable of displaying either a typed constant or constant expression OR a symbolically marked angle (by measure, marker, 2-straights, or 3-points).  Behind the scenes, we invent a new type of Cocoa Dialog Box control capable of alternating between arbitrary MFS and a typed expression, styled based on the Plot Points/Plot Values control that is capable of alternating between a specific GObj label and a typed expression (i.e. red background, indicating "suitable for backclicking"). Along the way we fix some bugs both in last WIP checkin and in Kirk's older Cocoa dialog handling.

- rotate_dlog.nib: replaced EditBox+StaticText items with combo FixedOrMarkedAngleEdit GSPMfsOrValueField.m; revised tab order

- KCPMFSField.h, KCPMFSField.m, mac_gobjfield.h, mac_gobjfield.c: refactored a lot of "the MFS is now selected" out of gobjvaluefield and promoted it up to the KCPMFSField-half of the two fields which combo gobjvaluefield manages, allowing it to be shared by combo mfsvaluefields as well. Fixed a bug in which gobjfield selection-rendering could be broken (for want of current MFS measurements) on MFS that had not been previously drawn.

- mac_gobjvaluefield.h, mac_gobjvaluefield.m, GSPMfsOrValueField.m [NEW]: defined new GSPMfsOrValueField as a peer of GObjValueField, which is revised to share a common delegate protocol. Renamed GObjValueTextField to BackclickableValueTextField, since it is no longer GObj specific.

- mac_dialogdatamap.h, mac_dialogdatamap.m, mac_gspcocoadlog.h, mac_gspcocoadlog.c: added excludeControlFromAutoHiding API to dialogDataMaps and their KCPDialog owners, to prevent KCPDialog from automatically showing and hiding items based on common code's DialogDataRecord visibility that a specific dialog prefers to manage on its own, or leave up to a combo-item (like GObjValueFields or MfsValueFields) to manage.

- DebugUtils.swift [NEW]: a useful utility for debugging the KeyViewLoop over dynamic view management

2018.11.12 CHECKIN: Warning suppression

- pictures.h: eliminated KLOOGE work around next warning
- colorui.h: revised #include order to fix #undefined OS_Color_CompressedSampleRGBAColor
- SwiftUtils.swift: atomic initialization of C structs rather than member-by-member
- clip_m.m: No_Genus rather than 0 since they are no longer type-identical

2018.11.09 CHECKIN: Cocoa Dialog Box Reform & Rotate WIP

Preliminary checkin on Rotate, which unearthed a perfect storm of revisionwork in which the OLDEST-era dialog.h dialogs in Sketchpad -- at a time when the common code model was brand new, and functional idioms and understandings were not yet in play, leading to in-hindsight wonky manipulation of the DialogDataRecords and lots of platform-specific "value add" -- run head into the OLDEST-era Cocoa code in Sketchpad, i.e. Kirk's MacGSPCocoaDialog, which unfurls a hefty architecture that only partly corresponds to the runtime model of the dialog.h common code model. So revisions necessary at both ends to chart progress forward, but along the way we fix some bugs in GSP5+- and GSP5.00 dating to these issues. See lengthy new header comments in mac_gspcocoadlog.* for new formalizations of backclicking, live-feedback for text edit controls, "synchronization" (where platform briefs common code on its changes, and common code potentially briefs platform back on >its< further changes), and "post-synchronization updating" (where platform pushes that second briefing out into realms of dialog-appearance that common code doesn't even know about.)

This checkin is to bank a week's work on new baseClass architecture. The Rotate dialog itself still has lots of cosmetic work left to do (itemized below) but is now 100% functional in servicing commonCode's RotateDialogData spec!

- mac_gspcocoadlog.*: (1) Formalized synchronization semantics, fixed incorrect Cocoa treatment of common code's DialogDataChanged API, (2) added baseCode support for live-reporting (CTRL_DYNAMIC) of floats and also for working around Cocoa problems in which requesting a ctrl's
value forces any in-progress edit to validate, potentially changing its contents and therefore making certain edits impossible. (3) Made first steps toward formalizing a contract between baseClass and subClasses for "post-sync updating" of local appearance dependencies, without pushing too hard on it; and (4) Added baseClass handling of the standard backTrack mouseHit_changeProc() contract, which Rotate and many other dialogs require, though not apparently the several which GSP5.00 already has in Cocoa. (Some of these, e.g. Properties, could definitely be migrated to this new base handler effectively.)

- KCPTextField.m: changed getUnvalidatedString() to provide the active field editor's version of the control's string, if there is one, to the control's itself, since the field editor pushes copies up to the control only on certain triggers which can molest the edit-in-progress.

- GSPDialogRotateController.swift (NEW): WIP Rotate dialog, taking advantage of all the name base-class architecture to give you Rotation with good backclicking and specular images. Lots left to do per above.

- **TODO/DONE:** Rotate Dialog still needs a real GSPGObjMfsOrValueField for angle, so you can see that backclicking is possible, and field- and window- width-resizing to handle all the custom MFS fields.

- **TODO/DONE:** MARK OBJECT ANIMATIONs need to be redesigned from scratch to be modeless rather than modal. Hmmm..

- **TODO/DONE:** Would be nice to fix GSP5.00 "problem" where an already-marked center cannot be re-backclicked to wrench us out of "By Fixed Angle".

- dialog_i.c, mac_dialoghelpers.h, mac_dialoghelpers.m, : C -> ObjC ->Swift dispatch of new Rotate Dialog

- GSPTextStylePrefsDialogController.m: got Fontsize menu working; fixed bug (below) in which patched-out Font menu caused general dialog misfunction; added an updatePreview actionProc for widgets since synchronizeControlsXXX() doesn't GUARANTEE that controls get refreshed from common code on each call; API renaming for calls to synchronizeControls

**TODO:**  Actual Prefs:Text Styles:Font menu still stubbed out and pending more global Font Reform.

- mac_propsheets.m: revised how Properties:Animation handled live-text shadowing of its numerical edits and menu choices regarding the current animation root to its tabular display of all animation roots' full animation descriptors using the new live-reporting architecture, allowing better behavior around edits and fixing a bug that (below) prevented various forms of expression-arithmetic from working in the number-entry boxes here; API renaming for (many) )calls to synchronizeControls

- mac_plotvalue.m, mac_advancedprefs.m, mac_properties.h, mac_properties.m, mac_dialogdatamap.m: API renaming for calls to synchronizeControls

- rotate_dlog.nib: new Rotate dialog

- editparam_dlog.nib, preferences_textstyles.nib, properties_animate.nib, properties_iteration.nib, properties_link.nib, plot_points.nib: God knows! XCode says I changed 'em and there's no diffing .nibs! I certainly updated some actionProcs to point to renamed methods in GSPDialogController, but I think there are other changes too. Note to self: do better job tracking NIB edits before checkin :-).

BUGS/FIXED (found, logged, fixed here): New in GSP5+-. In Prefs:Text, Font menu and Font Size menu are both empty, and the dialog is badly screwed up and easy to crash.  Most of this tracks to the stubbed font menu being interpreted as an MFS_Style_Empty font choice, and downstream code being unable to deal with an undefined font. We substitute MFS_Style_Default for the debugging era. Also we resurrect text_os.h and text.c to define proper values for the Font Size menu.

BUG/FIXED (found, logged, and fixed here): In GSP 5.0x, Properties:Animation, the number entry boxes (Domain, Parameter Speed Per Time Unit, etc., are somewhat defective. You can enter PI and PI multiples in them but not full arithmetic (e.g. π/2), although if you enter something like "0.5π" it will display in the list of animation roots as "π/2". Bizarre!

BUGS/OPEN: In GSP/5.0x and current, there are first-responder or dialog modality issues with Font Size menu. Display the menu with a click release. Arrow about in it to a choice. Press RETURN to activate the choice. Instead the RETURN goes straight to the OK button, dismissing the dialog. Happens in GSP/5.00, but does not happen to the Text Font menu (which is a different menu type; not a combo pop-up and type-in box).


BUG/OPEN: In GSP 5+ dating way back, go to Properties:Object and hover over a hyperlink in the ObjDescText so that a target-highlight appears on the hovered object. Cancel the dialog by pressing ESC, and the target highlighting will linger. Does not happen in GSP5.00.

BUG/OPEN: In GSP 5.0x, in a sketch with a parameter t1 and a path, select the path and Graph | Plot Value. Type "1" and then immediately back-click t1. Rather than instantiate the parameter t1 into the Plot Value, the click acts as a tab-advance to the PLOT button. Doesn't happen (and things work bugfree) if you haven't typed anything in the box first.

2018.10.29 CHECKIN: Misc bugfixing and greatly-improved rendering performance

- skmouse_m.c: Fixed "Object/Sketch Context Menu not under mouse in scrolled sketches. Needs better coordinate conversion" from 10/27. We were converting the common-code sketch coord to CanvasView rather than to PrimalView.

- mac_params.m: Fixed "Edit Parameter Dialog" double-click crashes, possibly as a result of SynthesizedRadioButtonGroups" from 10/27. This was a benign GSP5.00-era bug in which EditParamDialog was attempting to map a nil ControlValue (that is meaningfully non-nil for its sibling NewParamDialog) as if it were a radio-button based on common code's say so. We now map only non-nil controls to data in this particular dialog, and assert on other nil ones where we see them.
- mac_dialogdatamap.m: aforementioned asserts
- mac_gspcocoadlog.m: ditto

- GSPCanvas.m: Mac GSP5+- was rendering the entire primal domain...all objects in the sketch...on every frame, regardless of the meticuluously-computed minimal dirtyRect offered by common code. We now render only the intersection of the primal dirtyRect and visible sketchRect, for much better performance (even with it all clipped out of frame, that additional rendering load was quite noticeable in some sketches). Along the way we diagnosed, but have not yet fixed, the problem we set out with, OPEN below, in which interiorSelection rendering "shimmer" under animation. Here the problem is one of graphic pattern registration with a drawing frame. In GPS5+, unlike GSP5.0, our fundamental quartzContext is no longer the sketchRect, which had a fixed origin relative to motionless selected polygons (the upper-left corner); instead our context is in reference to the primalView/documentView of our scroller, which can get bigger and smaller in all directions as a result of animations happening simultaneous to attempt to display a motionless selected polygon. So fundamentally need to register the pattern to a fixed coordinate, but Quartz (unlike Quickdraw) has no apparent API for this, so instead we're going to have to figure out how to manually offset the pattern by the (modular) offset of the view bounds to some fixed point. Ugh!

- project.pbxproj: Turned "Swift @objc inference" to Default, eliminating warning about deprecated inference. Keep an eye on the console for inference errors!

- editparam_dlog.nib: updated version format

BUG/OPEN: Animate a circle in front of a selected polygon. The polygon's selection pattern flickers and strobes unpredictably as the circle expands outside of the default canvas view; some sort of issue with the pattern origin. See above for analysis.
PDF Export To Do:
- Eliminate "Bitmap Only" from Advanced Prefs
- Fix klooges in RenderBackgroundForExport, compiler warning on PaintLayerForExport
- Fix BROKEN TEXT EXPORT
- Test traces, loci of polygons, iterated pictures, other fringe cases
- BANK IT DANNO

2018.10.28 CHECKIN: Swift 4.2 "simultaneous access" Bugfixing.

- CalculatorWindowController.swift: Moved member variables out of internal singleton struct since this gave rise to false positives in Swift's runtime "exclusive vs. simultaneous access" police. See code comment for details.

2018.10.27 CHECKIN: T011. Clipboard Support, first pass. Copy/Paste of sketch objects works, Paste of (foreign) pictures now works [*], and paste (elsewhere) of a single copied sketch PictureGObj works. PASTING ELSEWHERE OF A PDF IMAGE OF 1 OR MORE SELECTED GEOMETRIC OBJECTS does NOT yet work; awaits redesign of printing architecture. Along the way removed support for Copy/Paste of pre-OS X PICT-format graphics.

Beneath the hood, imported a lot of mac_clip.* and ported to Objective C to work with NSClipboard. Could probably have kept it in C targetting CFPasteboard, which still seems to be supported, but moving to NSClipboard enhances interoperability with Swift (of which there is only a small amount in this transition). Also added a timer-job to poll clibboard contents stability since Cocoa does not provide notifications when pasteboard contents change

- pictures_apple.m: ported Apple_GetOSPictureFromDataOrURL()
- apple_pictures.h: ditto
- pictures.h: added workaround for undiagnosed compiler bug in resolving header #defines?
- clip.*: made backwards-compatible revision to Clip_NewClipboardContentsAreAvailable() API for smoother access from Swift
- apple_clip.h: [NEW] Exposed UTTypes for Mac clipboard
- pasteboard.swift [NEW]: new PasteboardPolling job, monitors pasteboard currency and notifies common code on change
- AppDelegate.m: launched new app-wide PasteboardPolling job
- clip_m.c: unstubbed, imported, and updated OS_ClipboardCopySketch() and its helpers (WriteMemRefToClipAndDispose(), Mac_GetTransformedOSPictureFromPictureGObj(), MacAddPictureToClip()), OS_GetScriptedGObjsFromClipboard() and OS_GrabPictureFromExternalSource().
- GSPIdle.swift: comment cleanup
- GSP-Bridging-Header.h: Swift eats more C

BUG/OPEN: Clipboard WIP. Revisit Copy/Paste to support export of PDF of selected objects.
BUG/FIXED (2018.10.29 CHECKIN): Object/Sketch Context Menu not under mouse in scrolled sketches. Needs better coordinate conversion
BUG/FIXED (2018.10.29 CHECKIN): "Edit Parameter Dialog" double-click crashes, possibly as a result of SynthesizedRadioButtonGroups
BUG/FIXED (2018.10.28 CHECKIN): Calculator crashes on launch as a result of Swift 4.2
BUG/OPEN: Some pictureGObjs fail on read (are they PICTs?) and display as an X. Cf. e.g. the "throbbing heart" (page "implementation 2") in /Users/user/Desktop/Nick GSP Archives Copies/5sketches/Sound/Nick_sound_sandbox.gsp. Has been true since GSP5+-.

----
2018.10.24 various CHECKINs: Ported to XCode 10.0 and Swift 4.2
----
2018.10.23 CHECKIN: background idling now works behind menus, dialog boxes

We retarget the Idler() to commonEventLoopModes, rather than just to the main run loop. This means sketch animations and idling now unconditionally runs behind everything, whereas before the UI could police it. So we're not done yet, just greatly improved.
**TODO/DONE:** Add API to SketchIdler() that lets us pause and resume idle-time processing; and turn OFF idling everyplace "run in background" is NOT allowed by common-code caller!

----
2018.10.23 CHECKIN: T010. OS_ContextMenuClick

The Context menu fully returns, for both Object and Sketch context applications.

- apple_colorui.c : adopted new ColorMenuItemView api
- context_menu.*: exposed gSpecialObjectContextMenu_LocalCommandIDs() from Common Code to Swift
- mnuset_m.c: adopted new UICMenuItem api
- ColorMenuItemView.swift: introduced new API to permit choice of large (main menu) vs. small (context menu) Color Menu Item Swatches
- GSP-Bridging-header: Swift needs to eat more C
- UICMenuItem.swift: introduced new API to allow clients to control whether menu items include default keyboard shortcuts
- skmouse_i.c: [REMOVED FROM BUILD] No mean need for OS_ContextMenuClick() stub
- skmouse_m.c: Obj-C bridge to Swift for OS_ContextMenuClick()
- contextmenu.swift: [NEW] build and display Context Menus
- project.pbxproj: new files in build

----
2018.10.22 CHECKIN: T009. OS_GetCustomToolName().

- miscui_m.c: OS_GetCustomToolName() Objective C to Swift bridge
- custom_tool_name.nib: [NEW] OS_GetCustomToolname() UI
- Classes/Dialogs/DialogGetCustomToolNameController.swift: OS_GetCustomToolname() Swift UI
- GSPDialogColorizationController.swift: moved into new subfolder without changing contents
- BookWindowController.*: added newToolCounter to Mac-specific Book Structures
- GSP-Bridging-Header.h: Swift needs to eat more C
- String+GSP.swift: more support utils for working with UTF16FixedStrings in Swift
- SwiftUtils.swift: ditto
- project.pbxproj: new files in build
----

2018.10.21 CHECKIN: T007. OS_ChooseDirectory() and T008. Custom Tools Folder Menu

[1] Visibly, the Custom Tools folder now appears and basic choice of Custom Tools works, for Toolplay and for (shift) Command-play. Also “Choose Tool Folder”/“Forgot Tool Folder” now works.

[2] Implemented the Choose Folder dialog, and the various logic required to scan a target folder for tools and optionally to populate Example Tools.gsp into the target folder.

**TODO/DONE:** Get SoftError() working. When you do, confirm that Change Tool Folder...'s summative reporting prompt appears correctly ("n tools loaded").

**NOWDONE:(cf. 2018.10.23 CHECKIN):** Get sketch animations, other background work, happening behind Choose File dialog. Deferred because idle-time motion handling may well need a global rethink, e.g. it doesn’t work behind menus or most modal dialogs.

[3] Rewrote but have not yet redesigned the recently-added GSP5+- file scanner. This uses Grand Central Dispatch to run custom-tools scanning in the background, but had never been tested since the rest of Custom Tools was broken. It had some bugs, but also a fundamental design challenge, which is that since it is multithreaded, once it starts in a background thread, it is difficult to stop. Thus changing tool folders naively queued TWO scanning jobs, the second of which would not complete til the first (which theoretically could take hours) completed. I’ve fixed this with a semaphore between the most recent job and any previous ones, but there are still multithreading bugs to be found if you try to quit GSP but yield to the run loop during the quit process (e.g. by posting an Assert dialog), the scanner will resume harvesting script tools even if the Quit-process has begun to shut down vital Charade services (e.g. gem). Badness ensues rapidly.

**TODO/DONE:** Implement orderly shutdown for DirectoryFileScanner and call it at a reliably place in the shutdown sequence.

[4] Changed OS_Menu_AppendSubMenu() API to take a new parameter indicating whether to dramatize the submenu header item in a way that indicates something in the submenu is particularly interesting (i.e. that submenu-head:“DOCUMENT NAME” contains current submenu-contents:”CURRENTLY CHECKED CUSTOM TOOL”). This means GPS5+ handles in common code a UI requirement, or perf, that GSP50 formerly handled only by platform-specific code (and may have been Mac Only).

**INTEGRATION** Windows would need to respect new argument to OS_Menu_AppendSubMenu(), though since offers a common core UI perq that WinGSP may already service through platform-specific logic (or may not implement at all, in GSP50), integration could be as minimal as declaring but ignoring the new parameter in Win’s OS_Menu_AppendSubmenu() implementation.

strm_apple.m: Implemented OS_CopySupplementalFile() and OS_FileSpecFromUTF8PathSpec() [1]

menu_os.h: Declared new API OS_Menu_AppendSubMenu() [4]

tool_menu.c: Common-code now passes extra parameter to OS_Menu_AppendSubMenu() for Document name submenu title when that Doc contains the active Script_Tool [4]

menu_m.c: Fixed theoretical bug around Mac Custom Tools menu item enabling; adopted new OS_Menu_AppendSubMenu() parameter by check-marking the submenu title. [1]. [2]

miscui_m.c: Objective-C bridge between OS_ChooseDirectory() and (Swift) OpenDirectoryDialog, and between OS_LoadToolFolder and (Swift) GSPCustomToolsScanner. [1], [2], [3]

**TODO:** (Code cleanup only.) Revise/eliminate ToolMenu_LoadToolFolderToolsDispatch() hack once you understand how to cast from Swift to C directly.

miscui_m.h: [NEW] new header

ToolboxController.swift: Custom Tools tool now has a longpress-handler that builds and displays Custom Tools menu [1]

OpenDirectoryDialog.swift: new class provides core implementation of OS_ChooseDirectory() [2]

Toolbutton.swift: shortened delay before which Toolbox popups appear (Arrows, Straights, Polygons, Custom Tools) [1]

DirectoryScanner.swift: fixed scanning bug and added a subclass (could technically be in different file) which both implements GSP’s Custom Tools scanning logic (rewriting old Obj-C tool-loading callback in swift) and which implements a cheap semaphore allowing a later Custom Tools scanning job (folder #2) to terminate an earlier one (folder #1). [1]

GSP-Bridging-Header.h: Swift needs more C

NSErrorToGSPError.*: [NEW] non-exhaustive mapping of former to latter, to help Mac report expected file errors back to common code. Currently only services the needs of Custom Tools dialogs but could grow as more File Manager API reports errors meaningfully. [2]

GSPIdler.swift: Revised new GSP5+- idle logic to eliminate a non-concern about background sketch redrawing (Sketchpad_Idle() handles this itself) and to handle deferred Charade_interactions (which it currently does inelegantly) [2]

**TODO:**: Worry about GSPIdle:tick():Charade_ProcessInteractionRequests() not being able to tell whether it’s actually a good time for interaction (the mouse is up, nothing important’s going on, etc.).

String+GSP.swift: new utility functions

OpenDirectoryDialog.swift: turned off a ton of Script View-related UNIMPLEMENTED ASSERTS, replaced them with compile-time and run-time logging asserts, so that Custom Tools can be useable.

checkin_history.txt: [NEW] Began this file on 21 Oct 2018, some GSP5+ checkins have already occured by this points (T00-T05) and it's unlikely I'll document them here but may in time. Also won't mention this file as "changed" ""in each checkin that it documents---that's obvious! Emerging protocols here so subj to negotiation.







