Cocoa Modul Serie

Kommentare anzeigen Worklog abonnieren
Gehe zu Seite Zurück  1, 2, 3, 4

Worklogs Cocoa Modul Serie

08 - TableView #2

Donnerstag, 29. Dezember 2011 von d-bug
Hallo,

eigentlich wollte ich mich ja intensiv mit Skyrim beschäftigen, aber irgend wie fasziniert mich die TableView zur Zeit mehr! Bin wohl doch anders als die anderen Kinder!

Da ich nun das hinter den Kulissen noch mal alles umstrukturiert habe, lassen sich Methoden noch einfacher wrappen, so dass ich für den Rest der TableView gerade mal ein paar Stunden brauchte. Aber um das zu realisieren, musste ich erst mit der OBJC-Runtime Bibliothek von Cocoa durch die Hölle gehen. Erst mein kleiner puscheliger hamZta brachte mich auf den Pfad der Erleuchtung zurück. Beim schreiben der ganzen Übergabefunktionen gab es überhaupt keine Probleme, bis ich auf mein erstes Float stieß. Ab dann ging es steil bergab. Erst sagte mir die Runtime immer nur, dass die Funktion objc_msgSend_fpret keine Daten zurück geben könne, dann, dass sie nicht existieren würde. Ich habe tatsächlich zwei genervte Tage nach dem Fehler gesucht, bis hamZta mir sagte wie es richtig geht und mir kurze Zeit später auffiel, dass ich vergessen hatte die benötigten *.h auch zu importieren. Letzteres ist mir erst nicht aufgefallen, da objc_msgSend und objc_msgSend_stret auch ohne die Libs ihren dienst verrichteten. Langes BlaBla...

Wie dem auch sei, heute hab ich dann damit zugebracht, munter alle Methoden und Delegates der NSTableView Klasse zu übertragen. Dies geht nun immens schnell, da ich nicht noch in OBJC eine extra Funktion für jede Methode schreiben muss.

Kurzer Ausschnitt aus der CCTableView Klasse:
BlitzMax: [AUSKLAPPEN]

'...

Rem
bbdoc: Sets the selection highlight style used by the receiver to indicate row and column selection. Available in Mac OS X v10.5 and later.
about:<table>
<tr>
<th>Parameter</th>
<th>Description</th>
</tr><tr>
<td>style:Int</td>
<td>Could be one of the following style flags:<br>
#CCTableViewSelectionHighlightStyleNone<br>
#CCTableViewSelectionHighlightStyleRegular<br>
#CCTableViewSelectionHighlightStyleSourceList
</td>
</tr>
</table>
EndRem

Method setSelectionHighlightStyle(style:Int)
If MAC_OS_X_VERSION < 105 Return
If style = -1 And MAC_OS_X_VERSION < 106 Return
OBJC_sendMessageVoidI(class(), "setSelectionHighlightStyle:", style)
End Method

'...

Rem
bbdoc: Returns a Boolean value that indicates whether the receiver uses the standard alternating row colors for its background.
returns: Bool value as Integer
EndRem

Method usesAlternatingRowBackgroundColors:Int()
Return OBJC_sendMessageBool(class(), "usesAlternatingRowBackgroundColors")
End Method

'...

Man sieht, ich benutze jetzt einfach nur noch die OBJC_ Funktionen nebst Angabe des Cocoa Methoden-Namens und der Pointer und schwups...




Aber jetzt mal zur TableView...

Das da:
BlitzMax: [AUSKLAPPEN]
SuperStrict

Framework cocoa.cocoa


'create global CCSampleController instance
Global controller:CCSampleController = New CCSampleController

'create global CCApplication instance
Global app:CCApplication = (New CCApplication).init()

'bind controller as delegate to the application
app.setDelegate(controller)

'start the applications main loop
app.run()


'Controller class
Type CCSampleController Extends CCObject

Field window:CCWindow

Field columnA:CCTableViewColumn
Field columnB:CCTableViewColumn
Field columnC:CCTableViewColumn

'use this method to initialize gadgets
Method applicationDidFinishLaunching(notification:CCNotification)

'create window
Local frame:CCRect = CCMakeRect(100.0, 100.0, 640.0, 480.0)
window = CCWindow.documentWindow(frame)
window.setDelegate(Self)
window.setTitle(AppTitle)
window.center()

Local scrollView:CCScrollView = CCScrollView.scrollView(window.contentView().frame())
scrollView.setLayout(CCAlignLeft | CCAlignTop | CCAlignWidthSizable | CCAlignHeightSizable)
scrollView.setDelegate(Self)
window.contentView().addSubView(scrollView)

Local tableView:CCTableView = (New CCTableView).initWithFrame(CCMakeRect(0,0,800,600))
scrollView.setDocumentView(tableView)
tableView.setDelegate(Self)
tableView.setFloatsGroupRows(NO)
tableView.setAllowsMultipleSelection(YES)
tableView.setUsesAlternatingRowBackgroundColors(YES)

columnC = (New CCSampleButtonColumn).init()
columnC.setEditable(NO)
columnC.sizeToFit()
tableView.addColumn(columnC)

columnA = tableView.addColumnWithTitle("Hundefutter Ration")
columnA.setEditable(NO)

columnB = tableView.addColumnWithTitle("Wurstfaktor")


For Local i:Int = 0 To 99
tableView.addRow((New CCSampleRow).init(String(i), "The magic tableView row number "+String(i)))
Next

tableView.sizeLastColumnToFit()
tableView.reloadData()

window.show()
End Method


'terminate application when last window is closed
Method applicationShouldTerminateAfterLastWindowClosed:Int()
Return YES
End Method

End Type


Type CCSampleRow Extends CCTableViewRow

Field _isChecked:Int
Field _title:String
Field _value:String

Method init:CCSampleRow(title:String, value:String)
_title = title
_value = value
_isChecked = NO
Return Self
End Method

'return value must be of type String or CCObject
'this method is abtract
Method dataForColumn:Object(column:CCTableViewColumn)
Select column
Case controller.columnA ; Return _title
Case controller.columnB ; Return _value
Case controller.columnC ; Return String(_isChecked)
End Select
End Method

'select only rows which aren't group rows
Method isSelectable:Int()
Return Not isGroupRow()
End Method

