On Tue, Jul 21, 2009 at 2:56 PM, J Elaych<microsc...@gmail.com> wrote:
>
>
>>
>> There is one more thing I want to try -- pyjamas, as pointed out
>> above. I already played with it yesterday, and what I saw so far is
>> *impressive*. So my next step will be to rewrite what I did into
>> pyjamas (e.g. just pure python both on the server and in the browser).
>> If that works and I think it could, well, that would be the way to go,
>> since I could debug all those functions like for calculating cursor
>> positions etc. in Python.
>>
>> Ondrej
>
> Well technically it wouldn't be 'python in the browser', right?  You
> would compile the pyjamas python code into javascript, store it
> on the server and send the js to the client browser.

Yes. But you don't have to write javascript and if you do things
correctly, the same file executes on your desktop using python, thus
you can doctest the whole thing.

I already implemented the textbox resizing, here is the code:

---------------

import pyjd # this is dummy in pyjs.
from pyjamas.ui.RootPanel import RootPanel
from pyjamas.ui.Button import Button
from pyjamas.ui.HTML import HTML
from pyjamas.ui.Label import Label
from pyjamas import Window
from pyjamas.ui.TextArea import TextArea
from pyjamas.ui import KeyboardListener


def greet(fred):
    print "greet button"
    Window.alert("Hello, AJAX!")

class InputArea(TextArea):

    def __init__(self, echo):
        TextArea.__init__(self)
        self.echo = echo
        self.addKeyboardListener(self)
        self.addClickListener(self)
        self.set_rows(1)
        self.setCharacterWidth(80)

    def onClick(self, sender):
        print "on_click"

    def rows(self):
        return self.getVisibleLines()

    def set_rows(self, rows):
        if rows in [0, 1]:
            # this is a bug in pyjamas, we need to use 2 rows
            rows = 2
        # the number of rows seems to be off by 1, another bug in pyjamas
        self.setVisibleLines(rows-1)

    def cols(self):
        return self.getCharacterWidth()

    def occupied_rows(self):
        text = self.getText()
        lines = text.split("\n")
        return len(lines)

    def cursor_coordinates(self):
        """
        Returns the cursor coordinates as a tuple (x, y).

        Example:

        >>> self.cursor_coordinates()
        (2, 3)
        """
        text = self.getText()
        lines = text.split("\n")
        pos = self.getCursorPos()
        i = 0
        cursor_row = -1
        cursor_col = -1
        #print "--------" + "start"
        for row, line in enumerate(lines):
            i += len(line) + 1  # we need to include "\n"
        #    print len(line), i, pos, line
            if pos < i:
                cursor_row = row
                cursor_col = pos - i + len(line) + 1
                break
        #print "--------"
        return (cursor_col, cursor_row)

    def insert_at_cursor(self, inserted_text):
        pos = self.getCursorPos()
        text = self.getText()
        text = text[:pos] + inserted_text + text[pos:]
        self.setText(text)

    def onKeyUp(self, sender, keyCode, modifiers):
        #print "on_key_up"
        x, y = self.cursor_coordinates()
        rows = self.occupied_rows()
        s = "row/col: (%s, %s), cursor pos: %d, %d, real_rows: %d" % \
                (self.rows(), self.cols(), x, y, rows)
        self.set_rows(rows)
        self.echo.setHTML("Info:" + s)

    def onKeyDown(self, sender, key_code, modifiers):
        if key_code == KeyboardListener.KEY_TAB:
            self.insert_at_cursor("    ")
            print "TAB"

    #def onKeyDownPreview(self, key, modifier):
    #    print "preview"

    def onKeyPress(self, sender, keyCode, modifiers):
        #print "on_key_press"
        pass


if __name__ == '__main__':
    pyjd.setup("../templates/Hello.html")
    b = Button("Click me", greet, StyleName='teststyle')
    h = HTML("<b>Hello World</b> (html)", StyleName='teststyle')
    l = Label("Hello World (label)", StyleName='teststyle')
    echo = HTML()
    t = InputArea(echo)
    RootPanel().add(b)
    RootPanel().add(h)
    RootPanel().add(l)
    RootPanel().add(t)
    RootPanel().add(echo)
    pyjd.run()


---------------

And it mostly works, up to some bugs in pyjamas (like that the textbox
can't be set to just 1 row, only 2 rows or more), that I will try to
solve with pyjamas developers, hopefully they are simple to fix.

If you look at the cursor_coordinates() function, this is really PITA
to debug in javascript -- I mean, you essentially need tests for the
javascript etc. If this could be avoided, that'd be a huge win. The
generated javascript for the function above is:

    cls_definition.cursor_coordinates =
pyjs__bind_method(cls_instance, 'cursor_coordinates', function() {
        if (this.__is_instance__ === true) {
            var self = this;
        } else {
            var self = arguments[0];
        }
        var text = self.getText();
        var lines = text.split(String('\x0A'));
        var pos = self.getCursorPos();
        var i = 0;
        var cursor_row = -1;
        var cursor_col = -1;
        var __temp_row = pyjslib.enumerate(lines).__iter__();
        try {
            while (true) {
                var temp_row = __temp_row.next();
                        var row = temp_row.__getitem__(0);      var
line = temp_row.__getitem__(1);
                i +=  ( pyjslib.len(line) + 1 ) ;
                if (pyjslib.bool((pyjslib.cmp(pos, i) == -1))) {
                    cursor_row = row;
                    cursor_col =  (  (  ( pos - i )  +
pyjslib.len(line) )  + 1 ) ;
                    break;
                }
            }
        } catch (e) {
            if (e.__name__ != 'StopIteration') {
                throw e;
            }
        }
        return new pyjslib.Tuple([cursor_col, cursor_row]);
    }


So that doesn't look bad. But it's definitely slower than it could be
if used javascript for loop directly. But as I said, let's wait until
I implement the whole thing and let's see. Also pyjamas allow to embed
javascript code, so we may write the critical code in javascript
itself.

Ondrej

--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to sage-devel@googlegroups.com
To unsubscribe from this group, send email to 
sage-devel-unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to