Alternative Cocoa framework, anyone?

Dude you’re from the future man!

Nice work young man (he claims in his poshest of British accents).

If I may air a few suggestions?
#1 Use the .h files instead, they’re often more upto date than the web based documentation.
#2 Use “External Methods” where possible, I love them to bits.

?-?

Yeah. I saw the typo too late to correct it. I meant 2015, naturally.

Using header files is a great idea, and I’m a little weirded out that it didn’t occur to me.

External methods - I’ve used a few. They were problematic for me in the past, but I can’t recall why at the moment. I’m not a huge fan, but they are useful here and there.

I guessed, but I couldn’t resist in making a joke :slight_smile:

Don’t be, our brains all work a little differently; I bring it up because often I have to resort to the header files because the online documentation is non-existent or not up to date.

I’m always amazed when people come up with different solutions to myself, like how do you think that. People often ask me the same thing. One situation recently, I completely ignored the fact that there were other people there, which turned out to be the key in resolving the situation quickly. It was a car where the driver had accidentally driven into the concrete ditch. Turns out the easy solution was to use 7 guys and lift it out!

In 2016r1.1 they are very usable and I’ve refactored large swathes of my own ‘AppKit’ to use them. In the past they also had a huge speed benefit, although with 64-Bit (and presumably LLVM) it’s not so significant, however using them as opposed to regular methods can help reduce the overall footprint of an application.

Having a unified library will help many users, some of us more experienced probably have their own already. I must confess that my own internal ‘AppKit’ is a mix-match of pure declares and convenience functions. When I sell source code, I try to use more convenience than pure (as it’s easier for people who are unfamiliar with the Cocoa API).

I’d gather the information from the Objective C Runtime, and then add the missing parts with help of BridgeSupport files.

A nice aspect of parsing the documentation is Daniel has included Apples description with each method.

Precisely, Will. That part is really handy for me. One of my goals was to make things really easy on myself. I comment obsessively because I tend to be forgetful, so embedding my own documentation in with the code prevents a lot of head scratching down the road. Not sure how that would work using external methods. I wasn’t aware of the speed difference, though.

Using the Obj-C runtime will get you a lot more than that is considered public API.

Yeah that’s true, I don’t think you can add comments to an external method.

That’s correct, but it was much easier to build my library that way than via the Apple docs, which I had tried first.

I banged this out yesterday for my day-job, and thought it might make a good example of how I use all of this. I added it as a method to the CojoTextArea subclass.

My process was to find a reasonable solution to the problem at hand (adding custom tab stops to a TextArea.) I found code posted on StackOverflow. I was able to read through the code line by line, translating to my dot syntax and adding comments as I went;

[code]Sub SetTextWithTabs(aString as String, tabs() as Single)
’ This mess overrides the default tab stops for NSTextView.
’ See the following link for details;

'http://stackoverflow.com/questions/14278119/premature-line-wrapping-in-nstextview-when-tabs-are-used

’ Pass in the text you want in the field, and an array of Singles describing where you want the tab stops, based on
’ 72 points per inch. This could probably be readliy adapted to other measurement systems.

’ ----------

dim points_per as Single = 72.0

dim tabArray as new CojoArray
dim cn as Integer = tabs.Ubound

’ Loop through the incoming array of singles, and make NSTextTab objects out of them.
’ Pack them into an NSMutableArray very easily using a CojoArray.
for idx as integer = 0 to cn

dim aTab as new NSPtr( "NSTextTab" ) ' New instance.
Call aTab.Alloc ' Allocated.

' Now init with our value.
aTab = Cojo.NSTextTab.initWithType( aTab, Cojo.NSTextTabType.NSLeftTabStopType, ( tabs( idx )  * points_per  ) )

' Add the object to the CojoArray.
tabArray.Append( aTab )

next