'allow editing of rows when column is editable and the rows aren't group rows
Method isEditable:Int(column:CCTableViewColumn)
If column.isEditable()
Return Not isGroupRow()
EndIf
Return NO
End Method

Method isGroupRow:Int()
Select Int(_title)
Case 0,10,20,30,40 Return YES
End Select
Return NO
End Method

Method showsExpansion:Int(column:CCTableViewColumn)
Return YES
End Method

Method setDataForColumn(data:Object, column:CCTableViewColumn)
Select column
Case controller.columnB
If String(data)
_value = String(data)
EndIf
Case controller.columnC
_isChecked = CCNumber(data).boolValue()
End Select
End Method

End Type


'this column demonstrades how to bind a button cell to a the table column.
'this is a dirty hack and needs some optimization
Type CCSampleButtonColumn Extends CCTableViewColumn

Method init:CCTableViewColumn()
Super.init()
Local button:CCButton = CCButton.switchButton(CCMakeRect(0,0,22,22), "", CCNullAction, CCNullTarget)
OBJC_sendMessageVoidO(class(), "setDataCell:", OBJC_sendMessageObject(button.class(), "cell"))
setTitle(" ")
Return Self
End Method

End Type

...macht das da:
user posted image

...also jetzt auch mit der Option auf Buttons und dergleichen in den Zellen. Außerdem kann man jetzt auch Daten setzen (Zellen umbenennen, Haken setzten usw...). Leider hab ich noch keine Möglichkeit gefunden Zellen zu unterdrücken. Ich meine, die SwitchBox und der Gruppen-Zeile ist irgendwie über. Die hätte ich ja gern da weg gehabt. Außerdem ist automatisch der Haken drin, bei normalen Zeilen aber nicht. Alles komisch da...



So, das war es dann auch mal wieder.

07 - TischGuck

Samstag, 24. Dezember 2011 von d-bug
Hallo zusammen,

da heute Heiligabend ist, dachte ich mir, dass ich ja mal mit der angekündigten TableView anfangen könne. Gedacht getan!

Folgendermaßen wird eine TableView zu gestalten sein: Erstmal wird die View als solche erstellt. Danach kann man beliebig viele Reihen (Columns) einfügen. Beliebig im Sinne von "Wieviel das System her gibt". Zeilen werden von einer Klasse namens CCTableViewRow abgeleitet und sind nur dazu gedacht die Daten zurück zu geben.

Momentan enthält die CCTableViewRow Klasse exakt zwei Methoden - row.dataForColumn und row.isGroupRow. Erstere gibt die Daten zurück, die angezeigt werden sollen. Letztere sagt der TableView, dass diese Zeile eine Gruppenzeile ist (siehe Bild (die grauen Zeilen)).

Ihr seht, da fehlt noch jede Menge Zeugs um die TableView vernünftig handhaben zu können. Im Prinzip ging es mir auch erst mal darum einen Anpack zu haben, auf den man aufbauen kann und der beliebig erweiterbar ist.

BlitzMax: [AUSKLAPPEN]
SuperStrict

Framework cocoa.cocoa


'create global CCSampleController instance
Global controller:CCSampleController = New CCSampleController

'create global CCApplication instance
Global app:CCApplication = (New CCApplication).init()

'bind controller as delegate to the application
app.setDelegate(controller)

'start the applications main loop
app.run()


'Controller class
Type CCSampleController Extends CCObject

Field window:CCWindow

Field columnA:CCTableViewColumn
Field columnB:CCTableViewColumn

'use this method to initialize gadgets
Method applicationDidFinishLaunching(notification:CCNotification)

'create window
Local frame:CCRect = CCMakeRect(100.0, 100.0, 640.0, 480.0)
window = CCWindow.documentWindow(frame)
window.setDelegate(Self)
window.setTitle(AppTitle)
window.center()

Local scrollView:CCScrollView = CCScrollView.scrollView(window.contentView().frame())
scrollView.setLayout(CCAlignLeft | CCAlignTop | CCAlignWidthSizable | CCAlignHeightSizable)
scrollView.setDelegate(Self)
window.contentView().addSubView(scrollView)


Local tableView:CCTableView = (New CCTableView).initWithFrame(CCMakeRect(0,0,800,600))
scrollView.setDocumentView(tableView)


columnA = tableView.addColumnWithTitle("Hundefutter Ration")
columnB = tableView.addColumnWithTitle("Wurstfaktor")


For Local i:Int = 0 To 99
tableView.addRow((New CCSampleRow).init(String(i), "The magic tableView row number "+String(i)))
Next

tableView.sizeToFit()
tableView.reloadData()

window.show()
End Method


'terminate application when last window is closed
Method applicationShouldTerminateAfterLastWindowClosed:Int()
Return YES
End Method

End Type


Type CCSampleRow Extends CCTableViewRow

Field _title:String
Field _value:String

Method init:CCSampleRow(title:String, value:String)
_title = title
_value = value
Return Self
End Method

'return value must be of type String or CCObject
'this method is abtract
Method dataForColumn:Object(column:CCTableViewColumn)
Select column
Case controller.columnA ; Return _title
Case controller.columnB ; Return _value
End Select
End Method

Method isGroupRow:Int()
Select Int(_title)
Case 0,10,20,30,40 ; Return YES
End Select
Return NO
End Method

End Type




user posted image

So, morgen geht's ab zur Familie und die Woche werd ich mich mal auf Skyrim stürzen! Also erwartet nicht zu viel in nächster Zeit.

06 - Scrollen bis der Arzt kommt

Montag, 12. Dezember 2011 von d-bug
Hallo zusammen,

als Vorbereitung auf die bereits erwähnten Table-und Outlineviews, hab ich schon mal begonnen die ScrollView zu schreiben. Dabei ist mir aufgefallen, dass ich total vergessen hatte den restlichen views beizubringen Notifications zu senden. Asche auf mein Haupt! Das hab ich mal eben schnell gefixt.

Zur ScrollView selbst gibt es nicht viel zu sagen. Im Gegensatz zur Vorgehensweise von MaxGUI wird in Cocoa jede zu scrollende View in einer ScrollView eingebettet. Die Scroller Klasse als solches sollte eigentlich gar nicht verwendet werden, so sagt es zumindest Apple. Ich hab die trotzdem mal gleich mit gewrappt. Im Moment würde mir dafür zwar nur ein Canvas als Anwendungsfall einfallen, aber da kommt bestimmt noch mehr.

