<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<meta content="text/html; charset=UTF-8">
<style type="text/css" style="">
<!--
p
        {margin-top:0;
        margin-bottom:0}
-->
</style>
<div dir="ltr">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:#000000; font-family:Calibri,Helvetica,sans-serif">
<p>+1 :-)</p>
<div id="x_Signature">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:rgb(0,0,0); font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols">
<div name="x_divtagdefaultwrapper" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:; margin:0">
<div>
<div class="x__rp_T4" id="x_Item.MessagePartBody">
<div class="x__rp_U4 x_ms-font-weight-regular x_ms-font-color-neutralDark x_rpHighlightAllClass x_rpHighlightBodyClass" id="x_Item.MessageUniqueBody" style="font-family:wf_segoe-ui_normal,"Segoe UI","Segoe WP",Tahoma,Arial,sans-serif,serif,EmojiFont">
<div dir="ltr">
<div id="x_divtagdefaultwrapper"><font face="Calibri,Helvetica,sans-serif,EmojiFont,Apple Color Emoji,Segoe UI Emoji,NotoColorEmoji,Segoe UI Symbol,Android Emoji,EmojiSymbols">
<div id="x_Signature">
<div style="margin:0px"><font style="font-family:Calibri,Arial,Helvetica,sans-serif,serif,EmojiFont">
<div><font size="3" color="black"><span style="font-size:12pt"><a href="http://www.hpi.de/" target="_blank" rel="noopener noreferrer" id="LPNoLP"><font size="2"><span id="LPlnk909538"><font color="#757B80"></font></span></font></a></span></font></div>
</font></div>
</div>
</font></div>
</div>
</div>
</div>
</div>
<div><font size="2" color="#808080"></font></div>
</div>
</div>
</div>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von commits@source.squeak.org <commits@source.squeak.org><br>
<b>Gesendet:</b> Freitag, 7. Februar 2020 23:38:45<br>
<b>An:</b> squeak-dev@lists.squeakfoundation.org<br>
<b>Betreff:</b> [squeak-dev] The Inbox: Morphic-kfr.1619.mcz</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">A new version of Morphic was added to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Morphic-kfr.1619.mcz">http://source.squeak.org/inbox/Morphic-kfr.1619.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Morphic-kfr.1619<br>
Author: kfr<br>
Time: 7 February 2020, 11:38:33.017512 pm<br>
UUID: 7e9d5c46-aad5-ed46-b88d-22f30b5f597f<br>
Ancestors: Morphic-cmm.1618<br>
<br>
Enhancement for PolygonMorph. When a vertex is dropped it will snap if it is close to another PolygonMorphs vertex. It is possible to toggle functionality on/ off in menu.<br>
( With suggestion from Christoph Thiede about basing snapping distance on screen resolution)<br>
<br>
=============== Diff against Morphic-cmm.1618 ===============<br>
<br>
Item was changed:<br>
  BorderedMorph subclass: #PolygonMorph<br>
