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 -~----------~----~----~----~------~----~------~--~---