Die Scroller-Klasse als solches habe ich noch nicht fertig gestellt. Ich brauchte sie erst mal nur um der ScrollView die Methoden scrollView.horizontalScroller() und scrollView.verticalScroller() beibringen zu können. Man kann zwar bereits einen Scroller erstellen, dieser nimmt aber dann noch keinerlei Einstellungen an.

Ich hatte eigentlich gedacht, dass die ScrollView ihre Scroll Positionen über die Scroller definiert. Dies war aber ein Trugschluss. Sie enthält zwei Views, die gegeneinander gerechnet werden müssen. Dazu hab ich ein paar Methoden implementiert, die die Rechnerei vereinfachen sollen. scrollView.horizontalValue() und scrollView.verticalValue() geben die aktuellen Positionen zurück, scrollView.maximumHorizontalValue() und scrollView.maximumVerticalValue() geben die maximal möglichen Positionen zurück. Zu den ersten beiden Methoden gibt's natürlich auch die passenden Setter Methoden. Ob das alle nötigen Methoden sind, wird der erste Einsatz in einer Applikation zeigen in der man die Position manipulieren bzw. abfragen muss.

Ein Bild zur ScrollView:
user posted image

Eins Sample zur ScrollView:
BlitzMax: [AUSKLAPPEN]
SuperStrict

Framework cocoa.cocoa


'create global CCSampleController instance
Global controller:CCSampleController = New CCSampleController

'create global CCApplication instance
Global app:CCApplication = (New CCApplication).init()

'bind controller as delegate to the application
app.setDelegate(controller)

'start the applications main loop
app.run()


'Controller class
Type CCSampleController Extends CCObject

Field window:CCWindow

'use this method to initialize gadgets
Method applicationDidFinishLaunching(notification:CCNotification)

'create window
Local frame:CCRect = CCMakeRect(100.0, 100.0, 300.0, 200.0)
window = CCWindow.documentWindow(frame)
window.setDelegate(Self)
window.setTitle(AppTitle)
window.center()

Local view:CCScrollView = CCScrollView.scrollView(window.contentView().frame())
view.setLayout(CCAlignLeft | CCAlignTop | CCAlignWidthSizable | CCAlignHeightSizable)
view.setDelegate(Self)

Local documentView:CCImageView = CCImageView.fromImage(CCImage.open("kuh.jpg"))
view.setDocumentView(documentView)
window.contentView().addSubView(view)
window.show()
End Method


'terminate application when last window is closed
Method applicationShouldTerminateAfterLastWindowClosed:Int()
Return YES
End Method

'posted when the scroll position of a scrollview has changed
Method viewBoundsDidChange(notification:CCNotification)
CCLog(notification)
End Method

End Type


Ganz nebenbei hab ich der CCImage Klasse noch das Laden beigebracht und sie gezwungen mal die Größe des Bildes preis zu geben. Außerdem hab ich dann noch die CCImageView Klasse um eine Funktion erweitert, die es erlaubt eine ImageView ohne große Umstände aus einem Image zu erstellen. Die ImageView nimmt dabei automatisch die Größe des Images an. Brauchte ich eigentlich auch nur um der ScrollView Leben einzuhauchen.

Grüße

05 - Unter der Haube #2

Samstag, 10. Dezember 2011 von d-bug
Hallöle,

heute gibt es mal keinen Screen zu sehen, dafür ein paar Neuerungen unter der Haube.

Zunächst habe ich aber mal, wie angekündigt, die ImageView Klasse fertig geschrieben. Dazu gibt es aber kein eigenes Sample. Drag'n Drop muss noch eingebaut werden, aber da bin ich mir noch nicht ganz im klaren, wie ich das gestalten werde.

Als nächstes hab ich dann mal zugesehen, dass Events verarbeitet werden. Dazu hab ich eine Klasse namens CCResponder erstellt. Von dieser Klasse erben nun alle Event fähigen Klassen. Dazu gehören CCWindow und alle Ableger der CCView Klasse (bisher CCImageView und CCSplitView). Diese müssen dann erweitert werden um auf die Event-Methoden zugreifen zu können. Ein paar Getter-Methoden im eigentlichen Event sorgen dafür, dass man die Daten erhält die man benötigt. Man schaue ins Sample um zu sehen was ich meine...

BlitzMax: [AUSKLAPPEN]
SuperStrict

Import cocoa.cocoa


'create global CCSampleController instance
Global controller:CCSampleController = New CCSampleController

'create global CCApplication instance
Global app:CCApplication = (New CCApplication).init()

'bind controller as delegate to the application
app.setDelegate(controller)

'start the applications main loop
app.run()


'Controller class
Type CCSampleController Extends CCObject

Field window:CCWindow

'action method
Method action(sender:CCObject)
If CCButton(sender) Notify("You've clicked "+CCButton(sender).title())
End Method


'use this method to initialize gadgets
Method applicationDidFinishLaunching(notification:CCNotification)

'create window
Local frame:CCRect = CCMakeRect(100.0, 100.0, 640.0, 480.0)
window = CCWindow.documentWindow(frame)
window.setDelegate(Self)
window.setTitle(AppTitle)
window.center()

frame = window.contentView().frame()
Local view:CCSubclassedView = (New CCSubclassedView).initWithFrame(frame)
window.contentView().addSubView(view)
window.makeFirstResponder(view)

window.show()

End Method

End Type


Type CCSubclassedView Extends CCView

Method initWithFrame:CCSubclassedView(frame:CCRect)
Super.initWithFrame(frame)
setLayout(CCAlignLeft | CCAlignTop | CCAlignWidthSizable | CCAlignHeightSizable)
Return Self
End Method

Method leftMouseDown(event:CCEvent)
CCLog(event)
End Method

Method rightMouseDown(event:CCEvent)
CCLog(event)
End Method

Method otherMouseDown(event:CCEvent)
CCLog(event)
End Method

Method scrollWheel(event:CCEvent)
CCLog(event)
End Method

End Type


Mehr ist auch nicht passiert. Werde mich wohl als nächstes mit der ScrollView, der TableView und der OutlineView auseinander setzen. Damit hätte ich den größten Batzen erschlagen und kann mich mit den einfacheren Sachen beschäftigen.

Grüße!

04 - SplitView und ImageView

Samstag, 3. Dezember 2011 von d-bug
Hallo zusammen,

