Skip to content
Snippets Groups Projects
Commit 70faf03d authored by Benoît Minisini's avatar Benoît Minisini :church:
Browse files

Image editor: Add a draw polygon / star tool.

[DEVELOPMENT ENVIRONMENT]
* NEW: Image editor: Add a draw polygon / star tool.
parent fc38b523
No related branches found
No related tags found
No related merge requests found
Pipeline #1109241103 passed
This diff is collapsed.
......@@ -475,6 +475,51 @@ Public Sub Rectangle(X As Float, Y As Float, W As Float, H As Float, Optional R
End
Public Sub Polygon(X As Float, Y As Float, W As Float, H As Float, N As Integer, Optional R As Float)
Dim XC As Float
Dim YC As Float
Dim I As Integer
If W = 0 Or If H = 0 Then Return
W /= 2
H /= 2
XC = X + W
YC = Y + H
If R > 0 And If R < 1 Then
For I = 0 To N
X = XC + Sin(Pi(2 * I / N)) * W
Y = YC - Cos(Pi(2 * I / N)) * H
If I = 0 Then
MoveTo(X, Y)
Else
LineTo(X, Y)
Endif
X = XC + Sin(Pi(2 * (I + 0.5) / N)) * W * R
Y = YC - Cos(Pi(2 * (I + 0.5) / N)) * H * R
LineTo(X, Y)
Next
Else
For I = 0 To N
X = XC + Sin(Pi(2 * I / N)) * W
Y = YC - Cos(Pi(2 * I / N)) * H
If I = 0 Then
MoveTo(X, Y)
Else
LineTo(X, Y)
Endif
Next
Endif
End
Public Sub Text(X As Float, Y As Float, sText As String, sFont As String, iAlign As Integer, bAlignBase As Boolean)
Dim hImage As Image
......@@ -1227,3 +1272,31 @@ Public Sub Expand(hImage As Image)
Scale(hImage.W / hExt.W, hImage.H / hExt.H, True)
End
Public Sub GetBarycenter() As PointF
Dim I As Integer
Dim hCenterShape As PointF
Dim hCenter As PointF
If Shapes.Count = 0 Then Return New PointF
If Current >= 0 Then Return Shapes[Current].GetBarycenter()
For I = 0 To Shapes.Max
hCenterShape = Shapes[I].GetBarycenter()
If Not hCenterShape Then Continue
If Not hCenter Then
hCenter = hCenterShape
Else
hCenter.X += hCenterShape.X
hCenter.Y += hCenterShape.Y
Endif
Next
hCenter.X /= Shapes.Count
hCenter.Y /= Shapes.Count
Return hCenter
End
......@@ -329,3 +329,20 @@ Public Sub ToPolygons() As Polygon[]
Return aPoly
End
Public Sub GetBarycenter() As PointF
Dim I As Integer
Dim X As Float
Dim Y As Float
If Points.Count = 1 Then Return Points[0].Copy()
For I = 1 To Points.Max
X += (Points[I].X - Points[0].X)
Y += (Points[I].Y - Points[0].Y)
Next
Return New PointF(Points[0].X + X / Points.Max, Points[0].Y + Y / Points.Max)
End
......@@ -525,7 +525,7 @@ Private Sub SetTool(sAction As String)
'If $sTool = sAction Then Return
For Each hCtrl In [btnMove, btnDraw, btnErase, btnRectangle, btnEllipse, btnLine, btnMagic, btnPaste, btnEditSelection, btnText]
For Each hCtrl In [btnMove, btnDraw, btnErase, btnRectangle, btnEllipse, btnPolygon, btnLine, btnMagic, btnPaste, btnEditSelection, btnText]
Object.Lock(hCtrl)
hCtrl.Value = hCtrl.Tag = sAction
Object.Unlock(hCtrl)
......@@ -549,7 +549,7 @@ Private Sub SetTool(sAction As String)
Case "move"
$iMouse = Mouse.SizeAll
Case "draw", "erase", "rectangle", "ellipse"
Case "draw", "erase", "rectangle", "ellipse", "polygon"
'$iMouse = Mouse.Cross
$iMouse = Mouse.Custom
$hCursor = New Cursor(Picture["img/32/cross.png"], 15, 15)
......@@ -580,7 +580,7 @@ Private Sub SetTool(sAction As String)
If $sTool <> "paste" Then $sToolBefore = $sTool
If HasSelection() Then
$hChangeRect = $hSelect.GetExtents()
$hChangeRotate = $hChangeRect.Center()
ResetChangeRotate()
Endif
Case "text"
......@@ -950,7 +950,7 @@ Public Sub imvImage_MouseDown()
Endif
Case "rectangle", "ellipse"
Case "rectangle", "ellipse", "polygon"
If $bPress Then
......@@ -981,8 +981,7 @@ Public Sub imvImage_MouseDown()
If $iChangeAction = CHANGE_CENTER And If Mouse.Click = 2 Then
$hChangeRotate = $hChangeRect.Center()
imvImage.Refresh
ResetChangeRotate()
$bIgnoreDblClick = True
Return
......@@ -1006,8 +1005,7 @@ Public Sub imvImage_MouseDown()
Else If $iChangeAction = CHANGE_CENTER And If Mouse.Click = 2 Then
$hChangeRotate = $hChangeRect.Center()
imvImage.Refresh
ResetChangeRotate()
$bIgnoreDblClick = True
Return
......@@ -1055,7 +1053,7 @@ Private Sub UpdateInfo()
$cInfo!Y = Format($hCurrentPoint.Y, "0.0")
Endif
If $bPress Then
If $sTool = "rectangle" Or If $sTool = "ellipse" Then
If $sTool = "rectangle" Or If $sTool = "ellipse" Or If $sTool = "polygon" Then
$cInfo!Width = Format($fLastSelectW, "0.0")
$cInfo!Height = Format($fLastSelectH, "0.0")
Endif
......@@ -1147,7 +1145,7 @@ Private Sub FindBestMagnet(hCurrent As PointF) As PointF
iIgnoreFrom = -1
If $bPress Then
If $sTool = "rectangle" Or If $sTool = "ellipse" Or If $sTool = "line" Then
If $sTool = "rectangle" Or If $sTool = "ellipse" Or If $sTool = "polygon" Or If $sTool = "line" Then
If $hSelect Then iIgnoreFrom = $hSelect.Count - 1
Else If $sTool = "text" Then
iIgnoreFrom = $hTextSelect.Count
......@@ -1325,7 +1323,7 @@ Public Sub imvImage_MouseMove()
Endif
Endif
Case "rectangle", "ellipse"
Case "rectangle", "ellipse", "polygon"
If $bCtrl Then $hCurrentPoint.Y = $hLastPoint.Y + Abs($hCurrentPoint.X - $hLastPoint.X) * Sgn($hCurrentPoint.Y - $hLastPoint.Y)
If $hLastPoint.X <> $hCurrentPoint.X Or If $hLastPoint.Y <> $hCurrentPoint.Y Then
......@@ -1352,27 +1350,39 @@ Public Sub imvImage_MouseMove()
HH = 0
Endif
If $sTool = "ellipse" Then
Select Case $sTool
If $bShift Then
$hSelect.Ellipse($hLastPoint.X - WW, $hLastPoint.Y - HH, WW * 2, HH * 2)
WW *= 2
HH *= 2
Else
$hSelect.Ellipse(Min($hLastPoint.X, $hCurrentPoint.X), Min($hLastPoint.Y, $hCurrentPoint.Y), WW, HH)
Endif
Case "ellipse"
Else
If $bShift Then
$hSelect.Ellipse($hLastPoint.X - WW, $hLastPoint.Y - HH, WW * 2, HH * 2)
WW *= 2
HH *= 2
Else
$hSelect.Ellipse(Min($hLastPoint.X, $hCurrentPoint.X), Min($hLastPoint.Y, $hCurrentPoint.Y), WW, HH)
Endif
Case "rectangle"
If $bShift Then
$hSelect.Rectangle(X1 - WW, Y1 - HH, WW * 2, HH * 2, FImageProperty.GetRoundness())
WW *= 2
HH *= 2
Else
$hSelect.Rectangle(X1, Y1, WW, HH, FImageProperty.GetRoundness())
Endif
If $bShift Then
$hSelect.Rectangle(X1 - WW, Y1 - HH, WW * 2, HH * 2, FImageProperty.GetRoundness())
WW *= 2
HH *= 2
Else
$hSelect.Rectangle(X1, Y1, WW, HH, FImageProperty.GetRoundness())
Endif
Case "polygon"
If $bShift Then
$hSelect.Polygon(X1 - WW, Y1 - HH, WW * 2, HH * 2, FImageProperty.GetSides(), FImageProperty.GetInnerRadius())
WW *= 2
HH *= 2
Else
$hSelect.Polygon(X1, Y1, WW, HH, FImageProperty.GetSides(), FImageProperty.GetInnerRadius())
Endif
Endif
End Select
imvImage.Refresh
$fLastSelectW = WW
......@@ -1756,13 +1766,9 @@ Public Sub imvImage_MouseUp()
'$hSelect.CleanLastShape
Case "rectangle", "ellipse"
Case "rectangle", "ellipse", "polygon"
If $hLastPoint.X <> $hCurrentPoint.X Or If $hLastPoint.Y <> $hCurrentPoint.Y Then
imvImage.Refresh
Else
'ClearSelection
Endif
imvImage.Refresh
Case "change"
......@@ -2753,6 +2759,18 @@ Public Sub Form_Activate()
End
Private Sub ResetChangeRotate()
If HasSelection() And If $sTool <> "paste" Then
$hChangeRotate = $hSelect.GetBarycenter()
imvImage.Refresh
Else If $hChangeRect
$hChangeRotate = $hChangeRect.Center()
imvImage.Refresh
Endif
End
Public Sub RefreshSelection()
imvImage.Refresh
......@@ -2764,7 +2782,7 @@ Public Sub RefreshSelection()
Endif
Endif
If $hChangeRect And If Not $hChangeRotate Then $hChangeRotate = $hChangeRect.Center()
If $hChangeRect And If Not $hChangeRotate Then ResetChangeRotate()
End
......@@ -3562,3 +3580,33 @@ Public Sub btnExpandSelection_Click()
ApplyTransformation(TRANS_EXPAND)
End
' Public Sub btnPolygon_Click()
'
' Dim I As Integer
' Dim XC As Float
' Dim YC As Float
' Dim N As Integer
' Dim X As Float
' Dim Y As Float
' Dim R As Float
'
' If FImagePolygon.Run() Then Return
'
' CreateSelection
' AddUndo($hSelect.Copy())
'
' XC = $hImage.W / 2
' YC = $hImage.H / 2
' N = FImagePolygon.Sides
' If FImagePolygon.DrawStar Then R = FImagePolygon.Radius
'
' $hSelect.Polygon(0, 0, $hImage.W, $hImage.H, N, R)
'
' If FImagePolygon.AddCircle Then
' AddUndo($hSelect.Copy())
' $hSelect.Ellipse(0, 0, $hImage.W, $hImage.H)
' Endif
'
' End
# Gambas Form File 3.0
{ Form Form
MoveScaled(0,0,175,90)
MoveScaled(0,0,188,90)
Persistent = True
Arrangement = Arrange.Vertical
{ mnuEditor Menu
......@@ -287,7 +287,7 @@
}
}
{ tlbMain ToolBar
MoveScaled(0,0,168,4)
MoveScaled(0,0,185,4)
Key = "image"
Text = ("Image editor")
{ btnSave MenuButton
......@@ -452,9 +452,18 @@
Picture = Picture["icon:/small/draw-circle"]
Toggle = True
}
{ btnPolygon ToolButton btnTool
Name = "btnPolygon"
MoveScaled(79,0,4,4)
Tag = "polygon"
ToolTip = ("Polygon")
Action = ".tool-polygon"
Picture = Picture["icon:/small/draw-polygon"]
Toggle = True
}
{ btnText ToolButton btnTool
Name = "btnText"
MoveScaled(79,0,4,4)
MoveScaled(82,0,4,4)
Tag = "text"
ToolTip = ("Text")
Action = ".tool-text"
......@@ -463,7 +472,7 @@
}
{ btnMagic ToolButton btnTool
Name = "btnMagic"
MoveScaled(83,0,4,4)
MoveScaled(85,0,4,4)
Tag = "magic"
ToolTip = ("Magic wand")
Action = ".tool-magic"
......@@ -471,14 +480,14 @@
Toggle = True
}
{ btnHide ToolButton
MoveScaled(86,0,4,4)
MoveScaled(102,0,4,4)
ToolTip = ("Hide selection")
Action = ".hide"
Picture = Picture["icon:/small/unselect"]
}
{ btnEditSelection ToolButton btnTool
Name = "btnEditSelection"
MoveScaled(91,0,4,4)
MoveScaled(107,0,4,4)
Tag = "change"
ToolTip = ("Edit selection")
Action = ".tool-change"
......@@ -486,108 +495,108 @@
Toggle = True
}
{ btnExpandSelection ToolButton
MoveScaled(95,0,4,4)
MoveScaled(111,0,4,4)
Tag = "change"
ToolTip = ("Fit selection to image")
Action = ".expand-selection"
Picture = Picture["img/draw/expand.png"]
}
{ btnSaveSelection ToolButton
MoveScaled(101,0,4,4)
MoveScaled(117,0,4,4)
ToolTip = ("Save selection")
Action = ".save-selection"
Picture = Picture["img/draw/save-selection.png"]
}
{ Separator8 Separator
MoveScaled(105,0,1,4)
MoveScaled(121,0,1,4)
}
{ btnUnion ToolButton
MoveScaled(106,0,4,4)
MoveScaled(122,0,4,4)
ToolTip = ("Union")
Action = ".union"
Picture = Picture["icon:/small/union"]
}
{ btnDifference ToolButton
MoveScaled(109,0,4,4)
MoveScaled(125,0,4,4)
ToolTip = ("Difference")
Action = ".difference"
Picture = Picture["icon:/small/difference"]
}
{ btnIntersection ToolButton
MoveScaled(112,0,4,4)
MoveScaled(128,0,4,4)
Visible = False
ToolTip = ("Intersection")
Action = ".intersection"
Picture = Picture["icon:/small/intersection"]
}
{ btnExclusive ToolButton
MoveScaled(115,0,4,4)
MoveScaled(131,0,4,4)
Visible = False
ToolTip = ("Exclusive or")
Action = ".exclusive"
Picture = Picture["icon:/small/exclusive"]
}
{ btnInvert ToolButton
MoveScaled(119,0,4,4)
MoveScaled(135,0,4,4)
ToolTip = ("Invert selection")
Action = ".invert"
Picture = Picture["img/draw/invert.png"]
}
{ btnDuplicate ToolButton
MoveScaled(122,0,4,4)
MoveScaled(138,0,4,4)
ToolTip = ("Duplicate selection")
Action = ".duplicate"
Picture = Picture["icon:/small/clone"]
}
{ btnOffset ToolButton
MoveScaled(126,0,4,4)
MoveScaled(142,0,4,4)
ToolTip = ("Offset selection")
Action = ".offset"
Picture = Picture["img/draw/offset.png"]
}
{ Separator5 Separator
MoveScaled(130,0,1,4)
MoveScaled(146,0,1,4)
}
{ btnCrop ToolButton
MoveScaled(131,0,4,4)
MoveScaled(147,0,4,4)
Visible = False
ToolTip = ("Crop")
Action = ".crop"
Picture = Picture["icon:/small/crop"]
}
{ btnFlipH ToolButton
MoveScaled(134,0,4,4)
MoveScaled(150,0,4,4)
ToolTip = ("Horizontal flip")
Action = ".flip-h"
Picture = Picture["icon:/small/flip-h"]
}
{ btnFlipV ToolButton
MoveScaled(137,0,4,4)
MoveScaled(153,0,4,4)
ToolTip = ("Vertical flip")
Action = ".flip-v"
Picture = Picture["icon:/small/flip-v"]
}
{ btnRotateR ToolButton
MoveScaled(140,0,4,4)
MoveScaled(156,0,4,4)
ToolTip = ("Rotate clockwise")
Action = ".rotate-r"
Picture = Picture["icon:/small/rotate-right"]
}
{ btnRotateL ToolButton
MoveScaled(143,0,4,4)
MoveScaled(159,0,4,4)
ToolTip = ("Rotate counter-clockwise")
Action = ".rotate-l"
Picture = Picture["icon:/small/rotate-left"]
}
{ btnResize ToolButton
MoveScaled(146,0,4,4)
MoveScaled(162,0,4,4)
ToolTip = ("Resize or stretch image")
Action = ".resize"
AutoResize = True
Picture = Picture["icon:/small/resize"]
}
{ btnRotate ToolButton
MoveScaled(149,0,4,4)
MoveScaled(165,0,4,4)
Visible = False
ToolTip = ("Rotate image")
Action = ".rotate"
......@@ -596,17 +605,17 @@
}
{ btnSaveAs ToolButton mnuSaveAs
Name = "btnSaveAs"
MoveScaled(154,0,4,4)
MoveScaled(170,0,4,4)
Visible = False
ToolTip = ("Save as")
Action = ".save-as"
Picture = Picture["icon:/small/save-as"]
}
{ Spring1 Spring
MoveScaled(159,0,2,4)
MoveScaled(175,0,2,4)
}
{ ToolButton7 ToolButton
MoveScaled(163,0,4,4)
MoveScaled(179,0,4,4)
ToolTip = ("Lock / unlock file")
Action = ".locked"
Picture = Picture["icon:/small/lock"]
......@@ -822,6 +831,10 @@
Text = "Paste"
Picture = "icon:/small/paste"
}
{ Action tool-polygon
Text = "Polygon"
Picture = "icon:/small/draw-polygon"
}
{ Action tool-rectangle
Text = "Rectangle"
Picture = "icon:/small/draw-rectangle"
......@@ -872,7 +885,7 @@
{ Toolbars
{ Toolbar image
Text = "Image editor"
List = "save,reload,undo,redo,zoom-in,zoom,zoom-out,zoom-normal,zoom-fit,grid,tooltip,copy,cut,tool-paste,tool-move,tool-draw,tool-erase,tool-line,tool-rectangle,tool-ellipse,tool-text,tool-magic,hide,tool-change,expand-selection,save-selection,union,difference,intersection,exclusive,invert,duplicate,offset,crop,flip-h,flip-v,rotate-r,rotate-l,resize,rotate,save-as,locked"
Default = "save,reload,|,undo,redo,|,zoom-in,zoom,zoom-out,zoom-normal,zoom-fit,grid,tooltip,|,copy,cut,tool-paste,|,tool-move,tool-draw,tool-erase,tool-line,tool-rectangle,tool-ellipse,tool-text,tool-magic,hide,tool-change,expand-selection,save-selection,|,union,difference,invert,duplicate,offset,|,flip-h,flip-v,rotate-r,rotate-l,resize,~,locked"
List = "save,reload,undo,redo,zoom-in,zoom,zoom-out,zoom-normal,zoom-fit,grid,tooltip,copy,cut,tool-paste,tool-move,tool-draw,tool-erase,tool-line,tool-rectangle,tool-ellipse,tool-polygon,tool-text,tool-magic,hide,tool-change,expand-selection,save-selection,union,difference,intersection,exclusive,invert,duplicate,offset,crop,flip-h,flip-v,rotate-r,rotate-l,resize,rotate,save-as,locked"
Default = "save,reload,|,undo,redo,|,zoom-in,zoom,zoom-out,zoom-normal,zoom-fit,grid,tooltip,|,copy,cut,tool-paste,|,tool-move,tool-draw,tool-erase,tool-line,tool-rectangle,tool-ellipse,tool-polygon,tool-text,tool-magic,hide,tool-change,expand-selection,save-selection,|,union,difference,invert,duplicate,offset,|,flip-h,flip-v,rotate-r,rotate-l,resize,~,locked"
}
}
......@@ -785,6 +785,18 @@ Public Sub GetOperator() As Integer
End
Public Sub GetSides() As Integer
Return slbSides.Value
End
Public Sub GetInnerRadius() As Float
Return slbInnerRadius.Value / 100
End
Public Sub ReadConfig()
tabBrush.TextFont = Project.GetSmallFont()
......@@ -1257,8 +1269,6 @@ Private Sub InitSelection()
AddSelection(CImageSelection.FromString(("Arrow #2"), "0,1;0,2;4,2;4,3;6,1.5*;4,0;4,1;0,1;0.5,1.5+"), True)
AddSelection(CImageSelection.FromString(("Triangle"), "0,0*;0,1*;0.86602540378444,0.5*;0,0;0.28867513459481,0.5+;0,0.5+;0.43301270189222,0.75+;0.43301270189222,0.25+"), True)
AddSelection(CImageSelection.FromString(("Square triangle"), "0,0*;1,0*;0,1*;0,0;1,0+;0,1+;0.333333333333,0.333333333333+;0.5,0+;0.5,0.5+;0,0.5+"), True)
AddSelection(CImageSelection.FromString(("Pentagon"), "1,0*;0.3090169944,0.9510565163*;-0.8090169944,0.5877852523*;-0.8090169944,-0.5877852523*;0.3090169944,-0.9510565163*;1,0"), True)
AddSelection(CImageSelection.FromString(("Hexagon"), "1,0*;0.5,0.8660254038*;-0.5,0.8660254038*;-1,0*;-0.5,-0.8660254038*;0.5,-0.8660254038*;1,0*"), True)
LoadAllSelections()
......@@ -1268,6 +1278,7 @@ End
Public Sub SaveSelection(hImageSelection As CImageSelection)
InitSelection
$hShowSelection = AddSelection(hImageSelection)
SaveAllSelections
tabBrush.Index = 3
......@@ -1432,6 +1443,8 @@ Public Sub OnToolChange(sTool As String)
panRoundness.Visible = sTool = "rectangle"
panTolerance.Visible = sTool = "magic"
panOperator.Visible = sTool = "paste"
panSides.Visible = sTool = "polygon"
panInnerRadius.Visible = panSides.Visible
End
......@@ -1584,7 +1597,6 @@ End
Private Sub LoadAllSelections()
Dim aSave As Collection[][]
Dim sSave As String
Dim hSel As CImageSelection
Dim I As Integer
......
# Gambas Form File 3.0
{ Form Form
MoveScaled(0,0,68,177)
MoveScaled(0,0,68,195)
Persistent = True
Arrangement = Arrange.Fill
{ svwImageProperty ScrollView
MoveScaled(1,1,65,175)
MoveScaled(1,1,65,193)
Arrangement = Arrange.Vertical
Border = False
ScrollBar = Scroll.Vertical
......@@ -268,7 +268,7 @@
MoveScaled(22,60,15,0)
}
{ panSlider VBox
MoveScaled(1,64,63,20)
MoveScaled(1,64,63,28)
Margin = True
{ HPanel1 HBox
MoveScaled(0,0,62,4)
......@@ -354,12 +354,43 @@
List = [("Clear destination"), ("Keep source"), ("Draw source on top of destination"), ("Replace destination by source"), ("Clear source with destination"), ("Draw source on destination only"), ("Keep destination"), ("Draw source above destination"), ("Replace source by destination"), ("Clear destination with source"), ("Draw destination on source only"), ("Keep source or destination alone"), ("Add source and destination"), ("Multiply source and destination")]
}
}
{ panSides HBox
MoveScaled(0,20,62,4)
Spacing = True
{ Label16 Label
MoveScaled(0,0,15,4)
Text = ("Sides count")
}
{ slbSides SliderBox
MoveScaled(18,0,38,4)
Expand = True
Picture = Picture["icon:/large/draw-polygon"]
MinValue = 5
MaxValue = 360
DefaultValue = 5
Value = 5
}
}
{ panInnerRadius HBox
MoveScaled(0,24,62,4)
Spacing = True
{ Label17 Label
MoveScaled(0,0,15,4)
Text = ("Inner radius")
}
{ slbInnerRadius SliderBox
MoveScaled(18,0,38,4)
Expand = True
Picture = Picture["icon:/large/draw-star"]
Step = 10
}
}
}
{ Separator3 Separator
MoveScaled(19,87,26,0)
MoveScaled(19,106,26,0)
}
{ Panel13 Panel
MoveScaled(1,88,64,43)
MoveScaled(1,107,64,43)
Arrangement = Arrange.Vertical
Margin = True
{ panEffect Expander
......@@ -527,10 +558,10 @@
}
}
{ sepText Separator
MoveScaled(21,132,15,0)
MoveScaled(21,151,15,0)
}
{ panText VBox
MoveScaled(3,133,60,23)
MoveScaled(3,152,60,23)
Visible = False
Margin = True
{ Panel11 HBox
......@@ -612,10 +643,10 @@
}
}
{ sepGrid Separator
MoveScaled(19,157,15,0)
MoveScaled(19,176,15,0)
}
{ panGrid VBox
MoveScaled(2,158,62,15)
MoveScaled(2,177,62,15)
Visible = False
Margin = True
{ Panel1 HBox
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment