How Do I Create a Clickable URL Hyperlink on Mac Desktop App?

How do I create a control on a Mac Desktop app that is a clickable hyperlink that looks like this:

Same as the WebLink for a WebApp

The Desktop app does not have a WebLink control. So I want to provide the link text and link URL so that the text is displayed like a normal hyperlink on a web page.

I’ve done a bit of searching, and found an example of using a Button control, that that is not what I want. It needs to look like a hyperlink, except that I would prefer it be blue and underlined.

I would like it to be a class that I can paste in a standard Markdown link, like [WebLink From Xojo Documentation](https://documentation.xojo.com/api/user_interface/web/weblink.html) and then when the app is run it formats it and makes it clickable.

TIA.

Quite simple, just use a simple Label and

  • set the font to ‘underline’
  • set text color to blue
  • set mouse cursor to ‘System.Cursors.FingerPointer’ in MouseEnter event
  • open URL in MouseDown event: ShowURL(“https://www.gate61.com”)

The only extra step is eventually to track down the url that were open before and change their color to purple.

Hi @Jim Underwood

Here you can download a fast implementation of the class suggested by Olivier (with the companion example project).

Hope you find it useful! If you have any doubt… don’t hesitate to ask :slight_smile:

Javier

Javier, thank you so much. This is outstanding! It is also a great example for me to learn from.

It will be very useful, but I have a newbie question: Where do I find the “URL” Property of the “URLLabel1” Control to view and set?
I feel foolish to ask this, but I have searhed, using the Find and manually, everywhere, but can’t find it.
The Find says it is in the “Layout”, but I don’t see it. Here is what I see:

Thanks again.

[quote=491699:@Olivier Colard]Quite simple, just use a simple Label and

set the font to ‘underline’
set text color to blue
set mouse cursor to ‘System.Cursors.FingerPointer’ in MouseEnter event
open URL in MouseDown event: ShowURL(“https://www.gate61.com”)[/quote]

Olivier, thanks for your quick reply. Although your post contained a few syntax errors, I was able to get it working thanks to your guidance.

Hi @Jim Underwood

Please, try to download the project again… I left it out of the Inspector Panel in a last minute change! Now you should be able to see that one!

No problem. I understand how stuff like that happens.

IAC, I figured it out when I finally came across this page:
Desktop Custom Controls

BTW, I think there may be a problem with the code in the Set method of URL:
(your original code is commented out)

// If Not value.BeginsWith("http://") Or Not value.BeginsWith("https://") Then
// value = "https://"+value
// End If

If Not value.BeginsWith("http") Then
  value = "https://" + value
End If

mURL = value

I found that when I entered a URL that included “https://” then it produced an invalid URL.

Also, I’m not clear on Get vs Set. It seems to me that you would need this code when another method was to Get the URL, like the MouseDown event: ShowURL Me.URL

So, I added this to the URL Get method:

If Not mURL.BeginsWith("http") Then
  mURL = "https://" + mURL
End If
Return mURL

With these changes it seems to work OK with and without a “http” at the start of the entered URL.

If I’ve done something wrong, please let me know.

although that will give you grief if you want a clickable URL display that holds an email URL or ftp or some other URL form

Hey @Jim Underwood

No problem! my fault (i was too fast on my side :-))

Simply change that lines for:

If Not value.BeginsWith("http://") And Not value.BeginsWith("https://") Then value = "https://"+value End If

In addition, you don’t need to put that code on the Getter… it simply returns the content (the URL) stored by the back private property mURL… that has been processed already by the Setter method. So if the url came in without “http” or “https” then it is going to be added by the Setter and properly returned by the getter.

Thanks again.

I think we need to consider URL schemes other than “http”, like “ftp”, mailto, and any of the many custom URL schemes available today on the Mac. This works for me:

Revised 2020-06-09 23:32 GMT-5

// --- Try to Match Standard URL Schemes ---
//   Can be in either format:  "protocol://"  OR  "protocol:"

dim rx as new RegEx
rx.SearchPattern = "(?mi-Us)^(?:\\w.+:\\/\\/)|(?:\\w.*\\:)"
dim match as RegExMatch = rx.Search( value )

// --- IF NO Match, Then Assume https ---
If match is Nil Then
  value = "https://" + value
End If

mURL = value

many schemes do not use //
mailto for instance

stackoverflow has some really nasty regex’for validating URLS
see https://stackoverflow.com/questions/161738/what-is-the-best-regular-expression-to-check-if-a-string-is-a-valid-url

[quote=491826:@Norman Palardy]many schemes do not use //
mailto for instance

stackoverflow has some really nasty regex’for validating URLS[/quote]

We do NOT need to validate the URL. We only need to determine if we should assume “https” and prefix the text with that.
If you would like to provide a better solution, please feel free to do so.

Actually, I don’t know of any URL schemes, other than mailto, that do not use “//”. If you do, please list them.

Javier, thank you again for being so helpful, and teaching me so much.

One of my objectives is to paste a Markdown link in the Label, and then use that.
Here is my Regex code for the Open() event to parse the MD link.
If it finds a MD Link, then it will parse it and set the Label properties.
Else it makes no changes.

So now the LinkLabel subclass will work with both a manual setting of the text and URL properties, and with a Markdown link.

Works so far in my testing.

[h]LinkLabel Open() Method[/h]

RaiseEvent Open
Me.Underline = True
Me.TextColor = LinkColor


//--- Parse Markdown Link IF It Exists in Label Value --- //ADD JMichaelTX 2020-06-09

dim rx as new RegEx
rx.SearchPattern = "(?mi-Us)\\[(.+)\\]\\((.+)\\)"

dim rxOptions as RegExOptions = rx.Options
rxOptions.MatchEmpty = false
rxOptions.LineEndType = 4

dim match as RegExMatch = rx.Search( Me.Value )

if Not (match is Nil) then
  
  //--- Set Label Value and URL Properties ---
  //     to Link Text and URL
  
  dim linkText as String = match.SubExpressionString(1)
  dim linkURL as String = match.SubExpressionString(2)
  
  Me.Value = linkText
  Me.URL = linkURL
  
end if

[quote=491825:@Jim Underwood]I think we need to consider URL schemes other than “http”, like “ftp”, mailto, and any of the many custom URL schemes available today on the Mac. This works for me:

[h]Revised 2020-06-09 23:32 GMT-5[/h]

// — Try to Match Standard URL Schemes —
// Can be in either format: “protocol://” OR “protocol:”[/quote]

OK, should now work with most URL schemes. I have revised my above post.

Happy of being of help and that you’re enjoying learning Xojo!

Go ahead and I hope to see your first Xojo App soon :slight_smile:

Javier

I’m nitpicking here, but since it’s a one-time change, I’d put this in the Open event instead. Unless you decide to set the cursor back to something else when you leave, but it seems pointless anyway.