seit dem letzten Eintrag verging ein wenig Zeit, bei der ich hauptsächlich mit RL-Problemen zu kämpfen hatte. Zum einen durfte ich am eigenen Leib erfahren, dass die Grippeimpfung nicht bei jedem Virus fruchtet und zum anderen ist ja wieder Vorweihnachtszeit. Wer von euch arbeitet weiß sicherlich, dass es zu dieser Jahreszeit meist rund geht und alles noch vor dem Jahreswechsel schnell erledigt werden muss. Eigentlich alles egal! Die Kernaussage ist auch nur, dass ich derzeit nur an den Wochenenden was programmieren kann, solange da keine Familienfeste stattfinden.

Kommen wir aber nun zu den letzten Gadgets:

Die SplitView als solches sollte eigentlich jedem bekannt sein, darum erspare mir die großen Erklärungen. Bei Cocoa ist die SplitView eine kleine Klasse, die von Haus aus so ziemlich nichts kann, außer die Divider zwischen ihre Subviews zu zeichnen. Man muss ihr mit Subclassing und Controllern zu Leibe rücken um sie halbwegs vernünftig handhaben zu können.

Da ich in CocoaExt auf einen vorgefertigten Controller setzte und dann schnell feststellen musste, dass dies zu naiv gedacht war, weil man ja auch mal mehr als 2 Subviews haben möchte oder sonst irgend einen custom Humbug treiben möchte. Diesmal hab ich eine Subclass geschrieben die nur die Farbe der Divider setzen kann. Dazu noch einen mini Controller der die Notifications und Delegates an BlitzMax weiter leitet. So ist es zwar etwas aufwendiger eine SplitView zu schreiben (siehe Beispiel-Code), aber man kann selbst entscheiden wie sie sich verhalten soll.

So quasi als Nebenprodukt hab ich dann noch die ImageView geschrieben, die nichts anderes macht als ein Bild anzuzeigen. Eigentlich brauchte ich sie um mal eben den zusätzlichen Griff zum Divider der SplitView darstellen zu können. Nur Bilder malen wäre aber auch langweilig! Man kann natürlich auch noch ein paar Sachen anpassen: z.B. wie der Rahmen um das Bild auszusehen hat, oder wie das Bild skaliert werden soll... (okay, letzteres ist zum jetzigen Zeitpunkt noch nicht implementiert. Kommt aber noch!)

Nun zum Code (Achtung lang):
BlitzMax: [AUSKLAPPEN]
SuperStrict

Framework cocoa.cocoa


'create global CCSampleController instance
Global controller:CCSampleController = New CCSampleController

'create global CCApplication instance
Global app:CCApplication = (New CCApplication).init()

'bind controller as delegate to the application
app.setDelegate(controller)

'start the applications main loop
app.run()


'Controller class
Type CCSampleController Extends CCObject

Field window:CCWindow
Field handleView:CCImageView
Field verticalSplitView:CCSplitView
Field horizontalSplitView:CCSplitView

'use this method to initialize gadgets
Method applicationDidFinishLaunching(notification:CCNotification)

'create window
Local frame:CCRect = CCMakeRect(100.0, 100.0, 1024.0, 480.0)
window = CCWindow.documentWindow(frame)
window.setDelegate(Self)
window.setTitle(AppTitle)
window.center()

'create a vertical splitview with three sub views and a thin divider
verticalSplitView = CCSplitView.verticalView(window.contentView().frame())
verticalSplitView.setLayout(CCAlignLeft | CCAlignTop | CCAlignWidthSizable | CCAlignHeightSizable)
verticalSplitView.setDelegate(Self)
verticalSplitView.setDividerStyle(CCSplitViewDividerStyleThin)
verticalSplitView.setDividerColor(CCMakeColor(0.0,0.0,0.0,0.3))

Local view:CCView

'create the left view
frame = verticalSplitView.frame()
view = (New CCView).initWithFrame(CCMakeRect(0.0,0.0,200.0, frame.height))
verticalSplitView.addSubview(view)

'add a handle for the first divider in the bottom right corner of the left view
'the handle is the visual representation of the delegate method splitViewAdditionalEffectiveRectOfDivider
handleView = CCImageView.imageView(CCMakeRect(188,frame.height-16,12,16), CCImage.imageNamed("CCSplitViewHandle.png"), CCAlignTop | CCAlignLeft)
handleView.setLayout(CCAlignRight | CCAlignBottom)
view.addSubView(handleView)

'create the middle view as horizontal splitview
horizontalSplitView = CCSplitView.horizontalView(CCMakeRect(0.0,0.0,frame.width - (2* verticalSplitView.dividerThickness()) - 400.0, frame.height))
horizontalSplitView.setDelegate(Self)
horizontalSplitView.setDividerStyle(CCSplitViewDividerStylePaneSplitter)
verticalSplitView.addSubview(horizontalSplitView)

'create the right view
view = (New CCView).initWithFrame(CCMakeRect(0.0,0.0,200.0, frame.height))
verticalSplitView.addSubview(view)
window.contentView().addSubview(verticalSplitView)

'add the top view to the horizontal splitview
frame = horizontalSplitView.frame()
view = (New CCView).initWithFrame(CCMakeRect(0.0,0.0,frame.width, 240))
view.setBackgroundColor(CCColorWhite)
horizontalSplitView.addSubview(view)

'add the bottom view to the horizontal splitview
view = (New CCView).initWithFrame(CCMakeRect(0.0,0.0,frame.width, 240 - horizontalSplitView.dividerThickness()))
view.setBackgroundColor(CCColorWhite)
horizontalSplitView.addSubview(view)

window.show()
End Method


'limit the minimum dragging range
Method splitViewConstrainMinCoordinate:Float(splitView:CCSplitView, proposedMin:Float, dividerIndex:Int)
Select splitView

'limit the outer subviews of the vertical splitview
Case verticalSplitView
Select dividerIndex
'the minimum position of the left divider
Case 0 Return 100.0
'the minimum position of the right divider
Case 1 Return splitView.frame().width - 300.0
End Select
End Select
Return proposedMin
End Method

'limit the maximum dragging range
Method splitViewConstrainMaxCoordinate:Float(splitView:CCSplitView, proposedMax:Float, dividerIndex:Int)
Select splitView

