UI line styles with rectangle or canvas

By line styles I mean ‘dotted’ or ‘segmented’ etc. I can’t see any obvious options looking at the Inspector. Can it be done programmatically?

The reason I ask is that the main part of my code is working fine, and now, as you do, I’m re-considering the user interface. There are scenarios where buttons are enabled/disabled depending on the circumstances etc. All the while, the user is guided by those button choices. Very procedural.

The construct is simple. There is only ever two options - the next button to proceed, or exit/quit the program.

However, there is one circumstance where the user is confronted with two options (apart from exit). I’d like one of those options to be less obvious - hence the dotted line around the button. Enabled/Disabled is too harsh.

Any other ideas are welcome.

it is not supported directly by Xojo
here is a piece of code I found from a while back… you can adapt it to the line patterns you desire

FUNCTION DrawDashedLine(g as graphics,x1 as integer,y1 as integer,x2 as integer,y2 as integer,pattern as integer=0)
  Const DashStyleSolid = 0
  Const DashStyleDash = 1
  Const DashStyleDot = 2
  Const DashStyleDashDot = 3
  Const DashStyleDashDotDot = 4
  //Const DashStyleCustom = 5
  If pattern<=DashStyleSolid Or pattern>DashStyleDashDotDot Then 
    // ** Solid Line is same regardless of Platform ** /
    g.drawline x1,y1,x2,y2
    Exit Sub
  Else
    #If TargetCocoa Then
      Const sizeOfSingle = 4
      // ************************** //
      // **  Cocoa Pattern Line  ** //
      // ************************** //
      Dim lengths(-1) As Double
      Dim x As Integer
      Dim lengthArray As MemoryBlock
      Dim offset As Integer = 0
      Dim dash As Double
      Dim dot As Double
      Dim spc As Double
      Dim aa_flag As Boolean=g.AntiAlias
      
      Declare Sub CGContextSetLineDash Lib "Cocoa" ( context As Integer, phase As Single, lengths As Ptr, count As UInt32)
      
      x=g.penwidth
      dash=x*3
      dot=x
      spc=dot
      g.AntiAlias=False
      Select Case pattern
      Case DashStyleDot
        lengths=Array(dot,spc) ' dotted line [.......]
      Case DashStyleDash
        lengths=Array(dash,spc) ' dashed line [- - - -]
      Case DashStyleDashDot 
        lengths=Array(dash,spc,dot,spc)
      Case DashStyleDashDotDot 
        lengths=Array(dash,spc,dash,spc,dot,spc,dot,spc)
      End Select
      //
      lengthArray=New MemoryBlock(sizeOfSingle*(1 + UBound(lengths)))
      For i As Integer = 0 To UBound(lengths)
        lengthArray.SingleValue(offset) = lengths(i)
        offset = offset + sizeOfSingle
      Next
      
      CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),0,lengthArray,lengths.Ubound+1
      //
      g.drawline x1,y1,x2,y2
      //
      CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),0,Nil,0 ' solid line
      //
      g.AntiAlias=aa_flag
    #ElseIf TargetWin32 Then
      // ************************** //
      // ** Windows Pattern Line ** //
      // ************************** //
      Dim pen As Integer
      Dim n As Integer
      Dim c As Color
      Dim gpx As Integer
      Dim mb As New MemoryBlock(4)
      
      Declare Function GdipCreatePen1 Lib "GDIPlus" (c As Integer, width As Single, unit As Integer, ByRef p As Integer) As Integer
      Declare Function GdipSetPenDashStyle Lib "GDIPlus" (pen As Integer, style As Integer) As Integer
      Declare Function GdipCreateFromHDC Lib "GDIPlus" (hdc As Integer, ByRef g As Integer) As Integer
      Declare Function GdipDrawLine Lib "GDIPlus" (g As Integer, pen As Integer, x1 As Single, y1 As Single, x2 As Single, y2 As Single) As Integer
      Declare Function GdipDeletePen Lib "GDIPlus" (pen As Integer) As Integer
      Declare Function GdipDeleteGraphics Lib "GDIPlus" (g As Integer) As Integer
      
      
      c = g.ForeColor
      mb.Byte(0) = c.blue
      mb.Byte(1) = c.green
      mb.Byte(2) = c.red
      mb.Byte(3) = 255    // alpha = opaque
      n = mb.Int32Value(0)
      Call GdipCreatePen1(n, g.PenWidth, 2, pen)
      Call GdipSetPenDashStyle(pen, pattern)
      Call GdipCreateFromHDC(g.handle(Graphics.HandleTypeHDC), gpx)
      Call GdipDrawLine(gpx, pen, x1, y1, x2, y2)
      Call GdipDeletePen(pen)
      Call GdipDeleteGraphics(gpx)
    #EndIf
  End If
END FUNCTION

Thanks for that Dave. It’s a lot for me to absorb at this point, but I’ll keep it marked for future reference.

I think I was being a bit lazy trying to come up with a ‘quick fix’. After having a better look, I think I can come to a good solution by simply re-ordering the events. Which is a better way to go and makes the UI more intuitive.

Nice to know that there is a workaround for dashed/dotted lines etc.

Cheers.