UIPainterView.st
changeset 134 d5ab85ec27fd
parent 131 715b3dbba87d
child 137 335faeed1663
equal deleted inserted replaced
133:e12f82d3afb7 134:d5ab85ec27fd
   401 
   401 
   402 deleteSelection
   402 deleteSelection
   403     "delete the selection; copy the selection into the cut&paste-buffer
   403     "delete the selection; copy the selection into the cut&paste-buffer
   404      and open a transaction
   404      and open a transaction
   405     "
   405     "
   406     |text specs coll|
   406     |specs coll|
   407 
   407 
   408     coll := self minSetOfSuperViews:(self selection).
   408     coll := self minSetOfSuperViews:(self selection).
   409 
   409 
   410     coll notNil ifTrue:[
   410     coll notNil ifTrue:[
   411         listHolder disableNotificationsWhileEvaluating:[
   411         listHolder disableNotificationsWhileEvaluating:[
   412             self select:nil.
   412             self select:nil.
   413             specs := coll collect:[:aView| self fullSpecFor:aView ].
   413             specs := coll collect:[:aView| self fullSpecFor:aView ].
   414             text  := self transactionTextFor:coll.
   414 
   415 
   415             self withinTransaction:#cut objects:coll do:[
   416             undoHistory transaction:#cut text:text do:[
   416                 coll reverseDo:[:aView|
   417                 coll reverseDo:[:o||p|
   417                     self createUndoRemove:aView.
   418                     (p := self propertyOfView:o) notNil ifTrue:[
   418                     self remove:aView
   419                         self undoRemove:(p identifier)
       
   420                     ].
       
   421                     self remove:o
       
   422                 ]
   419                 ]
   423             ].
   420             ].
   424             self setSelection:specs.
   421             self setSelection:specs.
   425         ]
   422         ]
   426     ]
   423     ]
   479             view realize.
   476             view realize.
   480             newSel add:view.
   477             newSel add:view.
   481         ].
   478         ].
   482     ].
   479     ].
   483 
   480 
   484     self transaction:#paste objects:newSel do:[:v|
   481     self withinTransaction:#paste objects:newSel do:[
   485         self undoCreate:((self propertyOfView:v) identifier)
   482         undoHistory addUndoSelector:#undoCreate:
   486     ].
   483                            withArgs:(newSel collect:[:v|(self propertyOfView:v) identifier])
       
   484     ].
       
   485 
   487     newSel size == 1 ifTrue:[
   486     newSel size == 1 ifTrue:[
   488         newSel := newSel at:1
   487         newSel := newSel at:1
   489     ].
   488     ].
   490     self realizeAllSubViews.
   489     self realizeAllSubViews.
   491     inputView raise.
   490     inputView raise.
   537       '    Transcript showCR:''action for ' , aspect , ' ...''.\' ,
   536       '    Transcript showCR:''action for ' , aspect , ' ...''.\' ,
   538       '!! !!\\') withCRs
   537       '!! !!\\') withCRs
   539 !
   538 !
   540 
   539 
   541 generateAspectMethodFor:aspect spec:protoSpec inClass:targetClass
   540 generateAspectMethodFor:aspect spec:protoSpec inClass:targetClass
       
   541     |modelClass|
       
   542 
       
   543     modelClass := protoSpec defaultModelClass.
       
   544 
   542     ^ ('!!' , targetClass name , ' methodsFor:''aspects''!!\\' ,
   545     ^ ('!!' , targetClass name , ' methodsFor:''aspects''!!\\' ,
   543       aspect , '\' ,
   546       aspect , '\' ,
   544       '    "automatically generated by UIPainter ..."\' ,
   547       '    "automatically generated by UIPainter ..."\' ,
   545       '\' ,
   548       '\' ,
   546       '    |holder|\' ,
   549       '    |holder|\' ,
   547       '\' ,
   550       '\' ,
   548       '    (holder := builder bindingAt:#' , aspect , ') isNil ifTrue:[\' ,
   551       '    (holder := builder bindingAt:#' , aspect , ') isNil ifTrue:[\' ,
   549       '        builder aspectAt:#' , aspect , ' put:(holder := ' , ' ValueHolder new' , ').\' ,
   552       '        builder aspectAt:#' , aspect , ' put:(holder := ' , ' ' , modelClass name , ' new' , ').\' ,
   550       '    ].\' ,
   553       '    ].\' ,
   551       '    ^ holder\' ,
   554       '    ^ holder\' ,
   552       '!! !!\\') withCRs
   555       '!! !!\\') withCRs
   553 !
   556 !
   554 
   557 
   564     cls := Smalltalk classNamed:className.
   567     cls := Smalltalk classNamed:className.
   565 
   568 
   566     listHolder propertiesDo:[:aProp |
   569     listHolder propertiesDo:[:aProp |
   567         |modelSelector menuSelector protoSpec thisCode|
   570         |modelSelector menuSelector protoSpec thisCode|
   568 
   571 
       
   572         protoSpec := aProp spec.
       
   573         protoSpec isNil ifTrue:[
       
   574             self halt.
       
   575             protoSpec := aProp view specClass basicNew.
       
   576         ].
   569         (modelSelector := aProp model) notNil ifTrue:[
   577         (modelSelector := aProp model) notNil ifTrue:[
   570             (cls implements:modelSelector asSymbol) ifFalse:[
   578             (cls implements:modelSelector asSymbol) ifFalse:[
   571                 protoSpec := aProp view specClass basicNew.
       
   572                 "/ kludge ..
   579                 "/ kludge ..
   573                 (protoSpec isMemberOf:ActionButtonSpec) ifTrue:[
   580                 (protoSpec isMemberOf:ActionButtonSpec) ifTrue:[
   574                     thisCode := (self generateActionMethodFor:modelSelector spec:protoSpec inClass:cls).
   581                     thisCode := (self generateActionMethodFor:modelSelector spec:protoSpec inClass:cls).
   575                 ] ifFalse:[
   582                 ] ifFalse:[
   576                     thisCode := (self generateAspectMethodFor:modelSelector spec:protoSpec inClass:cls).
   583                     thisCode := (self generateAspectMethodFor:modelSelector spec:protoSpec inClass:cls).
   579             ].
   586             ].
   580         ].
   587         ].
   581 
   588 
   582         (menuSelector := aProp menu) notNil ifTrue:[
   589         (menuSelector := aProp menu) notNil ifTrue:[
   583             (cls implements:menuSelector asSymbol) ifFalse:[
   590             (cls implements:menuSelector asSymbol) ifFalse:[
   584                 protoSpec := aProp view specClass basicNew.
       
   585                 "/ kludge ..
   591                 "/ kludge ..
   586                 thisCode := (self generateAspectMethodFor:menuSelector spec:protoSpec inClass:cls).
   592                 thisCode := (self generateAspectMethodFor:menuSelector spec:protoSpec inClass:cls).
   587                 code := code , thisCode
   593                 code := code , thisCode
   588             ]
   594             ]
   589         ].
   595         ].
   590 
   596 
   591         aProp spec aspectSelectors do:[:aSel|
   597         aProp spec aspectSelectors do:[:aSel|
   592             (cls implements:aSel asSymbol) ifFalse:[
   598             (cls implements:aSel asSymbol) ifFalse:[
   593                 protoSpec := aProp view specClass basicNew.
       
   594                 "/ kludge ..
   599                 "/ kludge ..
   595                 thisCode := (self generateAspectMethodFor:aSel spec:protoSpec inClass:cls).
   600                 thisCode := (self generateAspectMethodFor:aSel spec:protoSpec inClass:cls).
   596                 code := code , thisCode
   601                 code := code , thisCode
   597             ]
   602             ]
   598         ].
   603         ].
   621 
   626 
   622 generateCode
   627 generateCode
   623     "generate code for the windowSpec method"
   628     "generate code for the windowSpec method"
   624 
   629 
   625     |code|
   630     |code|
       
   631 
       
   632     self resetModification.
   626 
   633 
   627     code := ''.
   634     code := ''.
   628 
   635 
   629 "/    (Smalltalk classNamed:className asSymbol) isNil ifTrue:[
   636 "/    (Smalltalk classNamed:className asSymbol) isNil ifTrue:[
   630 "/        code := code , self generateClassDefinition.
   637 "/        code := code , self generateClassDefinition.
   993     ((spec respondsTo:#label:) and:[self supportsLabel:anObject]) ifTrue:[
  1000     ((spec respondsTo:#label:) and:[self supportsLabel:anObject]) ifTrue:[
   994         anObject label:(props name).
  1001         anObject label:(props name).
   995         spec label:(props name)
  1002         spec label:(props name)
   996     ].
  1003     ].
   997 
  1004 
   998     undoHistory transaction:#create text:(props name) do:[
  1005     undoHistory withinTransaction:#create text:(props name) do:[
   999         self undoCreate:(props identifier).
  1006         undoHistory addUndoSelector:#undoCreate: withArgs:(props identifier)
  1000     ].
  1007     ].
  1001 !
  1008 !
  1002 
  1009 
  1003 setupFromSpec:specOrSpecArray
  1010 setupFromSpec:specOrSpecArray
  1004     |spec builder|
  1011     |spec builder|
  1047         canPaste := (canPaste and:[self canPasteInto:(self selection)])
  1054         canPaste := (canPaste and:[self canPasteInto:(self selection)])
  1048     ] ifFalse:[
  1055     ] ifFalse:[
  1049         menu disableAll
  1056         menu disableAll
  1050     ].
  1057     ].
  1051     menu enabledAt:#paste put:canPaste.
  1058     menu enabledAt:#paste put:canPaste.
  1052     menu enabledAt:#undo  put:(undoHistory notEmpty).
  1059     menu enabledAt:#undo  put:(undoHistory isEmpty not).
  1053     menu startUp.
  1060     menu startUp.
  1054   ^ nil
  1061   ^ nil
  1055 
  1062 
  1056 
  1063 
  1057 
  1064 
  1104 !UIPainterView methodsFor:'removing components'!
  1111 !UIPainterView methodsFor:'removing components'!
  1105 
  1112 
  1106 remove:anObject
  1113 remove:anObject
  1107     "remove anObject from the contents do redraw
  1114     "remove anObject from the contents do redraw
  1108     "
  1115     "
  1109     listHolder remove:anObject.
  1116     anObject notNil ifTrue:[
       
  1117         listHolder remove:anObject
       
  1118     ]
  1110 !
  1119 !
  1111 
  1120 
  1112 removeAll
  1121 removeAll
  1113     "remove all objects and properties
  1122     "remove all objects and properties
  1114     "
  1123     "
  1115     listHolder disableNotificationsWhileEvaluating:[
  1124     listHolder disableNotificationsWhileEvaluating:[
  1116         self select:nil.
  1125         self select:nil.
  1117         listHolder  removeAll.
  1126         listHolder removeAll.
  1118         undoHistory reinitialize.
  1127         self removeUndoHistory.
  1119     ]
  1128     ]
  1120 ! !
  1129 ! !
  1121 
  1130 
  1122 !UIPainterView methodsFor:'searching'!
  1131 !UIPainterView methodsFor:'searching'!
  1123 
  1132 
  1388                     (self propertyOfName:name) notNil ifTrue:[
  1397                     (self propertyOfName:name) notNil ifTrue:[
  1389                         name := props name
  1398                         name := props name
  1390                     ]
  1399                     ]
  1391                 ].
  1400                 ].
  1392                 aSpec name:name.
  1401                 aSpec name:name.
  1393                 self undoSpecModify:(props identifier).
  1402                 self createUndoSpecModify:props.
  1394 
  1403 
  1395                 aSpec needsRebuildForAttributes ifTrue:[
  1404                 aSpec needsRebuildForAttributes ifTrue:[
  1396                     v := aSpec buildViewWithLayoutFor:builder in:aView superView.
  1405                     v := aSpec buildViewWithLayoutFor:builder in:aView superView.
  1397                     v realize.    
  1406                     v realize.    
  1398                     aView destroy.
  1407                     aView destroy.
  1472 
  1481 
  1473 transaction:aType objects:something do:aOneArgBlock
  1482 transaction:aType objects:something do:aOneArgBlock
  1474     "opens a transaction and evaluates a block within the transaction; the
  1483     "opens a transaction and evaluates a block within the transaction; the
  1475      argument to the block is a view from derived from something
  1484      argument to the block is a view from derived from something
  1476     "
  1485     "
  1477     |text|
  1486     self withinTransaction:aType objects:something do:[
  1478 
  1487         self forEach:something do:aOneArgBlock
  1479     something notNil ifTrue:[
  1488     ]
  1480         text := self transactionTextFor:something.
  1489 !
  1481 
  1490 
  1482         undoHistory transaction:aType text:text do:[
  1491 withinTransaction:aType objects:objects do:aNoneArgBlock
  1483             something isCollection ifTrue:[
  1492     "evaluate a block with no arguments within a transaction
  1484                 something do:[:aView| aOneArgBlock value:aView ]
  1493     "
  1485             ] ifFalse:[
  1494     |text size prop|
  1486                 aOneArgBlock value:something
  1495 
  1487             ]
  1496     objects isNil ifTrue:[ ^ self ].
  1488         ]
  1497 
  1489     ]
  1498     size := objects size.
  1490 !
  1499 
  1491 
  1500     objects isCollection ifTrue:[
  1492 transactionTextFor:anElementOrCollection
  1501         size == 0 ifTrue:[ ^ self ].
  1493     "returns text used by transaction or nil
  1502         size == 1 ifTrue:[ prop := self propertyOfView:(objects first) ]
  1494     "
  1503     ] ifFalse:[
  1495     |props size|
  1504         prop := self propertyOfView:objects
  1496 
  1505     ].
  1497     anElementOrCollection notNil ifTrue:[
  1506 
  1498         anElementOrCollection isCollection ifTrue:[
  1507     prop notNil ifTrue:[
  1499             size := anElementOrCollection size.
  1508         text := prop name
  1500             size == 0 ifTrue:[^ nil].
  1509     ] ifFalse:[
  1501             size ~~ 1 ifTrue:[^ size printString, ' elements'].
  1510         text := size printString, ' elements'
  1502 
  1511     ].
  1503             props := self propertyOfView:(anElementOrCollection at:1).
  1512 
  1504         ] ifFalse:[
  1513     undoHistory withinTransaction:aType text:text do:[
  1505             props := self propertyOfView:anElementOrCollection
  1514         aNoneArgBlock value
  1506         ].
  1515     ]
  1507         props notNil ifTrue:[ ^ props name ]
       
  1508     ].
       
  1509     ^ nil
       
  1510 ! !
  1516 ! !
  1511 
  1517 
  1512 !UIPainterView methodsFor:'undo actions'!
  1518 !UIPainterView methodsFor:'undo actions'!
  1513 
  1519 
  1514 undoCreate:aViewId
  1520 createUndoLayout:aView
  1515     "undo method when creating or pasting an object
  1521     "create undo action before changing a views layout
  1516     "
  1522     "
  1517     undoHistory addUndoBlock:[
  1523     |lyt args prop|
  1518         self remove:(self findViewWithId:aViewId)
       
  1519     ]
       
  1520 
       
  1521 !
       
  1522 
       
  1523 undoLayout:aViewId
       
  1524     "undo method when changing the layout (position or dimension)
       
  1525     "
       
  1526     |view layout extent|
       
  1527 
       
  1528     (view := self findViewWithId:aViewId) notNil ifTrue:[
       
  1529         (layout := view geometryLayout copy) isNil ifTrue:[
       
  1530             extent := view extent copy
       
  1531         ].
       
  1532         undoHistory addUndoBlock:[
       
  1533             (view := self findViewWithId:aViewId) notNil ifTrue:[
       
  1534                 layout notNil ifTrue:[view geometryLayout:layout]
       
  1535                              ifFalse:[view extent:extent]
       
  1536             ]
       
  1537         ]
       
  1538     ].
       
  1539     view := nil
       
  1540 !
       
  1541 
       
  1542 undoLayoutView:aView
       
  1543     "undo method for changing layout on a view
       
  1544     "
       
  1545     |prop|
       
  1546 
  1524 
  1547     undoHistory isTransactionOpen ifTrue:[
  1525     undoHistory isTransactionOpen ifTrue:[
  1548         prop := self propertyOfView:aView.
  1526         prop := self propertyOfView:aView.
       
  1527 
  1549         prop notNil ifTrue:[
  1528         prop notNil ifTrue:[
  1550             self undoLayout:(prop identifier)
  1529             args := Array new:3.
  1551         ]
  1530             args at:1 put:(prop identifier).
  1552     ]
  1531 
  1553 !
  1532             (lyt := aView geometryLayout) notNil ifTrue:[
  1554 
  1533                 args at:2 put:#geometryLayout:
  1555 undoRemove:aViewId
  1534             ] ifFalse:[
  1556     "undo method when removing an object
  1535                 lyt extent.
  1557     "
  1536                 args at:2 put:#extent:
  1558     |frame prop spec parentId|
  1537             ].
  1559 
  1538             args at:3 put:(lyt copy).
  1560     frame := self findViewWithId:aViewId.
  1539             undoHistory addUndoSelector:#undoLayout: withArgs:args.
  1561     spec  := self fullSpecFor:frame.
  1540         ]
  1562     frame := frame superView.
  1541     ]
  1563 
  1542 !
  1564     (self canPasteInto:frame) ifTrue:[
  1543 
  1565         (prop := self propertyOfView:frame) notNil ifTrue:[
  1544 createUndoRemove:aView
  1566             parentId := prop identifier
  1545     "create undo method before deleting views
  1567         ]
  1546     "
  1568     ].
  1547     |frame prop pId spec|
  1569     frame := nil.
  1548 
  1570     prop  := nil.
  1549     (prop := self propertyOfView:aView) notNil ifTrue:[
  1571 
  1550         spec  := self fullSpecFor:aView.
  1572     undoHistory addUndoBlock:[
  1551         frame := aView superView.
  1573         |view|
  1552 
  1574 
  1553         (self canPasteInto:frame) ifTrue:[
  1575         frame := self findViewWithId:parentId.
  1554             (frame := self propertyOfView:frame) notNil ifTrue:[
  1576         frame isNil ifTrue:[
  1555                 pId := frame identifier
  1577             frame := self
  1556             ]
  1578         ].
  1557         ].
  1579         view := self addSpec:spec builder:(UIBuilder new) in:frame.
  1558         undoHistory addUndoSelector:#undoRemove:
  1580         view realize.
  1559                            withArgs:(Array with:spec with:(prop identifier) with:pId)
  1581         inputView raise.
  1560     ]
  1582     ]
  1561 !
  1583 !
  1562 
  1584 
  1563 createUndoSpecModify:aProp
  1585 undoSpecModify:aViewId
       
  1586     "undo method when changing the specification for an object
  1564     "undo method when changing the specification for an object
  1587     "
  1565     "
       
  1566     aProp notNil ifTrue:[
       
  1567         undoHistory addUndoSelector:#undoSpecModify:
       
  1568                            withArgs:(Array with:(aProp spec) with:(aProp identifier))
       
  1569     ]
       
  1570 !
       
  1571 
       
  1572 undoCreate:something
       
  1573     "undo method for creating or pasting an object
       
  1574     "
       
  1575     self forEach:something do:[:anId|self remove:(self findViewWithId:anId)].
       
  1576 !
       
  1577 
       
  1578 undoLayout:args
       
  1579     "undo method to set the old layout; see 'createUndoLayout:'
       
  1580     "
       
  1581     |view|
       
  1582 
       
  1583     (view := self findViewWithId:(args at:1)) notNil ifTrue:[
       
  1584         view perform:(args at:2) with:(args at:3)
       
  1585     ]
       
  1586 !
       
  1587 
       
  1588 undoRemove:args
       
  1589     "undo method when removing an object; see 'createUndoRemove:'
       
  1590     "
       
  1591     |frame prop view|
       
  1592 
       
  1593     (args at:3) notNil ifTrue:[
       
  1594         frame := self findViewWithId:(args at:3).
       
  1595     ].
       
  1596     frame isNil ifTrue:[
       
  1597         frame := self
       
  1598     ].
       
  1599     view := self addSpec:(args at:1) builder:(UIBuilder new) in:frame.
       
  1600     view realize.
       
  1601     inputView raise.
       
  1602 
       
  1603     prop := self propertyOfView:view.
       
  1604     prop identifier:(args at:2).
       
  1605 
       
  1606 !
       
  1607 
       
  1608 undoSpecModify:args
       
  1609     "undo method when changing a spec; see 'createUndoSpecModify:'
       
  1610     "
  1588     |builder view spec v props|
  1611     |builder view spec v props|
  1589 
  1612 
  1590     (view := self findViewWithId:aViewId) notNil ifTrue:[
  1613     props := self propertyOfIdentifier:(args at:2).
  1591         spec := self specFor:view.
  1614 
  1592         view := nil.
  1615     props notNil ifTrue:[
  1593 
  1616         view    := props view.
  1594         undoHistory addUndoBlock:[
  1617         spec    := args at:1.
  1595             props := self propertyOfIdentifier:aViewId.
  1618         builder := UIBuilder new.
  1596             props notNil ifTrue:[
  1619         props spec:spec.
  1597                 view    := props view.
  1620 
  1598                 builder := UIBuilder new.
  1621         spec needsRebuildForAttributes ifTrue:[
  1599                 props spec:spec.
  1622             v := spec buildViewWithLayoutFor:builder in:view superView.
  1600 
  1623             v realize.    
  1601                 spec needsRebuildForAttributes ifTrue:[
  1624             view destroy.
  1602                     v := spec buildViewWithLayoutFor:builder in:view superView.
  1625             view become:v
  1603                     v realize.    
  1626         ] ifFalse:[
  1604                     view destroy.
  1627             spec setAttributesIn:view with:builder.
  1605                     view become:v
  1628             self elementChangedSize:view.
  1606                 ] ifFalse:[
  1629         ].
  1607                     spec setAttributesIn:view with:builder.
  1630         listHolder propertyChanged:props.
  1608                     self elementChangedSize:view.
  1631     ] ifFalse:[
  1609                 ].
  1632         self halt
  1610                 listHolder propertyChanged:props.
  1633     ]
  1611             ]
       
  1612         ]
       
  1613     ].
       
  1614 
  1634 
  1615 
  1635 
  1616 
  1636 
  1617 ! !
  1637 ! !
  1618 
  1638 
  1639 
  1659 
  1640 identifier
  1660 identifier
  1641     "return the unique identifier assigned to property
  1661     "return the unique identifier assigned to property
  1642     "
  1662     "
  1643     ^ identifier
  1663     ^ identifier
       
  1664 !
       
  1665 
       
  1666 identifier:anIdentifier
       
  1667     "set the unique identifier assigned to property; called after an restore of
       
  1668      a deleted instance
       
  1669     "
       
  1670     identifier := anIdentifier
  1644 !
  1671 !
  1645 
  1672 
  1646 spec
  1673 spec
  1647     "return the value of the instance variable 'spec' (automatically generated)"
  1674     "return the value of the instance variable 'spec' (automatically generated)"
  1648 
  1675