'limit the outer subviews of the vertical splitview
Case verticalSplitView
Select dividerIndex
'the maximum position of the left divider
Case 0 Return 300.0
'the maximum position of the right divider
Case 1 Return splitView.frame().width - 100.0
End Select

End Select
Return proposedMax
End Method

'This method demonstrades the resizing behaviors for splitviews while the parent window is resized.
'Since CCSplitView is a basic rip of the NSSplitView class you need to implement the behaviors by yourself
Method splitViewResizeSubviewsWithOldSize(splitView:CCSplitView, oldWidth:Float, oldHeight:Float)
If Not splitView Return
Local newFrame:CCRect = splitView.frame()
Local subviews:TList = splitView.subviews()

Select splitView

'Resizing behavior for a vertical splitview with three subviews.
'The left and right views will keep their width while the middle view is flexible.
Case verticalSplitView
Local leftView:CCView = CCView(subviews.valueAtIndex(0))
Local leftFrame:CCRect = leftView.frame()
Local midView:CCView = CCView(subviews.valueAtIndex(1))
Local midFrame:CCRect = midView.frame()
Local rightView:CCView = CCView(subviews.valueAtIndex(2))
Local rightFrame:CCRect = rightView.frame()

'adjust left frame height
leftFrame.height = newFrame.height

'adjust middle frame position and size
midFrame.x = leftFrame.width + splitView.dividerThickness()
midFrame.width = newFrame.width - leftFrame.width - rightFrame.width - (2 * splitView.dividerThickness())
midFrame.height = newFrame.height

'adjust right frame position and height
rightFrame.x = newFrame.width - rightFrame.width
rightFrame.height = newFrame.height

'set the calculated frames back to their views
leftView.setFrame(leftFrame)
midView.setFrame(midFrame)
rightView.setFrame(rightFrame)


Default
splitView.adjustSubviews()
End Select
End Method

'allow the left subview of the vertical splitview to be collapsed by double clicking
Method splitViewShouldCollapseSubviewOnDoubleClick:Int(splitView:CCSplitView, subView:CCView, dividerIndex:Int)
Select splitView

'limit the outer subviews of the vertical splitview
Case verticalSplitView
Select dividerIndex
'the maximum position of the left divider
Case 0 Return YES
'the maximum position of the right divider
Case 1 Return NO
End Select

End Select
End Method

'add the additional dragging rect to the first divider of the vertical splitview
Method splitViewAdditionalEffectiveRectOfDivider:CCRect(splitView:CCSplitView, dividerIndex:Int)
Select splitView
Case verticalSplitView
Select dividerIndex
Case 0
If handleView Return handleView.frame()
End Select
End Select
Return CCNullRect
End Method




'terminate application when last window is closed
Method applicationShouldTerminateAfterLastWindowClosed:Int()
Return YES
End Method

End Type


...und noch ein Bild dazu:
user posted image


Außerdem hab ich den original bmk überarbeitet. Er kann nun alle Files aus dem Ordner Contents in das Bundle kopieren. Der Ordner sollte sich im Hauptverzeichnis des Projekts befinden. Eben auch da wo sich das kompilierte Bundle später befinden wird. Der Ordner Contents sollte der Struktur des Bundles folgen. Sprich darin sollte ein Ordner Resources enthalten sein in dem sich alle zusätzlichen Bilder, Localizations und auch das Icon befinden. Außerdem darf noch Frameworks als Unterordner existieren. Praktisch für zukünftige Module... Dazu darf es auch noch den Ordner Contents/MacOS geben für die dylibs wie das bass Modul von brucey oder dergleichen geben.

Außerdem hab ich ihm beigebracht, dass das Icon der App jetzt AppIcon.icns zu heißen hat. Somit kann man sein eigenes Icon mit dem Namen AppIcon.icns in den Ordner Contents/Resources legen, dass dann das original BlitzMax Icon überschreibt.

Jetzt muss ich ihm nur noch beibringen, dass es auch eine info.plist geben darf, die die original info.plist von BlitzMax-Bundles überschreibt.



Als nächstes werde ich also erst mal die ImageView fertig machen, den bmk weiter pimpen und dann ein paar kleine Umstrukturierungen vornehmen. Im Moment ist es so, dass man die komplette GUI mit importieren muss, wenn man eigentlich nur CCImage oder CCRect oder dergleichen in einem Modul benötigen würde. ...gefällt mir so nicht und muss geändert werden! :>

Bis dahin...

03 - Unter der Haube

Sonntag, 20. November 2011 von d-bug
Hallo zusammen,

wirklich wichtiges habe ich an diesem Wochenende nicht vollbracht. Ein kleiner Fix hier, ein kleines Feature da...

Unter anderem habe ich Aufbaufehler in den AppStore-Style Fenstern behoben und selbige beschleunigt. Leider ist dies ja kein natives Cocoa Fenster, so dass ich NSWindow subclassen musste und den Farbverlauf in der Titelzeile selbst zeichnen muss. Dazu gehört es auch mittels NSBezierPath die Ecken abzurunden. Das bin ich vorher etwas kompliziert angegangen, denn ich hab versucht nur die oberen beiden Ecken zu runden. Jetzt hab ich einfach den BezierPath um den Radius, über den sichtbaren Bereich hinaus, vergrößert und nutze die eingebaute Abrund-Methode! Dabei kam es dann aber zu Aufbaufehlern beim Rendern die alle noch korrigiert werden mussten. Dies nahm fast den ganzen heutigen Tag in Anspruch. Mag sein, dass die Fehler auch vorher schon vorhanden waren und ich sie nur nicht gesehen habe...

Gestern hingegen hab ich dann die CCView Klasse um Hintergrundfarbe und Farbverläufe erweitert. Dazu gibt es nun die Klassen CCGradient und CCColor. Beide dienen eigentlich nur der Optik und haben sonst nicht viel zu tun.

Wo wir eben bei Fenstern waren:
Ich hab den Fenstern noch das Cascading beigebracht. Mittels der Methode windowA.cascadeWithWindow(windowB) wird windowA jetzt versetzt, unterhalb der Titelzeile, zu windowB angeordnet. (siehe Bild)

user posted image

Der CCApplication Klasse hab ich auch noch bei gebracht, dass sie optional auch terminiert wird wenn das letzte Fenster geschlossen wurde. (Kinderkrams)

So, dass war es auch schon wieder... Schönes Wochenende noch!

02 - Buttons

