[MacRuby-devel] macruby/hotcocoa questions
Gary Weaver
gary.weaver at duke.edu
Fri Feb 19 12:21:59 PST 2010
To answer some of my own questions or present new ones:
I gave up on Marshal to file and back for now. Laurent told me that
active_support is planned to be supported in MacRuby 0.6, so instead of
using to_xml/from_xml or to_json/from_json, I took Isaac Kearse's advice
and looked into using plist included in HotCocoa.
I noticed that the read_plist method in HotCocoa 0.5.1 is on the
HotCocoa module as an instance method which would mean I would need to
include HotCocoa in Hash, Array, etc. to call it on one of those
classes, so I did the following to be sure I had both methods on Object
itself:
# HotCocoa 0.5.1 puts a to_plist on Object but a from_plist on HotCocoa.
Having to include HotCocoa in your object in order to call read_plist is
not intuitive and
# may cause adverse effects if having to extend Hash, Array, or Object
with include HotCocoa. So instead, we add the same implementation plus a
few lines to support
# reading from files, etc. like from_json/from_xml in ActiveSupport
implementations do. While at first Object doesn't seem an appropriate
place to put this method,
# it allows any object to have a from_plist class method as a companion
to the to_plist instance method, which is intuitive. Examples:
# Hash.from_plist({:data=>'mydata'}.to_plist),
Array.from_plist(['x','y','z'].to_plist),
AnObject.from_plist(an_object.to_plist)
class Object
# from_plist is the same as the HotCocoa 0.5.1 version. Could remove
it, but keeping it here for now, in case need to debug.
def self.from_plist(data, mutability=:all)
# not sure if this will work
if data.respond_to?(:read)
data = data.read
end
mutability = case mutability
when :none
NSPropertyListImmutable
when :containers_only
NSPropertyListMutableContainers
when :all
NSPropertyListMutableContainersAndLeaves
else
raise ArgumentError, "invalid mutability `#{mutability}'"
end
if data.is_a?(String)
data = data.dataUsingEncoding(NSUTF8StringEncoding)
if data.nil?
raise ArgumentError, "cannot convert string `#{data}' to data"
end
end
#error = Pointer.new(:object)
result = NSPropertyListSerialization.propertyListFromData(data,
mutabilityOption:mutability,
format:nil,
errorDescription:nil)
#raise error[0] if error[0].to_s.size > 0
end
# NSPropertyListSerialization can only take NSData, NSString,
NSNumber, NSDate, NSArray, or NSDictionary object. Container objects
must also contain only these kinds of objects.
# So you must convert everything to either these types or hashes,
arrays, strings, and other simple types before to_plist.
def to_plist(format=:xml)
format = case format
when :xml
NSPropertyListXMLFormat_v1_0
when :binary
NSPropertyListBinaryFormat_v1_0
when :open_step
NSPropertyListOpenStepFormat
else
raise ArgumentError, "invalid format `#{format}'"
end
#error = Pointer.new(:object)
data = NSPropertyListSerialization.dataFromPropertyList(self,
format:format,
errorDescription:nil)
#raise error[0] if error[0].to_s.size > 0
NSMutableString.alloc.initWithData(data, encoding:NSUTF8StringEncoding)
end
end
I also tried out those lines commented above to get the errors currently
swallowed from NSPropertyListSerialization, but didn't get much out of that.
I also learned that those methods on NSPropertyListSerialization don't
support nils or custom class instances, so I ended up writing some
methods to convert my data into a hash containing array of hashes
without any nil values in order to be able to have the to_plist and
from_plist work. It would be nice if this supported custom types (custom
class instances) and nils the way that activesupport's to_xml/from_xml
do (I think), but I didn't have time to work out a solution to that.
And for now I just made closing the window exit the app. I wrote it so
that if you start the app and start a task and kill the app, the task is
still active and timer works even when computer is off (since it is
storing the start_time of the task). It is very simplistic, but it works.
So yay, a working standlone multiple-timer application in
HotCocoa/MacRuby! Let me know if you have any thoughts on this.
Thanks,
Gary
Gary Weaver wrote:
> Hello,
>
> I wrote a small application in HotCocoa/MacRuby just to get familiar
> with it ( http://github.com/garysweaver/hourz ). MacRuby and HotCocoa
> are awesome! I did have a few issues during development that I thought
> I'd share in case anyone can assist.
>
> I'm using MacRuby 0.5 and HotCocoa 0.5.1 on OS X 10.6.2, was using
> TextMate vs. XCode to develop it. I have some experience with Ruby,
> but consider me a newbie to MacRuby, HotCocoa, and Cocoa (and Obj-C
> for that matter).
>
> Here is what I ran into:
>
> * If I take a stringValue from a text field, Marshal.dump it to a
> file, and then Marshal.load it, and put it back into the text field,
> it puts wierd characters in the end of the value like 'Òÿýÿÿÿ'. I
> think this might be a result of the class that I'm Marshalling that
> contains "include HotCocoa::Behaviors"? Not sure. I wasn't able to
> reproduce the issue via macirb using simple array or array of simple
> custom class Marshalling to file and back, but I'm able to reproduce
> the issue everytime in my app, but the class is more complicated.
>
> * I wasn't able to get File.copy to work so I wrote my own method to
> copy a file. Could you provide an example that can copy a file in
> MacRuby using File.copy or using FileUtils?
>
> * I wasn't able to set the (HotCocoa) layout_view frame or hidden
> properties successfully via calls by a button on_action. I could set
> them fine as long as they were called during startup of the
> application. For example, I wanted to do the following to hide a
> layout_view and replace it with another layout_view and vice versa in
> the same area of the window, but these methods only worked if being
> called during the initial load. I'm thinking maybe there is some sort
> of refresh method I need to call?
>
> def in_add_mode
> @edit_view.frame = [0, 0, 0, 0]
> @edit_view.hidden = true
> @add_view.frame = [0, 0, 0, 40]
> @add_view.hidden = false
> end
>
> def in_edit_mode
> @add_view.frame = [0, 0, 0, 0]
> @add_view.hidden = true
> @edit_view.frame = [0, 0, 0, 40]
> @edit_view.hidden = false
> # ...
> end
>
> * (window).will_miniaturize { exit } works great to keep the app
> active (in the dock) after closing the window, but I don't know what
> to call such that I could close the window and then click on the icon
> in the dock it then show the window. Also when I close it, it doesn't
> appear to be in the hidden state, because the dock menu indicates that
> I can hide the window (but it is hidden).
>
> * I couldn't figure out how to access the dock_menu in
> HotCocoa/MacRuby (I'm not using XCode or
> http://www.echographia.com/blog/2009/02/08/dynamic-dock-menus-in-macruby/
> would have helped). I'd like to be able to manage it dynamically in
> HotCocoa if possible to be able to choose which Task I'm working on at
> the moment without showing the window. It would also be cool to
> dynamically change the dock icon when this happens to somehow indicate
> which task is being worked on (similar to Thunderbird showing the
> number of new messages, maybe I could show a number or some brief text?).
>
> * I couldn't figure out how to alter the "About" part of the
> application to provide the authorship, license, and link to the
> project, although I know the version number is specified in
> config/build.yml. It would also be cool to have full control over that
> area and define the window, etc.
>
> * I wasn't sure what the best practice would be to ensure that the
> window could be resized if someone somehow is using larger/smaller
> fonts, but to keep it from being resized so much that it is unusable.
> Maybe the right thing to do is to just specify a defined size/frame
> for the window that cannot be changed?
>
> * Note that I might also look into storing the task data as xml or
> json. I'd rather it be hand-editable if needed. (I assume I could just
> put the array into a hash and use to_xml/from_xml or to_json/from_json.)
>
> Again, thanks so much for all of your work on this. It is really cool
> to develop apps for OS X this quickly! (<16 hours total dev time, not
> including time to post to GitHub, and a lot of that was research,
> documentation, making an icon, etc.)
>
> Thanks in advance for any assistance!
>
> Gary
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
More information about the MacRuby-devel
mailing list