+        instanceVariableNames: 'vertices closed filledForm arrows arrowForms smoothCurve curveState borderDashSpec handles borderForm snapToOtherPolygons'<br>
-        instanceVariableNames: 'vertices closed filledForm arrows arrowForms smoothCurve curveState borderDashSpec handles borderForm'<br>
         classVariableNames: ''<br>
         poolDictionaries: ''<br>
         category: 'Morphic-Basic'!<br>
  <br>
  !PolygonMorph commentStamp: 'md 2/24/2006 20:34' prior: 0!<br>
  This class implements a morph which can behave as four different objects depending on the the following two facts:<br>
  - is it OPEN or CLOSED?<br>
  - is it SEGMENTED or SMOOTHED.<br>
  <br>
  1. The OPEN and SEGMENTED variant looks like polyline.<br>
  <br>
  2. The OPEN and SMOOTHED variant looks like spline (kind of curve)<br>
  <br>
  3. The CLOSED and SEGMENTED variant looks like polygon. This is actually what you get when you do<br>
         PolygonMorph new openInWorld<br>
  You get a triangle. See below how to manipulate these objects...<br>
  <br>
  4. The CLOSED and SMOOTHED variant looks like blob (???)<br>
  <br>
  Prototypes of this morph can also be found in "Object Catalog". Several (different variants) of this object are among "Basic" morphs.<br>
  <br>
  Explore the assiciated morph-menu. It enables you<br>
  - to toggle showing of "handles". They make it possible to<br>
         - reposition already existing vertices (by moving yellow handles)<br>
         - create new vertices (by moving green handles)<br>
         - delete already existing vertices (by dragging and dropping one yellow handle closely<br>
           nearby the adjacent yellow handle<br>
    Handles can be made visible/hidden by shift+leftclicking the morph. This way it is possible<br>
    to quickly show handles, adjust vertices and then again hide handles.<br>
  - making closed polygon open, i.e. converting it to a curve (and vice versa)<br>
  - toggle smoothed/segmented line/outline<br>
  - set up custom dashing (for line, curves or borders of closed polygons<br>
  - set up custom arrow-heads (for lines resp. curves)<br>
  <br>
  ------------------------------------------------------------------------------------------<br>
  Implementation notes:<br>
  <br>
  This class combines the old Polygon and Curve classes.<br>
  <br>
  The 1-bit fillForm to make display and containment tests reasonably fast.  However, this functionality is in the process of being supplanted by balloon capabilities, which should eventually provide anti-aliasing as well.<br>
  <br>
  wiz 7/18/2004 21:26<br>
  s have made some changes to this class to<br>
  <br>
  1) correct some bugs associated with one vertex polygons.<br>
  <br>
  2) prepare for some enhancements with new curves.<br>
  <br>
  3) add shaping items to menu.!<br>
