My News: TOP - Autos Intimate goods Chairs Underwear Ladies handbag Bracelets Sportswear Top auto-moto furniture Dating Boots FDA Approved Pharmacy Boats Necklace Yachts Medical tests Suits Medicine news Building materials Top casino Rington ya.by Tunings Sale Auto Chronometer Blog Search the Web Cases Mobiles Cigarettes Cars auto-moto Ear rings Cigarette Green Card Information
uncommonplace
 

    Follow me

     Watch out for shiny keys
    Filed under: — David @ 10:11 am

    One of the cool things about Cocoa bindings is the number of different things that a key can represent on an object. It could just be the value returned by valueForKey:, but the default implementation will also check for an instance variable or a method with the same name.

    Having the key refer to a method is appealing because then you can return a calculated value. I was trying to do this in XVG yesterday, where the document’s “selection” key would return either the current selection or a placeholder object. That placeholder object holds the attributes applied to new graphics created with the drawing tools. This allows the inspector window, whose controls are bound to the document’s selection, to have a dual purpose: inspect and modify existing objects, or set up the properties of new ones.

    So I had this -[XVGDocument selection] method which would check whether anything was selected, and return either the selection or the placeholder. And the app crashed.

    The problem with that approach was that the value being returned for the “selection” key could change before the document could send a proper KVO notification. Lots of internal Cocoa bindings stuff was operating under the assumption that my code was being a good bindings citizen, and when I failed at that bad things happened.

    So I went for the caching approach. I added an instance variable to XVGDocument to contain the last calculated “selection” value, and updated it whenever the selection changed. No more crashing.

    Caching is often a less attractive approach because it means duplicating information, and it carries the risk that you could mess up and fail to update your cached value in some cases. In this case I’m relying on notifications that the actual selection has changed, since that’s the only situation that would require me to update this value. But depending on these notifications is at the core of using bindings in the first place, so I feel relatively safe in this assumption.

     When computers disagree
    Filed under: — David @ 10:15 pm

    I’ve got an odd situation at the moment - unit tests that work on one computer, but fail on the other. I’ve run comparisons on the project folders on both machines, re-downloaded source files, cleaned and rebuilt the projects, and they still don’t agree.

    The tests are what I was working on last week while I was at WWDC - hit testing of shapes when the object or a parent group has a transformation applied (e.g. scaling, rotation). On my PowerBook, where I did the work, the tests pass, and manual testing works too. On my soon-to-be-replaced G4, it behaves just like it did before last week’s fix, so the tests fail. Same graphic, same mouse point, same transformation. Grrr…

    Maybe if I had a third data point… but my Mac Pro isn’t even due to ship for a month. This is where it would be good to have a project team size bigger than one.

     Visible progress
    Filed under: — David @ 3:21 pm

    I got some good momentum again working on XVG the last few days. There is visible progress on filters finally, though none of the test suite images are working 100% yet. I also added support for loading external image files (except other SVG files), and implemented the <symbol> and <use> elements.

    I kind of wish I had taken a more methodical approach to adding features: implement some new SVG thing, and then add the editing UI before moving on. I think that would have made it more convincing in the early stages of development to anyone checking it out. But it’s so nice to see the test suite coming together.

     Open PSD
    Filed under: — David @ 7:38 pm

    This article on NewsForge talks about efforts to create an open-standard Photoshop-like file format, capable of storing raster (pixel-based) images, text, paths, etc. This is interesting to me because such a format would be a candidate for the XVG and/or Icon Machine 4 file format, instead of the SVG-based format that I currently have in mind.

    I was disappointed to find that the PSD file format isn’t open (though according to the article it used to be). You can use QuickTime to get at individual layer images, but that doesn’t get you everything. So I’m going to be following OpenRaster (a tentative title that doesn’t appear on that wiki page) and similar efforts, and see if I end up using a resulting standard or just some of their ideas.

     XVG page added
    Filed under: — David @ 7:26 pm

    Although it will be a while yet before I have an actual release, I’ve added an XVG page to the site with an overview of the project.

    Currently I’m still in the middle of object resizing - I need to do lines, polygons, and paths. Next will be creating basic shapes, and then possibly refining the inspector interface. I’m thinking of adding a Calatog palette, which will hold things like gradients, filters, symbols, and CSS styles.

    What I really want to do for the XVG web site is set up Trac at xvg.sourceforge.net, but currently Trac requires that Subversion be set up on the same server which SourceForge doesn’t do. I can’t do it here at uncommonplace.com either, since I can’t run Subversion at all (unless I switched to a different web host, but that would be a big pain and probably too expensive). Hopefully there will be either a fix or a workaround soon.

     Cutting corners
    Filed under: — David @ 11:54 am

    The basics of tool switching are in place, though of course the tools themselves have a ways to go. The arrow tool can still only drag. I also have a path editing tool, which so far just draws the anchor points, and a rectangle drawing tool which for the moment just has its own cursor.

    Being able to switch tools meant adding a window toolbar, with a custom multi-button item like the one seen in OmniGraffle. The twist in making the tool selection item was that I couldn’t quite do it through the Magic of Cocoa Bindings. The thing that was lacking was that NSMatrix doesn’t let you bind the images of its cells. Otherwise, I could just take my existing NSArrayController with its list of tools, wire it all up, and I’d be set. Fortunately, since my list of tools isn’t going to change, I can just set the tool images manually and content myself with binding the selection index.

    I was going to start on the resizing feature of the arrow tool, but somehow got sidetracked on round-cornered rectangles. A casual observer might think I already had that working, but I was missing something: SVG allows you to specify an x and y radius for the corners, yielding oval-shaped corners instead of circular ones. In Quartz, the only way to draw an oval arc is by scaling it by the ratio of the x and y radii. That’s where things got messy. Scaling happens relative to the origin, not relative to the current point, so you have to apply a translation on top of the scaling. And somehow I couldn’t quite get it right. For some cases it worked, but for others it was off by a few pixels.

    The Quartz documentation mentions that when you tell it to draw an arc, it actually approximates it with cubic Bezier curves - since Bezier curves can’t perfectly recreate a true arc. So I started to think maybe I should do that myself, since Quartz’s version didn’t work for me. Google gave me a page from a Stanford computer science class in which students were asked to approximate a 90° arc with a single Bezier segment. Fortunately this was the answer page.

    I plugged in their little formula, 4(√2-1)/3 multiplied by each radius, replacing one of my corner arcs with this approximation. I was assuming I’d need at least two curve segments to make it look really good. But just the one segment looked pretty good. So I did another corner, and then brought the result into Photoshop to get a more exact comparison (new layer via copy, flip horizontal, difference mode, and levels to enhance the differences). There were differences, but not nearly as much as I expected and definitely good enough. So I did the other two corners and called it done.

    This arc issue may come up again as I get into path drawing. Most drawing apps just use cubic Bezier segments for their paths, but SVG allows each segment to be one of four things: straight line, quadratic Bezier, cubic Bezier, or arc. And of course, that can be an oval arc. Not only that, SVG describes arcs differently from how they’re described in Quartz. So if I’m going to support arc segments, I’m faced with the choice of figuring out how to convert between SVG and Quartz arcs, or doing more cubic Bezier approximations. Before, I didn’t give the approximation route much thought, but now it’s looking a lot more attractive.

    It’s interesting what a little taste of success will do for you.

     Open Source and Diligence
    Filed under: — David @ 2:10 pm

    XVG was my first new open source project in a few years, and I’ve taken a somewhat different approach with it than I did with the others (at least at first). I’m going by two basic rules: work on one thing at a time, and keep the repository in a state where someone can build the application and run it at any time. Unit tests definitely help with that second one. I’m also trying to be responsible about maintaining XVG as an open source project. I try to keep in mind that it is basically on display to the whole world (even if, in practice, not many people are looking at it right now), so I should think of it as a front lawn instead of as a closet.

    ACCELA wasn’t as easy to work on under those rules, since for the most part it’s a collection of mostly independent parts. There may still be a few things that are not well tested; I never wrote a test/demo app to test everything. I mainly left that for features that were more my own code than just simple wrappers: the auto toolbar and the document classes.

    Volley, on the other hand, definitely would benefit from those practices, but when I started it I didn’t quite have the habits of focused development that I’m trying to adhere to now. For example, a while back I made a fairly major change - switching over to the boost classes for threads - but I have yet to check that in because I started working on other things at the same time, and I never quite got everything fully working. I didn’t really get into the concept of unit tests until Xcode 2 made it convenient. One of these days I need to get back and finalize these changes; perhaps I should plan to do that after the first release of XVG.

    There is always the temptation to decide I’m bored of working on a feature, and skip over to something else instead. But then I end up with a mess of half-completed features. I caught myself going down that road just recently with XVG. I had started to implement drawing and editing tools, and I had a chain of logic that led me to start implementing the Bring to Front/Send to Back commands.

    You see, to be able to switch tools, I needed to have the tool palette item in the toolbar (since I plan to do that instead of a floating tool palette). But I wanted the window to look good, so there should be some other toolbar items too. The item ordering commands seemed like good candidates, so I started working on those. But once I had the code written for them, I remembered that I still hadn’t tackled the issue of Undo, which I would need not only for these new commands, but also for the recently-started editing tools, not to mention the inspector palette that’s been there for a while. So really Undo needed to be the next task; putting it off would only mean more work when the time came to adding it in to already-written commands.

    That’s why, if you were to look at the XVGView.m source file right now, you’d see all the written-but-untested item ordering commands commented out. For the sake of keeping things clean, I don’t want to leave anything in that hasn’t been reasonably tested, and it simply wasn’t the time to test those commands.

    These principles of unit tests and focused development appeal to me a lot, and I often think there are some good life lessons that can be extracted from them. These practices do not happen in isolation; when you develop good habits in one area of your life, it’s going to help you in others too. And of course, the same goes for bad habits.

    Focus is a good thing. It helps fight laziness, and it gives you a way to express that you care about what you’re doing. If your work on a project consists of randomly poking at various individual tasks, then you won’t get much satisfaction or progress. If you don’t actively demonstrate that you care about the project, you will come to care about it less. It will mean less to you because you haven’t given it meaning.

    Unit tests are a way of defining the goals and standards for a program. They give you a way to tell the computer what you expect out of the program, so that the computer can tell you if it lives up to those expectations. I only wish there were such a quick and easy way to run unit tests on my life, giving me a report of any ways in which I am not meeting my own goals and standards. Instead, I have to do it the old-fashioned way, through introspection and developing the good habits that defend me against the bad ones.

     Implementation questions
    Filed under: — David @ 8:33 am

    XVG development has slowed down a bit as I face the design challenges involved in doing drawing tools and object manipulation.

    • What should selection handles and path control points look like, and how will they be differentiated?
    • Which object should draw them? The view, the tool, or the selected object itself?
    • How will multiple selections be handled? I’m leaning toward the OmniGraffle method of drawing one set of selection handles as if the selected objects were in a group.
    • What determines the properties of a new graphic object? If it’s based on the previous selection, what happens if it was a multiple selection with mixed properties? Maybe that question itself is enough to rule out the previous selection idea.
    • What should the tool cursors and icons look like? For path editing, I’m probably going to do something like Photoshop’s white-centered arrow. I think the outlined appearance matches well the idea of editing paths. I’ve made my own version based on the system arrow (complete with shadow), where the white center is semi-transparent.

    It also occurred to me yesterday that maybe Core Data would be an appropriate solution for the XVG internals. But I’m not sure I’m familiar enough with it to decide that for certain. I played around with constructing a data model document in Xcode’s visual editor, but it got somewhat complex because of the many different kinds of SVG object properties. Fill color, for example, can be a literal color, or it can be a reference to a gradient. I’m not sure if that maps well into the Core Data system. Also, the only attribute types that seem to be available are numbers, strings, and binary data - no structures, such as points and rectangles. That seems awkward to work with in a graphics application.

    Edit: After actually reading that Core Data page, I see that they even mention a “vector-art illustration program” as the kind of application in which Core Data can be used. So I’m giving it another look. Anyway, it turned out that my first stab at creating an XVG Core Data data model wasn’t the best way to go. I created it from scratch, but you can have Xcode create one automatically from your existing classes… though for some reason it ignores parent classes.


    This is my personal blog. The views expressed on these pages are mine alone and not those of my employer.

    Powered by WordPress

    Shareware Icons Games
    Topic - News Blogs: Bracelets auto-moto Chairs Blog Search the Web Top auto-moto Boats Autos Cases Intimate goods Necklace Trousers Underwear Top casino Sale Auto Building materials Evening dress Yachts Tunings Medicine news furniture Rington Replica Rolex Mobiles Rolex Replica Boots Ear rings Fashions Green Card Information ya.by Balans Cigarettes Medical tests Sport Betting Cars