a
@@ -12,7 +12,10 @@ import Cocoa
|
|||||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
|
||||||
@IBOutlet weak var window: NSWindow!
|
@IBOutlet weak var window: NSWindow!
|
||||||
@IBOutlet weak var windowToolbox: NSWindow!
|
@IBOutlet weak var projectWindow: NSWindow!
|
||||||
|
|
||||||
|
|
||||||
|
@IBOutlet weak var closeButton: NSButton!
|
||||||
|
|
||||||
func applicationDidFinishLaunching(aNotification: NSNotification) {
|
func applicationDidFinishLaunching(aNotification: NSNotification) {
|
||||||
// Insert code here to initialize your application
|
// Insert code here to initialize your application
|
||||||
@@ -23,4 +26,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
return NSApplicationTerminateReply.TerminateNow
|
return NSApplicationTerminateReply.TerminateNow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction func closeButtonClicked(sender: AnyObject ) {
|
||||||
|
projectWindow.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Cube4Fun/Arrows.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
@@ -330,69 +330,69 @@
|
|||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Format" id="375">
|
<menuItem title="Format" hidden="YES" enabled="NO" id="375">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Format" id="376">
|
<menu key="submenu" title="Format" id="376">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Font" id="377">
|
<menuItem title="Font" enabled="NO" id="377">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
|
<menuItem title="Show Fonts" enabled="NO" keyEquivalent="t" id="389">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
|
<menuItem title="Bold" tag="2" enabled="NO" keyEquivalent="b" id="390">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="addFontTrait:" target="420" id="421"/>
|
<action selector="addFontTrait:" target="420" id="421"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
|
<menuItem title="Italic" tag="1" enabled="NO" keyEquivalent="i" id="391">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="addFontTrait:" target="420" id="422"/>
|
<action selector="addFontTrait:" target="420" id="422"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Underline" keyEquivalent="u" id="392">
|
<menuItem title="Underline" enabled="NO" keyEquivalent="u" id="392">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="underline:" target="-1" id="432"/>
|
<action selector="underline:" target="-1" id="432"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="393"/>
|
<menuItem isSeparatorItem="YES" id="393"/>
|
||||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
|
<menuItem title="Bigger" tag="3" enabled="NO" keyEquivalent="+" id="394">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="modifyFont:" target="420" id="425"/>
|
<action selector="modifyFont:" target="420" id="425"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
|
<menuItem title="Smaller" tag="4" enabled="NO" keyEquivalent="-" id="395">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="modifyFont:" target="420" id="423"/>
|
<action selector="modifyFont:" target="420" id="423"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="396"/>
|
<menuItem isSeparatorItem="YES" id="396"/>
|
||||||
<menuItem title="Kern" id="397">
|
<menuItem title="Kern" enabled="NO" id="397">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Kern" id="415">
|
<menu key="submenu" title="Kern" id="415">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Use Default" id="416">
|
<menuItem title="Use Default" enabled="NO" id="416">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="useStandardKerning:" target="-1" id="438"/>
|
<action selector="useStandardKerning:" target="-1" id="438"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Use None" id="417">
|
<menuItem title="Use None" enabled="NO" id="417">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="turnOffKerning:" target="-1" id="441"/>
|
<action selector="turnOffKerning:" target="-1" id="441"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Tighten" id="418">
|
<menuItem title="Tighten" enabled="NO" id="418">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="tightenKerning:" target="-1" id="431"/>
|
<action selector="tightenKerning:" target="-1" id="431"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Loosen" id="419">
|
<menuItem title="Loosen" enabled="NO" id="419">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="loosenKerning:" target="-1" id="435"/>
|
<action selector="loosenKerning:" target="-1" id="435"/>
|
||||||
@@ -401,23 +401,23 @@
|
|||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Ligatures" id="398">
|
<menuItem title="Ligatures" enabled="NO" id="398">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Ligatures" id="411">
|
<menu key="submenu" title="Ligatures" id="411">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Use Default" id="412">
|
<menuItem title="Use Default" enabled="NO" id="412">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Use None" id="413">
|
<menuItem title="Use None" enabled="NO" id="413">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Use All" id="414">
|
<menuItem title="Use All" enabled="NO" id="414">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="useAllLigatures:" target="-1" id="434"/>
|
<action selector="useAllLigatures:" target="-1" id="434"/>
|
||||||
@@ -426,35 +426,35 @@
|
|||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Baseline" id="399">
|
<menuItem title="Baseline" enabled="NO" id="399">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Baseline" id="405">
|
<menu key="submenu" title="Baseline" id="405">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Use Default" id="406">
|
<menuItem title="Use Default" enabled="NO" id="406">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="unscript:" target="-1" id="437"/>
|
<action selector="unscript:" target="-1" id="437"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Superscript" id="407">
|
<menuItem title="Superscript" enabled="NO" id="407">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="superscript:" target="-1" id="430"/>
|
<action selector="superscript:" target="-1" id="430"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Subscript" id="408">
|
<menuItem title="Subscript" enabled="NO" id="408">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="subscript:" target="-1" id="429"/>
|
<action selector="subscript:" target="-1" id="429"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Raise" id="409">
|
<menuItem title="Raise" enabled="NO" id="409">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="raiseBaseline:" target="-1" id="426"/>
|
<action selector="raiseBaseline:" target="-1" id="426"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Lower" id="410">
|
<menuItem title="Lower" enabled="NO" id="410">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="lowerBaseline:" target="-1" id="427"/>
|
<action selector="lowerBaseline:" target="-1" id="427"/>
|
||||||
@@ -464,19 +464,19 @@
|
|||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="400"/>
|
<menuItem isSeparatorItem="YES" id="400"/>
|
||||||
<menuItem title="Show Colors" keyEquivalent="C" id="401">
|
<menuItem title="Show Colors" enabled="NO" keyEquivalent="C" id="401">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="402"/>
|
<menuItem isSeparatorItem="YES" id="402"/>
|
||||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
<menuItem title="Copy Style" enabled="NO" keyEquivalent="c" id="403">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="copyFont:" target="-1" id="428"/>
|
<action selector="copyFont:" target="-1" id="428"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
<menuItem title="Paste Style" enabled="NO" keyEquivalent="v" id="404">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="pasteFont:" target="-1" id="436"/>
|
<action selector="pasteFont:" target="-1" id="436"/>
|
||||||
@@ -485,54 +485,54 @@
|
|||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Text" id="496">
|
<menuItem title="Text" enabled="NO" id="496">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Text" id="497">
|
<menu key="submenu" title="Text" id="497">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Align Left" keyEquivalent="{" id="498">
|
<menuItem title="Align Left" enabled="NO" keyEquivalent="{" id="498">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="alignLeft:" target="-1" id="524"/>
|
<action selector="alignLeft:" target="-1" id="524"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Center" keyEquivalent="|" id="499">
|
<menuItem title="Center" enabled="NO" keyEquivalent="|" id="499">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="alignCenter:" target="-1" id="518"/>
|
<action selector="alignCenter:" target="-1" id="518"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Justify" id="500">
|
<menuItem title="Justify" enabled="NO" id="500">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="alignJustified:" target="-1" id="523"/>
|
<action selector="alignJustified:" target="-1" id="523"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Align Right" keyEquivalent="}" id="501">
|
<menuItem title="Align Right" enabled="NO" keyEquivalent="}" id="501">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="alignRight:" target="-1" id="521"/>
|
<action selector="alignRight:" target="-1" id="521"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="502"/>
|
<menuItem isSeparatorItem="YES" id="502"/>
|
||||||
<menuItem title="Writing Direction" id="503">
|
<menuItem title="Writing Direction" enabled="NO" id="503">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Writing Direction" id="508">
|
<menu key="submenu" title="Writing Direction" id="508">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Paragraph" enabled="NO" id="509">
|
<menuItem title="Paragraph" enabled="NO" id="509">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem id="510">
|
<menuItem enabled="NO" id="510">
|
||||||
<string key="title"> Default</string>
|
<string key="title"> Default</string>
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem id="511">
|
<menuItem enabled="NO" id="511">
|
||||||
<string key="title"> Left to Right</string>
|
<string key="title"> Left to Right</string>
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem id="512">
|
<menuItem enabled="NO" id="512">
|
||||||
<string key="title"> Right to Left</string>
|
<string key="title"> Right to Left</string>
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -543,21 +543,21 @@
|
|||||||
<menuItem title="Selection" enabled="NO" id="514">
|
<menuItem title="Selection" enabled="NO" id="514">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem id="515">
|
<menuItem enabled="NO" id="515">
|
||||||
<string key="title"> Default</string>
|
<string key="title"> Default</string>
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem id="516">
|
<menuItem enabled="NO" id="516">
|
||||||
<string key="title"> Left to Right</string>
|
<string key="title"> Left to Right</string>
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem id="517">
|
<menuItem enabled="NO" id="517">
|
||||||
<string key="title"> Right to Left</string>
|
<string key="title"> Right to Left</string>
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -568,19 +568,19 @@
|
|||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="504"/>
|
<menuItem isSeparatorItem="YES" id="504"/>
|
||||||
<menuItem title="Show Ruler" id="505">
|
<menuItem title="Show Ruler" enabled="NO" id="505">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="toggleRuler:" target="-1" id="520"/>
|
<action selector="toggleRuler:" target="-1" id="520"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
<menuItem title="Copy Ruler" enabled="NO" keyEquivalent="c" id="506">
|
||||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="copyRuler:" target="-1" id="522"/>
|
<action selector="copyRuler:" target="-1" id="522"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
<menuItem title="Paste Ruler" enabled="NO" keyEquivalent="v" id="507">
|
||||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="pasteRuler:" target="-1" id="519"/>
|
<action selector="pasteRuler:" target="-1" id="519"/>
|
||||||
@@ -592,16 +592,16 @@
|
|||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="View" id="295">
|
<menuItem title="View" hidden="YES" enabled="NO" id="295">
|
||||||
<menu key="submenu" title="View" id="296">
|
<menu key="submenu" title="View" id="296">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
<menuItem title="Show Toolbar" enabled="NO" keyEquivalent="t" id="297">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Customize Toolbar…" id="298">
|
<menuItem title="Customize Toolbar…" enabled="NO" id="298">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||||
</connections>
|
</connections>
|
||||||
@@ -648,7 +648,7 @@
|
|||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
<window title="3D Cube" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
<window title="3D Cube" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="335" y="390" width="764" height="530"/>
|
<rect key="contentRect" x="335" y="390" width="764" height="530"/>
|
||||||
@@ -671,8 +671,34 @@
|
|||||||
</view>
|
</view>
|
||||||
<point key="canvasLocation" x="447" y="477"/>
|
<point key="canvasLocation" x="447" y="477"/>
|
||||||
</window>
|
</window>
|
||||||
|
<window title="Projects" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="P9J-nG-QID">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
|
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||||
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
|
<rect key="contentRect" x="335" y="390" width="614" height="388"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
|
||||||
|
<view key="contentView" id="foi-86-Bqi">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="614" height="388"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PYX-1J-bHb">
|
||||||
|
<rect key="frame" x="266" y="177" width="82" height="32"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="VZs-gj-ZTX">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="closeButtonClicked:" target="494" id="c6Q-Hy-8Ju"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
</view>
|
||||||
|
<point key="canvasLocation" x="522" y="548"/>
|
||||||
|
</window>
|
||||||
<customObject id="494" customClass="AppDelegate" customModule="Cube4Fun" customModuleProvider="target">
|
<customObject id="494" customClass="AppDelegate" customModule="Cube4Fun" customModuleProvider="target">
|
||||||
<connections>
|
<connections>
|
||||||
|
<outlet property="closeButton" destination="PYX-1J-bHb" id="faa-7N-syB"/>
|
||||||
|
<outlet property="projectWindow" destination="P9J-nG-QID" id="5We-YJ-PIt"/>
|
||||||
<outlet property="window" destination="371" id="532"/>
|
<outlet property="window" destination="371" id="532"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
|
|||||||
@@ -184,19 +184,20 @@ void CubeNetwork::updateFrame() {
|
|||||||
void CubeNetwork::updateFrame(const unsigned char * frameSequence, unsigned int frameCount) {
|
void CubeNetwork::updateFrame(const unsigned char * frameSequence, unsigned int frameCount) {
|
||||||
// check for empty pointer
|
// check for empty pointer
|
||||||
if ( frameSequence != NULL ) {
|
if ( frameSequence != NULL ) {
|
||||||
for (int frame = 0; frame<frameCount;frame++) {
|
//for (startFrame = 0; startFrame<lastByte;startFrame++) {
|
||||||
for (i=0;i<64;i++) {
|
for (i=0;i<64;i++) {
|
||||||
// Fill buffer
|
// Fill buffer
|
||||||
buffer3D[i] = frameSequence[i+(frame*64)];
|
buffer3D[i] = frameSequence[i+((frameCount-1)*64)];
|
||||||
}
|
}
|
||||||
// Send the frame
|
// Send the frame
|
||||||
ds.sendBytes(buffer3D, 64);
|
ds.sendBytes(buffer3D, 64);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeNetwork::openConnection() {
|
void CubeNetwork::openConnection() {
|
||||||
try {
|
try {
|
||||||
|
printf("Try open the connection\n");
|
||||||
ds.connect(SocketAddress("192.168.1.79", 8081));
|
ds.connect(SocketAddress("192.168.1.79", 8081));
|
||||||
fillBufferWithMsg();
|
fillBufferWithMsg();
|
||||||
ds.sendBytes(buffer3D, 9);
|
ds.sendBytes(buffer3D, 9);
|
||||||
|
|||||||
@@ -10,10 +10,252 @@ import SceneKit
|
|||||||
|
|
||||||
var lastMousePos: NSPoint = NSPoint()
|
var lastMousePos: NSPoint = NSPoint()
|
||||||
var startAngle: CGFloat = CGFloat()
|
var startAngle: CGFloat = CGFloat()
|
||||||
|
var klickedColor: Byte = Byte(1)
|
||||||
|
let relativeBarPosition: CGFloat = 500.0
|
||||||
|
|
||||||
|
|
||||||
class GameView: SCNView {
|
class GameView: SCNView {
|
||||||
|
|
||||||
//var lastMousePos: NSPoint
|
func updateButtonVisibility() {
|
||||||
|
// init
|
||||||
|
var nextFrame = false;
|
||||||
|
var lastFrame = false;
|
||||||
|
var prevFrame = false;
|
||||||
|
var firstFrame = false;
|
||||||
|
var delFrame = false;
|
||||||
|
|
||||||
|
// first Frame, only one Frame
|
||||||
|
// -> no button visible
|
||||||
|
if myFrameCount == 1 && myMaxFrameCount == 1 {
|
||||||
|
nextFrame = false;
|
||||||
|
lastFrame = false;
|
||||||
|
prevFrame = false;
|
||||||
|
firstFrame = false;
|
||||||
|
delFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first Frame, second exists.
|
||||||
|
if myFrameCount == 1 && myMaxFrameCount > 1 {
|
||||||
|
// Visible:
|
||||||
|
nextFrame = true;
|
||||||
|
lastFrame = true;
|
||||||
|
delFrame = true;
|
||||||
|
// Invisible:
|
||||||
|
prevFrame = false;
|
||||||
|
firstFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// previous Frame exists, no more Frames
|
||||||
|
if myFrameCount > 1 && myFrameCount == myMaxFrameCount {
|
||||||
|
// Visible:
|
||||||
|
prevFrame = true;
|
||||||
|
firstFrame = true;
|
||||||
|
delFrame = true;
|
||||||
|
// Invisible
|
||||||
|
nextFrame = false;
|
||||||
|
lastFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// previous Frame exists and next Frame exists {
|
||||||
|
if myFrameCount > 1 && myFrameCount < myMaxFrameCount {
|
||||||
|
// Visible:
|
||||||
|
prevFrame = true;
|
||||||
|
firstFrame = true;
|
||||||
|
delFrame = true;
|
||||||
|
nextFrame = true;
|
||||||
|
lastFrame = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let rootNode = self.scene?.rootNode {
|
||||||
|
for childNode in rootNode.childNodes {
|
||||||
|
let buttonNode: SCNNode = childNode as SCNNode
|
||||||
|
if buttonNode.name == "myNextFrameButton" {
|
||||||
|
buttonNode.hidden = !nextFrame;
|
||||||
|
}
|
||||||
|
if buttonNode.name == "myPrevFrameButton" {
|
||||||
|
buttonNode.hidden = !prevFrame
|
||||||
|
}
|
||||||
|
if buttonNode.name == "myStartFrameButton" {
|
||||||
|
buttonNode.hidden = !firstFrame
|
||||||
|
}
|
||||||
|
if buttonNode.name == "myLastFrameButton" {
|
||||||
|
buttonNode.hidden = !lastFrame
|
||||||
|
}
|
||||||
|
if buttonNode.name == "myDelFrameButton" {
|
||||||
|
buttonNode.hidden = !delFrame
|
||||||
|
}
|
||||||
|
if buttonNode.name == "myFrameText" {
|
||||||
|
let geometry:SCNText = buttonNode.geometry as SCNText
|
||||||
|
geometry.string = "Frame: \(myFrameCount)/\(myMaxFrameCount)"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateLEDFrame() {
|
||||||
|
// get actuall frame data
|
||||||
|
|
||||||
|
let data : UnsafePointer<Byte> = UnsafePointer<Byte>(myFrames.mutableBytes)
|
||||||
|
//NSMutableData
|
||||||
|
if let rootNode = self.scene?.rootNode {
|
||||||
|
if let cubeNode = rootNode.childNodeWithName("cubeNode", recursively: true) {
|
||||||
|
for myLED in cubeNode.childNodes {
|
||||||
|
if let name:NSString = myLED.name {
|
||||||
|
if name != "myBox" { // LED lamps
|
||||||
|
if let geometry: SCNGeometry = myLED.geometry {
|
||||||
|
let ledID: Int = Int(name.integerValue)
|
||||||
|
if let material: SCNMaterial = geometry.firstMaterial {
|
||||||
|
var color: NSColor = NSColor()
|
||||||
|
let colorPosition: Int = ((myFrameCount-1)*64) + ledID
|
||||||
|
let savedColor: Byte = data[colorPosition]
|
||||||
|
if data[colorPosition] == 255 {
|
||||||
|
color = NSColor.grayColor()
|
||||||
|
}else{
|
||||||
|
let hueColor = CGFloat(savedColor) / 255.0
|
||||||
|
color = NSColor(calibratedHue: hueColor, saturation: 1.0, brightness: 1.0, alpha: 1.0)
|
||||||
|
}
|
||||||
|
material.diffuse.contents = color
|
||||||
|
//println(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func plusButtonPressed() {
|
||||||
|
// Extend the data array with one frame
|
||||||
|
myFrames.appendBytes(emptyFrame, length: 64)
|
||||||
|
|
||||||
|
// Add frame
|
||||||
|
myMaxFrameCount++;
|
||||||
|
|
||||||
|
// Goto new frame
|
||||||
|
myFrameCount = myMaxFrameCount;
|
||||||
|
|
||||||
|
// Update LEDs
|
||||||
|
updateLEDFrame()
|
||||||
|
|
||||||
|
// Update control button visibility
|
||||||
|
updateButtonVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
func minusButtonPressed() {
|
||||||
|
// remove one frame from the data array
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
// Remove frame
|
||||||
|
if myMaxFrameCount > 1 {
|
||||||
|
myMaxFrameCount--;
|
||||||
|
}
|
||||||
|
if myFrameCount > 1 {
|
||||||
|
myFrameCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update control button visibility
|
||||||
|
updateButtonVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
func prevButtonPressed() {
|
||||||
|
if myFrameCount > 1 {
|
||||||
|
myFrameCount--
|
||||||
|
}
|
||||||
|
// Update LEDs
|
||||||
|
updateLEDFrame()
|
||||||
|
|
||||||
|
// Update control button visibility
|
||||||
|
updateButtonVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
func nextButtonPressed() {
|
||||||
|
if myFrameCount < myMaxFrameCount {
|
||||||
|
myFrameCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update LEDs
|
||||||
|
updateLEDFrame()
|
||||||
|
|
||||||
|
// Update control button visibility
|
||||||
|
updateButtonVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
func firstButtonPressed() {
|
||||||
|
myFrameCount = 1;
|
||||||
|
|
||||||
|
// Update LEDs
|
||||||
|
updateLEDFrame()
|
||||||
|
|
||||||
|
// Update control button visibility
|
||||||
|
updateButtonVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
func lastButtonPressed() {
|
||||||
|
myFrameCount = myMaxFrameCount
|
||||||
|
|
||||||
|
// Update LEDs
|
||||||
|
updateLEDFrame()
|
||||||
|
|
||||||
|
// Update control button visibility
|
||||||
|
updateButtonVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
func playButtonPressed() {
|
||||||
|
// Change the button from Play to Pause
|
||||||
|
let myPauseButtonNode: SCNNode = self.scene!.rootNode.childNodeWithName("myPauseButton", recursively: true)!
|
||||||
|
let myPlayButtonNode: SCNNode = self.scene!.rootNode.childNodeWithName("myPlayButton", recursively: true)!
|
||||||
|
myPlayButtonNode.hidden = true
|
||||||
|
myPauseButtonNode.hidden = false
|
||||||
|
|
||||||
|
// Start the animation
|
||||||
|
_playAllFrames = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func pauseButtonPressed() {
|
||||||
|
// Change the button from Pause to Play
|
||||||
|
let myPauseButtonNode: SCNNode = self.scene!.rootNode.childNodeWithName("myPauseButton", recursively: true)!
|
||||||
|
let myPlayButtonNode: SCNNode = self.scene!.rootNode.childNodeWithName("myPlayButton", recursively: true)!
|
||||||
|
myPauseButtonNode.hidden = true
|
||||||
|
myPlayButtonNode.hidden = false
|
||||||
|
|
||||||
|
// Stop the animation
|
||||||
|
_playAllFrames = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override func rightMouseDown(theEvent: NSEvent) {
|
||||||
|
let p = self.convertPoint(theEvent.locationInWindow, fromView: nil)
|
||||||
|
if let hitResults = self.hitTest(p, options: nil) {
|
||||||
|
// check that we clicked on at least one object
|
||||||
|
if hitResults.count > 0 {
|
||||||
|
// retrieved the first clicked object
|
||||||
|
let result: AnyObject = hitResults[0]
|
||||||
|
if let node = result.node {
|
||||||
|
if let geom = node.geometry {
|
||||||
|
if let name:NSString = geom.name {
|
||||||
|
if name.integerValue >= 0 && name.integerValue < 64 { // LED lamps
|
||||||
|
let color: NSColor = geom.firstMaterial?.diffuse.contents as NSColor
|
||||||
|
if color != NSColor.grayColor() {
|
||||||
|
// Make sure we are in range of 0...255
|
||||||
|
let ledColor = (color.hueComponent * 255) % 255
|
||||||
|
if ( ledColor >= 0 && ledColor < 255 ) {
|
||||||
|
klickedColor = Byte(ledColor)
|
||||||
|
}
|
||||||
|
klickedColor = Byte (color.hueComponent * 255)
|
||||||
|
moveArrows(Int(klickedColor))
|
||||||
|
//println(klickedColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func mouseDown(theEvent: NSEvent) {
|
override func mouseDown(theEvent: NSEvent) {
|
||||||
lastMousePos = theEvent.locationInWindow
|
lastMousePos = theEvent.locationInWindow
|
||||||
@@ -34,6 +276,59 @@ class GameView: SCNView {
|
|||||||
// get its material
|
// get its material
|
||||||
let material = result.node!.geometry!.firstMaterial!
|
let material = result.node!.geometry!.firstMaterial!
|
||||||
|
|
||||||
|
if let clickedNode = result.node {
|
||||||
|
if clickedNode.name == "myBox" {
|
||||||
|
anim = false
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myPlayButton" && myMaxFrameCount > 1 {
|
||||||
|
playButtonPressed()
|
||||||
|
anim = false
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myPauseButton" {
|
||||||
|
pauseButtonPressed()
|
||||||
|
anim = false
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myAddFrameButton" {
|
||||||
|
plusButtonPressed()
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myDelFrameButton" {
|
||||||
|
minusButtonPressed()
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myPrevFrameButton" {
|
||||||
|
prevButtonPressed()
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myNextFrameButton" {
|
||||||
|
nextButtonPressed()
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myStartFrameButton" {
|
||||||
|
firstButtonPressed()
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myLastFrameButton" {
|
||||||
|
lastButtonPressed()
|
||||||
|
}
|
||||||
|
if clickedNode.name == "myColorBar" || clickedNode.name == "myArrows" {
|
||||||
|
let colorInt = Int(round(relativeBarPosition - theEvent.locationInWindow.y))
|
||||||
|
if colorInt < 0 {
|
||||||
|
klickedColor = 0 // Minimum value
|
||||||
|
}else{
|
||||||
|
if colorInt > 253 {
|
||||||
|
klickedColor = 253 // Maximum value
|
||||||
|
}else{
|
||||||
|
klickedColor = Byte(colorInt)
|
||||||
|
println(klickedColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Move arrows to the clicked position
|
||||||
|
moveArrows(colorInt)
|
||||||
|
|
||||||
|
//println("BarX: \(barRootPositionX) ClickedX: \(theEvent.locationInWindow.x) ")
|
||||||
|
//println("BarY: \(barRootPositionY) ClickedY: \(theEvent.locationInWindow.y) ")
|
||||||
|
|
||||||
|
|
||||||
|
anim = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get its name
|
// get its name
|
||||||
if let node = result.node {
|
if let node = result.node {
|
||||||
if let geom = node.geometry {
|
if let geom = node.geometry {
|
||||||
@@ -47,7 +342,8 @@ class GameView: SCNView {
|
|||||||
geom.firstMaterial?.diffuse.contents = NSColor.grayColor()
|
geom.firstMaterial?.diffuse.contents = NSColor.grayColor()
|
||||||
ledColorOn = false
|
ledColorOn = false
|
||||||
}else{
|
}else{
|
||||||
geom.firstMaterial?.diffuse.contents = NSColor(calibratedHue: (10/255), saturation: 1.0, brightness: 1.0, alpha: 1.0)
|
let hueColor = CGFloat(klickedColor) / 255.0
|
||||||
|
geom.firstMaterial?.diffuse.contents = NSColor(calibratedHue: hueColor, saturation: 1.0, brightness: 1.0, alpha: 1.0)
|
||||||
ledColorOn = true
|
ledColorOn = true
|
||||||
}
|
}
|
||||||
ledPressed = Int(name.intValue)
|
ledPressed = Int(name.intValue)
|
||||||
@@ -55,13 +351,7 @@ class GameView: SCNView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let boxNode = result.node {
|
|
||||||
if boxNode.name == "myBox" {
|
|
||||||
anim = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if let rootNode = self.scene?.rootNode {
|
if let rootNode = self.scene?.rootNode {
|
||||||
if let cubeNode = rootNode.childNodeWithName("cubeNode", recursively: true) {
|
if let cubeNode = rootNode.childNodeWithName("cubeNode", recursively: true) {
|
||||||
@@ -88,42 +378,54 @@ class GameView: SCNView {
|
|||||||
|
|
||||||
//println(name);
|
//println(name);
|
||||||
|
|
||||||
|
|
||||||
if anim {
|
if anim {
|
||||||
|
|
||||||
// highlight it
|
// highlight it
|
||||||
SCNTransaction.begin()
|
SCNTransaction.begin()
|
||||||
SCNTransaction.setAnimationDuration(0.5)
|
SCNTransaction.setAnimationDuration(0.2)
|
||||||
|
|
||||||
// on completion - unhighlight
|
// on completion - unhighlight
|
||||||
SCNTransaction.setCompletionBlock() {
|
SCNTransaction.setCompletionBlock() {
|
||||||
SCNTransaction.begin()
|
SCNTransaction.begin()
|
||||||
SCNTransaction.setAnimationDuration(0.5)
|
SCNTransaction.setAnimationDuration(0.2)
|
||||||
|
|
||||||
material.emission.contents = NSColor.blackColor()
|
material.emission.contents = NSColor.blackColor()
|
||||||
|
|
||||||
SCNTransaction.commit()
|
SCNTransaction.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
material.emission.contents = NSColor.whiteColor()
|
material.emission.contents = NSColor.grayColor()
|
||||||
|
|
||||||
SCNTransaction.commit()
|
SCNTransaction.commit()
|
||||||
|
|
||||||
// Update the LED frame
|
// Update the LED frame
|
||||||
var myByte: [Byte]
|
var myByte: [Byte]
|
||||||
if ledColorOn {
|
if ledColorOn {
|
||||||
myByte = [10]
|
myByte = [klickedColor]
|
||||||
}else{
|
}else{
|
||||||
myByte = [255] // Off
|
myByte = [255] // Off
|
||||||
}
|
}
|
||||||
myFrames.replaceBytesInRange(NSMakeRange(ledPressed, 1), withBytes: myByte)
|
myFrames.replaceBytesInRange(NSMakeRange(((myFrameCount-1)*64)+ledPressed, 1), withBytes: myByte)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.mouseDown(theEvent)
|
super.mouseDown(theEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func moveArrows(colorY: Int) {
|
||||||
|
// Range is from y=+15 ... -1
|
||||||
|
let myArrowsNode = self.scene!.rootNode.childNodeWithName("myArrows", recursively: true)
|
||||||
|
let myRelativePos = 16.0 * CGFloat(colorY) / 255.0
|
||||||
|
SCNTransaction.begin()
|
||||||
|
SCNTransaction.setAnimationDuration(0.5)
|
||||||
|
myArrowsNode?.position = SCNVector3(x:17, y: (16 - myRelativePos)-1, z:0.1)
|
||||||
|
SCNTransaction.commit()
|
||||||
|
}
|
||||||
|
|
||||||
func rotateCamera(var x: CGFloat, var y: CGFloat) {
|
func rotateCamera(var x: CGFloat, var y: CGFloat) {
|
||||||
// Save the angle for reset
|
// Save the angle for reset
|
||||||
startAngle = startAngle + y
|
startAngle = startAngle + y
|
||||||
@@ -179,10 +481,21 @@ class GameView: SCNView {
|
|||||||
if let rootNode = self.scene?.rootNode {
|
if let rootNode = self.scene?.rootNode {
|
||||||
if let cubeNode = rootNode.childNodeWithName("cubeNode", recursively: true) {
|
if let cubeNode = rootNode.childNodeWithName("cubeNode", recursively: true) {
|
||||||
for myLED in cubeNode.childNodes {
|
for myLED in cubeNode.childNodes {
|
||||||
//myLED.firstMaterial?.diffuse.contents = NSColor.grayColor()
|
if let name:NSString = myLED.name {
|
||||||
|
if name != "myBox" { // LED lamps
|
||||||
|
if let geometry: SCNGeometry = myLED.geometry {
|
||||||
|
if let material: SCNMaterial = geometry.firstMaterial {
|
||||||
|
material.diffuse.contents = NSColor.grayColor()
|
||||||
|
//println(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
super.keyDown(theEvent)
|
super.keyDown(theEvent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
import SceneKit
|
import SceneKit
|
||||||
import QuartzCore
|
import QuartzCore
|
||||||
|
|
||||||
var myFrameCount: UInt32 = 0;
|
var myFrameCount: UInt32 = 1;
|
||||||
|
var myMaxFrameCount: UInt32 = 1;
|
||||||
var myFrames: NSMutableData = NSMutableData()
|
var myFrames: NSMutableData = NSMutableData()
|
||||||
|
|
||||||
|
|
||||||
@@ -31,29 +32,81 @@ let emptyFrame: [Byte] = [
|
|||||||
255,255,255,255,
|
255,255,255,255,
|
||||||
255,255,255,255]
|
255,255,255,255]
|
||||||
|
|
||||||
class GameViewController: NSViewController {
|
var _previousUpdateTime: NSTimeInterval = NSTimeInterval()
|
||||||
|
var _deltaTime: NSTimeInterval = NSTimeInterval()
|
||||||
|
let _minSendDelay: NSTimeInterval = 0.200 // 200 milliseconds
|
||||||
|
let _frameSendDelay: NSTimeInterval = 0.2 // one second
|
||||||
|
var _playSendDelay: NSTimeInterval = 0.5 // 500 milliseconds as default
|
||||||
|
var _playAllFrames = false
|
||||||
|
|
||||||
|
class GameViewController: NSViewController { // SCNSceneRendererDelegate
|
||||||
|
|
||||||
@IBOutlet weak var gameView: GameView!
|
@IBOutlet weak var gameView: GameView!
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
|
||||||
|
//sendFrame(time)
|
||||||
|
sendFrame(NSDate.timeIntervalSinceReferenceDate())
|
||||||
|
//println("This will be called before each frame draw")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
self.gameView!.delegate = self
|
||||||
|
|
||||||
|
super.viewDidLoad()
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func sendFrame() {
|
func sendFrame() {
|
||||||
//let string = UnsafePointer<UInt8>(myFrames.bytes)
|
sendFrame(NSDate.timeIntervalSinceReferenceDate())
|
||||||
CubeNetworkObj.updateFrame(UnsafePointer<UInt8>(myFrames.bytes), count: myFrameCount)
|
}
|
||||||
|
|
||||||
|
func sendFrame(time: NSTimeInterval) {
|
||||||
|
//println(time)
|
||||||
|
|
||||||
|
if (_previousUpdateTime == 0.0) {
|
||||||
|
_previousUpdateTime = time;
|
||||||
|
}
|
||||||
|
_deltaTime = time - _previousUpdateTime;
|
||||||
|
|
||||||
|
//var ms = Int((time % 1) * 1000)
|
||||||
|
if ( _playAllFrames ) {
|
||||||
|
if ( _deltaTime >= _playSendDelay ){
|
||||||
|
if myFrameCount >= myMaxFrameCount {
|
||||||
|
self.gameView!.firstButtonPressed()
|
||||||
|
}else{
|
||||||
|
self.gameView!.nextButtonPressed()
|
||||||
|
}
|
||||||
|
CubeNetworkObj.updateFrame(UnsafePointer<UInt8>(myFrames.bytes), count: myFrameCount)
|
||||||
|
_previousUpdateTime = time;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if ( _deltaTime >= _minSendDelay ) {
|
||||||
|
CubeNetworkObj.updateFrame(UnsafePointer<UInt8>(myFrames.bytes), count: myFrameCount)
|
||||||
|
//println("SendFrame: \(_deltaTime)")
|
||||||
|
_previousUpdateTime = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//CubeNetworkObj.updateFrame(UnsafePointer<UInt8>(myFrames.bytes), count: myFrameCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func awakeFromNib(){
|
override func awakeFromNib(){
|
||||||
|
|
||||||
//NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(5), invocation: CubeNetworkObj.initObjects(), repeats: true)
|
//NSTimer.scheduledTimerWithTimeInterval(_frameSendDelay, invocation: CubeNetworkObj.initObjects(), repeats: true)
|
||||||
// CubeNetworkObj.initObjects();
|
// CubeNetworkObj.initObjects();
|
||||||
|
|
||||||
// Init first frame
|
// Init first frame
|
||||||
|
|
||||||
myFrames = NSMutableData(bytes: emptyFrame, length: 64)
|
myFrames = NSMutableData(bytes: emptyFrame, length: 64)
|
||||||
myFrameCount = 1
|
myFrameCount = 1
|
||||||
// Open connection to the LED cube
|
// Open connection to the LED cube
|
||||||
CubeNetworkObj.openConnection()
|
CubeNetworkObj.openConnection()
|
||||||
|
|
||||||
NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: Selector("sendFrame"), userInfo: nil, repeats: true)
|
// Fallback timer if nothing render at the moment
|
||||||
|
NSTimer.scheduledTimerWithTimeInterval(_frameSendDelay, target: self, selector: Selector("sendFrame"), userInfo: nil, repeats: true)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// create a new scene
|
// create a new scene
|
||||||
@@ -115,6 +168,9 @@ class GameViewController: NSViewController {
|
|||||||
scene.rootNode.addChildNode(ambientLightNode)
|
scene.rootNode.addChildNode(ambientLightNode)
|
||||||
|
|
||||||
|
|
||||||
|
// Background image
|
||||||
|
scene.background.contents = NSImage(named: "Background.jpg")
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// retrieve the ship node
|
// retrieve the ship node
|
||||||
@@ -128,15 +184,17 @@ class GameViewController: NSViewController {
|
|||||||
ship.addAnimation(animation, forKey: nil)
|
ship.addAnimation(animation, forKey: nil)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
scene.paused = false
|
||||||
|
|
||||||
// set the scene to the view
|
// set the scene to the view
|
||||||
self.gameView!.scene = scene
|
self.gameView!.scene = scene
|
||||||
|
|
||||||
|
|
||||||
// allows the user to manipulate the camera
|
// allows the user to manipulate the camera
|
||||||
//self.gameView!.allowsCameraControl = true
|
//self.gameView!.allowsCameraControl = true
|
||||||
|
|
||||||
// show statistics such as fps and timing information
|
// show statistics such as fps and timing information
|
||||||
self.gameView!.showsStatistics = true
|
//self.gameView!.showsStatistics = true
|
||||||
|
|
||||||
// configure the view
|
// configure the view
|
||||||
self.gameView!.backgroundColor = NSColor.blackColor()
|
self.gameView!.backgroundColor = NSColor.blackColor()
|
||||||
|
|||||||
BIN
Cube4Fun/Gradient.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
Cube4Fun/Gradient2.png
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
Cube4Fun/Pics/Background.jpg
Normal file
|
After Width: | Height: | Size: 51 KiB |
@@ -10,8 +10,98 @@ import Cocoa
|
|||||||
import SceneKit
|
import SceneKit
|
||||||
import QuartzCore
|
import QuartzCore
|
||||||
|
|
||||||
|
let debugOn = false
|
||||||
|
let animRun = false
|
||||||
|
|
||||||
class PrimitivesScene: SCNScene {
|
class PrimitivesScene: SCNScene {
|
||||||
|
|
||||||
|
func createPlayback() {
|
||||||
|
// Play - Button
|
||||||
|
let playImage = SCNPlane(width: 2.2, height: 2.2)
|
||||||
|
playImage.firstMaterial?.diffuse.contents = NSImage(named: "media-playback-start-5.png")
|
||||||
|
let playImageNode = SCNNode(geometry: playImage)
|
||||||
|
playImageNode.name = "myPlayButton"
|
||||||
|
playImageNode.position = SCNVector3(x:0, y:14, z:0)
|
||||||
|
self.rootNode.addChildNode(playImageNode)
|
||||||
|
|
||||||
|
// Pause - Button
|
||||||
|
let pauseImage = SCNPlane(width: 2.5, height: 2.5)
|
||||||
|
pauseImage.firstMaterial?.diffuse.contents = NSImage(named: "media-playback-pause-5.png")
|
||||||
|
let pauseImageNode = SCNNode(geometry: pauseImage)
|
||||||
|
pauseImageNode.name = "myPauseButton"
|
||||||
|
pauseImageNode.position = SCNVector3(x:0, y:14, z:0)
|
||||||
|
pauseImageNode.hidden = true
|
||||||
|
if myFrameCount == 1 && myMaxFrameCount == 1 {
|
||||||
|
pauseImageNode.hidden = true
|
||||||
|
}
|
||||||
|
self.rootNode.addChildNode(pauseImageNode)
|
||||||
|
|
||||||
|
// NextFrame - Button
|
||||||
|
let nextFrameImage = SCNPlane(width: 2.0, height: 2.0)
|
||||||
|
nextFrameImage.firstMaterial?.diffuse.contents = NSImage(named: "media-seek-forward-5.png")
|
||||||
|
let nextFrameImageNode = SCNNode(geometry: nextFrameImage)
|
||||||
|
nextFrameImageNode.name = "myNextFrameButton"
|
||||||
|
nextFrameImageNode.position = SCNVector3(x:2, y:14, z:0)
|
||||||
|
if myFrameCount == 1 && myMaxFrameCount == 1 {
|
||||||
|
nextFrameImageNode.hidden = true
|
||||||
|
}
|
||||||
|
self.rootNode.addChildNode(nextFrameImageNode)
|
||||||
|
|
||||||
|
// PrevFrame - Button
|
||||||
|
let prevFrameImage = SCNPlane(width: 2.0, height: 2.0)
|
||||||
|
prevFrameImage.firstMaterial?.diffuse.contents = NSImage(named: "media-seek-backward-5.png")
|
||||||
|
let prevFrameImageNode = SCNNode(geometry: prevFrameImage)
|
||||||
|
prevFrameImageNode.name = "myPrevFrameButton"
|
||||||
|
prevFrameImageNode.position = SCNVector3(x:-2, y:14, z:0)
|
||||||
|
if myFrameCount == 1 {
|
||||||
|
prevFrameImageNode.hidden = true
|
||||||
|
}
|
||||||
|
self.rootNode.addChildNode(prevFrameImageNode)
|
||||||
|
|
||||||
|
// StartFrame - Button
|
||||||
|
let startFrameImage = SCNPlane(width: 2.0, height: 2.0)
|
||||||
|
startFrameImage.firstMaterial?.diffuse.contents = NSImage(named: "media-skip-backward-5.png")
|
||||||
|
let startFrameImageNode = SCNNode(geometry: startFrameImage)
|
||||||
|
startFrameImageNode.name = "myStartFrameButton"
|
||||||
|
startFrameImageNode.position = SCNVector3(x:-5, y:14, z:0)
|
||||||
|
if myFrameCount == 1 {
|
||||||
|
startFrameImageNode.hidden = true
|
||||||
|
}
|
||||||
|
self.rootNode.addChildNode(startFrameImageNode)
|
||||||
|
|
||||||
|
// LastFrame - Button
|
||||||
|
let lastFrameImage = SCNPlane(width: 2.0, height: 2.0)
|
||||||
|
lastFrameImage.firstMaterial?.diffuse.contents = NSImage(named: "media-skip-forward-5.png")
|
||||||
|
let lastFrameImageNode = SCNNode(geometry: lastFrameImage)
|
||||||
|
lastFrameImageNode.name = "myLastFrameButton"
|
||||||
|
lastFrameImageNode.position = SCNVector3(x:5, y:14, z:0)
|
||||||
|
if myFrameCount == myMaxFrameCount {
|
||||||
|
lastFrameImageNode.hidden = true
|
||||||
|
}
|
||||||
|
self.rootNode.addChildNode(lastFrameImageNode)
|
||||||
|
|
||||||
|
// AddFrame - Button
|
||||||
|
let addFrameImage = SCNPlane(width: 1.7, height: 1.7)
|
||||||
|
addFrameImage.firstMaterial?.diffuse.contents = NSImage(named: "list-add-2.png")
|
||||||
|
let addFrameImageNode = SCNNode(geometry: addFrameImage)
|
||||||
|
addFrameImageNode.name = "myAddFrameButton"
|
||||||
|
addFrameImageNode.position = SCNVector3(x:-16.5, y:12, z:0)
|
||||||
|
self.rootNode.addChildNode(addFrameImageNode)
|
||||||
|
|
||||||
|
// DeleteFrame - Button
|
||||||
|
let delFrameImage = SCNPlane(width: 1.7, height: 1.7)
|
||||||
|
delFrameImage.firstMaterial?.diffuse.contents = NSImage(named: "list-remove-2.png")
|
||||||
|
let delFrameImageNode = SCNNode(geometry: delFrameImage)
|
||||||
|
delFrameImageNode.name = "myDelFrameButton"
|
||||||
|
delFrameImageNode.position = SCNVector3(x:-18.7, y:12, z:0)
|
||||||
|
// for first frame, there is nothing to delete
|
||||||
|
if ( myFrameCount == 1 ) {
|
||||||
|
delFrameImageNode.hidden = true
|
||||||
|
}
|
||||||
|
self.rootNode.addChildNode(delFrameImageNode)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
@@ -30,15 +120,49 @@ class PrimitivesScene: SCNScene {
|
|||||||
let boxSizeZ:CGFloat = CGFloat(zCount-1) * spaceBetweenLEDs + 2 * radius
|
let boxSizeZ:CGFloat = CGFloat(zCount-1) * spaceBetweenLEDs + 2 * radius
|
||||||
let boxPosY:CGFloat = (CGFloat(yCount-1) * spaceBetweenLEDs / 2) + radius + 0.5
|
let boxPosY:CGFloat = (CGFloat(yCount-1) * spaceBetweenLEDs / 2) + radius + 0.5
|
||||||
|
|
||||||
let text = SCNText(string: "Klick", extrusionDepth: 1)
|
|
||||||
|
// ID for the LED
|
||||||
|
let text = SCNText(string: "Klick", extrusionDepth: 0)
|
||||||
|
text.font = NSFont(name: "Arial", size: 1.5)
|
||||||
let textNode = SCNNode(geometry: text)
|
let textNode = SCNNode(geometry: text)
|
||||||
textNode.name = "myDescr"
|
textNode.name = "myDescr"
|
||||||
textNode.position = SCNVector3(x:-14.0 , y: 7.0, z: 0.0)
|
if ( debugOn ) {
|
||||||
textNode.scale = SCNVector3Make(0.1, 0.1, 0.1);
|
textNode.position = SCNVector3(x:-20.0 , y: -14.0, z: 0.0)
|
||||||
|
}else{
|
||||||
|
textNode.position = SCNVector3(x:-20.0 , y: -24.0, z: 0.0)
|
||||||
|
}
|
||||||
self.rootNode.addChildNode(textNode)
|
self.rootNode.addChildNode(textNode)
|
||||||
|
|
||||||
|
// Frame
|
||||||
|
let textFrame = SCNText(string: "Frame: \(myFrameCount)/\(myMaxFrameCount)", extrusionDepth: 0)
|
||||||
|
textFrame.font = NSFont(name: "Arial", size: 1.2)
|
||||||
|
let textFrameNode = SCNNode(geometry: textFrame)
|
||||||
|
textFrameNode.name = "myFrameText"
|
||||||
|
textFrameNode.position = SCNVector3(x:-20.0 , y: 13.7, z: 0.0)
|
||||||
|
self.rootNode.addChildNode(textFrameNode)
|
||||||
|
|
||||||
|
|
||||||
|
// Action Buttons
|
||||||
|
createPlayback()
|
||||||
|
|
||||||
|
// color picker
|
||||||
|
let colorBar = SCNPlane(width: 3, height: 16)
|
||||||
|
colorBar.firstMaterial?.diffuse.contents = NSImage(named: "Gradient2.png")
|
||||||
|
let colorBarNode = SCNNode(geometry: colorBar)
|
||||||
|
colorBarNode.name = "myColorBar"
|
||||||
|
colorBarNode.position = SCNVector3(x: 17, y: 7, z:0.0)
|
||||||
|
self.rootNode.addChildNode(colorBarNode)
|
||||||
|
|
||||||
|
// Arrows
|
||||||
|
let arrowImage = SCNPlane(width: 3, height: 2.0)
|
||||||
|
arrowImage.firstMaterial?.diffuse.contents = NSImage(named: "Arrows.png")
|
||||||
|
let arrowImageNode = SCNNode(geometry: arrowImage)
|
||||||
|
arrowImageNode.name = "myArrows"
|
||||||
|
arrowImageNode.position = SCNVector3(x:17, y:15, z:0.1)
|
||||||
|
self.rootNode.addChildNode(arrowImageNode)
|
||||||
|
|
||||||
|
|
||||||
|
// All movable objects
|
||||||
let cubeNode = SCNNode()
|
let cubeNode = SCNNode()
|
||||||
cubeNode.name = "cubeNode"
|
cubeNode.name = "cubeNode"
|
||||||
|
|
||||||
@@ -70,6 +194,7 @@ class PrimitivesScene: SCNScene {
|
|||||||
|
|
||||||
let sphereNode = SCNNode(geometry: sphereGeometry)
|
let sphereNode = SCNNode(geometry: sphereGeometry)
|
||||||
sphereNode.position = SCNVector3(x: y, y: x, z: z)
|
sphereNode.position = SCNVector3(x: y, y: x, z: z)
|
||||||
|
sphereNode.name = myIndex.description
|
||||||
|
|
||||||
|
|
||||||
cubeNode.addChildNode(sphereNode)
|
cubeNode.addChildNode(sphereNode)
|
||||||
|
|||||||
BIN
Cube4Fun/list-add-2.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Cube4Fun/list-remove-2.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Cube4Fun/media-playback-pause-5.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
Cube4Fun/media-playback-start-5.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
Cube4Fun/media-seek-backward-5.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
Cube4Fun/media-seek-forward-5.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
Cube4Fun/media-skip-backward-5.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
Cube4Fun/media-skip-forward-5.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |