[Cuis-dev] Preferennce save/load and actionMap
Hilaire Fernandes
hilaire at drgeo.eu
Fri May 6 02:52:43 PDT 2022
With the file out.
Le 06/05/2022 à 11:51, Hilaire Fernandes a écrit :
>
> Here is the updated PreferencesNG class.
>
--
GNU Dr. Geo
http://drgeo.eu
http://blog.drgeo.eu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20220506/efcfea87/attachment-0001.htm>
-------------- next part --------------
'From Cuis 6.0 [latest update: #5113] on 6 May 2022 at 11:52:04 am'!
!classDefinition: #PreferenceNG category: #'System-Support'!
Object subclass: #PreferenceNG
instanceVariableNames: 'name description category value type'
classVariableNames: 'ThePreferences'
poolDictionaries: ''
category: 'System-Support'!
!PreferenceNG commentStamp: '<historical>' prior: 0!
My instance is a Preference whose value is of a given class (type), or follow the description of the type instance
- name, category: symbol
- description: string
- type: a class (Boolean, String, Color, BlockClosure, etc.) or an instance (collection, intervale, etc.)
- value: an object whose class match type or the instance description of the type
Modus Operendi
- To create a Preference, invoke the instance creation class method (Preference name:description:category:type:value:). The new preference is automatically remembered. If a preference with same name already exist, its instance is updated with the new provided data and its instance returned.
- To access, invoke as dictionary (Preference at: #biggerCursors), a short cut exist (Preference biggerCursors)!
!PreferenceNG methodsFor: 'printing' stamp: 'hlsf 5/5/2022 12:31:23'!
printOn: aStream
aStream nextPutAll: self class name ;
nextPutAll: ' (#';
nextPutAll: name ;
nextPutAll: ' = ';
nextPutAll: type printString;
nextPutAll: '::';
nextPutAll: value printString;
nextPut: $)! !
!PreferenceNG methodsFor: 'initialization' stamp: 'hlsf 5/5/2022 12:21:27'!
name: nameSymbol description: aString category: categorySymbol type: aType value: aValue
name _ nameSymbol.
description _ aString.
category _ categorySymbol.
type _ aType ifNotNil: [aType] ifNil: [self class detectType: aValue ].
value _ aValue! !
!PreferenceNG methodsFor: 'accessing' stamp: 'hlsf 4/30/2022 14:25:45'!
category
^ category ! !
!PreferenceNG methodsFor: 'accessing' stamp: 'hlsf 5/2/2022 22:19:11'!
category: aSymbol
aSymbol isNil ifFalse: [category _ aSymbol ]! !
!PreferenceNG methodsFor: 'accessing' stamp: 'hlsf 4/30/2022 14:25:57'!
description
^ description! !
!PreferenceNG methodsFor: 'accessing' stamp: 'hlsf 5/2/2022 22:18:30'!
description: aString
aString isEmptyOrNil ifFalse: [description _ aString ]! !
!PreferenceNG methodsFor: 'accessing' stamp: 'hlsf 4/30/2022 14:26:02'!
name
^ name! !
!PreferenceNG methodsFor: 'accessing' stamp: 'hlsf 5/4/2022 23:32:57'!
type
^ type! !
!PreferenceNG methodsFor: 'accessing' stamp: 'hlsf 5/3/2022 21:16:04'!
value
" If my type is closure without argument, return my value "
^ (type == BlockClosure and: [value argumentCount = 0])
ifTrue: [value value]
ifFalse: [value]
! !
!PreferenceNG methodsFor: 'accessing' stamp: 'hlsf 5/3/2022 20:54:17'!
value: aValue
type class class == Metaclass "type is a Class"
ifTrue: [
(aValue isKindOf: type) ifFalse: [self error: aValue printString, ' is not a ', type printString].
value _ aValue .
]
ifFalse: [ "Should be handled somehow by the preference editor "
value _ aValue].
self triggerEvent: #preferenceChanged with: self! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
!classDefinition: 'PreferenceNG class' category: #'System-Support'!
PreferenceNG class
instanceVariableNames: ''!
!PreferenceNG class methodsFor: 'accessing' stamp: 'hlsf 4/30/2022 21:11:22'!
all
^ ThePreferences
! !
!PreferenceNG class methodsFor: 'accessing' stamp: 'hlsf 4/30/2022 22:21:36'!
at: symbolName
^ (self instanceAt: symbolName) value! !
!PreferenceNG class methodsFor: 'accessing' stamp: 'hlsf 5/3/2022 20:47:15'!
at: symbolName put: aValue
| myPref |
myPref _ self instanceAt: symbolName.
myPref value: aValue! !
!PreferenceNG class methodsFor: 'accessing' stamp: 'hlsf 4/30/2022 14:28:57'!
categories
| categories |
categories _ Set new.
ThePreferences values do: [:aPreference | categories add: aPreference category].
^ categories sorted! !
!PreferenceNG class methodsFor: 'accessing' stamp: 'hlsf 4/30/2022 22:19:26'!
instanceAt: symbolName
^ ThePreferences at: symbolName ifAbsent: [self error: 'Unknown preference ', symbolName ]! !
!PreferenceNG class methodsFor: 'accessing' stamp: 'hlsf 4/30/2022 14:29:56'!
select: aCategory
" I select the preferences of the given category "
^ ThePreferences values select: [:aPreference | aPreference category == aCategory ]! !
!PreferenceNG class methodsFor: 'instance creation' stamp: 'hlsf 5/3/2022 19:16:59'!
name: nameSymbol category: categorySymbol value: aValue
self name: nameSymbol description: nil category: categorySymbol type: nil value: aValue
! !
!PreferenceNG class methodsFor: 'instance creation' stamp: 'hlsf 5/3/2022 19:59:49'!
name: nameSymbol description: aString category: categorySymbol type: aType value: aValue
"If I exist, I am updated with the newer sent data "
(nameSymbol isSymbol or: [categorySymbol isSymbol]) ifFalse:
[self error: 'Preference Name & Category are not valid symbol.'].
^ ThePreferences
at: nameSymbol
ifPresent: [:thePref |
thePref
description: aString;
category: categorySymbol;
value: aValue;
yourself]
ifAbsent: [ | newPref |
newPref _ self new ::
name: nameSymbol
description: aString
category: categorySymbol
type: aType
value: aValue.
ThePreferences at: nameSymbol put: newPref ].
! !
!PreferenceNG class methodsFor: 'error handling' stamp: 'hlsf 4/30/2022 22:20:35'!
doesNotUnderstand: aMessage
aMessage hasArguments ifTrue: [^ super doesNotUnderstand: aMessage].
^ self at: aMessage selector! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/4/2022 16:13:29'!
cuisDefaultsFont
^ #(
# (aaFontsColormapDepth 4)
#(cacheTrueTypeGlyphs true )
#(loadOnlyLatinGlyphData true )
#(properDisplayAlphaForFonts false )
#(subPixelRenderColorFonts true )
)! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/4/2022 20:22:05'!
cuisDefaultsGui
^ #(
#(balloonHelpEnabled true )
#(biggerCursors false )
#(cacheDisplayContentWhenMovingMorphs true )
#(cheapWindowReframe false )
#(clickGrabsMorphs false )
#(ctrlArrowsScrollHorizontally false )
#(drawKeyboardFocusIndicator true )
#(focusFollowsMouse true )
#(focusIndicatorWidth 1)
#(fullScreenLeavesDeskMargins true )
#(haloEnclosesFullBounds true )
#(halosShowCoordinateSystem true )
#(menuKeyboardControl true )
#(optionalButtons true )
#(selectiveHalos true )
#(subPixelRenderFonts true )
#(tapAndHoldEmulatesButton2 true )
#(tileResizerInWindowMenu true )
#(wantsMenuIcons true )
)! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/4/2022 16:26:09'!
cuisDefaultsProgramming
^ #(
#(allowBlockArgumentAssignment false )
#(alternativeBrowseIt false )
#(backgroundColorFillsAllBackground true )
#(browseWithPrettyPrint false )
#(classAnnotations #(instanceMethodsCount classMethodsCount linesOfCode))
#(debugHaloHandle true )
#(debugLogTimestamp true )
#(debugShowDamage false )
#(decorateBrowserButtons true )
#(diffsInChangeList true )
#(diffsWithPrettyPrint false )
#(extraDebuggerButtons true )
#(fullPrintItInWorkspaces false )
#(highlightBlockNesting true )
#(italicsInShout true)
#(leftArrowAssignmentsInGeneratedCode false )
#(listClassesHierarchically true )
#(logDebuggerStackToFile false )
#(methodAnnotations #(timeStamp linesOfCode messageCategory implementorsCount sendersCount packages changeSets))
#(prettyPrintRectangularBlocks false )
#(shiftClickShowsImplementors false )
#(shoutInWorkspaces true )
#(showAnnotations true )
#(showLinesInHierarchyViews true )
#(stylingWithEmphasisInWorkspaces false )
#(systemCategoryAnnotations #(classCount instanceMethodsCount classMethodsCount linesOfCode))
#(syntaxHighlightingAsYouType true )
#(syntaxHighlightingAsYouTypeAnsiAssignment false )
#(syntaxHighlightingAsYouTypeLeftArrowAssignment false )
#(thoroughSenders true )
)
! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/4/2022 20:23:44'!
cuisDefaultsSystem
^ #( #(allowNonLocalReturnsInExceptionHandlers true )
#(askConfirmationOnQuit true )
#(askToInstallComplexPackage true )
#(automaticPlatformSettings true )
#(autoNumberUserChanges false )
#(caseSensitiveFinds false )
#(changeSetVersionNumbers true )
#(checkForSlips true )
#(checkLostChangesOnStartUp false )
#(cmdDotEnabled true )
#(cmdDotInterruptTakesStatistics false )
#(dismissAllOnOptionClose false )
#(initialFileListDirectories #roots )
#(selectionsMayShrink true )
#(serverMode false )
#(systemWindowEmbedOK false )
#(transcriptLogVerbose true )
#(warnAboutNonLocalReturnsInExceptionHandlers false)
#(warnIfNoChangesFile true )
#(warnIfNoSourcesFile true )
)! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/1/2022 18:48:26'!
iconicHaloSpecifications
"Answer an array that characterizes the locations, colors, icons, and selectors of the halo handles
that may be used in the iconic halo scheme"
^ #( "selector horiz vert color info icon key"
(addDismissHandle: left top (red) haloDismissIcon 'Remove')
(addMenuHandle: leftCenter top (blue lighter) haloMenuIcon 'Menu')
(addGrabHandle: center top (black) haloGrabIcon 'Pick up')
(addDragHandle: rightCenter top (brown) haloDragIcon 'Move')
(addDupHandle: right top (green) haloDuplicateIcon 'Duplicate')
(addExploreHandle: left topCenter (orange) haloDebugIcon 'Explore')
(addDebugHandle: right topCenter (orange) haloDebugIcon 'Debug')
(addCollapseHandle: left center (tan) haloCollapseIcon 'Collapse')
(addScaleHandle: right center (blue) haloScaleIcon 'Change scale')
(addRotateHandle: left bottom (blue) haloRotateIcon 'Rotate')
(addHelpHandle: center bottom (lightBlue) haloHelpIcon 'Help')
(addResizeHandle: right bottom (yellow) haloResizeIcon 'Change size')
"FIXME - Currently non-functional...
(addRecolorHandle: right bottomCenter (magenta darker) haloColorIcon 'Change color')
"
)! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/5/2022 20:59:18'!
initialize
ThePreferences _ Dictionary new.
#(font gui programming system) do: [: category | self installDefault: category].
self installHaloPreferencesWith: self iconicHaloSpecifications.
self installFontPreferences.
self installMiscPreferences ! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/4/2022 20:26:20'!
installDefault: category
(self perform: (#cuisDefaults, category capitalized) asSymbol) do: [:anArray |
self
name: anArray first description: '' category: category
type: (self detectType: anArray second) value: anArray second]
! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/4/2022 16:10:30'!
installFontPreferences
| myPref |
myPref _ PreferenceNG
name: #guiElementsSize
description: 'Size of the graphic intereface element'
category: #gui
type: #(tinyFonts verySmallFonts smallFonts standardFonts largeFonts veryLargeFonts hugeFonts)
value: #standardFonts.
myPref when: #preferenceChanged send: #defaultFontSize: to: PreferenceNG.
"Trigger manually, the preference was instantiated with value, so no setter message sent"
myPref triggerEvent: #preferenceChanged with: myPref. ! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/4/2022 16:10:52'!
installHaloPreferencesWith: anArray
| aColor |
^ PreferenceNG
name: #haloSpecifications
description: 'Halo specifications describing which halos are to be used, what they should look like, and where they should be situated'
category: #gui
type: Array
value: (anArray collect: [ :each |
aColor _ Color.
each fourth do: [ :sel | aColor _ aColor perform: sel].
HaloSpec new
horizontalPlacement: each second
verticalPlacement: each third
color: aColor
iconSymbol: each fifth
addHandleSelector: each first
hoverHelp: each sixth])! !
!PreferenceNG class methodsFor: 'class initialization' stamp: 'hlsf 5/4/2022 16:11:03'!
installMiscPreferences
"Preference balue defined with closure. We could insert in a dynamic array..."
| myPref |
PreferenceNG
name: #haloHandleSize category: #gui
value: [(PreferenceNG at: #standardListFont) pointSize * 5 // 3 max: 16].
PreferenceNG
name: #roundedButtonsRadius category: #gui
value: [(PreferenceNG at: #standardListFont) pointSize * 8 // 14].
PreferenceNG
name: #roundedWindowRadius category: #gui value: [(PreferenceNG at: #standardListFont) pointSize].
PreferenceNG
name: #scrollbarThickness category: #gui value: [(PreferenceNG at: #windowTitleFont) pointSize + 2].
PreferenceNG name: #classFinder category: #programming value: [ BrowserWindow findClass ].
PreferenceNG name: #defaultAuthorName category: #programming value: [Utilities authorName].
PreferenceNG name: #userChangeFileNameExtension category: #system value: '.user.changes'.
" Shout assignment character "
myPref _ PreferenceNG name: #assignmentGlyphSelector description: 'How should look like the assignment character?' category: #programming type: #(useLeftArrow useAlwaysLeftArrow) value: #useLeftArrow.
myPref when: #preferenceChanged send: #assignmentGlyph: to: PreferenceNG.! !
!PreferenceNG class methodsFor: 'fileIn/Out' stamp: 'hlsf 5/6/2022 11:42:57'!
loadFrom: aFileEntry
" Load all preferences from file, update the existing preferences with the data from file "
(SmartRefStream restoreFromFile: aFileEntry) do: [:aPref |
PreferenceNG
name: aPref name
description: aPref description
category: aPref category
type: aPref type
value: (aPref instVarNamed: #value) " We want the raw value "]! !
!PreferenceNG class methodsFor: 'fileIn/Out' stamp: 'hlsf 4/30/2022 22:20:56'!
save: nameSymbol to: aFileEntry
" Save one preference to a file, even for a sole preference we save in a Dictionary"
| myPref |
myPref _ self instanceAt: nameSymbol.
SmartRefStream
dumpOnFile: aFileEntry
object: {myPref name -> myPref} asDictionary! !
!PreferenceNG class methodsFor: 'fileIn/Out' stamp: 'hlsf 4/30/2022 21:58:19'!
saveAllTo: aFileEntry
" Save all the preferences to a file "
SmartRefStream dumpOnFile: aFileEntry object: ThePreferences! !
!PreferenceNG class methodsFor: 'fileIn/Out' stamp: 'hlsf 4/30/2022 21:57:59'!
saveCategory: categorySymbol to: aFileEntry
| myPref |
myPref _ self select: categorySymbol.
SmartRefStream
dumpOnFile: aFileEntry
object: (myPref collect: [:aPref | aPref name -> aPref ]) asDictionary! !
!PreferenceNG class methodsFor: 'helpers' stamp: 'hlsf 5/5/2022 12:21:56'!
detectType: anObject
"When the type is not provided, we can try to deduce it "
^ anObject class
caseOf: {
[True] -> [Boolean].
[False] -> [Boolean].
}
otherwise: [anObject class]
! !
!PreferenceNG class methodsFor: 'event handlers' stamp: 'hlsf 5/4/2022 16:12:03'!
assignmentGlyph: assignmentPref
AbstractFont withAllSubclassesDo: [ :fontClass | fontClass assignmentGlyphSelectorPreferenceChanged ]! !
!PreferenceNG class methodsFor: 'event handlers' stamp: 'hlsf 5/3/2022 20:54:30'!
defaultFontSize: guiElementSizePref
| font titleFont pointSize |
pointSize _ self fontSizes at: guiElementSizePref value.
font _ FontFamily familyName: FontFamily defaultFamilyName pointSize: pointSize.
PreferenceNG name: #standardListFont category: #font value: font.
PreferenceNG name: #standardMenuFont category: #font value: font.
PreferenceNG name: #standardCodeFont category: #font value: font.
PreferenceNG name: #standardButtonFont category: #font value: font.
FontFamily defaultFamilyName: font familyName defaultPointSize: pointSize.
titleFont _ FontFamily familyName: FontFamily defaultFamilyName pointSize: pointSize * 12//10.
PreferenceNG name: #windowTitleFont category: #font value: titleFont.
MorphicCanvas allSubclassesDo: [ :c| c guiSizePreferenceChanged ].
UISupervisor ui ifNotNil: [ :w | w fontPreferenceChanged ].
PreferenceNG at: #biggerCursors put: (pointSize > 14).
Cursor defaultCursor activateCursor.
^font! !
!PreferenceNG class methodsFor: 'fonts' stamp: 'hlsf 5/3/2022 18:58:38'!
fontSizes
^ `{
#tinyFonts -> 7 .
#verySmallFonts -> 9 .
#smallFonts ->11 .
#standardFonts -> 14 .
#largeFonts -> 18 .
#veryLargeFonts -> 24 .
#hugeFonts -> 32} asDictionary`
! !
!PreferenceNG class methodsFor: 'fonts' stamp: 'hlsf 5/3/2022 19:38:13'!
setDefaultFont: aFontName
"Change the font on the whole system without changing point sizes."
FontFamily defaultFamilyName: aFontName.
Preferences
setDefaultFont: FontFamily defaultFamilyName
spec: {
{#standardListFont. (PreferenceNG at: #standardListFont) pointSize.}.
{#standardMenuFont. (PreferenceNG at: #standardMenuFont) pointSize.}.
{#windowTitleFont. (PreferenceNG at: #windowTitleFont) pointSize.}.
{#standardCodeFont. (PreferenceNG at: #standardCodeFont) pointSize.}.
{#standardButtonFont. (PreferenceNG at: #standardButtonFont) pointSize.}.
}.
MorphicCanvas allSubclassesDo: [ :c| c guiSizePreferenceChanged ].
UISupervisor ui ifNotNil: [ :w | w fontPreferenceChanged ].! !
!PreferenceNG class methodsFor: 'fonts' stamp: 'hlsf 5/3/2022 19:39:30'!
setDefaultFont: fontFamilyName spec: defaultFontsSpec
| font |
defaultFontsSpec do: [ :triplet |
font _ FontFamily familyName: fontFamilyName pointSize: triplet second.
font ifNil: [ font _ FontFamily defaultFamilyAndPointSize ].
triplet size > 2 ifTrue: [ font _ font emphasized: triplet third ].
PreferenceNG at: triplet first put: font ].
MorphicCanvas allSubclassesDo: [ :c| c guiSizePreferenceChanged ].
UISupervisor ui ifNotNil: [ :w | w fontPreferenceChanged ].! !
!PreferenceNG class methodsFor: 'obsolete' stamp: 'hlsf 5/4/2022 14:56:05'!
desktopMenuTitle
"I have project to get rid of this one"
^ 'World' ! !
!PreferenceNG class methodsFor: 'obsolete' stamp: 'hlsf 4/30/2022 14:39:32'!
import
"Import the preferences from the old system"
Preferences preferencesDictionary valuesDo: [:oldPref |
PreferenceNG
name: oldPref name
description: (oldPref instVarNamed: #helpString)
category: (oldPref instVarNamed: #categoryList) first
type: Object
value: oldPref preferenceValue
]! !
PreferenceNG initialize!
More information about the Cuis-dev
mailing list