Installing and Running CamelBones apps
OK. I have my app built and working. I have the runtime for CamelBones ready to install on the client computer. What do I need to do to convert this into a bundle and/or separately runnable app recognized as such by OS X? I can run it through XCode, but that is a bit much for most users.
CamelBones runtime
I am getting an error running a Camelbones app on another machine. I installed the runtime and copied over the .app file/directory. I get the following errors: ZeroLink: could not load .o file: /Users/alan/Documents/XCode Projects/KingCNCProgrammer.build/KingCNCProgrammer.build/Objects- normal/ppc/main.ob ZeroLink: unknown symbol '_main' It looks like there are some absolute paths that should not exist that are getting generated. This is a symbol in the generated code. Anyway to fix this short of a hex editor?
Re: Installing and Running CamelBones apps
On Aug 24, 2004, at 2:26 PM, Sherm Pendley wrote: On Aug 24, 2004, at 5:03 PM, Alan Olsen wrote: I have the runtime for CamelBones ready to install on the client computer. Make sure you have the .pkg installer for the runtime. Different versions of CamelBones.framework are needed for different versions of Mac OS X. The installer detects the OS version and installs the correct framework for it. That is installed. What do I need to do to convert this into a bundle and/or separately runnable app recognized as such by OS X? I don't understand the question. When you click build in Xcode, you get a runnable app. What am I missing? It was where it put it. It is not in the same location as the source files. Once I clicked on info on the app in xcode, it told me where it was putting the completed project. I can run it through XCode, but that is a bit much for most users. If your app runs in Xcode but not on a Mac without the dev tools, two things to look for: 1. Make sure the user's machine has the runtime framework. 2. Make certain you built the app using the Deployment target in Xcode, not the Development target. I finally found that setting. It is in an incredibly non-obvious (to me) location. For those who are wondering... It is located by getting to the build results menu. Look for the little hammer icon and build message under the search box on the project window. Click on that and you will get to the build results screen. Or you can go to Window_Tools-Build Results. Also, you have to clean all targets before rebuilding or the change from development to deployment does nothing. Thanks. That gave me the clue I needed.
Re: Windows and Camelbones
On Aug 20, 2004, at 1:34 PM, Sherm Pendley wrote: On Aug 20, 2004, at 3:31 PM, Alan Olsen wrote: I am opening it as a modal dialog box. What I am trying to do is get it to act like OpenPanel or the alert dialog. Those return to the calling process when they are done and not before. That *is* how a modal session acts. For example, let's assume a panel that's connected to the outlet named MyPanel. In that panel you have a table view named TableView. In some action method, you open the panel like this: my $row = NSApplication-sharedApplication()-runModalForWindow($self- myPanel()); How do you set the datasource for tableview. I usually call it right after displaying the window. I am not certain what procedure to put it in since there is not a constructor for the window that I am aware of. The call to runModalForWindow: won't return until the modal session is stopped with stopModal, stopModalWithCode:, or abortModal. Let's assume you want it to return the selected row in TableView. In the action handler for the OK button, you'd have something like this: sub okClicked : Selector(okClicked:) ArgTypes(@) ReturnType(v) { my ($self, $sender) = @_; my $rowSel = $self-tableView()-selectedRow(); NSApplication-sharedApplication()-stopModalWithCode($rowSel); } This does not want to kill the window. I am looking for the description in the api docs. It looks like it is missing a reference to what window needs to be destroyed. It does act as it should, however. If you need to do something more complex, like return a string or object, just store it in an instance variable and use stopModal instead of returning it directly with stopModalWithCode. I have tried waiting in a loop until a message comes back, but that gives me the technicolor pizza. Like I said, that's by design. If you're spinning in a tight loop, you're not responding to events, and that means pizza. Mmmm... Pizza
Re: Windows and Camelbones
On Aug 20, 2004, at 3:00 PM, Sherm Pendley wrote: On Aug 20, 2004, at 5:30 PM, Alan Olsen wrote: On Aug 20, 2004, at 1:34 PM, Sherm Pendley wrote: my $row = NSApplication-sharedApplication()-runModalForWindow($self- myPanel()); How do you set the datasource for tableview. I usually call it right after displaying the window. I am not certain what procedure to put it in since there is not a constructor for the window that I am aware of. Are you asking when to call setDatasource:? Whenever you want. You could do it in the controller class' constructor - the MyPanel outlet is connected when you load the .nib, even if the window is offscreen. The table view won't actually call the data source methods until it actually needs to display data; i.e. when the window its in appears onscreen. You could delay it until just before calling runModalForWindow(). You could make the controller the delegate of MyPanel, and implement the NSWindow delegate method windowDidBecomeKey:. (Careful if you do this though; the controller is also the delegate of the main window, so in the delegate method, you'll have to check *which* window became key.) You could create a separate object, and assign it to be both the datasource and the delegate of MyPanel in the controller's constructor. It could initially be empty, and fill and/or empty itself in response to the windowDidBecomeKey: and windowDidResignKey: delegate methods. You could do it in Interface Builder. Double-click the scroll view to select the table view inside it, then control-drag a connection from it to File's Owner and select the datasource outlet. Believe it or not, I actually got it working! I had to move back to my previous code and then extrapolate what was going on. At some point I will post the code that i came up with. (After I clean it up so it does not look so Gordian knot-like.) The call to runModalForWindow: won't return until the modal session is stopped with stopModal, stopModalWithCode:, or abortModal. Let's assume you want it to return the selected row in TableView. In the action handler for the OK button, you'd have something like this: sub okClicked : Selector(okClicked:) ArgTypes(@) ReturnType(v) { my ($self, $sender) = @_; my $rowSel = $self-tableView()-selectedRow(); NSApplication-sharedApplication()-stopModalWithCode($rowSel); } This does not want to kill the window. I am looking for the description in the api docs. It looks like it is missing a reference to what window needs to be destroyed. It closes whatever window is running modally. Since, by definition, only one window can be running modally at any given time, there's no need to refer to a specific window. Actually it appears to break the modal loop, not close the window. I just close the window before that and everything is happy.
Windows and Camelbones
This is probably a modal v.s. non-modal issue. I want to find out the right way to do it... I have a window that I display that has a table view. The user needs to select a row off the table. The problem is that the window is displayed and then the program just keeps on going and does not wait for anything to return. How do I force the program to wait for an item to be selected before continuing on?
Re: Windows and Camelbones
On Aug 19, 2004, at 12:21 PM, Alan Olsen wrote: This is probably a modal v.s. non-modal issue. I want to find out the right way to do it... I have a window that I display that has a table view. The user needs to select a row off the table. The problem is that the window is displayed and then the program just keeps on going and does not wait for anything to return. How do I force the program to wait for an item to be selected before continuing on? I have tried this as both a sheet and a window. It displays the window and then just keeps on going. Any way to get this to wait until exit of the window to continue?
Re: XCode/CamelBones question
On Aug 10, 2004, at 6:44 PM, Sherm Pendley wrote: On Aug 10, 2004, at 6:56 PM, Alan Olsen wrote: Well, I figured out why I was getting the disconnect message... Connecting to first responder instead of file's owner helps... Sorry, I misunderstood the question - I was describing how you create a window by loading a Nib, and connect button clicks and other events generated from within that window to its owner. As you've found, menu events are different, as they're not connected to a particular window instance; generally, you want to send them to whatever instance is currently active, or failing that, to the application controller. So instead of making a hard connection to a single object, the first responder sends a message to the first object in the responder chain that implements the necessary method. So, you don't have to worry about which window is currently the main window - Cocoa automatically ensures that the main window is at the top of the responder chain. For more about the responder chain and handling menu events, see the Getting Started tutorial: http://camelbones.sourceforge.net/getstarted/index.php I figured that out. 2004-08-10 15:42:53.600 PerlButtonTest[1001] Perl error: Can't call method makeKeyAndOrderFront on an undefined value at /Users/alan/Documents/XCode projects/PerlButtonTest.app/Contents/Resources/PerlButtonTest.pm line 45. The method name here is significant - the name of the method is 'makeKeyAndOrderFront:'. Note the trailing colon - it's important, and signifies that the method requires a single argument. The lack of that colon in the error message shows the required argument is missing. Except that it is the exact code used in ShuX2 and your example. It appears that the problem in that the window is a panel, not a window. The argument is there. It is an undef, just like in the example. It make be that the constructor before it is not getting built for whatever reason. The problem I am encountering is not in the Perl code so much as what needs to be connected where in XCode and Interface Builder. Either I am missing a delegate link or some other set of links in the toolkit. The examples do not help in this case because you have to go back into the interface builder and try and guess what links are made where and what is relevant in the particular case.
Re: XCode/CamelBones question
On Aug 6, 2004, at 11:16 PM, Sherm Pendley wrote: It's not done in Xcode, but in Interface Builder. You create a new Nib with whatever panel(s) and such you want in it, and add that Nib to your project. (Okay, I lied - part of it is in Xcode.) In the MainMenu Nib, connect the AppName Preferences to an action method in AppName.pm. In that action method, create a new controller object. Here's an example from ShuX: sub showPreferences { my ($self, $sender) = @_; unless (defined $self-{'_preferences'}) { $self-{'_preferences'} = new PreferencesDelegate; } $self-{'_preferences'}-{'Window'}-makeKeyAndOrderFront(undef); } In the constructor for the PreferencesDelegate class, create an NSWindowController and use it to load the Nib, telling it that the current object is the Nib's owner. Thus, action messages you've connected to the File's Owner in IB will be sent to this object. Here's part of the PreferencesDelegate new() method from ShuX - I've deleted some code that isn't relevant: sub new { # Typical Perl constructor # See 'perltoot' for details my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; bless ($self, $class); $self-{'wc'} = NSWindowController-alloc-initWithWindowNibName_owner(Preferences, $self); $self-{'wc'}-window; return $self; } Once you call NSWindowController's initWithWindowNibName_owner() method, the outlets that you've connected in IB will be connected to the corresponding outlets declared in your Perl code, and action methods sent by the Nib will be sent to the newly-created object. You can also use the same technique to create multiple instances of the same Nib, each owned by a different controller object - ShuX does this to manage multiple browser windows. Well, I figured out why I was getting the disconnect message... Connecting to first responder instead of file's owner helps... Now onto the next message... When i try and get the preferences dialog to display, I get the following: 2004-08-10 15:42:53.587 PerlButtonTest[1001] NSWindow does not support utility styleMask 0x10 2004-08-10 15:42:53.600 PerlButtonTest[1001] Perl error: Can't call method makeKeyAndOrderFront on an undefined value at /Users/alan/Documents/XCode projects/PerlButtonTest.app/Contents/Resources/PerlButtonTest.pm line 45. This might be a panel instead of window issue. Kind of wondering what utility style mask 0x10 is...
Re: XCode/CamelBones question
On Aug 6, 2004, at 11:16 PM, Sherm Pendley wrote: On Aug 6, 2004, at 7:01 PM, Alan Olsen wrote: This is probably simple, I am just not seeing it. It's simple in hindsight, but it can be difficult to get your head around it at first. I have a couple of dialog boxes that are getting called in specific cases. (A preferences panel and a couple of other panels needed to select data.) I am not quite understanding how to call the various panels. I know i need to connect something to something in the xcode interface, but I am not certain what. It's not done in Xcode, but in Interface Builder. You create a new Nib with whatever panel(s) and such you want in it, and add that Nib to your project. (Okay, I lied - part of it is in Xcode.) In the MainMenu Nib, connect the AppName Preferences to an action method in AppName.pm. In that action method, create a new controller object. Here's an example from ShuX: sub showPreferences { my ($self, $sender) = @_; unless (defined $self-{'_preferences'}) { $self-{'_preferences'} = new PreferencesDelegate; } $self-{'_preferences'}-{'Window'}-makeKeyAndOrderFront(undef); } In the constructor for the PreferencesDelegate class, create an NSWindowController and use it to load the Nib, telling it that the current object is the Nib's owner. Thus, action messages you've connected to the File's Owner in IB will be sent to this object. Here's part of the PreferencesDelegate new() method from ShuX - I've deleted some code that isn't relevant: sub new { # Typical Perl constructor # See 'perltoot' for details my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; bless ($self, $class); $self-{'wc'} = NSWindowController-alloc-initWithWindowNibName_owner(Preferences, $self); $self-{'wc'}-window; return $self; } Once you call NSWindowController's initWithWindowNibName_owner() method, the outlets that you've connected in IB will be connected to the corresponding outlets declared in your Perl code, and action methods sent by the Nib will be sent to the newly-created object. You can also use the same technique to create multiple instances of the same Nib, each owned by a different controller object - ShuX does this to manage multiple browser windows. The problem is that when i try setting this up i get the following error on build: 2004-08-10 15:24:41.964 PerlButtonTest[995] Could not connect the action showPreferences: to target of class NSApplication I am sure I do not have something connected correctly in XCode/IB. The ShuX code uses a window and I am using a panel. (The Objective C book I am using is Cocoa Programming For Mac OS X second edition by Arron Hillegass. His examples use a panel for preferences instead of a window.) Still not certain where I am going wrong...
Re: XCode/CamelBones question
On Aug 6, 2004, at 11:16 PM, Sherm Pendley wrote: On Aug 6, 2004, at 7:01 PM, Alan Olsen wrote: This is probably simple, I am just not seeing it. It's simple in hindsight, but it can be difficult to get your head around it at first. Especially when you are not used to Objective C and the methodology used in connecting everything together. I have a couple of dialog boxes that are getting called in specific cases. (A preferences panel and a couple of other panels needed to select data.) I am not quite understanding how to call the various panels. I know i need to connect something to something in the xcode interface, but I am not certain what. It's not done in Xcode, but in Interface Builder. You create a new Nib with whatever panel(s) and such you want in it, and add that Nib to your project. (Okay, I lied - part of it is in Xcode.) Sometimes hard to remember that interface builder is a separate app... Moving things between nib files works with copy and paste. I wish that drop and drag worked. It is a bit more intuitive. (Though intuitive and Cocoa programming do not seem to be intersecting sets.) In the MainMenu Nib, connect the AppName Preferences to an action method in AppName.pm. In that action method, create a new controller object. Here's an example from ShuX: sub showPreferences { my ($self, $sender) = @_; unless (defined $self-{'_preferences'}) { $self-{'_preferences'} = new PreferencesDelegate; } $self-{'_preferences'}-{'Window'}-makeKeyAndOrderFront(undef); } In the constructor for the PreferencesDelegate class, create an NSWindowController and use it to load the Nib, telling it that the current object is the Nib's owner. Thus, action messages you've connected to the File's Owner in IB will be sent to this object. Here's part of the PreferencesDelegate new() method from ShuX - I've deleted some code that isn't relevant: sub new { # Typical Perl constructor # See 'perltoot' for details my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; bless ($self, $class); $self-{'wc'} = NSWindowController-alloc-initWithWindowNibName_owner(Preferences, $self); $self-{'wc'}-window; return $self; } Once you call NSWindowController's initWithWindowNibName_owner() method, the outlets that you've connected in IB will be connected to the corresponding outlets declared in your Perl code, and action methods sent by the Nib will be sent to the newly-created object. You can also use the same technique to create multiple instances of the same Nib, each owned by a different controller object - ShuX does this to manage multiple browser windows. I will try that. I need to reorganize things before I can do that. (I have everything crammed into the same nib.) The only thing really left after this is getting NSTableView to work. (I have example code for that. I will work o that once I have this solved.) Have you looked at the Data Access example app? No I had not. That is very useful.
Odd Camelbones bug
Here is an odd problem i found. $self-{'textBoxen'}-setString($file); if file is undefined, the app blows up real good. 2004-08-06 15:06:38.993 PerlButtonTest[3392] An uncaught exception was raised 2004-08-06 15:06:38.993 PerlButtonTest[3392] *** -[NSTextView replaceCharactersInRange:withString:]: nil NSString given. 2004-08-06 15:06:38.993 PerlButtonTest[3392] *** Uncaught exception: NSInvalidArgumentException *** -[NSTextView replaceCharactersInRange:withString:]: nil NSString given. PerlButtonTest has exited due to signal 5 (SIGTRAP).
Re: Mac::Glue::VERSION
On Jul 20, 2004, at 11:17 PM, John Delacour wrote: At 9:42 pm -0700 20/7/04, Chris Nandor wrote: On what OS (I figures it is Mac OS X, but just checking)? How do I discover that? :-) As to VERSION, again, maybe there's clues in your setup. There's no reason I can see for it to be failing like that, and no one else has reported such a problem, that I can recall. Could it be that the stuff Fink installed (5.8.4 think) has messed something up? I had no option but to allow that installation when I tried to get lilypond working, but I see I'm still running 5.8.3 in fact. My personal experiences with fink have not been good. The dependancy handling is not very consistent. (It has problems remembering previous packages that it installed or figuring out what the working environment is at install time.) It caused all sorts of problems building anything outside of fink. (Not to mention insisting on rebuilding packages that already existed on the system, like X.) I have no experience with lilypond, so I don't know why it would need fink. The only way I have found the way to fix the problems in fink is rm -rf /sw. (fix as in veterinarian.) If you are having problems with a dependent cpan module, figure out which module it is, download it and try compiling it separately. i have found that CPAN does not always deal with required, but non-standard C libraries. The error messages will usually tell you what is missing. (It may be that fink has installed some version that is not compatible with the test code.)
Re: More CamelBones questions
On Jul 17, 2004, at 12:21 AM, Pierre Vaudrey wrote: Alan, Please find sherm's answer to a similar question : Le samedi, 17 jul 2004, à 03:15 Europe/Paris, Alan Olsen a écrit : Anyone have a good example of usage of NSString and/or NSRunPanelAlert? D'oh! I thought I'd fixed that bug for good. Okay, I see what's causing it now, it'll be fixed in the next release. Meanwhile, there's a work-around. When you need to pass an NSString to a function - just a function, object and class methods aren't affected by this - pass a reference. It can be a reference to an NSString object, or to an ordinary scalar. So the easiest thing is to simply put a backslash in front of your constant strings, like this: NSRunAlertPanel(\Warning!, \Are you sure...?, \OK, \Cancel, \); Wow. That is the most non-obvious solution i have seen in a while. It does work though. Thanks.
More CamelBones questions
I think I am getting somewhere. Hard to say at this point. (I have managed some spectacular crashes.) I am assuming that PerlObjCBridge does not work with CamelBones? It seems that way. What i am trying to do is get NSRunAlertPanel to run. It complains that the first arg is not in NSString format. So I do the following: my $choice = NSRunAlertPanel(NSString-stringWithCString_('Is this the program you want to send?'),NSString-stringWithCString_(''), NSString-stringWithCString_('Yes'),NSString-stringWithCString_( 'Cancel'), NSString-stringWithCString_('No')); That blows up real good. I am not finding any examples using NSString or NSRunPanelAlert. (Nor any pod documentation in CamelBones.pm. Maybe i should report you guys to the pod-people.) Anyone have a good example of usage of NSString and/or NSRunPanelAlert?
Re: Mason and undefined symbols error
On Jul 15, 2004, at 1:45 PM, Joseph Alotta wrote: This might be a little out of our developed world mindset, but I have heard numerous missionaries report that people in their host countries will do the exorcism first off on all kinds of equipment, especially cars and trucks and generators and household appliances. The general conclusion is that it works well and it is lot cheaper then finding a mechanic or engineer. Could be they know things that some of us don't know. No! No! No! Hardware requires *blood* sacrifices. Software required applied daemonology. (Or percussive maintenance.) Joe. On Jul 15, 2004, at 2:41 PM, Sherm Pendley wrote: Yes, Voodoo is great fun ;-) I'm glad you think so, because the next step involves a bell, a book, a candle, and liberal applications of holy water. The demons in the machine must be exorcised! ;-) sherm--
NSOpenPanel and CamelBones
Does anyone have a good snippet of example code for calling NSOpenPanel with CamelBones? I am not certain what the syntax should be and there are few examples I can find. Thanks!
Re: NSOpenPanel and CamelBones
On Jul 12, 2004, at 6:12 PM, Alan Olsen wrote: Does anyone have a good snippet of example code for calling NSOpenPanel with CamelBones? I am not certain what the syntax should be and there are few examples I can find. It figures that I have to post here to find where the examples are kept. Never mind!
Interface advice needed
I have a program that I am writing on Mac OS X. It might need to run on OS 9, but I can probably avoid that. I will state up front that i prefer Linux, mainly because I know it better. (And I find the way the Mac does things to be totally alien to what i am used to.) I need a very simple set of interface elements. I need a file selection dialog. I need a dialog that supports multiple (more than three) buttons. A selection list dialog that returns an index. That is pretty much it. The rest of the code is pretty much done. all I need is the GUI code. Suggestions? All the examples I am finding are not giving primitives, they are giving talk to this app over there and tell it do do something. Maybe i need to break down and learn Cocoa and Objective-C.
Mixing MacPerl and Glue causes Halucinations
here is a short Perl program: #!/usr/bin/perl #use Mac::Glue; use MacPerl; $val = MacPerl::Answer(Pick your function,Edit Program, Receive Program, Send Program); Now if you run this you get a graphical UI dialog box. If you uncomment the Mac::Glue line, it will no longer be a graphical UI, but a text one on the console. What am I doing wrong here? (Other than using a Mac...) All I need for this program is a simple UI for picking files from a directory, a save dialog and a couple of list dialogs with buttons. The rest is socket code and misc processing to talk to a serial to ethernet box. Alan Olsen [EMAIL PROTECTED] [EMAIL PROTECTED]