349 "add the objects in the paste-buffer to the object view; |
347 "add the objects in the paste-buffer to the object view; |
350 don't change the layout if more than a single item has been selected" |
348 don't change the layout if more than a single item has been selected" |
351 |
349 |
352 |sel clipboard| |
350 |sel clipboard| |
353 |
351 |
|
352 self enabled ifFalse:[ |
|
353 Dialog warn:'Operation currently disabled (In geometry test mode)'. |
|
354 ^ self |
|
355 ]. |
|
356 |
354 clipboard := self getClipboardObject. |
357 clipboard := self getClipboardObject. |
355 sel := self pasteSpecifications:clipboard keepLayout:(clipboard size > 1). |
358 sel := self pasteSpecifications:clipboard keepLayout:true "(clipboard size > 1)". |
356 self changeSelectionAfterPasteOf:sel. |
359 self changeSelectionAfterPasteOf:sel. |
357 ! |
360 ! |
358 |
361 |
359 pasteKeepingPosition |
362 pasteKeepingPosition |
360 "add the objects in the paste-buffer to the object view; |
363 "add the objects in the paste-buffer to the object view; |
387 "add the specs to the object view; returns list of pasted widgets" |
391 "add the specs to the object view; returns list of pasted widgets" |
388 |
392 |
389 ^ self |
393 ^ self |
390 pasteSpecifications:aSpecificationOrList |
394 pasteSpecifications:aSpecificationOrList |
391 keepLayout:keepLayout |
395 keepLayout:keepLayout |
392 keepPosition:false |
396 keepPosition:true |
393 at:aPointOrNil |
397 at:aPointOrNil |
394 ! |
398 ! |
395 |
399 |
396 pasteSpecifications:aSpecificationOrList keepLayout:keepLayout keepPosition:keepPosition at:aPointOrNil |
400 pasteSpecifications:aSpecificationOrList keepLayout:keepLayout keepPosition:keepPosition at:aPointOrNil |
397 "add the specs to the object view; returns list of pasted widgets" |
401 "add the specs to the object view; returns list of pasted widgets" |
398 |
402 |
399 |specsToPaste pasteOrigin pasteOffset builder newSel bounds containerToPasteInto| |
403 |specsToPaste pasteOffset builder newSel |
|
404 bounds containerToPasteInto pastePoint| |
400 |
405 |
401 treeView askForSelectionChangeAllowed ifFalse:[^ nil]. |
406 treeView askForSelectionChangeAllowed ifFalse:[^ nil]. |
402 |
407 |
403 containerToPasteInto := self singleSelection. |
408 (self window sensor shiftDown |
|
409 or:[ self window sensor ctrlDown ]) ifTrue:[ |
|
410 "/ paste into the selection |
|
411 containerToPasteInto := self singleSelection. |
|
412 ] ifFalse:[ |
|
413 "/ ignore the selection and paste where we drop!! |
|
414 pastePoint := aPointOrNil. |
|
415 pastePoint isNil ifTrue:[ |
|
416 pastePoint := device |
|
417 translatePoint:(self sensor mousePoint) |
|
418 fromView:nil |
|
419 toView:self. |
|
420 ]. |
|
421 containerToPasteInto := self findObjectAt:pastePoint |
|
422 ]. |
|
423 |
404 containerToPasteInto isNil ifTrue:[ |
424 containerToPasteInto isNil ifTrue:[ |
405 self selection size > 0 ifTrue:[ |
425 self selection size > 0 ifTrue:[ |
406 containerToPasteInto := self commonContainerOf:self selection |
426 containerToPasteInto := self commonContainerOf:self selection |
407 ] ifFalse:[ |
427 ] ifFalse:[ |
408 containerToPasteInto := self |
428 containerToPasteInto := self |
409 ]. |
429 ]. |
410 "/ self selection:containerToPasteInto. |
430 "/ self selection:containerToPasteInto. |
411 ]. |
431 ]. |
412 |
432 |
413 (self canPasteInto:containerToPasteInto) ifFalse:[ |
433 "/ search up parent list for something we can paste into |
414 containerToPasteInto notNil ifTrue:[ |
434 [containerToPasteInto notNil and:[(self canPasteInto:containerToPasteInto) not]] whileTrue:[ |
415 "/ search up parent list for something we can paste into |
435 containerToPasteInto == self ifTrue:[ |
416 [containerToPasteInto notNil and:[(self canPasteInto:containerToPasteInto) not]] whileTrue:[ |
436 containerToPasteInto := nil |
417 containerToPasteInto == self ifTrue:[ |
437 ] ifFalse:[ |
418 containerToPasteInto := nil |
438 containerToPasteInto := containerToPasteInto container. |
419 ] ifFalse:[ |
|
420 containerToPasteInto := containerToPasteInto container. |
|
421 ]. |
|
422 ]. |
|
423 "/ self selection:containerToPasteInto. |
|
424 ]. |
439 ]. |
425 ]. |
440 ]. |
426 containerToPasteInto isNil ifTrue:[ |
441 containerToPasteInto isNil ifTrue:[ |
427 containerToPasteInto := self |
442 containerToPasteInto := self |
428 ]. |
443 ]. |
429 |
444 |
430 (self canPaste:aSpecificationOrList into:containerToPasteInto) |
445 (self canPaste:aSpecificationOrList into:containerToPasteInto) |
431 ifFalse:[ |
446 ifFalse:[ |
432 Dialog warn:'Cannot paste into selected component (not a container ?)'. |
447 self enabled ifTrue:[ |
|
448 Dialog warn:'Cannot paste into selected component (not a container ?)'. |
|
449 ] ifFalse:[ |
|
450 Dialog warn:'Operation currently disabled (In Geometry test mode)'. |
|
451 ]. |
433 ^ nil |
452 ^ nil |
434 ]. |
453 ]. |
435 |
454 |
436 aSpecificationOrList isCollection ifTrue:[ |
455 aSpecificationOrList isCollection ifTrue:[ |
437 specsToPaste := aSpecificationOrList |
456 specsToPaste := aSpecificationOrList |
444 builder := UIBuilder new isEditing:true. |
463 builder := UIBuilder new isEditing:true. |
445 |
464 |
446 className notNil ifTrue:[ |
465 className notNil ifTrue:[ |
447 builder applicationClass:(self resolveName:className) |
466 builder applicationClass:(self resolveName:className) |
448 ]. |
467 ]. |
449 |
468 bounds := Rectangle origin:0@0 extent:(containerToPasteInto bounds extent). |
450 (keepLayout not or:[keepPosition]) ifTrue:[ |
469 |
451 pasteOffset := 0@0. |
470 pasteOffset := 0. |
|
471 |
|
472 specsToPaste do:[:eachSpec| |
|
473 |view newOrigin uiPainterAttributes thisAbsOrigin| |
|
474 |
|
475 uiPainterAttributes := eachSpec otherAttributeAt:#uiPainterAttributes. |
|
476 eachSpec otherAttributeAt:#uiPainterAttributes put:nil. |
|
477 |
|
478 view := self addSpec:eachSpec builder:builder in:containerToPasteInto. |
452 |
479 |
453 keepPosition ifTrue:[ |
480 keepPosition ifTrue:[ |
454 pasteOrigin := device translatePoint:0@0 |
481 thisAbsOrigin := uiPainterAttributes at:#absOrigin. |
455 fromView:self |
482 newOrigin := device |
456 toView:containerToPasteInto. |
483 translatePoint:thisAbsOrigin |
|
484 fromView:self |
|
485 toView:containerToPasteInto. |
457 ] ifFalse:[ |
486 ] ifFalse:[ |
458 aPointOrNil isNil ifTrue:[ |
487 pastePoint isNil ifTrue:[ pastePoint := 0@0 ]. |
459 pasteOrigin := device translatePoint:(self sensor mousePoint) |
488 newOrigin := device |
460 fromView:nil |
489 translatePoint:pastePoint |
461 toView:containerToPasteInto. |
490 fromView:self |
462 ] ifFalse:[ |
491 toView:containerToPasteInto. |
463 pasteOrigin := device translatePoint:aPointOrNil |
492 ]. |
464 fromView:self |
493 |
465 toView:containerToPasteInto. |
494 (bounds containsPoint:newOrigin) ifFalse:[ |
466 ] |
495 newOrigin := pasteOffset asPoint. |
467 ]. |
496 pasteOffset := pasteOffset + 4. |
468 |
497 ]. |
469 bounds := Rectangle origin:0@0 extent:(containerToPasteInto bounds extent) |
498 newOrigin notNil ifTrue:[ |
470 ]. |
499 self moveObject:view to:newOrigin. |
471 |
|
472 specsToPaste do:[:eachSpec| |
|
473 |view newOrigin| |
|
474 |
|
475 view := self addSpec:eachSpec builder:builder in:containerToPasteInto. |
|
476 |
|
477 keepPosition ifTrue:[ |
|
478 self moveObject:view to:(view origin + pasteOrigin). |
|
479 ] ifFalse:[ |
|
480 keepLayout ifFalse:[ |
|
481 (bounds containsPoint:pasteOrigin) ifFalse:[ |
|
482 newOrigin := pasteOffset. |
|
483 ] ifTrue:[ |
|
484 newOrigin := pasteOrigin + pasteOffset. |
|
485 ]. |
|
486 self moveObject:view to:newOrigin. |
|
487 pasteOffset := pasteOffset + 4 |
|
488 ]. |
|
489 ]. |
500 ]. |
490 view realize. |
501 view realize. |
491 newSel add:view. |
502 newSel add:view. |
492 ]. |
503 ]. |
493 |
504 |
2281 ^ aSpecification buildViewWithLayoutFor:aBuilder in:aFrame. |
2293 ^ aSpecification buildViewWithLayoutFor:aBuilder in:aFrame. |
2282 |
2294 |
2283 "Modified: 4.7.1997 / 23:48:55 / cg" |
2295 "Modified: 4.7.1997 / 23:48:55 / cg" |
2284 ! |
2296 ! |
2285 |
2297 |
2286 fullSpecFor:anObject |
2298 fullSpecFor:aView |
2287 "generate a full spec for an object |
2299 "generate a full spec for an object |
2288 " |
2300 " |
2289 |mySpec subSpecs| |
2301 |mySpec subSpecs| |
2290 |
2302 |
2291 mySpec := self specFor:anObject. |
2303 mySpec := self specFor:aView. |
2292 |
2304 |
2293 (mySpec notNil and:[mySpec class supportsSubComponents]) ifTrue:[ |
2305 (mySpec notNil and:[mySpec class supportsSubComponents]) ifTrue:[ |
2294 (anObject subViews notNil) ifTrue:[ |
2306 (aView subViews notNil) ifTrue:[ |
2295 anObject subViews do:[:aSubView||spec| |
2307 aView subViews do:[:aSubView||spec| |
2296 spec := self fullSpecFor:aSubView. |
2308 spec := self fullSpecFor:aSubView. |
2297 spec notNil ifTrue:[ |
2309 spec notNil ifTrue:[ |
2298 subSpecs isNil ifTrue:[ |
2310 subSpecs isNil ifTrue:[ |
2299 subSpecs := OrderedCollection new |
2311 subSpecs := OrderedCollection new |
2300 ]. |
2312 ]. |
2301 subSpecs add:spec. |
2313 subSpecs add:spec. |
2302 ]. |
2314 ]. |
2303 ]. |
2315 ]. |
2304 subSpecs notNil ifTrue:[ |
2316 subSpecs notNil ifTrue:[ |
2305 mySpec component:(SpecCollection new collection:subSpecs) |
2317 mySpec component:(SpecCollection new collection:subSpecs) |
2306 ] |
2318 ] |
2307 ] |
2319 ] |
2308 ]. |
2320 ]. |
2309 ^ mySpec |
2321 ^ mySpec |
2310 |
2322 ! |
2311 |
2323 |
2312 |
2324 fullSpecWithAbsolutePositionFor:aView |
2313 |
2325 |spec| |
2314 |
2326 |
2315 |
2327 spec := self fullSpecFor:aView. |
|
2328 spec |
|
2329 otherAttributeAt:#uiPainterAttributes |
|
2330 put:(Dictionary new |
|
2331 at:#origin put:aView origin; |
|
2332 at:#extent put:aView extent; |
|
2333 at:#absOrigin put:(aView originRelativeTo:self); |
|
2334 yourself). |
|
2335 ^ spec |
2316 ! |
2336 ! |
2317 |
2337 |
2318 rebuildView:aView fromSpec:aSpec withBuilder:aBuilderOrNil |
2338 rebuildView:aView fromSpec:aSpec withBuilder:aBuilderOrNil |
2319 self |
2339 self |
2320 rebuildView:aView fromSpec:aSpec withBuilder:aBuilderOrNil forceNewView:false |
2340 rebuildView:aView fromSpec:aSpec withBuilder:aBuilderOrNil forceNewView:false |
2372 aSpec setAttributesIn:aView with:builder. |
2392 aSpec setAttributesIn:aView with:builder. |
2373 self elementChangedSize:aView. |
2393 self elementChangedSize:aView. |
2374 ]. |
2394 ]. |
2375 ! |
2395 ! |
2376 |
2396 |
2377 specFor:anObject |
2397 specFor:aView |
2378 "returns spec assigned to an object |
2398 "returns a copy of the spec assigned to an object" |
2379 " |
2399 |
2380 |prop spec| |
2400 |prop spec| |
2381 |
2401 |
2382 (prop := self propertyOfView:anObject) isNil ifTrue:[^ nil]. |
2402 (prop := self propertyOfView:aView) isNil ifTrue:[^ nil]. |
|
2403 |
2383 spec := prop spec copy. |
2404 spec := prop spec copy. |
2384 spec layoutFromView:anObject. |
2405 spec layoutFromView:aView. |
2385 ^ spec |
2406 ^ spec |
2386 ! |
2407 ! |
2387 |
2408 |
2388 specForSelection |
2409 specForSelection |
2389 "returns spec assigned to current single selection or nil |
2410 "returns spec assigned to current single selection or nil |
2427 ! ! |
2448 ! ! |
2428 |
2449 |
2429 !UIPainterView methodsFor:'testing'! |
2450 !UIPainterView methodsFor:'testing'! |
2430 |
2451 |
2431 canChangeLayoutOfView:aView |
2452 canChangeLayoutOfView:aView |
2432 "returns true if the view can change its layout which is dependant on |
2453 "returns true if the view can change its layout. |
2433 its parent view. |
2454 This is dependent on its parent view." |
2434 " |
2455 |
2435 |item prnt| |
2456 |item parent granny| |
2436 |
2457 |
2437 ( (item := treeView itemOfView:aView) isNil |
2458 item := treeView itemOfView:aView. |
2438 or:[(prnt := item parent) isNil] |
2459 item isNil ifTrue:[ |
2439 ) ifTrue:[ |
2460 "/ I dont know anything about that view (cg: how can this happen ?) |
2440 ^ false |
2461 "/ self breakPoint:#cg. |
2441 ]. |
2462 ^ false |
2442 ^ (prnt parent isNil or:[prnt contents spec class isLayoutContainer not]) |
2463 ]. |
|
2464 parent := item parent. |
|
2465 parent isNil ifTrue:[ |
|
2466 "/ that view has no parent (cg: does this mean its the canvas itself ?) |
|
2467 "/ self breakPoint:#cg. |
|
2468 ^ false |
|
2469 ]. |
|
2470 granny := parent parent. |
|
2471 granny isNil ifTrue:[ |
|
2472 "/ cg: why that ? |
|
2473 "/ self breakPoint:#cg. |
|
2474 ^ true |
|
2475 ]. |
|
2476 parent contents spec class isLayoutContainer ifTrue:[ |
|
2477 "/ self breakPoint:#cg. |
|
2478 ^ false |
|
2479 ]. |
|
2480 ^ true |
2443 ! |
2481 ! |
2444 |
2482 |
2445 canExchangeSelectionLayouts |
2483 canExchangeSelectionLayouts |
2446 "returns true if the selection size is exactly 2 |
2484 "returns true if the selection size is exactly 2 |
2447 and all elements in the selection can be moved or aligned |
2485 and all elements in the selection can be moved or aligned |
2465 canMove:something |
2503 canMove:something |
2466 "checks whether something is not nil and if all widgets derived from |
2504 "checks whether something is not nil and if all widgets derived from |
2467 something can change their layout ( move, align, ... operation ). |
2505 something can change their layout ( move, align, ... operation ). |
2468 " |
2506 " |
2469 something notNil ifTrue:[ |
2507 something notNil ifTrue:[ |
2470 self forEach:something do:[:aView| |
2508 self forEach:something do:[:aView| |
2471 (self canChangeLayoutOfView:aView) ifFalse:[^ false] |
2509 (self canChangeLayoutOfView:aView) ifFalse:[^ false] |
2472 ]. |
2510 ]. |
2473 ^ true |
2511 ^ true |
2474 ]. |
2512 ]. |
2475 ^ false |
2513 ^ false |
2476 ! |
2514 ! |
2477 |
2515 |
2478 canMoveOrAlignSelection |
2516 canMoveOrAlignSelection |
2479 "returns true if a selection exists and all elements in the selection |
2517 "returns true if a selection exists and all elements in the selection |
2480 can be moved or aligned |
2518 can be moved or aligned |
2481 " |
2519 " |
2482 ^ self canMove:(self selection) |
2520 ^ self canMove:(self selection) |
2483 |
|
2484 ! ! |
2521 ! ! |
2485 |
2522 |
2486 !UIPainterView methodsFor:'transaction'! |
2523 !UIPainterView methodsFor:'transaction'! |
2487 |
2524 |
2488 transaction:aType objects:something do:aOneArgBlock |
2525 transaction:aType objects:something do:aOneArgBlock |
2493 self forEach:something do:aOneArgBlock |
2530 self forEach:something do:aOneArgBlock |
2494 ] |
2531 ] |
2495 ! |
2532 ! |
2496 |
2533 |
2497 withinTransaction:aType objects:objects do:aNoArgBlock |
2534 withinTransaction:aType objects:objects do:aNoArgBlock |
2498 "evaluate a block with no arguments within a transaction |
2535 "evaluate a block within a transaction" |
2499 " |
2536 |
2500 |text size prop| |
2537 |text size prop| |
2501 |
2538 |
2502 objects isNil ifTrue:[ ^ self ]. |
2539 objects isNil ifTrue:[ ^ self ]. |
2503 |
2540 |
2504 size := objects size. |
2541 size := objects size. |
2505 |
2542 |
2506 objects isCollection ifTrue:[ |
2543 objects isCollection ifTrue:[ |
2507 size == 0 ifTrue:[ ^ self ]. |
2544 size == 0 ifTrue:[ ^ self ]. |
2508 size == 1 ifTrue:[ prop := self propertyOfView:(objects first) ] |
2545 size == 1 ifTrue:[ |
|
2546 prop := self propertyOfView:(objects first) |
|
2547 ] |
2509 ] ifFalse:[ |
2548 ] ifFalse:[ |
2510 prop := self propertyOfView:objects |
2549 prop := self propertyOfView:objects |
2511 ]. |
2550 ]. |
2512 |
2551 |
2513 prop notNil ifTrue:[ |
2552 prop notNil ifTrue:[ |