<br>
Item was changed:<br>
  ----- Method: PolygonMorph>>addCustomMenuItems:hand: (in category 'menu') -----<br>
  addCustomMenuItems: aMenu hand: aHandMorph<br>
         "Add morph-specific items to the given menu which was invoked by the given hand.  This method provides is invoked both from the halo-menu and from the control-menu regimes."<br>
  <br>
         super addCustomMenuItems: aMenu hand: aHandMorph.<br>
         aMenu addUpdating: #handlesShowingPhrase target: self action: #showOrHideHandles.<br>
         vertices size > 2 ifTrue:<br>
                 [aMenu addUpdating: #openOrClosePhrase target: self action: #makeOpenOrClosed].<br>
  <br>
         aMenu addUpdating: #smoothPhrase target: self action: #toggleSmoothing.<br>
+        aMenu addUpdating: #snapToOtherPolygonPhrase target: self action: #toggleSnapToOtherPolygons.<br>
         aMenu addLine.<br>
         aMenu add: 'specify dashed line' translated action:  #specifyDashedLine.<br>
  <br>
         self isOpen ifTrue:<br>
                 [aMenu addLine.<br>
                 aMenu addWithLabel: '---' enablement: [self isOpen and: [arrows ~~ #none]] action:  #makeNoArrows.<br>
                 aMenu addWithLabel: '-->' enablement: [self isOpen and: [arrows ~~ #forward]] action:  #makeForwardArrow.<br>
                 aMenu addWithLabel: '<--' enablement: [self isOpen and: [arrows ~~ #back]] action:  #makeBackArrow.<br>
                 aMenu addWithLabel: '<->' enablement: [self isOpen and: [arrows ~~ #both]] action:  #makeBothArrows.<br>
                 aMenu add: 'customize arrows' translated action: #customizeArrows:.<br>
                 (self hasProperty: #arrowSpec)<br>
                         ifTrue: [aMenu add: 'standard arrows' translated action: #standardArrows]].!<br>
<br>
Item was changed:<br>
  ----- Method: PolygonMorph>>dropVertex:event:fromHandle: (in category 'editing') -----<br>
+ dropVertex: ix event: evt fromHandle: handle <br>
+        "Leave vertex in new position. If dropped ontop another vertex delete<br>
+        this one.<br>
- dropVertex: ix event: evt fromHandle: handle<br>
-        "Leave vertex in new position. If dropped ontop another vertex delete this one.<br>
         Check for too few vertices before deleting. The alternative <br>
+        is not pretty -wiz"<br>
+        | p nearestOwner distance |<br>
-                                is not pretty -wiz"<br>
-        | p |<br>
         p := vertices at: ix.<br>
+        distance := (3 * RealEstateAgent scaleFactor).  <br>
+        "snap the dropped vertex to a vertex of another PolygonMorph if it is in near proximity"<br>
+        self isSnappingToOtherPolygons<br>
+                ifTrue: [nearestOwner := self ownerThatIsA: PasteUpMorph.<br>
+                        nearestOwner submorphs<br>
+                                do: [:each | ((each respondsTo: #vertices)<br>
+                                                        and: [each ~= self])<br>
+                                                ifTrue: [each vertices<br>
+                                                                do: [:otherMorphsVertex | (otherMorphsVertex dist: p)<br>
+                                                                                        <  distance<br>
+                                                                                ifTrue: [vertices at: ix put: otherMorphsVertex]]]]].<br>
         (vertices size >= 2<br>
                         and: ["check for too few vertices before deleting. The alternative
<br>
                                 is not pretty -wiz"<br>
                                 ((vertices atWrap: ix - 1)<br>
                                                 dist: p)<br>
+                                                < distance<br>
-                                                < 3<br>
                                         or: [((vertices atWrap: ix + 1)<br>
                                                         dist: p)<br>
+                                                        < distance]])<br>
-                                                        < 3]])<br>
                 ifTrue: ["Drag a vertex onto its neighbor means delete"<br>
+                        self deleteVertexAt: ix].<br>
-                                self deleteVertexAt: ix .].<br>
         evt shiftPressed<br>
                 ifTrue: [self removeHandles]<br>
                 ifFalse: [self addHandles<br>
                         "remove then add to recreate"]!<br>
<br>
Item was changed:<br>
  ----- Method: PolygonMorph>>initialize (in category 'initialization') -----<br>
  initialize<br>
  "initialize the state of the receiver"<br>
         super initialize.<br>
  ""<br>
         vertices := Array<br>
                                 with: 5 @ 0<br>
                                 with: 20 @ 10<br>
                                 with: 0 @ 20.<br>
         closed := true.<br>
         smoothCurve := false.<br>
         arrows := #none.<br>
+        snapToOtherPolygons := false.<br>
         self computeBounds!<br>
<br>
Item was added:<br>
+ ----- Method: PolygonMorph>>isSnappingToOtherPolygons (in category 'access') -----<br>
+ isSnappingToOtherPolygons<br>
+   ^snapToOtherPolygons ifNil:[ snapToOtherPolygons := false].<br>
+  !<br>
<br>
Item was added:<br>
+ ----- Method: PolygonMorph>>snapToOtherPolygonPhrase (in category 'menu') -----<br>
+ snapToOtherPolygonPhrase<br>
+        "Answer a string characterizing whether my vertices should snap to another polygons vertices."<br>
+ <br>
+        ^ (self isSnappingToOtherPolygons ifTrue: ['<yes>'] ifFalse: ['<no>']), 'snap to other polygons' translated !<br>
<br>
Item was added:<br>
+ ----- Method: PolygonMorph>>toggleSnapToOtherPolygons (in category 'menu') -----<br>
+ toggleSnapToOtherPolygons<br>
+      ^snapToOtherPolygons := snapToOtherPolygons not!<br>
<br>
<br>
</div>
</span></font>
</body>
</html>