Samstag, 19. November 2011 von d-bug
Hallo zusammen,

eigentlich sind die Buttons schon seit Dienstag fertig, aber da ich anderweitig viel zu tun hatte, poste ich den Worklog eben jetzt erst. Ich bitte dies zu verzeihen!

Viel gibt es dazu wirklich nicht zu sagen und ein Sample-Code spricht ja eigentlich auch für sich (Achtung langer Code):
BlitzMax: [AUSKLAPPEN]
SuperStrict

Framework cocoa.cocoa


'create global CCSampleController instance
Global controller:CCSampleController = New CCSampleController

'create global CCApplication instance
Global app:CCApplication = (New CCApplication).init()

'bind controller as delegate to the application
app.setDelegate(controller)

'start the applications main loop
app.run()


'Controller class
Type CCSampleController Extends CCObject

Field window:CCWindow

'action method
Method action(sender:CCObject)
If CCButton(sender) Notify("You've clicked "+CCButton(sender).title())
End Method


'use this method to initialize gadgets
Method applicationDidFinishLaunching(notification:CCNotification)

'create window
Local frame:CCRect = CCMakeRect(100.0, 100.0, 640.0, 480.0)
window = CCWindow.documentWindow(frame)
window.setDelegate(Self)
window.setTitle(StripAll(AppFile))
window.center()

'get content view of the window
Local view:CCView = window.contentView()

