diff --git a/README.md b/README.md index 94c8131..9d2b261 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ To find your plugins directory... # Changelog +* **14.0** - Added new Group Space feature and improved appearance of settings window. Improved sorting and grouping; group title case will now be ignored, and group titles which are numbers will now sort properly. * **13.1** - Display Group Titles will now prefer to use "SFProText-Bold" by default, and if the font doesn't exist, will fall back to "SFUIText-Bold", or "HelveticaNeue-Bold". Remove Unused Symbols will now only remove symbols on current page. * **13.0** - Remove Unused Symbols will now present checklist of removal candidates, requiring the user to review and confirm. * **12.8** - Another attempt to ensure all/only unused symbols are removed. diff --git a/Screenshots/Symbol Organizer.png b/Screenshots/Symbol Organizer.png index bfef3ef..aee59cb 100644 Binary files a/Screenshots/Symbol Organizer.png and b/Screenshots/Symbol Organizer.png differ diff --git a/Symbol Organizer.sketchplugin/Contents/Sketch/functions.js b/Symbol Organizer.sketchplugin/Contents/Sketch/functions.js index 3279e84..d9e62bc 100644 --- a/Symbol Organizer.sketchplugin/Contents/Sketch/functions.js +++ b/Symbol Organizer.sketchplugin/Contents/Sketch/functions.js @@ -35,92 +35,102 @@ function createTextStyle(styleData) { } function createSelect(items,selectedItemIndex,frame) { - selectedItemIndex = (selectedItemIndex > -1) ? selectedItemIndex : 0; - var comboBox = [[NSComboBox alloc] initWithFrame:frame]; - [comboBox addItemsWithObjectValues:items]; - [comboBox selectItemAtIndex:selectedItemIndex]; + var comboBox = NSComboBox.alloc().initWithFrame(frame), + selectedItemIndex = (selectedItemIndex > -1) ? selectedItemIndex : 0; + + comboBox.addItemsWithObjectValues(items); + comboBox.selectItemAtIndex(selectedItemIndex); return comboBox; } function createRadioButtons(options,selected,format,x,y) { - // Set number of rows and columns - if (!format || format == 0) { - var rows = options.length; - var columns = 1; - var buttonMatrixWidth = 300; - var buttonCellWidth = buttonMatrixWidth; - } else { - var rows = options.length / 2; - var columns = 2; - var buttonMatrixWidth = 300; - var buttonCellWidth = buttonMatrixWidth / columns; + var rows = options.length, + columns = 1, + buttonMatrixWidth = 300, + buttonCellWidth = buttonMatrixWidth, + x = (x) ? x : 0, + y = (y) ? y : 0; + + if (format && format != 0) { + rows = options.length / 2; + columns = 2; + buttonMatrixWidth = 300; + buttonCellWidth = buttonMatrixWidth / columns; } - var x = (x) ? x : 0; - var y = (y) ? y : 0; + var buttonCell = NSButtonCell.alloc().init(); + + buttonCell.setButtonType(NSRadioButton); - // Make a prototype cell - var buttonCell = [[NSButtonCell alloc] init]; - [buttonCell setButtonType:NSRadioButton] + var buttonMatrix = NSMatrix.alloc().initWithFrame_mode_prototype_numberOfRows_numberOfColumns( + NSMakeRect(x,y,buttonMatrixWidth,rows*20), + NSRadioModeMatrix, + buttonCell, + rows, + columns + ); - // Make a matrix to contain the radio cells - var buttonMatrix = [[NSMatrix alloc] initWithFrame: NSMakeRect(x,y,buttonMatrixWidth,rows*25) mode:NSRadioModeMatrix prototype:buttonCell numberOfRows:rows numberOfColumns:columns]; - [buttonMatrix setCellSize: NSMakeSize(buttonCellWidth,20)]; + buttonMatrix.setCellSize(NSMakeSize(buttonCellWidth,20)); // Create a cell for each option for (i = 0; i < options.length; i++) { - [[[buttonMatrix cells] objectAtIndex: i] setTitle: options[i]]; - [[[buttonMatrix cells] objectAtIndex: i] setTag: i]; + buttonMatrix.cells().objectAtIndex(i).setTitle(options[i]); + buttonMatrix.cells().objectAtIndex(i).setTag(i); } // Select the default cell - [buttonMatrix selectCellAtRow:selected column:0] + buttonMatrix.selectCellAtRow_column(selected,0); // Return the matrix return buttonMatrix; } function createField(value,frame) { - var field = [[NSTextField alloc] initWithFrame:frame]; - [field setStringValue:value]; + var field = NSTextField.alloc().initWithFrame(frame); + + field.setStringValue(value); return field; } function createLabel(text,size,frame) { - var label = [[NSTextField alloc] initWithFrame:frame]; - [label setStringValue:text]; - [label setFont:[NSFont boldSystemFontOfSize:size]]; - [label setBezeled:false]; - [label setDrawsBackground:false]; - [label setEditable:false]; - [label setSelectable:false]; + var label = NSTextField.alloc().initWithFrame(frame); + + label.setStringValue(text); + label.setFont(NSFont.boldSystemFontOfSize(size)); + label.setBezeled(false); + label.setDrawsBackground(false); + label.setEditable(false); + label.setSelectable(false); return label; } -function createDescription(text,size,frame) { - var label = [[NSTextField alloc] initWithFrame:frame]; - [label setStringValue:text]; - [label setFont:[NSFont systemFontOfSize:size]]; - [label setTextColor:[NSColor colorWithCalibratedRed:(0/255) green:(0/255) blue:(0/255) alpha:0.6]]; - [label setBezeled:false]; - [label setDrawsBackground:false]; - [label setEditable:false]; - [label setSelectable:false]; +function createDescription(text,size,frame,alpha) { + var label = NSTextField.alloc().initWithFrame(frame), + alpha = (alpha) ? alpha : 0.6; + + label.setStringValue(text); + label.setFont(NSFont.systemFontOfSize(size)); + label.setTextColor(NSColor.colorWithCalibratedRed_green_blue_alpha(0/255,0/255,0/255,alpha)); + label.setBezeled(false); + label.setDrawsBackground(false); + label.setEditable(false); + label.setSelectable(false); return label; } function createCheckbox(item,flag,frame) { - flag = ( flag == false ) ? NSOffState : NSOnState; - var checkbox = [[NSButton alloc] initWithFrame:frame]; - [checkbox setButtonType: NSSwitchButton]; - [checkbox setBezelStyle: 0]; - [checkbox setTitle: item.name]; - [checkbox setTag: item.value]; - [checkbox setState: flag]; + var checkbox = NSButton.alloc().initWithFrame(frame), + flag = (flag == false) ? NSOffState : NSOnState; + + checkbox.setButtonType(NSSwitchButton); + checkbox.setBezelStyle(0); + checkbox.setTitle(item.name); + checkbox.setTag(item.value); + checkbox.setState(flag); return checkbox; } @@ -200,13 +210,13 @@ function renameDuplicateSymbols(symbols) { function setKeyOrder(alert,order) { for (var i = 0; i < order.length; i++) { - var thisItem = order[i]; - var nextItem = order[i+1]; + var thisItem = order[i], + nextItem = order[i+1]; if (nextItem) thisItem.setNextKeyView(nextItem); } - alert.alert().window().setInitialFirstResponder(order[0]); + alert.window().setInitialFirstResponder(order[0]); } function createGroupObject(symbols,depth) { @@ -237,7 +247,7 @@ function createGroupObject(symbols,depth) { // If no symbol group has been set yet... if (symbolGroup == 0) { // Set symbol group if a match was found - if (groupLayout[key]['prefix'] == groupPrefix) symbolGroup = groupLayout[key]['group']; + if (groupLayout[key]['prefix'].toLowerCase() == groupPrefix.toLowerCase()) symbolGroup = groupLayout[key]['group']; } } @@ -295,7 +305,7 @@ function removeUnusedSymbols(context,pluginDomain) { alertWindow.setIcon(NSImage.alloc().initByReferencingFile(context.plugin.urlForResourceNamed("icon.png").path())); alertWindow.setMessageText("Remove Unused Symbols"); - alertWindow.addTextLabelWithValue("The following symbols appear to be unused..."); + alertWindow.setInformativeText("The following symbols appear to be unused. Symbols which are nested in other symbols, or used as overrides, were ignored."); var symbolListInnerFrameHeight = listItemHeight * (removeSymbols.length), symbolListFrame = NSScrollView.alloc().initWithFrame(NSMakeRect(0,0,300,200)), @@ -400,3 +410,31 @@ function systemFontExists(fontName) { return fontExists; } + +function createDivider(frame) { + var divider = NSView.alloc().initWithFrame(frame); + + divider.setWantsLayer(1); + divider.layer().setBackgroundColor(CGColorCreateGenericRGB(204/255,204/255,204/255,1.0)); + + return divider; +} + +function sortSymbolsByName(a,b) { + var match = /([^a-zA-Z0-9])|([0-9]+)|([a-zA-Z]+)/g, + ax = [], + bx = []; + + a.name().replace(match,function(_,$1,$2,$3) { ax.push([$1 || "", $2 || Infinity, $3 || "0"])}); + b.name().replace(match,function(_,$1,$2,$3) { bx.push([$1 || "", $2 || Infinity, $3 || "0"])}); + + while (ax.length && bx.length) { + var an = ax.shift(), + bn = bx.shift(), + nn = an[0].localeCompare(bn[0]) || (an[1] - bn[1]) || an[2].localeCompare(bn[2]); + + if (nn) return nn; + } + + return ax.length - bx.length; +} diff --git a/Symbol Organizer.sketchplugin/Contents/Sketch/manifest.json b/Symbol Organizer.sketchplugin/Contents/Sketch/manifest.json index b5adc9a..3ebc44e 100644 --- a/Symbol Organizer.sketchplugin/Contents/Sketch/manifest.json +++ b/Symbol Organizer.sketchplugin/Contents/Sketch/manifest.json @@ -3,32 +3,32 @@ "commands" : [ { "name" : "Configure Symbol Organizer", - "shortcut": "cmd option shift o", + "shortcut" : "cmd option shift o", "identifier" : "symbol-organizer-config", "description" : "Configure and run Symbol Organizer.", - "script" : "symbol-organizer.js", + "script" : "script.cocoascript", "icon" : "icon-sr.png", "handler" : "config" }, { "name" : "Run Symbol Organizer", - "shortcut": "cmd option control o", + "shortcut" : "cmd option control o", "identifier" : "symbol-organizer-run", "description" : "Run Symbol Organizer using last settings.", - "script" : "symbol-organizer.js", + "script" : "script.cocoascript", "icon" : "icon-sr.png", "handler" : "run" } ], "menu" : { - "title": "Symbol Organizer", - "items": [ + "title" : "Symbol Organizer", + "items" : [ "symbol-organizer-config", "symbol-organizer-run" ] }, "identifier" : "com.sonburn.sketchplugins.symbol-organizer", - "version" : "13.1", + "version" : "14.0", "description" : "Organize your symbols page, and layer list, alphabetically and into groupings determined by your symbol names.", "authorEmail" : "jason.burns@synchronoss.com", "name" : "Symbol Organizer", diff --git a/Symbol Organizer.sketchplugin/Contents/Sketch/symbol-organizer.js b/Symbol Organizer.sketchplugin/Contents/Sketch/script.cocoascript similarity index 66% rename from Symbol Organizer.sketchplugin/Contents/Sketch/symbol-organizer.js rename to Symbol Organizer.sketchplugin/Contents/Sketch/script.cocoascript index beb90a4..ecd1a89 100644 --- a/Symbol Organizer.sketchplugin/Contents/Sketch/symbol-organizer.js +++ b/Symbol Organizer.sketchplugin/Contents/Sketch/script.cocoascript @@ -13,6 +13,10 @@ var strSymbolLayoutComplete = "Symbols are now organized"; var strSymbolLayoutCompleteWithRemoves = " unused symbol(s) removed"; var strProblemFetchingSettings = "Unable to fetch settings"; var strProblemSavingSettings = "Unable to save settings"; +var strAlertInformativeText = "Organize your symbols page alphabetically (including layer list) and into groups, determined by your symbol names."; +var strGroupGranularityDesc = "Specifies the \"/\" position in each symbol name which should define the group."; +var strSymbolMaxPerRow = "Max Per Row"; +var strSymbolMaxPerCol = "Max Per Column"; // Style variables var titleStyleName = "Symbol Organizer/Group Title"; @@ -51,6 +55,7 @@ var symbolOrganizer = function(context,type) { // Layout variables var x = 0; var y = 0; + var gPad = parseInt(layoutSettings.gPad); var xPad = parseInt(layoutSettings.xPad); var yPad = parseInt(layoutSettings.yPad); var maxPer = (layoutSettings.maxPer > 0) ? layoutSettings.maxPer : 0; @@ -73,8 +78,7 @@ var symbolOrganizer = function(context,type) { var symbols = (layoutSettings.gatherSymbols == 1) ? (MSApplicationMetadata.metadata().appVersion > 46) ? doc.documentData().localSymbols() : doc.documentData().allSymbols() : page.symbols(); // Sort the symbols object by name - var sortByName = [NSSortDescriptor sortDescriptorWithKey:"name" ascending:1]; - symbols = [symbols sortedArrayUsingDescriptors:[sortByName]]; + symbols.sort(sortSymbolsByName); // if user wants to rename duplicate symbols... if (layoutSettings.renameSymbols == 1) { @@ -171,9 +175,9 @@ var symbolOrganizer = function(context,type) { // Update title position variables per the layout direction if (layoutSettings.sortDirection == 0) { - titleTextX = (objectCount == 1) ? 0 : x+groupSpace+xPad; + titleTextX = (objectCount == 1) ? 0 : x + groupSpace + gPad; } else { - titleTextY = (objectCount == 1) ? 0 : y+groupSpace+yPad; + titleTextY = (objectCount == 1) ? 0 : y + groupSpace + gPad; titleTextAlign = 1; } @@ -203,11 +207,11 @@ var symbolOrganizer = function(context,type) { if (layoutSettings.sortDirection == 0) { // Reset y position, set the x position of the next row y = 0; - x += groupSpace + xPad; + x += groupSpace + gPad; } else { // Reset x position, set the y position of the next row x = 0; - y += groupSpace + yPad; + y += groupSpace + gPad; } // Reset the group space tracker @@ -317,14 +321,15 @@ function getLayoutSettings(context,type) { // Setting variables var defaultSettings = {}; defaultSettings.groupDepth = 1; - defaultSettings.displayTitles = 0; defaultSettings.sortDirection = 0; + defaultSettings.gPad = '200'; + defaultSettings.displayTitles = 0; + defaultSettings.reverseOrder = 0; + defaultSettings.gatherSymbols = 0; defaultSettings.xPad = '100'; defaultSettings.yPad = '100'; defaultSettings.maxPer = ''; - defaultSettings.reverseOrder = 0; defaultSettings.renameSymbols = 0; - defaultSettings.gatherSymbols = 0; defaultSettings.removeSymbols = 0; // Update default settings with cached settings @@ -332,115 +337,169 @@ function getLayoutSettings(context,type) { // If type is set and equal to "config", operate in config mode... if (type && type == "config") { - // Layout variables - var groupPadding = 16; + var fieldHeight = 22, + fieldWidth = 60, + labelHeight = 16, + leftColWidth = 120, + maxPerLabelText = (defaultSettings.sortDirection == 0) ? strSymbolMaxPerCol : strSymbolMaxPerRow, + settingPad = 10, + settingY = 0, + switchHeight = 14, + textOffset = 2, + windowWidth = 350; + + var alert = NSAlert.alloc().init(), + alertIconPath = context.plugin.urlForResourceNamed("icon.png").path(), + alertIcon = NSImage.alloc().initByReferencingFile(alertIconPath), + alertContent = NSView.alloc().init(); + + alert.setIcon(alertIcon); + alert.setMessageText(pluginName); + alert.setInformativeText(strAlertInformativeText); + alert.addButtonWithTitle("Organize"); + alert.addButtonWithTitle("Cancel"); + + alertContent.setFlipped(true); + + var groupGranularityLabel = createLabel("Group Definition",12,NSMakeRect(0,settingY+textOffset*2,leftColWidth,labelHeight)); + alertContent.addSubview(groupGranularityLabel); + + var groupGranularityValue = createSelect(["1st","2nd","3rd","4th","5th","6th","7th","8th"],defaultSettings.groupDepth,NSMakeRect(leftColWidth,settingY,fieldWidth,28)); + alertContent.addSubview(groupGranularityValue); + + var groupGranularityExtra = createDescription("Match",12,NSMakeRect(CGRectGetMaxX(groupGranularityValue.frame())+textOffset,settingY+textOffset*2,60,labelHeight),1.0); + alertContent.addSubview(groupGranularityExtra); + + settingY = CGRectGetMaxY(groupGranularityValue.frame()) + textOffset; + + var groupGranularityDesc = createDescription(strGroupGranularityDesc,11,NSMakeRect(leftColWidth,settingY,windowWidth-leftColWidth,28)); + alertContent.addSubview(groupGranularityDesc); + + settingY = CGRectGetMaxY(groupGranularityDesc.frame()) + settingPad; + + var groupDirectionLabel = createLabel("Layout Direction",12,NSMakeRect(0,settingY,leftColWidth,labelHeight)); + alertContent.addSubview(groupDirectionLabel); + + var groupDirectionValue = createRadioButtons(["Horizontal","Vertical"],defaultSettings.sortDirection,0,leftColWidth,settingY); + alertContent.addSubview(groupDirectionValue); - // Create the alert window - var alertWindow = COSAlertWindow.new(); + groupDirectionValue.cells().objectAtIndex(0).setAction("callAction:"); + groupDirectionValue.cells().objectAtIndex(0).setCOSJSTargetFunction(function(sender) { + symbolMaxPerLabel.setStringValue(strSymbolMaxPerCol); + }); - alertWindow.setIcon(NSImage.alloc().initByReferencingFile(context.plugin.urlForResourceNamed("icon.png").path())); - alertWindow.setMessageText(pluginName); + groupDirectionValue.cells().objectAtIndex(1).setAction("callAction:"); + groupDirectionValue.cells().objectAtIndex(1).setCOSJSTargetFunction(function(sender) { + symbolMaxPerLabel.setStringValue(strSymbolMaxPerRow); + }); - // Grouping options - var groupFrame = NSView.alloc().initWithFrame(NSMakeRect(0,0,300,118+groupPadding)); - groupFrame.setFlipped(true); + settingY = CGRectGetMaxY(groupDirectionValue.frame()) + settingPad; - var groupGranularityLabel = createLabel('Group Definition',12,NSMakeRect(0,0,140,16)); - groupFrame.addSubview(groupGranularityLabel); + var groupSpaceLabel = createLabel("Group Space",12,NSMakeRect(0,settingY,leftColWidth,labelHeight)); + alertContent.addSubview(groupSpaceLabel); - var groupGranularityDescription = createDescription('Symbol Organizer uses a "/" in the name of each symbol to determine the grouping. This setting specifies which "/" should be used.',11,NSMakeRect(0,20,300,42)); - groupFrame.addSubview(groupGranularityDescription); + var groupSpaceValue = createField(defaultSettings.gPad,NSMakeRect(leftColWidth,settingY,fieldWidth,fieldHeight)); + alertContent.addSubview(groupSpaceValue); - var groupGranularityValue = createSelect(['1st','2nd','3rd','4th','5th','6th','7th','8th'],defaultSettings.groupDepth,NSMakeRect(0,70,60,28)); - groupFrame.addSubview(groupGranularityValue); + settingY = CGRectGetMaxY(groupSpaceValue.frame()) + settingPad + textOffset; - var groupTitlesCheckbox = createCheckbox({name:"Display group titles",value:1},defaultSettings.displayTitles,NSMakeRect(0,108,300,14)); - groupFrame.addSubview(groupTitlesCheckbox); + var groupTitlesCheckbox = createCheckbox({name:"Display group titles",value:1},defaultSettings.displayTitles,NSMakeRect(leftColWidth,settingY,windowWidth-leftColWidth,switchHeight)); + alertContent.addSubview(groupTitlesCheckbox); - alertWindow.addAccessoryView(groupFrame); + settingY = CGRectGetMaxY(groupTitlesCheckbox.frame()) + settingPad; - // Layout options - var layoutFrame = NSView.alloc().initWithFrame(NSMakeRect(0,0,300,214+groupPadding)); - layoutFrame.setFlipped(true); + var groupDivider = createDivider(NSMakeRect(0,settingY,windowWidth,1)); + alertContent.addSubview(groupDivider); - var layoutDirectionLabel = createLabel('Layout Direction',12,NSMakeRect(0,0,140,16)); - layoutFrame.addSubview(layoutDirectionLabel); + settingY = CGRectGetMaxY(groupDivider.frame()) + settingPad; - var layoutDirectionValue = createRadioButtons(['Horizontal','Vertical'],defaultSettings.sortDirection,0,0,24); - layoutFrame.addSubview(layoutDirectionValue); + var reverseOrderLabel = createLabel("Layer List",12,NSMakeRect(0,settingY,leftColWidth,labelHeight)); + alertContent.addSubview(reverseOrderLabel); - var layoutHorizontalLabel = createLabel('Horizontal Space',12,NSMakeRect(0,72,140,16)); - layoutFrame.addSubview(layoutHorizontalLabel); + var reverseOrderCheckbox = createCheckbox({name:"Reverse sort order",value:1},defaultSettings.reverseOrder,NSMakeRect(leftColWidth,settingY+textOffset,windowWidth-leftColWidth,switchHeight)); + alertContent.addSubview(reverseOrderCheckbox); - var layoutHorizontalValue = createField(defaultSettings.xPad,NSMakeRect(0,92,60,22)); - layoutFrame.addSubview(layoutHorizontalValue); + settingY = CGRectGetMaxY(reverseOrderCheckbox.frame()) + settingPad; - var layoutVerticalLabel = createLabel('Vertical Space',12,NSMakeRect(0,122,140,16)); - layoutFrame.addSubview(layoutVerticalLabel); + var symbolDivider = createDivider(NSMakeRect(0,settingY,windowWidth,1)); + alertContent.addSubview(symbolDivider); - var layoutVerticalValue = createField(defaultSettings.yPad,NSMakeRect(0,142,60,22)); - layoutFrame.addSubview(layoutVerticalValue); + settingY = CGRectGetMaxY(symbolDivider.frame()) + settingPad; - var layoutMaxLabel = createLabel('Max Per Row/Column',12,NSMakeRect(0,172,140,16)); - layoutFrame.addSubview(layoutMaxLabel); + var gatherSymbolsCheckbox = createCheckbox({name:"Gather symbols from other pages",value:1},defaultSettings.gatherSymbols,NSMakeRect(leftColWidth,settingY,windowWidth-leftColWidth,switchHeight)); + alertContent.addSubview(gatherSymbolsCheckbox); - var layoutMaxValue = createField(defaultSettings.maxPer,NSMakeRect(0,192,60,22)); - layoutFrame.addSubview(layoutMaxValue); + settingY = CGRectGetMaxY(gatherSymbolsCheckbox.frame()) + settingPad; - alertWindow.addAccessoryView(layoutFrame); + var horizontalSpaceLabel = createLabel("Horizontal Space",12,NSMakeRect(0,settingY+textOffset,leftColWidth,labelHeight)); + alertContent.addSubview(horizontalSpaceLabel); - // Other options - var otherFrame = NSView.alloc().initWithFrame(NSMakeRect(0,0,300,138)); - otherFrame.setFlipped(true); + var horizontalSpaceValue = createField(defaultSettings.xPad,NSMakeRect(leftColWidth,settingY,fieldWidth,fieldHeight)); + alertContent.addSubview(horizontalSpaceValue); - var reverseOrderCheckbox = createCheckbox({name:"Reverse layer list sort order",value:1},defaultSettings.reverseOrder,NSMakeRect(0,0,300,14)); - otherFrame.addSubview(reverseOrderCheckbox); + settingY = CGRectGetMaxY(horizontalSpaceValue.frame()) + settingPad; - var renameSymbolsCheckbox = createCheckbox({name:"Sequentially number duplicate symbols",value:1},defaultSettings.renameSymbols,NSMakeRect(0,26,300,14)); - otherFrame.addSubview(renameSymbolsCheckbox); + var verticalSpaceLabel = createLabel("Vertical Space",12,NSMakeRect(0,settingY+textOffset,leftColWidth,labelHeight)); + alertContent.addSubview(verticalSpaceLabel); - var gatherSymbolsCheckbox = createCheckbox({name:"Gather symbols from other pages",value:1},defaultSettings.gatherSymbols,NSMakeRect(0,52,300,14)); - otherFrame.addSubview(gatherSymbolsCheckbox); + var verticalSpaceValue = createField(defaultSettings.yPad,NSMakeRect(leftColWidth,settingY,fieldWidth,fieldHeight)); + alertContent.addSubview(verticalSpaceValue); - var removeSymbolsCheckbox = createCheckbox({name:"Remove unused symbols on page",value:1},defaultSettings.removeSymbols,NSMakeRect(0,78,300,14)); - otherFrame.addSubview(removeSymbolsCheckbox); + settingY = CGRectGetMaxY(verticalSpaceValue.frame()) + settingPad; - var removeSymbolsDescription = createDescription('Presents a checklist of unused symbols for your confirmation. Symbols which are nested in other symbols, or used as overrides, will be ignored.',11,NSMakeRect(18,96,282,42)); - otherFrame.addSubview(removeSymbolsDescription); + var symbolMaxPerLabel = createLabel(maxPerLabelText,12,NSMakeRect(0,settingY + textOffset,leftColWidth,labelHeight)); + alertContent.addSubview(symbolMaxPerLabel); - alertWindow.addAccessoryView(otherFrame); + var symbolMaxPerValue = createField(defaultSettings.maxPer,NSMakeRect(leftColWidth,settingY,fieldWidth,fieldHeight)); + alertContent.addSubview(symbolMaxPerValue); - // Buttons - alertWindow.addButtonWithTitle("OK"); - alertWindow.addButtonWithTitle("Cancel"); + settingY = CGRectGetMaxY(symbolMaxPerValue.frame()) + settingPad; - // Set key order and first responder - setKeyOrder(alertWindow,[ + var renameSymbolsCheckbox = createCheckbox({name:"Sequentially number duplicates",value:1},defaultSettings.renameSymbols,NSMakeRect(leftColWidth,settingY,windowWidth-leftColWidth,switchHeight)); + alertContent.addSubview(renameSymbolsCheckbox); + + settingY = CGRectGetMaxY(renameSymbolsCheckbox.frame()) + settingPad; + + var removeSymbolsCheckbox = createCheckbox({name:"Remove unused symbols on page",value:1},defaultSettings.removeSymbols,NSMakeRect(leftColWidth,settingY,windowWidth-leftColWidth,switchHeight)); + alertContent.addSubview(removeSymbolsCheckbox); + + settingY = CGRectGetMaxY(removeSymbolsCheckbox.frame()) + textOffset; + + var removeSymbolsDesc = createDescription("Presents a checklist for your review and confirmation.",11,NSMakeRect(leftColWidth+18,settingY,windowWidth-leftColWidth-18,28)); + alertContent.addSubview(removeSymbolsDesc); + + alertContent.frame = NSMakeRect(0,0,windowWidth,CGRectGetMaxY(removeSymbolsDesc.frame())); + + alert.accessoryView = alertContent; + + setKeyOrder(alert,[ groupGranularityValue, + groupDirectionValue, + groupSpaceValue, groupTitlesCheckbox, - layoutDirectionValue, - layoutHorizontalValue, - layoutVerticalValue, - layoutMaxValue, reverseOrderCheckbox, - renameSymbolsCheckbox, gatherSymbolsCheckbox, + horizontalSpaceValue, + verticalSpaceValue, + symbolMaxPerValue, + renameSymbolsCheckbox, removeSymbolsCheckbox ]); - var responseCode = alertWindow.runModal(); + var responseCode = alert.runModal(); if (responseCode == 1000) { try { context.command.setValue_forKey_onLayer([groupGranularityValue indexOfSelectedItem],"groupDepth",page); + context.command.setValue_forKey_onLayer([[groupDirectionValue selectedCell] tag],"sortDirection",page); + context.command.setValue_forKey_onLayer([groupSpaceValue stringValue],"gPad",page); context.command.setValue_forKey_onLayer([groupTitlesCheckbox state],"displayTitles",page); - context.command.setValue_forKey_onLayer([[layoutDirectionValue selectedCell] tag],"sortDirection",page); - context.command.setValue_forKey_onLayer([layoutHorizontalValue stringValue],"xPad",page); - context.command.setValue_forKey_onLayer([layoutVerticalValue stringValue],"yPad",page); - context.command.setValue_forKey_onLayer([layoutMaxValue stringValue],"maxPer",page); context.command.setValue_forKey_onLayer([reverseOrderCheckbox state],"reverseOrder",page); - context.command.setValue_forKey_onLayer([renameSymbolsCheckbox state],"renameSymbols",page); context.command.setValue_forKey_onLayer([gatherSymbolsCheckbox state],"gatherSymbols",page); + context.command.setValue_forKey_onLayer([horizontalSpaceValue stringValue],"xPad",page); + context.command.setValue_forKey_onLayer([verticalSpaceValue stringValue],"yPad",page); + context.command.setValue_forKey_onLayer([symbolMaxPerValue stringValue],"maxPer",page); + context.command.setValue_forKey_onLayer([renameSymbolsCheckbox state],"renameSymbols",page); context.command.setValue_forKey_onLayer(0,"removeSymbols",page); if (page.userInfo() && page.userInfo().valueForKey(oldPluginDomain)) { @@ -464,14 +523,15 @@ function getLayoutSettings(context,type) { return { groupDepth : [groupGranularityValue indexOfSelectedItem], + sortDirection : [[groupDirectionValue selectedCell] tag], + gPad : [groupSpaceValue stringValue], displayTitles : [groupTitlesCheckbox state], - sortDirection : [[layoutDirectionValue selectedCell] tag], - xPad : [layoutHorizontalValue stringValue], - yPad : [layoutVerticalValue stringValue], - maxPer : [layoutMaxValue stringValue], reverseOrder : [reverseOrderCheckbox state], - renameSymbols : [renameSymbolsCheckbox state], gatherSymbols : [gatherSymbolsCheckbox state], + xPad : [horizontalSpaceValue stringValue], + yPad : [verticalSpaceValue stringValue], + maxPer : [symbolMaxPerValue stringValue], + renameSymbols : [renameSymbolsCheckbox state], removeSymbols : [removeSymbolsCheckbox state] } } else return false; @@ -481,14 +541,15 @@ function getLayoutSettings(context,type) { // Return updated settings return { groupDepth : defaultSettings.groupDepth, - displayTitles : defaultSettings.displayTitles, sortDirection : defaultSettings.sortDirection, + gPad : defaultSettings.gPad, + displayTitles : defaultSettings.displayTitles, + reverseOrder : defaultSettings.reverseOrder, + gatherSymbols : defaultSettings.gatherSymbols, xPad : defaultSettings.xPad, yPad : defaultSettings.yPad, maxPer : defaultSettings.maxPer, - reverseOrder : defaultSettings.reverseOrder, renameSymbols : defaultSettings.renameSymbols, - gatherSymbols : defaultSettings.gatherSymbols, removeSymbols : defaultSettings.removeSymbols } } diff --git a/appcast.xml b/appcast.xml index a882674..db76c19 100644 --- a/appcast.xml +++ b/appcast.xml @@ -6,15 +6,15 @@ Organize your symbols page, and layer list, alphabetically and into groupings determined by your symbol names. en - Version 13.1 + Version 14.0 -
  • Display Group Titles will now prefer to use "SFProText-Bold" by default, and if the font doesn't exist, will fall back to "SFUIText-Bold", or "HelveticaNeue-Bold". Remove Unused Symbols will now only remove symbols on current page.
  • +
  • Added new Group Space feature and improved appearance of settings window. Improved sorting and grouping; group title case will now be ignored, and group titles which are numbers will now sort properly.
  • ]]>
    - +