’ Create a new paragraph style with our array of tabs.
dim aMutableParagraphStyle as NSPtr = Cojo.NSParagraphStyle.defaultParagraphStyle.MutableCopy
Cojo.NSMutableParagraphStyle.setTabStops( aMutableParagraphStyle, tabArray.NSPtr )

’ Here we initialize an attributed string with our incoming string, and make a mutable copy.
dim attributedString as new NSPtr( “NSAttributedString” )
Call attributedString.Alloc
attributedString = Cojo.NSAttributedString.initWithString( attributedString, aString ).MutableCopy

’ We need a range describing all the text.
dim aRange as NSRange
aRange.location = 0
aRange.length = Len( aString )

’ Now we apply the paragraph style over that range.
dim nam as String = Cojo.StringConstant( “NSParagraphStyleAttributeName” )
Cojo.NSMutableAttributedString.addAttribute( attributedString, nam, aMutableParagraphStyle, aRange )

’ Now we drill down from TextArea to its Document view, and then that thing’s Text Storage.
dim docView as NSPtr = Cojo.NSScrollView.DocumentView( me.NSPtr )
dim aTextStorage as NSPtr = Cojo.NSTextView.textStorage( docView )

’ Finally, we plug our attributed string into the text storage, and voila!
Cojo.NSMutableAttributedString.setAttributedString( aTextStorage, attributedString )

’ These force the TextArea to redraw with our spiffy new contents.
me.SetFocus
me.Refresh

End Sub
[/code]

I also set the following values in the open event of the TextArea so I can see the ruler;

me.isRichText = True me.usesFindPanel = True me.isRulerVisible = True

This process of translation works phenomenally well in my brain. Not sure everyone will agree.

Lots of updates to the project, due in large part to the fact that I posted it in public at all. That alone made it a worthwhile exercise. Changes suggested by Joe Ranieri above were also put in place. More details in the Version note.

I finally updated to 2016 r1.1 and just compiled a 64 bit app with it. It ran without complaint. That doesn’t mean there might not be some lingering oddities (NSColor seems weird,) but overall I’m happy.

The original link above has the updated version. Posted here for convenience;

https://dl.dropboxusercontent.com/u/28082075/Cojo%20Master.xojo_binary_project.zip

Could you be a bit more specific?

Sure. When I compiled and ran the project as 64-bit, everything I tried appeared to work as expected, except that my Cocoa drawing example (which is an absolute mess to begin with) filled the circle with an unexpected color. I made a mental note to look into it eventually. I suspect I’ve overlooked something simple in my Color<>NSColor conversion routines, but I’m not sure yet. Just noticed it like 10 minutes ago.

Ahh. And I just noticed the search field doesn’t work all of a sudden. Thankfully, that was a quick fix. I was a victim of my own overthinking. Links updated.

With NSColor make sure you’re using CGFloat as the Xojo data type. Singles will only work on 32-Bit.

Well. NSColor isn’t something I use that much, so I wasn’t really familiar with how to use them (didn’t realize I was responsible for retain/release.) There were definitely mistakes in my interconversion with Xojo colors, though not what I thought. They’re better now.

However, that didn’t solve the problem. I think I need a better Cocoa drawing example. (Or to better understand what I’m doing there at all.)

Thank you very much Daniel!

Great work.

By the way, in spanish prefixing a word with “cojo” means that thing is fantastic. “CojoWindow” for spaniards would be read like “Window cool as hell”, and the rest are the same. Using these feels weirdly epic :slight_smile:

NSColor fixes are in the download now, although the drawing demo is still a minor train wreck. Last change for awhile I swear.

And thanks for the Spanish insight, Eduardo. I had no idea!

… Tim examines project, thinks back to reinventing the X11 xt intrinsics for Python (pre-TKInter) back in the mid-90’s, places @Daniel Bronson into appropriately sized pedestal due to sheer stick-to-it-iveness.

That’s QUITE an effort you’ve assembled, Daniel. I’m looking forward to digging in.

Now, once you’re had dinner, how about getting started on a GTK version :O.