'button types
Local button:CCButton
frame = CCMakeRect(10.0, 10.0, 150.0, 24.0)
button = CCButton.pushButton(frame, "Push Button", CCButtonStyleRounded, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.toggleButton(frame, "Toggle Button", CCButtonStyleRounded, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.toggleButton(frame, ["Toggle Alternate Off", "Toggle Alternate On"] , CCButtonStyleRounded, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.changeButton(frame, ["Change Button Off", "Change Button On"] , CCButtonStyleRounded, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.helpButton(CCMakeRect(frame.x, frame.y, frame.width, frame.height), "action", Self)
view.addSubview(button)

frame.y:+(frame.height+2.0)
button = CCButton.disclosureButton(CCMakeRect(frame.x, frame.y, frame.width, frame.height), CCNullAction, CCNullTarget)
view.addSubview(button)

frame.y:+(frame.height+2.0)
button = CCButton.switchButton(frame, "Switch Button A", CCNullAction, CCNullTarget)
view.addSubview(button)

frame.y:+(frame.height+2.0)
button = CCButton.switchButton(frame, "Switch Button B", CCNullAction, CCNullTarget)
button.check()
view.addSubview(button)

frame.y:+(frame.height+2.0)
button = CCButton.switchButton(frame, "Switch Button C", CCNullAction, CCNullTarget)
button.setAllowsMixedState(YES)
button.mixedCheck()
view.addSubview(button)


frame.y:+(frame.height+2.0) ; frame.width = 200
button = CCButton.radioButton(frame, "Ungrouped Radio Button A", CCNullAction, CCNullTarget)
view.addSubview(button)

frame.y:+(frame.height+2.0)
button = CCButton.radioButton(frame, "Ungrouped Radio Button B", CCNullAction, CCNullTarget)
button.check()
view.addSubview(button)

frame.y:+(frame.height+2.0)
button = CCButton.radioButton(frame, "Ungrouped Radio Button C", CCNullAction, CCNullTarget)
button.setAllowsMixedState(YES)
button.mixedCheck()
view.addSubview(button)





'grouping radio items
'each item added to a group will be unchecked before the sender is checked

Local group:CCGroup = (New CCGroup).init()

frame.y:+(frame.height+2.0) ; frame.width = 200
button = CCButton.radioButton(frame, "Grouped Radio Button A", CCNullAction, CCNullTarget)
group.addItem(button)
view.addSubview(button)
button.check()

frame.y:+(frame.height+2.0)
button = CCButton.radioButton(frame, "Grouped Radio Button B", CCNullAction, CCNullTarget)
group.addItem(button)
view.addSubview(button)

frame.y:+(frame.height+2.0)
button = CCButton.radioButton(frame, "Grouped Radio Button C", CCNullAction, CCNullTarget)
group.addItem(button)
button.setAllowsMixedState(YES)
view.addSubview(button)





'image buttons
Local image:CCImage = CCImage.imageNamed("NSImageNameInfo")
Local alternateImageA:CCImage = CCImage.imageNamed("NSImageNameTrashEmpty")
Local alternateImageB:CCImage = CCImage.imageNamed("NSImageNameTrashFull")
frame.x:+(frame.width) ; frame.y = 10 ; frame.width = 150 ; frame.height = 64.0;
button = CCButton.pushButton(frame, "Image Left", CCButtonStyleRegularSquare, "action", Self)
button.setImage(image, CCAlignLeft)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Image Right", CCButtonStyleRegularSquare, "action", Self)
button.setImage(image, CCAlignRight)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.toggleButton(frame, ["Image Above Off", "Image Above On"], CCButtonStyleRegularSquare, CCNullAction, CCNullTarget)
button.setImage([alternateImageA, alternateImageB], CCAlignTop)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Image Below", CCButtonStyleRegularSquare, "action", Self)
button.setImage(image, CCAlignBottom)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Image Behind", CCButtonStyleRegularSquare, "action", Self)
button.setImage(image, CCAlignCenter)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Image Only", CCButtonStyleRegularSquare, "action", Self)
button.setImage(image, -1)
view.addSubview(button)





'button styles
frame = button.frame() ; frame.x:+(frame.width+10.0) ; frame.y = 10 ; frame.width = 180 ; frame.height = 24.0;
button = CCButton.pushButton(frame, "Style Rounded", CCButtonStyleRounded, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Style RegularSquare", CCButtonStyleRegularSquare, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Style ShadowlessSquare", CCButtonStyleShadowlessSquare, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Style TexturedSquare", CCButtonStyleTexturedSquare, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Style SmallSquare", CCButtonStyleSmallSquare, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Style TexturedRounded", CCButtonStyleTexturedRounded, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Style RoundRect", CCButtonStyleRoundRect, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Style Recessed", CCButtonStyleRecessed, "action", Self)
view.addSubview(button)

frame = button.frame() ; frame.y:+(frame.height+2.0)
button = CCButton.pushButton(frame, "Style Inline", CCButtonStyleInline, "action", Self)
view.addSubview(button)

window.show()
End Method

End Type


Es gibt also nun zwei neue Klassen. Zum einen wäre da die CCButton-Klasse, die die Buttons initiiert und verwaltet und zum anderen noch die Klasse CCGroup.

CCGroup dient im momentanen Entwicklungsstadium nur der Kontrolle über Radio-Buttons, Switch-Buttons usw.. Derzeit macht sie nichts anderes als sich in die Aktivieren-Aktion eines Buttons zu klinken alle weiteren Radio-Buttons in der Gruppe zu deaktivieren. Im weiteren Verlauf der Modul-Programmierung werde ich allerdings noch weitere Features hinzufügen. Z.B. soll die Klasse später auch zum automatischen ausrichten mehrerer Gadgets dienen. Wie sich die Gadgets innerhalb einer Gruppe verhalten - basiert auf Callbacks. Das macht es möglich das ganze recht variabel zu gestalten.

Ein Bild hab ich auch noch:
user posted image




Zu guter letzt möchte ich noch kurz klarstellen, dass ich die Art und Weise meiner Worklog-Einträge nicht für einen einzelnen ändern werde! Erstens finde ich meinen Schreibstil gar nicht so schlimm und zweitens muss man es ja nicht lesen, wenn man sich davon persönlich angegriffen fühlt...

01 - NSToolbar die (gefühlte) 100.

Sonntag, 13. November 2011 von d-bug
Jap, ich machte das schon ein paar mal, bevor ich mich an die Öffentlichkeit damit wagte...

Gestern verbrachte ich den ganzen Tag damit die NSToolbar-Klasse und die NSToolbarItem-Klasse in ein gescheites Format zu pressen. Gescheit in dem Sinne, dass man die Items genau so nutze können soll wie die Items eines Menüs oder ähnlichen Gadgets. Nativ ist das bei Cocoa nicht so. Da haben die Toolbar-Items eine Sonderwurst im Sinne von String-Identifiern statt wie alle anderen Gadgets einen Pointer. Gut, sie haben trotzdem einen Pointer, aber der ist alles andere als sicher!

Das merkt man nämlich an der Tatsache, dass sie öfters mal ihren Pointer wechseln bzw. einfach neu erstellt werden. Gerade, wenn sie vom Customization-Sheet (siehe Bild) in die Toolbar gezogen werden. Eigentlich werden die Items nämlich auf BlitzMax-Seite vorher schon generiert. Allerdings juckt das Cocoa so rein gar nicht. Wenn es meint es müsse das Item neu erstellen, dann erstellt es eben das Item neu! Stures Mistvieh! Als ich das heute morgen bemerkte, musste ich erst mal ein paar Routinen debuggen. Jetzt verrichtet es allerdings zuverlässig seinen Dienst.

Auch recht fein: Geht man unter 10.7 in den Vollbild-Modus eines Fensters und versucht dann, mittels Cocoa-Bordmitteln, die Customization-Palette zu öffnen, schmierst ab. Netter Trick, Apple! Total professionell und so...
Das hab ich dann heute morgen auch noch schnell unterbunden. Sperren und entsperren der zugehörigen Items muss man allerdings selbst übernehmen.

Und noch einer: Hat irgend jemand etwas darüber gelesen, dass es seit 10.7 keinen Toolbar-Separator mehr gibt? Man kann ihn zwar noch erstellen, bekommt aber nur einen Null-Pointer zurück. Wahrscheinlich noch ein Bug...

Zum guten Schluss das Beispiel in Wort und Bild:
BlitzMax: [AUSKLAPPEN]
SuperStrict

Framework cocoa.cocoa


'create global CCSampleController instance
Global controller:CCSampleController = New CCSampleController

'create global CCApplication instance
Global app:CCApplication = (New CCApplication).init()

'bind controller as delegate to the application
app.setDelegate(controller)

'start the applications main loop
app.run()


'Controller class
Type CCSampleController Extends CCObject

Field window:CCWindow

Field viewMenu:CCMenu
Field viewMenu_toggleToolbarItem:CCMenuItem
Field viewMenu_customizationPaletteItem:CCMenuItem

Field toolbar:CCToolbar
Field toolbar_customizationPaletteItem:CCToolbarItem

'action method
Method action(sender:CCObject)
If CCToolbarItem(sender) Notify("You've clicked "+CCToolbarItem(sender).title())
End Method


'use this method to initialize gadgets
Method applicationDidFinishLaunching(notification:CCNotification)

'create window
Local frame:CCRect = CCMakeRect(100.0, 100.0, 640.0, 480.0)
window = CCWindow.documentWindow(frame)
window.setDelegate(Self)
window.setTitle("CCToolbar Sample")
window.center()


'create view menu
viewMenu = app.addMenuWithTitle("View")
viewMenu.setDelegate(Self)

'create toolbar show/hide menu item
viewMenu_toggleToolbarItem = viewMenu.addItemWithTitle("Hide Toolbar", "toggleToolbarShown", "", window)

'create toolbar customization palette menu item
viewMenu_customizationPaletteItem = viewMenu.addItemWithTitle("Customize Toolbar…", "runToolbarCustomizationPalette", "", window)



'create a toolbar and bind it's delegate to the controller
toolbar = CCToolbar.toolbar(CCToolbarMaskIcon | CCToolbarMaskSizeSmall)
toolbar.setDelegate(Self)


'add an item to the toolbar with a tooltip
Local item:CCToolbarItem
item = toolbar.addItemWithTitle("Elefant", CCImage.imageNamed("NSImageNameFolderBurnable"), "action", Self)
item.setTooltip("Elefanten sind große graue Dinger mit Rüssel")

'add an item to the toolbar and disable it
item = toolbar.addItemWithTitle("Löwe", CCImage.imageNamed("NSImageNameTrashEmpty"), "action", Self)
item.disable()

'add a flexible Space item to the toolbar
item = toolbar.addItemSpace()

'add an selectable item to the toolbar which is checked
item = toolbar.addItemWithTitle("Hund", CCImage.imageNamed("NSImageNameUser"), "action", Self)
item.setSelectable(YES)
item.check()

'add an selectable item to the toolbar
item = toolbar.addItemWithTitle("Katze", CCImage.imageNamed("NSImageNameUserGroup"), "action", Self)
item.setSelectable(YES)

'add an selectable item to the toolbar
item = toolbar.addItemWithTitle("Maus", CCImage.imageNamed("NSImageNameEveryone"), "action", Self)
item.setSelectable(YES)

'add a flexible Space item to the toolbar
item = toolbar.addItemFlexibleSpace()

'add an item to the toolbar which opens the customization palette
toolbar_customizationPaletteItem = toolbar.addItemWithTitle("Pferd", CCImage.imageNamed("NSImageNamePreferencesGeneral"), "runToolbarCustomizationPalette", window)


'add some items to the customization palette only
item = toolbar.addItemWithTitle("Pottwal", CCImage.imageNamed("NSImageNameColorPanel"), "action", Self)
item.setDefault(NO)
item = toolbar.addItemWithTitle("Buckelwal", CCImage.imageNamed("NSImageNameInfo"), "action", Self)
item.setDefault(NO)


window.setToolbar(toolbar)
window.show()
End Method


Method toolbarWillAddItem(notification:CCNotification)
Local item:CCToolbarItem = CCToolbarItem(notification.userInfo.valueForKey("item"))
If item CCLog(item.identifier() +" --> "+ item.title())
End Method


'change view menu item states and titles to accordings to the toolbar states
Method menuWillOpen(notification:CCNotification)

Select CCMenu(notification.obj)
Case viewMenu

'toggle title of the toolbar according to the toolbars visibility state
viewMenu_toggleToolbarItem.setTitle([CCLocalizedString("Show Toolbar"),CCLocalizedString("Hide Toolbar")][toolbar.isVisible()])

'set Enable/Disable state according to the visibility of the toolbars customization palette
If Not window.isFullscreen() viewMenu_customizationPaletteItem.setEnabled(Not toolbar.customizationPaletteIsRunning())

End Select
End Method



'do not use customization-palette in fullscreen mode. this leads to a crash

'when entering fullscreen mode disable customization palette items
Method windowWillEnterFullScreen(notification:CCNotification)
viewMenu_customizationPaletteItem.setEnabled(NO)
toolbar_customizationPaletteItem.setEnabled(NO)
End Method

'after leaving fullscreen mode enable customization palette items
Method windowDidExitFullScreen(notification:CCNotification)
viewMenu_customizationPaletteItem.setEnabled(YES)
toolbar_customizationPaletteItem.setEnabled(YES)
End Method

End Type


user posted image

00 - Das Rad neu erfinden!

Freitag, 11. November 2011 von d-bug
Hallo zusammen,

lange war es still um mich! Das lag zum einen an einem Übermaß an beruflichem Stress und zum anderen an einem Untermaß an Motivation. Neuerdings, hab ich allerdings letzteres zum Teil wieder erlangt und hab mich frohen Mutes an die Erfindung des Rades begeben.

Da ich ja schon in der Vergangenheit über MaxGUI herzog und sich an meiner Einstellung dazu nichts geändert hat, habe ich beschlossen eine kleine Modul Serie zu schreiben, die es mir erlauben soll unter Mac OS X "vernünftige" Applikationen zu schreiben. Vernünftig in dem Sinne, dass die Applikationen auch nach OS X aussehen und sich so anfühlen sollen.

Mein Augenmerk möchte ich dabei besonders auf eine gute Strukturierung, Dokumentation und dergleichen legen. Auch wenn ich diese Module weitestgehend für mich selbst schreibe, wird wohl früher oder später ein Release unters Volk geworfen. Vielleicht auch in Verbindung mit einem MaxGUI-Treiber... Allerdings steht der eher in den Sternen.

Ob ich das ganze durchziehe hängt von meiner Motivation ab.

Begonnen habe ich erst vor ein paar Tagen mit dem ganzen, kann aber immerhin schon Menüs und Fenster erstellen und verwalten. Zur Kommunikation stehen bereits Notifications, Target-Action Mechanismus und Delegates zur Verfügung. Das ganze gestaltet sich um einiges flexibler als die Event basierende Grütze die man sonst so gewohnt ist.

Lange Rede, kurzes Beispiel...

BlitzMax: [AUSKLAPPEN]

SuperStrict

Framework cocoa.cocoa


'create global CCSampleController instance
Global controller:CCSampleController = New CCSampleController

'create a global instance if CCApplication
Global app:CCApplication = (New CCApplication).init()

'bind controller as delegate for the application
app.setDelegate(controller)

'start the applications main loop
app.run()


'Controller class
Type CCSampleController Extends CCObject

'use this method to initialize gadgets
Method applicationDidFinishLaunching(notification:CCNotification)

'create the windows menu
CCWindowMenu.menu()

'create window
Local frame:CCRect = CCMakeRect(100.0, 100.0, 640.0, 480.0)
Local window:CCWindow = CCWindow.documentwindow(frame)

'bind controller as delegate for the window
window.setDelegate(Self)

'set the window title
window.setTitle("Hundefutter")

'center window on screen
window.center()

'set bottom bar
window.setBottombarHeight(24.0)

'set Safari, Pages, Numbers zooming behavior
window.setBehavior(CCWindowBehaviorZoomDocumental)

'show window
window.show()

End Method

'post notification when window is closed
Method windowWillClose(notification:CCNotification)
CCLog(notification)
End Method

End Type


... so ähnlich sieht ein kleiner Controller aus, der ein Fenster namens "Hundefutter" nach dem initialisieren der Applikation erstellt. Das Fenster textet die Konsole zu, wenn es geschlossen wird.

Es gibt natürlich noch zig andere Notifications für Fenster und Applikation, aber da dieses ganze System auf brl.reflections beruht, müssen die nicht alle im Controller auftauchen, sondern können bei bedarf hinzu gefügt werden. Im großen und ganzen ziemlich simpler Shit.

Ach ja, das 10.7 Fullscreen-Zeugs hab ich natürlich auch schon drin. Dazu musste noch ein Minimodul her, dass mir die Version des derzeitigen Betriebssystems ausgibt. Mit Compiler-Direktiven kam man da nicht sonderlich weit.

Das passende Bild zum Beispiel:
user posted image

AppStore-mäßige Fensterchen sind auch möglich (extra hohe Titlebar):
user posted image

Auch die sogenannten Inspektoren sind implementiert:
user posted image

Quicklook Gedöns:
user posted image

Ein Menü:
user posted image

Gehe zu Seite Zurück  1, 2, 3, 4