Saturday, January 12, 2008

The Plan: merging swap behaviour with other libraries, part 1

The trick to merging "drag&drop/swap to multiple containers"-behaviour (resp. dragndrop, dragnswap) into other code is by isolating which prerequisite subcomponents (subfunctionalities) are already present in other libraries.

Dragndrop is actually a simple variant of dragnswap. So, I shall start by describing which stuff I need to build the dragndrop-ability present in jsTool:
  1. Function that will check if the pointer (mouse cursor) intersects an html element.
    • A function which gets two parameters, a point (2d coordinate) and an html element (containing the top-left coordinate and width and height), returns a boolean
    • A function which gets two parameters, a point and a list of html elements, returns the intersecting element with the point

  2. A function that will hook a handler, to the following events: "mouseup, mouseover, moseout, mouseenter". This handler will pass a message to the the listening item, if there has been an intersection with an item's container.
    • Function which hooks the message passing mechanism to the containers.
    • The message passing mechanism itself. (Most probably a shared closure)

  3. Something to unhook the message passing mechanism from the containers.

  4. Something to verify the message, so if the message is a false positive, we can still brute-force the correct intersecting container.

  5. Something to calculate the item's position (in html the position of an element in 2d is not defined, css defines this, so we have to make a translation from 2d to 1d) using the information of the container and the relative position of the pointer coordinates. I call this, the virtual index. So a means to calculate the virtual index, so we can sort items within a container. The current implementation assumes that all the items in the container have uniform dimensions. So expect it to break where this assumption does not hold.
Unless the user-agent (browser) provides built-in methods to do any or all of these functionalities, or subsumes two or many of these functionalities, these must all be implemented.

If I recall correctly, mozilla firefox 3.0 has built-in drag and drop events, and also a function to return the element on which a pointer intersects. Which makes the aformentioned functionalities 1 to 4, redundant.

Dragndrop goes through three stages, the start of the drag, the dragging itself and the end of the drag, respectively, the dragstart event, the drag event and the dragend event.
  1. Dragstart: Dragndrop starts by hooking "motion detectors" (message passing mechanism) to the containers of the currently dragged item.


  2. Drag: Dragndrop uses the message passing mechanism to determine which container the pointer is intersecting (current container), and when the dragndrop ends (the user releases the mouse button), it will see if there's a message about the current container and then it verifies the message. The verification procedure is simple, because it requires only an intersection test of the pointer coordinate, and the container. If the message is a false positive, we loop through all the container for the item, and do intersection tests on each and every one. (brute-force) If there is no message, we do the same, as in the case of the false positive message.
    Then the virtual index for the current dragndrop item is calculated, and a proxy item (a visual indicator for the virtual index) is docked, but the dragndrop-item itself is not docked (yet)


  3. Dragend: The "motion detectors" are disabled, by unhooking the message passers. And the dragndrop item is docked to the current container, by replacing the proxy item with the dragndrop item, given there is a proxy. (Which implies there is an active container)
Dragnswap is actually a slightly modified version of dragndrop. It uses the same message passing, message verification and virtual index mechanisms. Instead of using the virtual index mechanism to dock a dragndrop item to a new container (a transfer), the new item is swapped with another item (already in the current active container), where the virtual index refers to.

Note: In the current jsTool dragnswap implementation, swapping-behaviour occurs when a container has no more "space" left. That "space" is expressed as an integer, and it has no relation to the actual element real-estate space (2d surface size), which is defined by the css for that element.

TODO
  • Make an indicator when swapping-behaviour is available.

In conclusion, these functionalities provide the means to drag and drop to multiple containers and drag and swap to multiple containers.

Thursday, January 10, 2008

Ext with Cows and jQueries

jQuery at first glance almost looks alien. It's cool though if you like being more productive by typing less. But to read the code, cut, copy & paste, emulate, before you get the semantics, is comparable to reading and writing hieroglyphics. Okay, that's a gross exaggeration. Reading and writing in (pick a type) hieroglyphics is probably not that hard. And the semantics might not be that hard to get, once you understand how they built the library from the ground up, and their motivations. I have to admit though, I have never touched their code (yet).

Mootools
is very cute. Quantitively, they showcase the most visual effects. Their example page is the best I've seen up 'til now. Highly copy&pastable, commented, the works. Their code resembles normal javascript code. But the main drawback is, the library does not play nice with other libraries. Mootools does not apply some type of namespace magic to distinguish their code from other objects in the global namespace. Ext is great in this respect. Every Ext component is called from the global object "Ext", which prevents probable global namespace collisions (with other libraries). It plays nice with everyone! While Mootools expects you to suck only on the teats of the holy cow. Ext even supports other libraries by building adapters to prevent code redundancy (aka fat).

Ext's example page isn't the worst, but it's not the best either. They do not comment sufficiently on their example code, making it hard to guess what the motivations are behind the code structure. They are stingy on whitespace symbols. They cram as much code as they can on one single line. Most of the examples try to nest objects inside objects as deep as they can, resulting in layers of layers of code, you have no idea when and why a certain block ends. The Ext guys could learn something from python, I quote the "Zen of Python" (try import this on the interpreter): "Flat is better than nested".
Why? Because this is called being friendly to your fellow programmer. You may think you're the end-all of all programmers, but people have to read this nested mess.

For isolated sites demanding cheap effects, Mootools, is probably the best choice. You can probably build some nice webapps with it, given that you do not stray from the cow.

Right now Ext deserves the highest praise for building webapps.

I changed my mind.

I'm going to donate my swap functionality to Ext, Mootools and jQuery. Starting with Ext.

Wednesday, January 9, 2008

Ext js studies: part 1 Layout manager and general impressions

The example code (before whitespace removal) is almost unreadable due to the allergy of the Ext js example coder's stinginess with whitespaces and endlines.

Whenever I reformat a whole script to something that resembles javascript, I get more insights on how the architects built the library.

At this moment I'm using the debug script (ext-all-debug.js), so everything takes a while longer to load than the deployment script.

Ext.Viewpoint is truly impressive. No more monkeying around with css anymore, to achieve a balanced partition of your browser's viewable area (cross-browser! Heck, cross-platform even, see Adobe AIR ). Combined with XHR (aka ajax, XmlHttpRequest), noone need ever to reload the browser again. Very very powerful stuff. And stupidly easy to deploy.

Ext can get tiring for the eyes though, when one has to nest a bunch of objects, to configure a single Ext object.

Mental notes
:
  • What is the basic pattern that occurs when configuring an Ext obj?
  • How does one plug-in data dynamically, using XHR?
  • How do I do the backend?!
  • How do I use haxe to generate graphs/trends?
  • Heck, how do I program in haxe?

Sunday, January 6, 2008

Thinking of donating codebase to Ext js

I'm thoroughly impressed by Ext js. I feel this strong urge to donate some of my time, knowledge and code to the project. And relicence my junk under lgpl.

Currently, I have no clue as to where to begin modifying my existing code to fit into the ext-way of doing things. I have to study how they (the architects of Ext js) think and how they build libraries.

I suspect that there are many gems hidden in the big mass of complexity they call Ext js. But it shouldn't be impossible.

I understand they already have a drag and drop component, I haven't tried it out yet. I don't know how easy it is to adapt it to support multiple target drag and drop, and swap behaviour.

I'll create a few examples of my own, and in due process merge my jsTool stuff to the Ext core.

Wish me luck.