lybniz-1.3.2/0000755000175000017500000000000010730465750011155 5ustar samsamlybniz-1.3.2/COPYING0000644000175000017500000000274610730464223012213 0ustar samsamCopyright (c) 2005-2006, Thomas Führinger, Sam Tygier All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Lybniz dev team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. lybniz-1.3.2/AUTHORS0000644000175000017500000000013710730464223012220 0ustar samsamCoders: Thomas Führinger Sam Tygier lybniz-1.3.2/extras/0000755000175000017500000000000010730465750012463 5ustar samsamlybniz-1.3.2/extras/lybniz_wb.py0000755000175000017500000002060210730464223015031 0ustar samsam#!/usr/bin/env python # -*- coding: UTF-8 -*- """ Simple Function Graph Plotter © Thomas Führinger, 2005-02-12 www.fuhringer.com/thomas Version 0.1.0 Requires PyGtk 2.6 Released under the terms of the revised BSD license Modified: 2005-11-01 """ import sys, gtk, math, Workbench, Graph AppWin = None Actions = gtk.ActionGroup("General") Script = \ """def y1(): return 1 / x**2 def y2(): return math.cos(x) Graph1.y = [y1, y2] Graph1.xMin = -6 Graph1.xMax = 6 Graph1.xScale = .5 Graph1.yMin = -2 Graph1.yMax = 6 Graph1.yScale = 1 Graph1.Refresh() """ x = None Workbench1 = None def ShowAboutDialog(Widget): AboutDialog = gtk.AboutDialog() AboutDialog.set_name("Lybniz Workbench") AboutDialog.set_version("0.1.0") AboutDialog.set_authors([u"Thomas Führinger"]) AboutDialog.set_comments("Function Graph Plotter") AboutDialog.set_license("Revised BSD") AboutDialog.show() def MenuToolbarCreate(): AppWin.MenuMain = gtk.MenuBar() MenuFile = gtk.Menu() MenuItemFile = gtk.MenuItem("_File") MenuItemFile.set_submenu(MenuFile) Actions.Save = gtk.Action("Save", "_Save", "Save graph as bitmap", gtk.STOCK_SAVE) Actions.Save.connect ("activate", Save) Actions.add_action(Actions.Save) MenuItemSave = Actions.Save.create_menu_item() MenuItemSave.add_accelerator("activate", AppWin.AccelGroup, ord("S"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) #MenuFile.append(MenuItemSave) Actions.Quit = gtk.Action("Quit", "_Quit", "Quit Application", gtk.STOCK_QUIT) Actions.Quit.connect ("activate", QuitDlg) Actions.add_action(Actions.Quit) MenuItemQuit = Actions.Quit.create_menu_item() MenuItemQuit.add_accelerator("activate", AppWin.AccelGroup, ord("Q"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) MenuFile.append(MenuItemQuit) MenuHelp = gtk.Menu() MenuItemHelp = gtk.MenuItem("_Help") MenuItemHelp.set_submenu(MenuHelp) Actions.Help = gtk.Action("Help", "_Contents", "Help Contents", gtk.STOCK_HELP) Actions.Help.connect ("activate", ShowYelp) Actions.add_action(Actions.Help) MenuItemContents = Actions.Help.create_menu_item() MenuItemContents.add_accelerator("activate", AppWin.AccelGroup, gtk.gdk.keyval_from_name("F1"), 0, gtk.ACCEL_VISIBLE) MenuHelp.append(MenuItemContents) Actions.About = gtk.Action("About", "_About", "About Box", gtk.STOCK_ABOUT) Actions.About.connect ("activate", ShowAboutDialog) Actions.add_action(Actions.About) MenuItemAbout = Actions.About.create_menu_item() MenuHelp.append(MenuItemAbout) AppWin.MenuMain.append(MenuItemFile) AppWin.MenuMain.append(MenuItemHelp) AppWin.ToolBar = gtk.Toolbar() AppWin.ToolBar.insert(Actions.Quit.create_tool_item(), -1) def Save(Widget, Event=None): "yet to be implemented" pass def QuitDlg(Widget, Event=None): gtk.main_quit() def ShowYelp(Widget): import os os.system("yelp lybniz-wb-manual.xml") class Editor: def __init__(self): self.WorkbenchWindow = None self.Output = None self.GtkWidget = gtk.VBox() self.ToolBar = gtk.Toolbar() self.ActionExecute = gtk.Action("Execute", "_Execute", "Execute Script", gtk.STOCK_EXECUTE) self.ActionExecute.connect ("activate", self.Execute) self.ToolBar.insert(self.ActionExecute.create_tool_item(), -1) self.ActionSave = gtk.Action("Save", "_Save", "Save script", gtk.STOCK_SAVE) self.ActionSave.connect ("activate", self.Save) self.HandleBox = gtk.HandleBox() self.HandleBox.add(self.ToolBar) self.GtkWidget.pack_start(self.HandleBox, False, False, 0) self.GtkTextView = gtk.TextView() #self.GtkTextView.set_wrap_mode(gtk.WRAP_WORD) self.GtkTextView.set_size_request(220, 200) self.GtkTextBuffer = self.GtkTextView.get_buffer() self.GtkTextBuffer.set_text(Script) Tag = gtk.TextTag(type) Tag.set_property("family", "monospace") #Tag.set_property("tabs", 4) TTable = self.GtkTextBuffer.get_tag_table() TTable.add(Tag) self.GtkTextBuffer.apply_tag(Tag, self.GtkTextBuffer.get_start_iter(), self.GtkTextBuffer.get_end_iter()) self.GtkScrolledWindow = gtk.ScrolledWindow() self.GtkScrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.GtkScrolledWindow.add(self.GtkTextView) self.GtkWidget.pack_start(self.GtkScrolledWindow) def Execute(self, Action=None): b = self.GtkTextBuffer.get_selection_bounds() if b != (): Script = self.GtkTextBuffer.get_text(b[0], b[1]) else: Script = self.GtkTextBuffer.get_text(self.GtkTextBuffer.get_start_iter(), self.GtkTextBuffer.get_end_iter()) SaveOut = sys.stdout SaveErr = sys.stderr try: if self.Output is not None: sys.stdout = self.Output sys.stderr = self.Output exec Script in globals(), locals() finally: sys.stdout = SaveOut sys.stderr = SaveErr def ConnectWindow(self, WorkbenchWindow): "make widget appear in WorkbenchWindow and add popup window" self.WorkbenchWindow = WorkbenchWindow self.WorkbenchWindow.Connect(self.GtkWidget) self.GtkTextView.connect ("populate-popup", self.PopulateMenu) def OutputTo(self, Output): "redirect output" self.Output = Output def PopulateMenu(self, Textview, Menu): "append the submenu for inserting addtional windows into popup menu" s = gtk.SeparatorMenuItem() s.show() Menu.append(s) MenuItemSave = self.ActionSave.create_menu_item() Menu.append(MenuItemSave) Menu.append(self.WorkbenchWindow.PopupMenuItemCreate()) def Save(self, Widget, Event=None): "Save script" FileDialog = gtk.FileChooserDialog("Save as..", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) FileDialog.set_default_response(gtk.RESPONSE_OK) Filter = gtk.FileFilter() Filter.add_mime_type("text/txt") Filter.add_pattern("*.py") FileDialog.add_filter(Filter) FileDialog.set_filename("Script1.py") Response = FileDialog.run() FileDialog.destroy() if Response == gtk.RESPONSE_OK: File = open(FileDialog.get_filename(), "w") File.write(self.GtkTextBuffer.get_text(self.GtkTextBuffer.get_start_iter(), self.GtkTextBuffer.get_end_iter())) File.close() class Output: "Output window" def __init__(self): self.WorkbenchWindow = None self.GtkTextView = gtk.TextView() self.GtkTextView.set_wrap_mode(gtk.WRAP_WORD) self.GtkTextView.set_size_request(220, 100) self.GtkTextBuffer = self.GtkTextView.get_buffer() Tag = gtk.TextTag(type) Tag.set_property("family", "monospace") TTable = self.GtkTextBuffer.get_tag_table() TTable.add(Tag) self.GtkTextBuffer.apply_tag(Tag, self.GtkTextBuffer.get_start_iter(), self.GtkTextBuffer.get_end_iter()) GtkScrolledWindow = gtk.ScrolledWindow() GtkScrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) GtkScrolledWindow.add(self.GtkTextView) self.GtkWidget = GtkScrolledWindow def write(self, String): "implement write method of file class for redirection of output" self.GtkTextBuffer.insert(self.GtkTextBuffer.get_end_iter(), String) def ConnectWindow(self, WorkbenchWindow): "make widget appear in WorkbenchWindow and add popup window" self.WorkbenchWindow = WorkbenchWindow self.WorkbenchWindow.Connect(self.GtkWidget) self.GtkTextView.connect ("populate-popup", self.PopulateMenu) def PopulateMenu(self, Textview, Menu): "append the submenu for inserting addtional windows into popup menu" s = gtk.SeparatorMenuItem() s.show() Menu.append(s) Menu.append(self.WorkbenchWindow.PopupMenuItemCreate()) def Main(): global AppWin, Graph1, Workbench1 AppWin = gtk.Window(gtk.WINDOW_TOPLEVEL) AppWin.set_title("Lybniz Workbench") AppWin.set_default_size(800, 600) AppWin.connect("delete-event", QuitDlg) AppWin.AccelGroup = gtk.AccelGroup() AppWin.add_accel_group(AppWin.AccelGroup) AppWin.VBox = gtk.VBox(False, 1) AppWin.VBox.set_border_width(1) AppWin.add(AppWin.VBox) MenuToolbarCreate() AppWin.VBox.pack_start(AppWin.MenuMain, False, True, 0) # create workbench with windows "Editor1", "Output1" and "Graph1" Workbench1 = Workbench.Workbench("Editor1") Workbench1.WindowInsert("Editor1", 2, 2, "Graph1") Workbench1.WindowInsert("Editor1", 1, 2, "Output1") Editor1 = Editor() Editor1.ConnectWindow(Workbench1.Window["Editor1"]) Output1 = Output() Output1.ConnectWindow(Workbench1.Window["Output1"]) Editor1.OutputTo(Output1) Graph1 = Graph.Graph2D() Graph1.ConnectWindow(Workbench1.Window["Graph1"]) AppWin.VBox.pack_start(Workbench1.GtkWidget, True, True, 0) AppWin.show_all() gtk.main() # Start it all if __name__ == '__main__': Main() lybniz-1.3.2/extras/lybniz-manual.xml0000644000175000017500000001033510730464223015763 0ustar samsam Lybniz"> ]>
&app; User Manual Thomas Führinger 2005 Thomas Führinger &date; Thomas Führinger Lybniz &app; is a simple mathematical function graph plotter. Using &app; Enter functions in Python syntax with x as the dependent variable. Press the Plot button to see the graph. Constants and functions of the math module are available. They have to be prefixed with 'math.', however. Examples: y1 = x**3 - 2 * x y2 = 2 * math.cos(x) y1 = math.e ** (x / -5) * math.sin(x) xMin, xMax, yMin, yMax define the boundaries of the range on the abszissa and ordinate to be displayed. xScale, yScale give the intervals at which marks are displayed on the respective axis. They can also be stated as expressions. Examples: xMin = math.pi * -2 xMax = math.pi * 2 xScale = math.pi / 2 To zoom in, activate the Zoom In tool button. It divides the range boundaries by half. Zoom out does the opposite. To closer inspect a specific section, drag the mouse cursor over an area. After release of the button the area thus marked will be displayed. To save the graph in PNG format choose FileSave. Using GraphEvaluate you get a dialog box that allows input of an x value and calculates y values. Accelerator Keys Accelerator Function CtrlL Plot graph Ctrl+ Zoom in Ctrl- Zoom out CtrlR Reset zoom CtrlS Save graph CtrlE Evaluate functions CtrlQ Quit &app;
About &app; &app; was written by Thomas Führinger (ThomasFuhringer@Yahoo.com). To find more information about &app;, please visit the &app; Web page. This program is distributed under the revised BSD license.
lybniz-1.3.2/extras/Workbench.py0000644000175000017500000001205710730464223014756 0ustar samsam# -*- coding: UTF-8 -*- """ Workbench module - handle screen separation Thomas Führinger, 2005-10-26 """ import gtk class Workbench: def __init__(self, FirstWindowName, Widget=None): if Widget is None: Widget = gtk.Label(FirstWindowName) self.Window = {} self.Window[FirstWindowName] = WorkbenchWindow(self, FirstWindowName) self.GtkWidget = gtk.HPaned() # dummy to keep WorkbenchWindow.Insert() happy self.Window[FirstWindowName].ParentContainer = self.GtkWidget self.Window[FirstWindowName].Place = 1 self.GtkWidget.pack1(Widget, True, True) self.Window[FirstWindowName].GtkWidget = Widget def WindowInsert(self, Window, SplitLine, Place, Name=None, NewWidget=None): "SplitLine: 1 = vertical, 2 = horizontal" # assign default window names "W1", "W2" ... if Name is None: Name = "W" + str(len(self.Window) + 1) self.Window[Name] = WorkbenchWindow(self, Name, NewWidget) self.Window[Window].Insert(SplitLine, Place, self.Window[Name]) class WorkbenchWindow: def __init__(self, Workbench, Name, Widget=None): def PopulateMenu(Textview, Menu): s = gtk.SeparatorMenuItem() s.show() Menu.append(s) Menu.append(self.PopupMenuItemCreate()) self.Workbench = Workbench # Workbench I am contained in self.Name = Name self.ParentContainer = None # parent GtkPaned, holds my own GtkWidget self.Place = None # my place in the parent GtkPaned if Widget is None: self.GtkWidget = gtk.Label(Name) self.GtkWidget.set_selectable(True) self.GtkWidget.connect ("populate-popup", PopulateMenu) else: self.GtkWidget = Widget def Insert(self, SplitLine, PlaceNew, NewWindow): # create new GtkPaned dependent on split line if SplitLine == 1: Paned = gtk.VPaned() else: Paned = gtk.HPaned() # unhook own widget self.ParentContainer.remove(self.GtkWidget) # pack new GtkPaned in previous place of own widget if self.Place == 1: self.ParentContainer.pack1(Paned, True, False) else: self.ParentContainer.pack2(Paned, True, False) # pack own widget and new window's into new GtkPaned if PlaceNew == 1: NewWindow.Place = 1 self.Place = 2 Paned.pack1(NewWindow.GtkWidget) Paned.pack2(self.GtkWidget) else: self.Place = 1 NewWindow.Place = 2 Paned.pack1(self.GtkWidget) Paned.pack2(NewWindow.GtkWidget) self.ParentContainer = Paned NewWindow.ParentContainer = Paned self.ParentContainer.show_all() def Connect(self, Widget): # replace my current Widget self.ParentContainer.remove(self.GtkWidget) # pack new Widget in previous place of own widget if self.Place == 1: self.ParentContainer.pack1(Widget) else: self.ParentContainer.pack2(Widget) self.GtkWidget = Widget def PopupMenuItemCreate(self): # create submenu item to use as popup WindowMenuItem = gtk.MenuItem("Window") WindowMenuItem.set_submenu(self.PopupMenuCreate()) WindowMenuItem.show() return WindowMenuItem def PopupMenuCreate(self): # create submenu to use as popup def InsertRight(Action=None): self.Workbench.WindowInsert(self.Name, 2, 2) def InsertBottom(Action=None): self.Workbench.WindowInsert(self.Name, 1, 2) def InsertLeft(Action=None): self.Workbench.WindowInsert(self.Name, 2, 1) def InsertTop(Action=None): self.Workbench.WindowInsert(self.Name, 1, 1) def ShowName(Action=None): "Display dialog box with window's name" def Close(self): DlgWin.destroy() DlgWin = gtk.Window(gtk.WINDOW_TOPLEVEL) DlgWin.set_title("Window Name") DlgWin.connect("destroy", Close) l = gtk.Label(self.Name) l.set_padding(39, 30) DlgWin.add(l) DlgWin.show_all() WindowMenu = gtk.Menu() ActionInsertRight = gtk.Action("InsertRight", "Insert Right", "Insert new window on right side", gtk.STOCK_GO_FORWARD) ActionInsertRight.connect ("activate", InsertRight) MenuItemInsertRight = ActionInsertRight.create_menu_item() ActionInsertBottom = gtk.Action("InsertBottom", "Insert Bottom", "Insert new window on bottom", gtk.STOCK_GO_DOWN) ActionInsertBottom.connect ("activate", InsertBottom) MenuItemInsertBottom = ActionInsertBottom.create_menu_item() ActionInsertLeft = gtk.Action("InsertLeft", "Insert Left", "Insert new window on left side", gtk.STOCK_GO_BACK) ActionInsertLeft.connect ("activate", InsertLeft) MenuItemInsertLeft = ActionInsertLeft.create_menu_item() ActionInsertTop = gtk.Action("InsertTop", "Insert Top", "Insert new window on top", gtk.STOCK_GO_UP) ActionInsertTop.connect ("activate", InsertTop) MenuItemInsertTop = ActionInsertTop.create_menu_item() ActionShowName = gtk.Action("ShowName", "Show Name", "Show window's name", None) ActionShowName.connect ("activate", ShowName) MenuItemShowName = ActionShowName.create_menu_item() WindowMenu.append(MenuItemInsertRight) WindowMenu.append(MenuItemInsertBottom) WindowMenu.append(MenuItemInsertLeft) WindowMenu.append(MenuItemInsertTop) s = gtk.SeparatorMenuItem() s.show() WindowMenu.append(s) WindowMenu.append(MenuItemShowName) WindowMenu.show() return WindowMenu lybniz-1.3.2/extras/lybniz-wb-manual.xml0000644000175000017500000000301610730464223016367 0ustar samsam Lybniz Workbench"> ]>
&app; User Manual Thomas Führinger 2005 Thomas Führinger &date; Thomas Führinger Lybniz &app; is a simple mathematical function graph plotter. Using &app; To open additional Workbench Windows right-click into an open one. About &app; &app; was written by Thomas Führinger (ThomasFuhringer@Yahoo.com). To find more information about &app;, please visit the &app; Web page. This program is distributed under the revised BSD license.
lybniz-1.3.2/extras/Graph.py0000644000175000017500000002061610730464223014075 0ustar samsam# -*- coding: UTF-8 -*- """ Graph module - plot function graphs Thomas Führinger, 2005-10-28 """ import gtk, sys, __main__ class Graph2D: def __init__(self): # Create backing pixmap of the appropriate size def ConfigureEvent(Widget, Event): x, y, w, h = Widget.get_allocation() self.PixMap = gtk.gdk.Pixmap(Widget.window, w, h) self.CanvasWidth = w self.CanvasHeight = h self.Refresh() return True # Redraw the screen from the backing pixmap def ExposeEvent(Widget, Event): x, y, w, h = Event.area Widget.window.draw_drawable(Widget.get_style().fg_gc[gtk.STATE_NORMAL], self.PixMap, x, y, x, y, w, h) return False def ButtonPressEvent(Widget, Event): global xSel, ySel # Start marking selection if Event.button == 1: self.Selection[0][0], self.Selection[0][1] = int(Event.x), int(Event.y) self.Selection[1][0], self.Selection[1][1] = None, None # Show popup menu allowing to split window if Event.button == 3 and self.WorkbenchWindow is not None: m = self.WorkbenchWindow.PopupMenuCreate() MenuItemSave = self.ActionSave.create_menu_item() m.append(MenuItemSave) m.popup(None, None, None, 3, Event.time) # End of selection def ButtonReleaseEvent(Widget, Event): if Event.button == 1 and Event.x != self.Selection[0][0] and Event.y != self.Selection[0][1]: xmi, ymi = min(self.GraphX(self.Selection[0][0]), self.GraphX(Event.x)), min(self.GraphY(self.Selection[0][1]), self.GraphY(Event.y)) xma, yma = max(self.GraphX(self.Selection[0][0]), self.GraphX(Event.x)), max(self.GraphY(self.Selection[0][1]), self.GraphY(Event.y)) self.xMin, self.yMin, self.xMax, self.yMax = xmi, ymi, xma, yma self.GtkSpinButton.set_value(1) self.Refresh() self.Selection[1][0] = None self.Selection[0][0] = None # Draw rectangle during mouse movement def MotionNotifyEvent(Widget, Event): if Event.is_hint: x, y, State = Event.window.get_pointer() else: x = Event.x y = Event.y State = Event.state if State & gtk.gdk.BUTTON1_MASK and self.Selection[0][0] is not None: gc = self.DrawingArea.get_style().black_gc gc.set_function(gtk.gdk.INVERT) if self.Selection[1][0] is not None: x0 = min(self.Selection[1][0], self.Selection[0][0]) y0 = min(self.Selection[1][1], self.Selection[0][1]) w = abs(self.Selection[1][0] - self.Selection[0][0]) h = abs(self.Selection[1][1] - self.Selection[0][1]) self.PixMap.draw_rectangle(gc, False, x0, y0, w, h) x0 = min(self.Selection[0][0], int(x)) y0 = min(self.Selection[0][1], int(y)) w = abs(int(x) - self.Selection[0][0]) h = abs(int(y) - self.Selection[0][1]) self.PixMap.draw_rectangle(gc, False, x0, y0, w, h) self.Selection[1][0], self.Selection[1][1] = int(x), int(y) self.DrawDrawable() self.xMax = 10.0 self.xMin = -10.0 self.xScale = 1 self.yMax = 10.0 self.yMin = -10.0 self.yScale = 1 self.y = [] self.Zoom = 1 self.ConnectPoints = True self.GtkWidget = gtk.VBox() self.WorkbenchWindow = None self.ToolBar = gtk.Toolbar() ti = gtk.ToolItem() ti.add(gtk.Label(" Zoom Factor ")) self.ToolBar.insert(ti, -1) self.GtkSpinButton = gtk.SpinButton(None, 1, 1) self.GtkSpinButton.set_numeric(True) self.GtkSpinButton.set_range(0.1, 100.0) self.GtkSpinButton.set_increments(.2, .2) self.GtkSpinButton.set_value(1) ti = gtk.ToolItem() ti.add(self.GtkSpinButton) self.ToolBar.insert(ti, -1) self.ActionRefresh = gtk.Action("Refresh", "_Refresh", "Refresh graphs", gtk.STOCK_REFRESH) self.ActionRefresh.connect ("activate", self.Refresh) self.ToolBar.insert(self.ActionRefresh.create_tool_item(), -1) self.HandleBox = gtk.HandleBox() self.HandleBox.add(self.ToolBar) self.GtkWidget.pack_start(self.HandleBox, False, False, 0) self.ActionSave = gtk.Action("Save", "_Save", "Save graph", gtk.STOCK_SAVE) self.ActionSave.connect ("activate", self.Save) # Marked area point[0, 1][x, y] self.Selection = [[None, None], [None, None]] self.DrawingArea = gtk.DrawingArea() self.DrawingArea.set_size_request(60, 60) self.DrawingArea.connect("expose_event", ExposeEvent) self.DrawingArea.connect("configure_event", ConfigureEvent) self.DrawingArea.connect("button_press_event", ButtonPressEvent) self.DrawingArea.connect("button_release_event", ButtonReleaseEvent) self.DrawingArea.connect("motion_notify_event", MotionNotifyEvent) self.DrawingArea.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.LEAVE_NOTIFY_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK |gtk.gdk.POINTER_MOTION_HINT_MASK) self.GtkWidget.pack_start(self.DrawingArea, True, True, 0) def DrawDrawable(self): x, y, w, h = self.DrawingArea.get_allocation() self.DrawingArea.window.draw_drawable(self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL], self.PixMap, 0, 0, 0, 0, w, h) def Refresh(self, Widget=None, Event=None): self.GtkSpinButton.update() self.Zoom = self.GtkSpinButton.get_value() self.PixMap.draw_rectangle(self.DrawingArea.get_style().white_gc, True, 0, 0, self.CanvasWidth, self.CanvasHeight) # draw cross self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [self.CanvasPoint(0, self.yMin * self.Zoom), self.CanvasPoint(0, self.yMax / self.Zoom)]) self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [self.CanvasPoint(self.xMin * self.Zoom, 0), self.CanvasPoint(self.xMax / self.Zoom, 0)]) # draw scaling x iv = int(self.xScale * self.CanvasWidth/(self.xMax - self.xMin) * self.Zoom) os = self.CanvasX(0) % iv for i in xrange(self.CanvasWidth / iv + 1): self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [(os + i * iv, self.CanvasY(0) - 5), (os + i * iv, self.CanvasY(0) + 5)]) # draw scaling x iv = int(self.yScale * self.CanvasHeight/(self.yMax - self.yMin) * self.Zoom) os = self.CanvasY(0) % iv for i in xrange(self.CanvasHeight / iv + 1): self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [(self.CanvasX(0) - 5, i * iv + os), (self.CanvasX(0) + 5, i * iv + os)]) # plot GC1 = self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL] GC1.foreground = gtk.gdk.color_parse("blue") PrevY = [] for i in xrange(len(self.y)): PrevY.append(None) for i in xrange(self.CanvasWidth): __main__.x = self.GraphX(i + 1) for ii in xrange(len(self.y)): try: y = self.y[ii]() yC = self.CanvasY(y) if yC < 0 or yC > self.CanvasHeight: raise ValueError if self.ConnectPoints and PrevY[ii] is not None: self.PixMap.draw_lines(GC1, [(i, PrevY[ii]), (i + 1, yC)]) else: self.PixMap.draw_points(GC1, [(i + 1, yC)]) PrevY[ii] = yC except: #print "Error at %d: %s" % (__main__.x, sys.exc_value) PrevY[ii] = None self.DrawDrawable() def CanvasX(self, x): "Calculate position on canvas to point on graph" return int((x - self.xMin / self.Zoom) * self.CanvasWidth/(self.xMax - self.xMin) * self.Zoom) def CanvasY(self, y): return int((self.yMax / self.Zoom - y) * self.CanvasHeight/(self.yMax - self.yMin) * self.Zoom) def CanvasPoint(self, x, y): return (self.CanvasX(x), self.CanvasY(y)) def GraphX(self, x): "Calculate position on graph from point on canvas" return x * (self.xMax - self.xMin) / self.Zoom / self.CanvasWidth + self.xMin / self.Zoom def GraphY(self, y): return self.yMax / self.Zoom - (y * (self.yMax * self.Zoom - self.yMin / self.Zoom) / self.CanvasHeight) def ConnectWindow(self, WorkbenchWindow): "make widget appear in WorkbenchWindow" self.WorkbenchWindow = WorkbenchWindow self.WorkbenchWindow.Connect(self.GtkWidget) self.GtkWidget.show_all() def Save(self, Widget, Event=None): "Save graph as .png" FileDialog = gtk.FileChooserDialog("Save as..", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) FileDialog.set_default_response(gtk.RESPONSE_OK) Filter = gtk.FileFilter() Filter.add_mime_type("image/png") Filter.add_pattern("*.png") FileDialog.add_filter(Filter) FileDialog.set_filename("FunctionGraph.png") Response = FileDialog.run() FileDialog.destroy() if Response == gtk.RESPONSE_OK: x, y, w, h = self.DrawingArea.get_allocation() PixBuffer = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h) PixBuffer.get_from_drawable(self.PixMap, self.PixMap.get_colormap(), 0, 0, 0, 0, w, h) PixBuffer.save(FileDialog.get_filename(), "png") lybniz-1.3.2/extras/README0000644000175000017500000000012710730464223013335 0ustar samsamThese file were included in the 1.0 release. These have not been modifided since then. lybniz-1.3.2/extras/lybniz-maemo_py0000644000175000017500000004054010730464223015516 0ustar samsam#!/var/lib/install/usr/bin/python2.4 # -*- coding: UTF-8 -*- """ Simple Function Graph Plotter Maemo version © Thomas Führinger, 2005-02-12 www.fuhringer.com/thomas Code contributions by Sam Tygier - thanks! Version 0.9.0 Requires PyGtk 2.6 Released under the terms of the revised BSD license Modified: 2006-02-26 """ import gtk, math, sys, hildon App = None Actions = gtk.ActionGroup("General") Graph = None ConnectPoints = True xMax = "5.0" xMin = "-5.0" xScale = "1.0" yMax = "3.0" yMin = "-3.0" yScale = "1.0" y1 = "" y2 = "" y3 = "" class GraphClass: def __init__(self): # Create backing pixmap of the appropriate size def ConfigureEvent(Widget, Event): x, y, w, h = Widget.get_allocation() self.PixMap = gtk.gdk.Pixmap(Widget.window, w, h) self.CanvasWidth = w self.CanvasHeight = h self.xMax = eval(xMax) self.xMin = eval(xMin) self.xScale = eval(xScale) self.yMax = eval(yMax) self.yMin = eval(yMin) self.yScale = eval(yScale) self.Plot() return True # Redraw the screen from the backing pixmap def ExposeEvent(Widget, Event): x, y, w, h = Event.area Widget.window.draw_drawable(Widget.get_style().fg_gc[gtk.STATE_NORMAL], self.PixMap, x, y, x, y, w, h) return False # Start marking selection def ButtonPressEvent(Widget, Event): global xSel, ySel if Event.button == 1: self.Selection[0][0], self.Selection[0][1] = int(Event.x), int(Event.y) self.Selection[1][0], self.Selection[1][1] = None, None # End of selection def ButtonReleaseEvent(Widget, Event): if Event.button == 1 and Event.x != self.Selection[0][0] and Event.y != self.Selection[0][1]: xmi, ymi = min(self.GraphX(self.Selection[0][0]), self.GraphX(Event.x)), min(self.GraphY(self.Selection[0][1]), self.GraphY(Event.y)) xma, yma = max(self.GraphX(self.Selection[0][0]), self.GraphX(Event.x)), max(self.GraphY(self.Selection[0][1]), self.GraphY(Event.y)) self.xMin, self.yMin, self.xMax, self.yMax = xmi, ymi, xma, yma ParameterEntriesRepopulate() Graph.Plot() self.Selection[1][0] = None self.Selection[0][0] = None # Draw rectangle during mouse movement def MotionNotifyEvent(Widget, Event): if Event.is_hint: x, y, State = Event.window.get_pointer() else: x = Event.x y = Event.y State = Event.state if State & gtk.gdk.BUTTON1_MASK and self.Selection[0][0] is not None: gc = self.DrawingArea.get_style().black_gc gc.set_function(gtk.gdk.INVERT) if self.Selection[1][0] is not None: x0 = min(self.Selection[1][0], self.Selection[0][0]) y0 = min(self.Selection[1][1], self.Selection[0][1]) w = abs(self.Selection[1][0] - self.Selection[0][0]) h = abs(self.Selection[1][1] - self.Selection[0][1]) self.PixMap.draw_rectangle(gc, False, x0, y0, w, h) x0 = min(self.Selection[0][0], int(x)) y0 = min(self.Selection[0][1], int(y)) w = abs(int(x) - self.Selection[0][0]) h = abs(int(y) - self.Selection[0][1]) self.PixMap.draw_rectangle(gc, False, x0, y0, w, h) self.Selection[1][0], self.Selection[1][1] = int(x), int(y) self.DrawDrawable() self.PrevY = [None, None, None] # Marked area point[0, 1][x, y] self.Selection = [[None, None], [None, None]] self.DrawingArea = gtk.DrawingArea() self.DrawingArea.connect("expose_event", ExposeEvent) self.DrawingArea.connect("configure_event", ConfigureEvent) self.DrawingArea.connect("button_press_event", ButtonPressEvent) self.DrawingArea.connect("button_release_event", ButtonReleaseEvent) self.DrawingArea.connect("motion_notify_event", MotionNotifyEvent) self.DrawingArea.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.LEAVE_NOTIFY_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK |gtk.gdk.POINTER_MOTION_HINT_MASK) def DrawDrawable(self): x, y, w, h = self.DrawingArea.get_allocation() self.DrawingArea.window.draw_drawable(self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL], self.PixMap, 0, 0, 0, 0, w, h) def Plot(self): self.PixMap.draw_rectangle(self.DrawingArea.get_style().white_gc, True, 0, 0, self.CanvasWidth, self.CanvasHeight) # draw cross self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [self.CanvasPoint(0, self.yMin), self.CanvasPoint(0, self.yMax)]) self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [self.CanvasPoint(self.xMin, 0), self.CanvasPoint(self.xMax, 0)]) # draw scaling x iv = int(self.xScale * self.CanvasWidth/(self.xMax - self.xMin)) os = self.CanvasX(0) % iv for i in xrange(self.CanvasWidth / iv + 1): self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [(os + i * iv, self.CanvasY(0) - 5), (os + i * iv, self.CanvasY(0) + 5)]) # draw scaling y iv = int(self.yScale * self.CanvasHeight/(self.yMax - self.yMin)) os = self.CanvasY(0) % iv for i in xrange(self.CanvasHeight / iv + 1): self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [(self.CanvasX(0) - 5, i * iv + os), (self.CanvasX(0) + 5, i * iv + os)]) # plot # (coloring of lines does not work yet) GC1 = self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL] GC1.foreground = gtk.gdk.color_parse("blue") GC2 = self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL] GC2.foreground = gtk.gdk.color_parse("red") GC3 = self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL] GC3.foreground = gtk.gdk.color_parse("DarkGreen") self.PrevY = [None, None, None] for i in xrange(self.CanvasWidth): x = self.GraphX(i + 1) for e in ((y1, 0, GC1), (y2, 1, GC2), (y3, 2, GC3)): try: y = eval(e[0]) yC = self.CanvasY(y) if yC < 0 or yC > self.CanvasHeight: raise ValueError if ConnectPoints and self.PrevY[e[1]] is not None: self.PixMap.draw_lines(e[2], [(i, self.PrevY[e[1]]), (i + 1, yC)]) else: self.PixMap.draw_points(e[2], [(i + 1, yC)]) self.PrevY[e[1]] = yC except: #print "Error at %d: %s" % (x, sys.exc_value) self.PrevY[e[1]] = None self.DrawDrawable() def CanvasX(self, x): "Calculate position on canvas to point on graph" return int((x - self.xMin) * self.CanvasWidth/(self.xMax - self.xMin)) def CanvasY(self, y): return int((self.yMax - y) * self.CanvasHeight/(self.yMax - self.yMin)) def CanvasPoint(self, x, y): return (self.CanvasX(x), self.CanvasY(y)) def GraphX(self, x): "Calculate position on graph from point on canvas" return x * (self.xMax - self.xMin) / self.CanvasWidth + self.xMin def GraphY(self, y): return self.yMax - (y * (self.yMax - self.yMin) / self.CanvasHeight) def MenuToolbarCreate(): MenuMain = hildon.AppView.get_menu(App.View) Actions.Plot = gtk.Action("Plot", "P_lot", "Plot Functions", gtk.STOCK_REFRESH) Actions.Plot.connect ("activate", Plot) Actions.add_action(Actions.Plot) MenuItemPlot = Actions.Plot.create_menu_item() MenuMain.append(MenuItemPlot) Actions.Evaluate = gtk.Action("Evaluate", "_Evaluate", "Evaluate Functions", gtk.STOCK_EXECUTE) Actions.Evaluate.connect ("activate", Evaluate) Actions.add_action(Actions.Evaluate) MenuItemEvaluate = Actions.Evaluate.create_menu_item() MenuMain.append(MenuItemEvaluate) Actions.ZoomIn = gtk.Action("ZoomIn", "Zoom _In", "Zoom In", gtk.STOCK_ZOOM_IN) Actions.ZoomIn.connect ("activate", ZoomIn) Actions.add_action(Actions.ZoomIn) MenuItemZoomIn = Actions.ZoomIn.create_menu_item() MenuMain.append(MenuItemZoomIn) Actions.ZoomOut = gtk.Action("ZoomOut", "Zoom _Out", "Zoom Out", gtk.STOCK_ZOOM_OUT) Actions.ZoomOut.connect ("activate", ZoomOut) Actions.add_action(Actions.ZoomOut) MenuItemZoomOut = Actions.ZoomOut.create_menu_item() MenuMain.append(MenuItemZoomOut) Actions.ZoomReset = gtk.Action("ZoomReset", "Zoom _Reset", "Zoom Reset", gtk.STOCK_ZOOM_100) Actions.ZoomReset.connect ("activate", ZoomReset) Actions.add_action(Actions.ZoomReset) MenuItemZoomReset = Actions.ZoomReset.create_menu_item() MenuMain.append(MenuItemZoomReset) MenuItemToggleConnect = gtk.CheckMenuItem("_Connect Points") MenuItemToggleConnect.set_active(True) MenuItemToggleConnect.connect ("toggled", ToggleConnect) MenuMain.append(MenuItemToggleConnect) Actions.About = gtk.Action("About", "_About", "About Box", gtk.STOCK_ABOUT) Actions.About.connect ("activate", ShowAboutDialog) Actions.add_action(Actions.About) MenuItemAbout = Actions.About.create_menu_item() MenuMain.append(MenuItemAbout) ToolBar = gtk.Toolbar() ToolBar.insert(Actions.Plot.create_tool_item(), -1) ToolBar.insert(Actions.Evaluate.create_tool_item(), -1) ToolBar.insert(gtk.SeparatorToolItem(), -1) ToolBar.insert(Actions.ZoomIn.create_tool_item(), -1) ToolBar.insert(Actions.ZoomOut.create_tool_item(), -1) ToolBar.insert(Actions.ZoomReset.create_tool_item(), -1) #App.View.set_toolbar(ToolBar) gtk.Widget.show_all(MenuMain) gtk.Widget.show_all(ToolBar) def Plot(Widget, Event=None): global xMax, xMin, xScale, yMax, yMin, yScale, y1, y2, y3 xMax = App.xMaxEntry.get_text() xMin = App.xMinEntry.get_text() xScale = App.xScaleEntry.get_text() yMax = App.yMaxEntry.get_text() yMin = App.yMinEntry.get_text() yScale = App.yScaleEntry.get_text() Graph.xMax = eval(xMax) Graph.xMin = eval(xMin) Graph.xScale = eval(xScale) Graph.yMax = eval(yMax) Graph.yMin = eval(yMin) Graph.yScale = eval(yScale) y1 = App.Y1Entry.get_text() y2 = App.Y2Entry.get_text() y3 = App.Y3Entry.get_text() Graph.Plot() def Evaluate(Widget, Event=None): "Evaluate a given x for the three functions" def EntryChanged(self): for e in ((y1, DlgWin.Y1Entry), (y2, DlgWin.Y2Entry), (y3, DlgWin.Y3Entry)): try: x = float(DlgWin.XEntry.get_text()) e[1].set_text(str(eval(e[0]))) except: if len(e[0]) > 0: e[1].set_text("Error: %s" % sys.exc_value) else: e[1].set_text("") def Close(self): DlgWin.destroy() DlgWin = gtk.Window(gtk.WINDOW_TOPLEVEL) DlgWin.set_title("Evaluate") DlgWin.connect("destroy", Close) DlgWin.XEntry = gtk.Entry() DlgWin.XEntry.set_size_request(200, 24) DlgWin.XEntry.connect("changed", EntryChanged) DlgWin.Y1Entry = gtk.Entry() DlgWin.Y1Entry.set_size_request(200, 24) DlgWin.Y1Entry.set_sensitive(False) DlgWin.Y2Entry = gtk.Entry() DlgWin.Y2Entry.set_size_request(200, 24) DlgWin.Y2Entry.set_sensitive(False) DlgWin.Y3Entry = gtk.Entry() DlgWin.Y3Entry.set_size_request(200, 24) DlgWin.Y3Entry.set_sensitive(False) Table = gtk.Table(2, 5) l = gtk.Label("x = ") l.set_alignment(0, .5) Table.attach(l, 0, 1, 0, 1, xpadding=1, ypadding=1, xoptions=gtk.FILL) Table.attach(DlgWin.XEntry, 1, 2, 0, 1) l = gtk.Label("y1 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("blue")) Table.attach(l, 0, 1, 1, 2, xpadding=1, ypadding=1, xoptions=gtk.FILL) Table.attach(DlgWin.Y1Entry, 1, 2, 1, 2) l = gtk.Label("y2 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red")) Table.attach(l, 0, 1, 2, 3, xpadding=1, ypadding=1, xoptions=gtk.FILL) Table.attach(DlgWin.Y2Entry, 1, 2, 2, 3) l = gtk.Label("y3 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("DarkGreen")) Table.attach(l, 0, 1, 3, 4, xpadding=1, ypadding=1, xoptions=gtk.FILL) Table.attach(DlgWin.Y3Entry, 1, 2, 3, 4) Table.set_border_width(2) DlgWin.add(Table) DlgWin.show_all() def ZoomIn(Widget, Event=None): "Narrow the plotted section by half" Graph.xMin /= 2 Graph.yMin /= 2 Graph.xMax /= 2 Graph.yMax /= 2 ParameterEntriesRepopulate() Graph.Plot() def ZoomOut(Widget, Event=None): "Double the plotted section" Graph.xMin *= 2 Graph.yMin *= 2 Graph.xMax *= 2 Graph.yMax *= 2 ParameterEntriesRepopulate() Graph.Plot() def ZoomReset(Widget, Event=None): "Set the range back to the user's input" Graph.xMin = eval(xMin) Graph.yMin = eval(yMin) Graph.xMax = eval(xMax) Graph.yMax = eval(yMax) ParameterEntriesPopulate() Graph.Plot() def ToggleConnect(Widget, Event=None): "Toggle between a graph that connects points with lines and one that does not" global ConnectPoints ConnectPoints = not ConnectPoints Graph.Plot() def ShowAboutDialog(Widget): AboutDialog = gtk.AboutDialog() AboutDialog.set_name("Lybniz") AboutDialog.set_version("0.9.0") #AboutDialog.set_copyright(u"© 2005 by Thomas Führinger") AboutDialog.set_authors([u"Thomas Führinger"]) AboutDialog.set_comments("Function Graph Plotter") AboutDialog.set_license("Revised BSD") #AboutDialog.set_website("http://www.fuhringer.com/thomas/lybniz") AboutDialog.show() def ParameterEntriesCreate(): # create text entries for parameters Table = gtk.Table(6, 3) App.Y1Entry = gtk.Entry() App.Y1Entry.set_size_request(300, 24) App.Y2Entry = gtk.Entry() App.Y3Entry = gtk.Entry() App.xMinEntry = gtk.Entry() App.xMinEntry.set_size_request(90, 24) App.xMinEntry.set_alignment(1) App.xMaxEntry = gtk.Entry() App.xMaxEntry.set_size_request(90, 24) App.xMaxEntry.set_alignment(1) App.xScaleEntry = gtk.Entry() App.xScaleEntry.set_size_request(90, 24) App.xScaleEntry.set_alignment(1) App.yMinEntry = gtk.Entry() App.yMinEntry.set_size_request(90, 24) App.yMinEntry.set_alignment(1) App.yMaxEntry = gtk.Entry() App.yMaxEntry.set_size_request(90, 24) App.yMaxEntry.set_alignment(1) App.yScaleEntry = gtk.Entry() App.yScaleEntry.set_size_request(90, 24) App.yScaleEntry.set_alignment(1) ParameterEntriesPopulate() l = gtk.Label("y1 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("blue")) Table.attach(l, 0, 1, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(App.Y1Entry, 1, 2, 0, 1) l = gtk.Label("xMin") l.set_alignment(1, .5) Table.attach(l, 2, 3, 0, 1, xpadding=5, ypadding=7, xoptions=gtk.FILL) Table.attach(App.xMinEntry, 3, 4, 0, 1, xoptions=gtk.FILL) l = gtk.Label("yMin") l.set_alignment(1, .5) Table.attach(l, 4, 5, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(App.yMinEntry, 5, 6, 0, 1, xpadding=5, xoptions=gtk.FILL) l = gtk.Label("y2 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red")) Table.attach(l, 0, 1, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(App.Y2Entry, 1, 2, 1, 2) l = gtk.Label("xMax") l.set_alignment(1, .5) Table.attach(l, 2, 3, 1, 2, xpadding=5, ypadding=7, xoptions=gtk.FILL) Table.attach(App.xMaxEntry, 3, 4, 1, 2, xoptions=gtk.FILL) l = gtk.Label("yMax") l.set_alignment(1, .5) Table.attach(l, 4, 5, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(App.yMaxEntry, 5, 6, 1, 2, xpadding=5, xoptions=gtk.FILL) l = gtk.Label("y3 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("DarkGreen")) Table.attach(l, 0, 1, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(App.Y3Entry, 1, 2, 2, 3) l = gtk.Label("xScale") l.set_alignment(0, .5) Table.attach(l, 2, 3, 2, 3, xpadding=5, ypadding=7, xoptions=gtk.FILL) Table.attach(App.xScaleEntry, 3, 4, 2, 3, xoptions=gtk.FILL) l = gtk.Label("yScale") l.set_alignment(0, .5) Table.attach(l, 4, 5, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(App.yScaleEntry, 5, 6, 2, 3, xpadding=5, xoptions=gtk.FILL) return Table def ParameterEntriesPopulate(): # set text in entries for parameters with user's input App.Y1Entry.set_text(y1) App.Y2Entry.set_text(y2) App.Y3Entry.set_text(y3) App.xMinEntry.set_text(xMin) App.xMaxEntry.set_text(xMax) App.xScaleEntry.set_text(xScale) App.yMinEntry.set_text(yMin) App.yMaxEntry.set_text(yMax) App.yScaleEntry.set_text(yScale) def ParameterEntriesRepopulate(): # set text in entries for parameters App.Y1Entry.set_text(y1) App.Y2Entry.set_text(y2) App.Y3Entry.set_text(y3) App.xMinEntry.set_text(str(Graph.xMin)) App.xMaxEntry.set_text(str(Graph.xMax)) App.xScaleEntry.set_text(str(Graph.xScale)) App.yMinEntry.set_text(str(Graph.yMin)) App.yMaxEntry.set_text(str(Graph.yMax)) App.yScaleEntry.set_text(str(Graph.yScale)) class Lybniz: def __init__(self): global App, Graph App = hildon.App() App.View = hildon.AppView("Lybniz") App.set_title("Lybniz") App.set_two_part_title(False) App.set_appview(App.View) MenuToolbarCreate() App.View.connect("destroy", self.destroy) App.VBox = gtk.VBox(False, 1) App.VBox.set_border_width(1) gtk.Container.add(App.View, App.VBox) App.VBox.pack_start(ParameterEntriesCreate(), False, True, 4) Graph = GraphClass() App.VBox.pack_start(Graph.DrawingArea, True, True, 0) App.VBox.show_all() App.show() gtk.main() def destroy(self, widget, data=None): gtk.main_quit() # Start it all if __name__ == "__main__": l = Lybniz() lybniz-1.3.2/extras/lybniz.py0000755000175000017500000004727610730464223014361 0ustar samsam#!/usr/bin/env python # -*- coding: UTF-8 -*- """ Simple Function Graph Plotter © Thomas Führinger, 2005-02-12 www.fuhringer.com/thomas Code contributions by Sam Tygier - thanks! Version 1.0 Requires PyGtk 2.6 Released under the terms of the revised BSD license Modified: 2005-10-30 """ import gtk, math, sys AppWin = None Actions = gtk.ActionGroup("General") Graph = None ConnectPoints = True xMax = "5.0" xMin = "-5.0" xScale = "1.0" yMax = "3.0" yMin = "-3.0" yScale = "1.0" y1 = "" y2 = "" y3 = "" class GraphClass: def __init__(self): # Create backing pixmap of the appropriate size def ConfigureEvent(Widget, Event): x, y, w, h = Widget.get_allocation() self.PixMap = gtk.gdk.Pixmap(Widget.window, w, h) self.CanvasWidth = w self.CanvasHeight = h self.xMax = eval(xMax) self.xMin = eval(xMin) self.xScale = eval(xScale) self.yMax = eval(yMax) self.yMin = eval(yMin) self.yScale = eval(yScale) self.Plot() return True # Redraw the screen from the backing pixmap def ExposeEvent(Widget, Event): x, y, w, h = Event.area Widget.window.draw_drawable(Widget.get_style().fg_gc[gtk.STATE_NORMAL], self.PixMap, x, y, x, y, w, h) return False # Start marking selection def ButtonPressEvent(Widget, Event): global xSel, ySel if Event.button == 1: self.Selection[0][0], self.Selection[0][1] = int(Event.x), int(Event.y) self.Selection[1][0], self.Selection[1][1] = None, None # End of selection def ButtonReleaseEvent(Widget, Event): if Event.button == 1 and Event.x != self.Selection[0][0] and Event.y != self.Selection[0][1]: xmi, ymi = min(self.GraphX(self.Selection[0][0]), self.GraphX(Event.x)), min(self.GraphY(self.Selection[0][1]), self.GraphY(Event.y)) xma, yma = max(self.GraphX(self.Selection[0][0]), self.GraphX(Event.x)), max(self.GraphY(self.Selection[0][1]), self.GraphY(Event.y)) self.xMin, self.yMin, self.xMax, self.yMax = xmi, ymi, xma, yma ParameterEntriesRepopulate() Graph.Plot() self.Selection[1][0] = None self.Selection[0][0] = None # Draw rectangle during mouse movement def MotionNotifyEvent(Widget, Event): if Event.is_hint: x, y, State = Event.window.get_pointer() else: x = Event.x y = Event.y State = Event.state if State & gtk.gdk.BUTTON1_MASK and self.Selection[0][0] is not None: gc = self.DrawingArea.get_style().black_gc gc.set_function(gtk.gdk.INVERT) if self.Selection[1][0] is not None: x0 = min(self.Selection[1][0], self.Selection[0][0]) y0 = min(self.Selection[1][1], self.Selection[0][1]) w = abs(self.Selection[1][0] - self.Selection[0][0]) h = abs(self.Selection[1][1] - self.Selection[0][1]) self.PixMap.draw_rectangle(gc, False, x0, y0, w, h) x0 = min(self.Selection[0][0], int(x)) y0 = min(self.Selection[0][1], int(y)) w = abs(int(x) - self.Selection[0][0]) h = abs(int(y) - self.Selection[0][1]) self.PixMap.draw_rectangle(gc, False, x0, y0, w, h) self.Selection[1][0], self.Selection[1][1] = int(x), int(y) self.DrawDrawable() self.PrevY = [None, None, None] # Marked area point[0, 1][x, y] self.Selection = [[None, None], [None, None]] self.DrawingArea = gtk.DrawingArea() self.DrawingArea.connect("expose_event", ExposeEvent) self.DrawingArea.connect("configure_event", ConfigureEvent) self.DrawingArea.connect("button_press_event", ButtonPressEvent) self.DrawingArea.connect("button_release_event", ButtonReleaseEvent) self.DrawingArea.connect("motion_notify_event", MotionNotifyEvent) self.DrawingArea.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.LEAVE_NOTIFY_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK |gtk.gdk.POINTER_MOTION_HINT_MASK) def DrawDrawable(self): x, y, w, h = self.DrawingArea.get_allocation() self.DrawingArea.window.draw_drawable(self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL], self.PixMap, 0, 0, 0, 0, w, h) def Plot(self): self.PixMap.draw_rectangle(self.DrawingArea.get_style().white_gc, True, 0, 0, self.CanvasWidth, self.CanvasHeight) # draw cross self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [self.CanvasPoint(0, self.yMin), self.CanvasPoint(0, self.yMax)]) self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [self.CanvasPoint(self.xMin, 0), self.CanvasPoint(self.xMax, 0)]) # draw scaling x iv = int(self.xScale * self.CanvasWidth/(self.xMax - self.xMin)) os = self.CanvasX(0) % iv for i in xrange(self.CanvasWidth / iv + 1): self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [(os + i * iv, self.CanvasY(0) - 5), (os + i * iv, self.CanvasY(0) + 5)]) # draw scaling y iv = int(self.yScale * self.CanvasHeight/(self.yMax - self.yMin)) os = self.CanvasY(0) % iv for i in xrange(self.CanvasHeight / iv + 1): self.PixMap.draw_lines(self.DrawingArea.get_style().black_gc, [(self.CanvasX(0) - 5, i * iv + os), (self.CanvasX(0) + 5, i * iv + os)]) # plot # (coloring of lines does not work yet) GC1 = self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL] GC1.foreground = gtk.gdk.color_parse("blue") GC2 = self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL] GC2.foreground = gtk.gdk.color_parse("red") GC3 = self.DrawingArea.get_style().fg_gc[gtk.STATE_NORMAL] GC3.foreground = gtk.gdk.color_parse("DarkGreen") self.PrevY = [None, None, None] for i in xrange(self.CanvasWidth): x = self.GraphX(i + 1) for e in ((y1, 0, GC1), (y2, 1, GC2), (y3, 2, GC3)): try: y = eval(e[0]) yC = self.CanvasY(y) if yC < 0 or yC > self.CanvasHeight: raise ValueError if ConnectPoints and self.PrevY[e[1]] is not None: self.PixMap.draw_lines(e[2], [(i, self.PrevY[e[1]]), (i + 1, yC)]) else: self.PixMap.draw_points(e[2], [(i + 1, yC)]) self.PrevY[e[1]] = yC except: #print "Error at %d: %s" % (x, sys.exc_value) self.PrevY[e[1]] = None self.DrawDrawable() def CanvasX(self, x): "Calculate position on canvas to point on graph" return int((x - self.xMin) * self.CanvasWidth/(self.xMax - self.xMin)) def CanvasY(self, y): return int((self.yMax - y) * self.CanvasHeight/(self.yMax - self.yMin)) def CanvasPoint(self, x, y): return (self.CanvasX(x), self.CanvasY(y)) def GraphX(self, x): "Calculate position on graph from point on canvas" return x * (self.xMax - self.xMin) / self.CanvasWidth + self.xMin def GraphY(self, y): return self.yMax - (y * (self.yMax - self.yMin) / self.CanvasHeight) def MenuToolbarCreate(): AppWin.MenuMain = gtk.MenuBar() MenuFile = gtk.Menu() MenuItemFile = gtk.MenuItem("_File") MenuItemFile.set_submenu(MenuFile) Actions.Save = gtk.Action("Save", "_Save", "Save graph as bitmap", gtk.STOCK_SAVE) Actions.Save.connect ("activate", Save) Actions.add_action(Actions.Save) MenuItemSave = Actions.Save.create_menu_item() MenuItemSave.add_accelerator("activate", AppWin.AccelGroup, ord("S"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) MenuFile.append(MenuItemSave) Actions.Quit = gtk.Action("Quit", "_Quit", "Quit Application", gtk.STOCK_QUIT) Actions.Quit.connect ("activate", QuitDlg) Actions.add_action(Actions.Quit) MenuItemQuit = Actions.Quit.create_menu_item() MenuItemQuit.add_accelerator("activate", AppWin.AccelGroup, ord("Q"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) MenuFile.append(MenuItemQuit) MenuGraph = gtk.Menu() MenuItemGraph = gtk.MenuItem("_Graph") MenuItemGraph.set_submenu(MenuGraph) Actions.Plot = gtk.Action("Plot", "P_lot", "Plot Functions", gtk.STOCK_REFRESH) Actions.Plot.connect ("activate", Plot) Actions.add_action(Actions.Plot) MenuItemPlot = Actions.Plot.create_menu_item() MenuItemPlot.add_accelerator("activate", AppWin.AccelGroup, ord("l"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) MenuGraph.append(MenuItemPlot) Actions.Evaluate = gtk.Action("Evaluate", "_Evaluate", "Evaluate Functions", gtk.STOCK_EXECUTE) Actions.Evaluate.connect ("activate", Evaluate) Actions.add_action(Actions.Evaluate) MenuItemEvaluate = Actions.Evaluate.create_menu_item() MenuItemEvaluate.add_accelerator("activate", AppWin.AccelGroup, ord("e"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) MenuGraph.append(MenuItemEvaluate) Actions.ZoomIn = gtk.Action("ZoomIn", "Zoom _In", "Zoom In", gtk.STOCK_ZOOM_IN) Actions.ZoomIn.connect ("activate", ZoomIn) Actions.add_action(Actions.ZoomIn) MenuItemZoomIn = Actions.ZoomIn.create_menu_item() MenuItemZoomIn.add_accelerator("activate", AppWin.AccelGroup, ord("+"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) MenuGraph.append(MenuItemZoomIn) Actions.ZoomOut = gtk.Action("ZoomOut", "Zoom _Out", "Zoom Out", gtk.STOCK_ZOOM_OUT) Actions.ZoomOut.connect ("activate", ZoomOut) Actions.add_action(Actions.ZoomOut) MenuItemZoomOut = Actions.ZoomOut.create_menu_item() MenuItemZoomOut.add_accelerator("activate", AppWin.AccelGroup, ord("-"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) MenuGraph.append(MenuItemZoomOut) Actions.ZoomReset = gtk.Action("ZoomReset", "Zoom _Reset", "Zoom Reset", gtk.STOCK_ZOOM_100) Actions.ZoomReset.connect ("activate", ZoomReset) Actions.add_action(Actions.ZoomReset) MenuItemZoomReset = Actions.ZoomReset.create_menu_item() MenuItemZoomReset.add_accelerator("activate", AppWin.AccelGroup, ord("r"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) MenuGraph.append(MenuItemZoomReset) MenuItemToggleConnect = gtk.CheckMenuItem("_Connect Points") MenuItemToggleConnect.set_active(True) MenuItemToggleConnect.connect ("toggled", ToggleConnect) MenuGraph.append(MenuItemToggleConnect) MenuHelp = gtk.Menu() MenuItemHelp = gtk.MenuItem("_Help") MenuItemHelp.set_submenu(MenuHelp) Actions.Help = gtk.Action("Help", "_Contents", "Help Contents", gtk.STOCK_HELP) Actions.Help.connect ("activate", ShowYelp) Actions.add_action(Actions.Help) MenuItemContents = Actions.Help.create_menu_item() MenuItemContents.add_accelerator("activate", AppWin.AccelGroup, gtk.gdk.keyval_from_name("F1"), 0, gtk.ACCEL_VISIBLE) MenuHelp.append(MenuItemContents) Actions.About = gtk.Action("About", "_About", "About Box", gtk.STOCK_ABOUT) Actions.About.connect ("activate", ShowAboutDialog) Actions.add_action(Actions.About) MenuItemAbout = Actions.About.create_menu_item() MenuHelp.append(MenuItemAbout) AppWin.MenuMain.append(MenuItemFile) AppWin.MenuMain.append(MenuItemGraph) AppWin.MenuMain.append(MenuItemHelp) AppWin.ToolBar = gtk.Toolbar() AppWin.ToolBar.insert(Actions.Plot.create_tool_item(), -1) AppWin.ToolBar.insert(Actions.Evaluate.create_tool_item(), -1) AppWin.ToolBar.insert(gtk.SeparatorToolItem(), -1) AppWin.ToolBar.insert(Actions.ZoomIn.create_tool_item(), -1) AppWin.ToolBar.insert(Actions.ZoomOut.create_tool_item(), -1) AppWin.ToolBar.insert(Actions.ZoomReset.create_tool_item(), -1) AppWin.ToolBar.insert(gtk.SeparatorToolItem(), -1) AppWin.ToolBar.insert(Actions.Quit.create_tool_item(), -1) def Plot(Widget, Event=None): global xMax, xMin, xScale, yMax, yMin, yScale, y1, y2, y3 xMax = AppWin.xMaxEntry.get_text() xMin = AppWin.xMinEntry.get_text() xScale = AppWin.xScaleEntry.get_text() yMax = AppWin.yMaxEntry.get_text() yMin = AppWin.yMinEntry.get_text() yScale = AppWin.yScaleEntry.get_text() Graph.xMax = eval(xMax) Graph.xMin = eval(xMin) Graph.xScale = eval(xScale) Graph.yMax = eval(yMax) Graph.yMin = eval(yMin) Graph.yScale = eval(yScale) y1 = AppWin.Y1Entry.get_text() y2 = AppWin.Y2Entry.get_text() y3 = AppWin.Y3Entry.get_text() Graph.Plot() def Evaluate(Widget, Event=None): "Evaluate a given x for the three functions" def EntryChanged(self): for e in ((y1, DlgWin.Y1Entry), (y2, DlgWin.Y2Entry), (y3, DlgWin.Y3Entry)): try: x = float(DlgWin.XEntry.get_text()) e[1].set_text(str(eval(e[0]))) except: if len(e[0]) > 0: e[1].set_text("Error: %s" % sys.exc_value) else: e[1].set_text("") def Close(self): DlgWin.destroy() DlgWin = gtk.Window(gtk.WINDOW_TOPLEVEL) DlgWin.set_title("Evaluate") DlgWin.connect("destroy", Close) DlgWin.XEntry = gtk.Entry() DlgWin.XEntry.set_size_request(200, 24) DlgWin.XEntry.connect("changed", EntryChanged) DlgWin.Y1Entry = gtk.Entry() DlgWin.Y1Entry.set_size_request(200, 24) DlgWin.Y1Entry.set_sensitive(False) DlgWin.Y2Entry = gtk.Entry() DlgWin.Y2Entry.set_size_request(200, 24) DlgWin.Y2Entry.set_sensitive(False) DlgWin.Y3Entry = gtk.Entry() DlgWin.Y3Entry.set_size_request(200, 24) DlgWin.Y3Entry.set_sensitive(False) Table = gtk.Table(2, 5) l = gtk.Label("x = ") l.set_alignment(0, .5) Table.attach(l, 0, 1, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(DlgWin.XEntry, 1, 2, 0, 1) l = gtk.Label("y1 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("blue")) Table.attach(l, 0, 1, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(DlgWin.Y1Entry, 1, 2, 1, 2) l = gtk.Label("y2 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red")) Table.attach(l, 0, 1, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(DlgWin.Y2Entry, 1, 2, 2, 3) l = gtk.Label("y3 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("DarkGreen")) Table.attach(l, 0, 1, 3, 4, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(DlgWin.Y3Entry, 1, 2, 3, 4) Table.set_border_width(24) DlgWin.add(Table) DlgWin.show_all() def ZoomIn(Widget, Event=None): "Narrow the plotted section by half" Graph.xMin /= 2 Graph.yMin /= 2 Graph.xMax /= 2 Graph.yMax /= 2 ParameterEntriesRepopulate() Graph.Plot() def ZoomOut(Widget, Event=None): "Double the plotted section" Graph.xMin *= 2 Graph.yMin *= 2 Graph.xMax *= 2 Graph.yMax *= 2 ParameterEntriesRepopulate() Graph.Plot() def ZoomReset(Widget, Event=None): "Set the range back to the user's input" Graph.xMin = eval(xMin) Graph.yMin = eval(yMin) Graph.xMax = eval(xMax) Graph.yMax = eval(yMax) ParameterEntriesPopulate() Graph.Plot() def ToggleConnect(Widget, Event=None): "Toggle between a graph that connects points with lines and one that does not" global ConnectPoints ConnectPoints = not ConnectPoints Graph.Plot() def Save(Widget, Event=None): "Save graph as .png" FileDialog = gtk.FileChooserDialog("Save as..", AppWin, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) FileDialog.set_default_response(gtk.RESPONSE_OK) Filter = gtk.FileFilter() Filter.add_mime_type("image/png") Filter.add_pattern("*.png") FileDialog.add_filter(Filter) FileDialog.set_filename("FunctionGraph.png") Response = FileDialog.run() FileDialog.destroy() if Response == gtk.RESPONSE_OK: x, y, w, h = Graph.DrawingArea.get_allocation() PixBuffer = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h) PixBuffer.get_from_drawable(Graph.PixMap, Graph.PixMap.get_colormap(), 0, 0, 0, 0, w, h) PixBuffer.save(FileDialog.get_filename(), "png") def QuitDlg(Widget, Event=None): gtk.main_quit() def ShowYelp(Widget): import os os.system("yelp lybniz-manual.xml") def ShowAboutDialog(Widget): AboutDialog = gtk.AboutDialog() AboutDialog.set_name("Lybniz") AboutDialog.set_version("1.0") #AboutDialog.set_copyright(u"© 2005 by Thomas Führinger") AboutDialog.set_authors([u"Thomas Führinger"]) AboutDialog.set_comments("Function Graph Plotter") AboutDialog.set_license("Revised BSD") #AboutDialog.set_website("http://www.fuhringer.com/thomas/lybniz") AboutDialog.show() def ParameterEntriesCreate(): # create text entries for parameters Table = gtk.Table(6, 3) AppWin.Y1Entry = gtk.Entry() AppWin.Y1Entry.set_size_request(300, 24) AppWin.Y2Entry = gtk.Entry() AppWin.Y3Entry = gtk.Entry() AppWin.xMinEntry = gtk.Entry() AppWin.xMinEntry.set_size_request(90, 24) AppWin.xMinEntry.set_alignment(1) AppWin.xMaxEntry = gtk.Entry() AppWin.xMaxEntry.set_size_request(90, 24) AppWin.xMaxEntry.set_alignment(1) AppWin.xScaleEntry = gtk.Entry() AppWin.xScaleEntry.set_size_request(90, 24) AppWin.xScaleEntry.set_alignment(1) AppWin.yMinEntry = gtk.Entry() AppWin.yMinEntry.set_size_request(90, 24) AppWin.yMinEntry.set_alignment(1) AppWin.yMaxEntry = gtk.Entry() AppWin.yMaxEntry.set_size_request(90, 24) AppWin.yMaxEntry.set_alignment(1) AppWin.yScaleEntry = gtk.Entry() AppWin.yScaleEntry.set_size_request(90, 24) AppWin.yScaleEntry.set_alignment(1) ParameterEntriesPopulate() l = gtk.Label("y1 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("blue")) Table.attach(l, 0, 1, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(AppWin.Y1Entry, 1, 2, 0, 1) l = gtk.Label("xMin") l.set_alignment(1, .5) Table.attach(l, 2, 3, 0, 1, xpadding=5, ypadding=7, xoptions=gtk.FILL) Table.attach(AppWin.xMinEntry, 3, 4, 0, 1, xoptions=gtk.FILL) l = gtk.Label("yMin") l.set_alignment(1, .5) Table.attach(l, 4, 5, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(AppWin.yMinEntry, 5, 6, 0, 1, xpadding=5, xoptions=gtk.FILL) l = gtk.Label("y2 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red")) Table.attach(l, 0, 1, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(AppWin.Y2Entry, 1, 2, 1, 2) l = gtk.Label("xMax") l.set_alignment(1, .5) Table.attach(l, 2, 3, 1, 2, xpadding=5, ypadding=7, xoptions=gtk.FILL) Table.attach(AppWin.xMaxEntry, 3, 4, 1, 2, xoptions=gtk.FILL) l = gtk.Label("yMax") l.set_alignment(1, .5) Table.attach(l, 4, 5, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(AppWin.yMaxEntry, 5, 6, 1, 2, xpadding=5, xoptions=gtk.FILL) l = gtk.Label("y3 = ") l.set_alignment(0, .5) l.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("DarkGreen")) Table.attach(l, 0, 1, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(AppWin.Y3Entry, 1, 2, 2, 3) l = gtk.Label("xScale") l.set_alignment(0, .5) Table.attach(l, 2, 3, 2, 3, xpadding=5, ypadding=7, xoptions=gtk.FILL) Table.attach(AppWin.xScaleEntry, 3, 4, 2, 3, xoptions=gtk.FILL) l = gtk.Label("yScale") l.set_alignment(0, .5) Table.attach(l, 4, 5, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL) Table.attach(AppWin.yScaleEntry, 5, 6, 2, 3, xpadding=5, xoptions=gtk.FILL) return Table def ParameterEntriesPopulate(): # set text in entries for parameters with user's input AppWin.Y1Entry.set_text(y1) AppWin.Y2Entry.set_text(y2) AppWin.Y3Entry.set_text(y3) AppWin.xMinEntry.set_text(xMin) AppWin.xMaxEntry.set_text(xMax) AppWin.xScaleEntry.set_text(xScale) AppWin.yMinEntry.set_text(yMin) AppWin.yMaxEntry.set_text(yMax) AppWin.yScaleEntry.set_text(yScale) def ParameterEntriesRepopulate(): # set text in entries for parameters AppWin.Y1Entry.set_text(y1) AppWin.Y2Entry.set_text(y2) AppWin.Y3Entry.set_text(y3) AppWin.xMinEntry.set_text(str(Graph.xMin)) AppWin.xMaxEntry.set_text(str(Graph.xMax)) AppWin.xScaleEntry.set_text(str(Graph.xScale)) AppWin.yMinEntry.set_text(str(Graph.yMin)) AppWin.yMaxEntry.set_text(str(Graph.yMax)) AppWin.yScaleEntry.set_text(str(Graph.yScale)) def Main(): global AppWin, Graph AppWin = gtk.Window(gtk.WINDOW_TOPLEVEL) AppWin.set_title("Lybniz") AppWin.set_default_size(800, 600) AppWin.connect("delete-event", QuitDlg) AppWin.AccelGroup = gtk.AccelGroup() AppWin.add_accel_group(AppWin.AccelGroup) AppWin.VBox = gtk.VBox(False, 1) AppWin.VBox.set_border_width(1) AppWin.add(AppWin.VBox) AppWin.StatusBar = gtk.Statusbar() AppWin.StatusBar.ContextId = AppWin.StatusBar.get_context_id("Dummy") MenuToolbarCreate() AppWin.VBox.pack_start(AppWin.MenuMain, False, True, 0) HandleBox = gtk.HandleBox() HandleBox.add(AppWin.ToolBar) AppWin.VBox.pack_start(HandleBox, False, True, 0) AppWin.VBox.pack_start(ParameterEntriesCreate(), False, True, 4) Graph = GraphClass() AppWin.VBox.pack_start(Graph.DrawingArea, True, True, 0) AppWin.VBox.pack_start(AppWin.StatusBar, False, True, 0) AppWin.show_all() gtk.main() # Start it all if __name__ == '__main__': Main() lybniz-1.3.2/doc/0000755000175000017500000000000010730465750011722 5ustar samsamlybniz-1.3.2/doc/figures/0000755000175000017500000000000010730465750013366 5ustar samsamlybniz-1.3.2/doc/figures/lybniz_colour_graph_small.png0000644000175000017500000012051710730464223021337 0ustar samsamPNG  IHDR PE pHYsftIME $9%n IDATxwXTG{SPQhlk1͘Ĵ/c4I1ƊQQA^ؾ~, "F=<CmHwf+d۟] jQ)PshLO E$I4c2"J|9){XgI@ IRE3Y7C,Z/h ]-8yE<+7P 0qIP KQ$N&$ łqCK EAEi;C~C WNqC44aߞhafhENbT#[(h"N; .J4IQM;eks'J]МHME4ARz}TBMekTR^̜ۋ{4ZGQ4I(0,$MT‚P C[((DRs(KaX*6ԥ=EI/dYvѣ=%-g SWXp(NǹmXgR_tOR IдD<@$!R4MR4MӦIKHzd;oXLM$ES4M@[/[%^1Fy:]KI+j4EY5x C"MNfYh ]͌uR#ȺX<եdDx?_O\֊}1qw2"( Kq]C3>vD{l-CcAhQ4}*kq.߼q E'%0d"I@Ӳ*qǰNBlbiGqb9b{2xL|"/Y6 YP!| jh~0 ?~1VIx1dӛG"T=ڞh4%7_w6ZnpV?l\njN @= 8E$Q&O's8i͡Qk*+0 Fn1h(iص+1'k=_h[3 C/V*#KH/ʬ:i7C10,<6XQi^-ss8^AH$ M2$a0G(@)ޞ-.,(PAoۉ@dV]%nCjeo@nl]@G")_$pdVg[[9$'\5^oiK"I'34vn~(Zڹ ;{^l8'
#Ӯ" Q(q.f@ =ˠIVWVf`رkϷ_}Kcԥ_rt\~I@\I4-0 re|z#Z9 Hmo}聡-,,T*U; m;uxyy;p(]9׎0"evey@ :0[W]x}ieZu䑸>v*=z9~6Ox,z ok t>}-AWmrӎǜ+i 9nX?v]TBN=g^?{ q2֢#㱧 j=Fd-j^e@ 'nxCոyI7<=ܛU|y3ġ-'{]6J `\˲NM;g; B_T?3=|!W}͟ G c|j7ޘ;T!I<#}?3EHšr/ºB.v\4+\fs9-@s`^gtq̬VR.ެ (? 0~-<hIxOusWe)쾛 FEسXGknԙ-6 ~ivk>Pm>}ϩX JU+[f7X!{ b*a3aY6rHsjf9,˖鲢bLfoT-Z%-X uI>cDz~B|Gȸ I[yrϥ.^mq/^%'m9pȜ&4̒0եpwCv, X֊ 3nΌiRNSR5'g q5E:E6+`d&Μ#>6h\rJc4TUIN"6er+E_Yj+h:~슺ڊ?V=htE诃\AU%%tFSMEk*J[o[$ <[ttyeCڸꫢ׬ :ӛFPޠ^7Dwd  XEߒ?7]蜏QuחaD{Q.e֔mEei+!9=^3+SFIzSse]Dyy51oJ&u}Xzq?+ό|$%ͻpqO;si3ݵF;qTsfMle@ n#( P~x;Mm:<ޝ.z<,¿Av ө<*1k<\]]\]]tU #Zɒ<2@ Hqqv2@ H><@ZGaT׫^ DaEQnNY9AA S sI`. Ũ2 ݾ`Zm:@ @ I@ : <:pGA555.^h4V|>AΥkqZܹZK _==~Vzj9::D9::jO~vZ all}y<ޓԛye/3t eQA maOUZB<+a܀Q\.>kƔg'`i'+">>>>vN!#+wC}nxTڻ$bYf?UzwOa*cݥovg4INĜ*++JJKkkX-((HOM$t=IԨMsT9 *d\Ju{ۋ]m2FӾ 'zsʟlI=՚̘D"0챵=pe슒7m~#eĉ"EQn߾zsK{K{i:z  \8˲&)b'O'""ǰ^{ޚ)//ieQFjZѨrrru:dA$K,$84C dEHRF.ӕ{KeYg/oʊ2'Gb.V $Ft DKW/XG*b0r\&mܸqǮ¢=#"$X,$T*J% fkkK|1[31O9[U]򠕕5/q !@nқ 5t⭲+9/eTb(iʗ R[B_G{gW |_ԛ~,2 >)[VUWo۱sڴi~~~֖:~ VVV3f̈=u&?w L/ĉ%Ç+ kkk\.8ϗdSN%NxZHQTZZZ+{GTz}CBAD" 03=KNIU3˴Y)Uj>G:(9WSO'y*<j~QR/2!ӏr{iIK78X"Š FSVV(++}6a\.wܸq{DFJA( ˲ PeoocԽhUUUM6DzkbbbL&So 0c4 / 2q3w[(ssq"(@a|ǝI,f'}.I.u8KQ뤔E\E2˲h/q\[;U+W:|D(a!}(:mʄ9iogP(zi0֨RòݻO eX|@ xךe\xq||[,4Ct>f0Ytme'S\~`úsӧ8sp( N5q8wŵdWA 00lr^sBD| )(R^EEQr%Cnia!;ft~~L&:$`42 u2|_VH>|ouuG/ B" 0,k4)R(oVs$A4MA444޻RFah(*::eiӦ1 0LocZ"3XY W/4^Rܜeeen8qy pܚr2LRBaWay8mO7_` &%2$YqD" Ԭ޽12viE^cA&MKO`O4 L&(++OIKfp|nUI{opDEIA}mNP'pKIfT"35sU'ȭ =Xfok! 3ft W$0 ]YYnuz'(T)S\T9h`\&C&j' ..΄ɴ+::##A^{=wMt…bo/Do"ñ޽ :骪m۶.xqO9egkp*@]gT`ߛ`M& Lz!7/70B'V$nrpjܕ-O(a(L&qN; ,˒4S]. vY?*go3ڦ0?9%}r,Q<ȲlTTԥK s:^"vv|_VUlݾNG!666cll|}&$={>%+*gEK~wՊ ]7i3XYZ.?pzAjkUݺ]͗r%rO98 $R_[E5haĻ`<ļzfC*88FѬD4 bf5MIrz*_{^ XȪB̸!}ꚺz/Vv IDAT8x֌8bT>bG`a]4-;$ ΞEĵ$WWםѻwip3":`hk+W\ܷO/]4 ipGJN;uڅ2 n.і>'v] ~r6?uE3IQP.q\.1 EǏo>G66JL*5;/1ofi>m*6oy7BP /$8",ke] /tz!("h;Ҥ}@^^`kZuˣeE ݻ9'd2MBMl|_(RTyJUGQ@ KƞSo!O>+,I<.A0  "jNJ Jxo #ݣ#l :;TWptzM]{ \'8w;~0gBDL-y/Ipiʾ旟:޼GP7ȼy7?3.5h^ܔV)C/?RiTU1v^NRM<߹U1k֮9MScǎ[k֮0 yvϞ14؛pn\J˲lUQn `{;YݫsxҷtNKۯ44;9y)..~t0!-֎]˾jC+XSps R;.heUhzTgkyX,HWXv}me~+8o>{W%_[毤f?GDJР7gY3(vɟm~5f{/`U2N!~XcӚ_ k@|~7ڟ$k)qB"YOxM>`6`ߺqv~wva>^ݦ-0O8?",Lqۄpě+>^v'Dʘw+jj_7 𑣙YfI8`P%^O.jZl{q?&KurrV.>C*HFAYX 4$eL+QfMN*+.{kyN˹=d#뫓畩D ې~\m}lndh:4<,Y1ށ.Xu^|yFLWB=13+;"<̜23+\0nR[yt>nI7,WdfekKca Bܥ@f=p 'yS8O>6:m@IhRndVev؈uWj عt &3׎:{0FN/D~~41{4sɤA=t/)jw2TXV\2!VW'arT.vwЇh 34>D>-kIiێ^2.9xPJ9v6?8z<8u랳*X,qfI$zI<.u&IJ7f@~fwcZ@R}p'sfyX\M̋+UFV߰f/_s%m]+5+GPwn\~EvҖm{rU{ɵM7Yϻv/Vo;o`0pxsyxƌY4iUzUmYyőcǛS&%HJ!t_hcBy _W˚-ZG;v\4_e mE5~bKY!*2~p%)W# ]{O^ePnmA] _O JWs%vX{_Ȫs1]ec&\&zWF4ȲU5߻dzR$wnch F^]}r&Cφ$[1Y[yވ˧L- j9W]QVZf'uaYİIc(akoK۹X^zJLjЁ,]ͲvUU1Yk):3l$ 7xܣ˷ ћ 4U%k_x~?gyZ{x쪹S.`zuߞqJh,xg{ڟ\?k)Chٶ(Fxгa|렅FxٛiMiՍU^}/Peۮ Yڕ 0|qJj>'>XFt‰飖5N#?P;X71bTRw2VSFr[L{_5l0x ^vB b89{4^ q %Cjh.صeߴ#?Ye (g%Bjl ^E|tXFZ]ҝ;8*x0X*RvQ;m]_Ҏ({gƪp| Whi|Xݹٳf4'+WiLFy儂+?a?~,3t`Ǝ)o1dR)_8fCK t('>rKʶrqg5A.6 -% Κ!,y~ݯl8r\-,Hm.m4ʭ8o2qyа}ZCeUm@Hy/ZS8|ϼ!MS|Qc Y ,K0 VY:- /α`տ5AF ,$fnmNiD'p"ZYp~vv~As?$ \ϾڷA{ |cLҷ.`bdYXZVg'D72ݧkʼOpaɕvE0v͟2sKCd\eY8tJ3GNTn^]{vrð$|p7<LTE}+*p9)11*ЁCK64_pؼgOw-uW3/^ha;hX@h[ />Fv'a/=vͫk4FV2e=} +7tʼZ?=n@ 'plצ+/N½Ǽw @60lLԾb$ [:O p_`$@ $ @@ 52P)ƹvI #yjQ(m9-Z}p6pM@sN@ I@ : @'@ $ 3A2 m4T5@z/"T$aX,$=*0\jm_VutSF 7ahZ*+<|"I7 U5e%=*eYVippr Dͯ~ u^Koφ04קR0eLppv$B'Dip@z/ qlTX*힌%R =4OnI hPX VFS^^A45fWT]$%ڻ9Ky*0 ?@D>4h4vvvm2PuեezqpssqBDt>{nkʋ+:#;x8*v;jᅤ:t~NF#mVi?++?\nݽ\꽝D+n.@KB/M /:cޝ%0MT~*ա{o4{挠uv{\z###_:[~__ap1dSfOo֤S=\kmPkt4@88qQs z}`'CMnG۬:%-Z* 9oˣ^WMb  ]HSɷFm\8Y4T̜coVZA|wd }zX{u;ldw%wg_.~E=t^!Qݘ!џ_LeRvdbc"m#$V#D3UTˏ96mڡuN?:"b茗ˬ7h\7;@,L?34w8Nvp4d. $;07N3,8W\J/Ȕ}<=ӮI@]-;>œsUUY9_Ι={7퍭3w_'>DVju,x+NǤD-`g!pX8Fz>|Z-_o&{}+D=\9Xrq+8{zn)cmRsH:Vѩyym;VZ<{?Chn/_}&ȫů5gylvdzp(ڹzoP 4Yh ]=t=u~MI&cC(2"DSXSX X:Ukc׭d2LɥOڿ6ʤg]眻tM꺺!NP4N|+ІtR(R_JX(M\X=}(ܹGoƐg_lat{& v^HG1;xQJ3%P=hjYL*juWQ39hQٝSF'. YK~)6[y6˖4RЊAIlGmrTs1uWKCznP<3IYJZT?Z)jN.QChiy;:aryؖ"^w,AZ_t^d¸^ϩk/&=mD=0h[#4U:u; sFI‚L,h\Bع߅7$m_W iN9PU-iw9!Ac\24`&Nj=6~VN[CCN R[v@KU0fO_+U1mGgb }ģՋVT9V\ĵe<=Z{]m{oIl>TPەG6|Lנ3Ǹ89`@uNϽa2Ϗj_{k Ο#cu(:S%_,|kRJ^߿m{͹-WvG{jAIm s3/MHNNn^_0Sɏ?s`/2y샧z`BED]J=[|A}mB]]EamcHXਨ(0ݫOdCq7ܢ?[l5'#?zIEB+ʊerR Rե9^sfN_ _=cG ;u@ϊo9{:)}Ί Ed޼2y+^gao-Ɛmӛ& \'lmjJ py=D'bD7nfJ0a5@n*OOY/rޜ)VMIPk?N(4!yyS7o$%e YL4Eo[py FU{y] 'Ev= Ó.9zz۱ ^N W3?/CO'!]GFDw5vlXd4+A\=:vzU꯿~6P[u]'pӑNM;aN{mDA>UҵuG{sU09vÖQ/F+nn;rZPi^a@ ]HmUH"n'akbIƎ7v #m*aݽӓݸ R]^ҧ80ښh~Y*KCf2ey uۃ^:GTAC EnIit'@"A"{@mzE*mtkܚD"mݓaaQOxO+ IDAT. #eyu9J@'@ a  ;HBhy@z/vV á* I{ uS:KΖBhh 77uE%EZ:RF ʑީ)m9E_yBn5 R$T RUQ*{BI6ݢ=aAyrDw^I\^COn8@oa@$$z?"ՃJ}G}]#ׯ=z]{3 X|͌|~ӧO7]lYƜruEީb0pg:]osRwD[NNO!㏛=W^i OSZo;Y:I8w[u{32eԴF`m0}`'!Z +SXJD 1x茸;kJ̉<'yKOa>b/;"}/zF`{n>bXdlgںgK=BIuhi9rQ`)4'#>Zez9 hx>Ң]jWVC"˥o:qtkWxĩyp`@ϗLo>]ȏ}\}Ĉѳ7~5D q6Gh=eqZ?9ZI~>FQ]N[]_y;f0oG9%CY't b T]BS ]_SQP\N<{GG;+ ( @ť2'Kc#hOJ-[P[.nXҟǺ\.ze噷h'oGaiʫ4%<ݮ릏޴uatzs3~ku6ϭXqm yY©UռִxS3eY-\f@[7˓r+s2ka!uZj}6y[7QcF"5Iy7<*-QwboU+\񟸤l#AkS!;fpuvF^neS=x@~eĩ7%K'/:eC 2q34Kjr-kWdn}"'˾3N4uHAŌ]9{CYeZ@ճw.3۲hUvoǟV9pBy];o3;3/95P_o۵p"Ų]Ϟ[4T_=n;$XMKDhKLݝ>=UHN{\M|dy|̹|B_!.7gz?7.s:w)c(oȻͪwC_A|V{pNsYY[-X8H?+5mذ!C 5J|/Y N{a.W Ϭ<3%ܽO:sb(S6Vy1|7^bTzJ: b wAM̅+y5yHBBL!ںQ\X_Q\U P*S"a ;$B#?ps=>}w.sfWmUt-Q2e#S3˛Tad+Hu_{S Ȍ;pżmtZ-NK?5~ h}D! 8NP2 WM9ciGܿw% e{/L(:v; $"HFdYP/X2 (P'@s_f?vÓ\_߫~2 K+zD5@iii5%7řk.˦F}Yt:현:A(4Vt4X_n.Rn74(˩}ka(nY14u)j>Kҵ517teFf}=i/ǡ%׮^1@"Wԉ$̬"P]ܗ8PF 7 >ARkf\L5@T)"5I`A~av%N`s2ק; "H$ D ԡmtZ,'TX}X1@>[S.71V˿q$$aN^3N[Lyq C`ͻws"1[v.N1tz͇W6;wn~,цY$K*u4JYq/5L rvr5^ (nfQ7o^Q }_EuLuaⰰ0iqn;#?)_0ּ)M΋V3 ݨO흰7E,X,b%"4ݶw$ho`gkvPI,E-pt9l5XNTf-Zwӱ[#|ڙێ=o?Oũ~toh}d煬gݹ|Y@a-k].>~sOk7(x /-mصVh3< W#d둮c &MV  5%Ĩ 72cw-[}H4;+SFN]U^t3yܯț]j~w="''%]'EMNTs%mIRa*xU4,ߕQj6N,AcTH ,ԋ.Oa>?)1ozq5ͭK0*duF \ntWaUrb O"uZFjPPod*o:@+}ǵwC ɟ&k}~~OU,vND)5H.bm$EEȨtOzÁ K S U5(:t;~'ңXMmNU+ujn(h O,ĩiJߢi]EfD𹓢-5M%IPoއ0g WB8z{T xILT쐱L AwSuBPmMi]-u#,=07޵徹PZEſױ=i=~ƕb[Mu,# }G((9X}Vq\A|ƟnIu=zeJTW'û Dqhr'aim>R4;F!0Prt2  9$’rs372Qø>zNȗVnkhڊS#^7xC]P({Y׫ PFF:~XhF(ϼHrR?!9G(w0 Itb1 DqIx@'!SQ/La|(O~,H$98UH*ť;6!I%īP 1X*Ņj`" % }ه˭!FonN;lHК!}O7g>z6]hN= )^ռ_:ugge(0մ# ӣDfbH󗹍|$޻&;n-"NDxqV^npOm{:~M«!3 +tL=lt0ӑD`z Wt2 C7$E ƭf2L&>eg=N4[q۳W>$zpi{mfDpd_)^qQ(Wr6{5bIe}|3saIl?[iٯF}3"AUD }[]]꜊$V+݆W",˨Gbg 0Dp*yQOM"ɤceүJjdMv/|[kֹ1݇b!hjjjׯ^HU))3rRRUpxS+g 5  s2|wN]z=~󕕔8E,] Y*C1#1VaIF1o&87lF3o anjzDGḀv=^i -9aF,Kgw+ 1Q*fOhi3 ҫٶ6Lq(:~g/:}wUOP[8?iRwC@X#z-ew[M_r> 5OK璱(Pʘ];<==g0{ἅhVI"bs. f1$g?0OfmcX-#@!v D&$aSsQ Gx0cMc} 7t×6nc@`3wy]:$iBÒc˲0i1\_ǎzdN j8HXSU]^9-UJC@ _uD@ h5GΜ9yyx26 k"H?Jc6SOJHܳN9n֙ n 1b󯕥x*Iˆz[۔6c DOFi' ۍĽ*j3ْV|='<e<2~Fj sA*(-g&yr>g7v~I(tJHvB#b}  &={hFiZ @h&XIOHqyĆ}"~ pSm<4Yc$$e*B( @R~VWw}-@G%%y'N#_y8ICp]FH= -\mmyrN^Qn)Y܍dȷÇ]b4lҏ{ۓf\#" +&X;Ƥ$ADw1'.y<}5)k?Cc雃6;JDMkku a34iC(0Hq@`=rdJIo\ 0(֐2{r$1z_/7`ePƩŪ&-^ޞ m^=Jz4`$伒›Ǖ':yRi'9NmTf-Z--]0pTU^{AlYm[84hoy ₏J=OrA % IH$b5PEדNIY`ï֋eD@ceի$}D:; P2G1&57>|x޽ C{HؠJ `a#i)*Cgkg^>ux^K P{,PQpr<.5lL^imr0 |)Zd|0MĢլ[!Z~ x b$ѓH$3a /U$*}B oB)bNo0.'#lbaESW1N# QQhB$ ItDI D~@@@ : t/H**E!ۼyҡCP;;sYVu!p1uQ8jk֝BYV{1AE5*P1L/X4c,-[,XJB(;#oZXB(:M$ :}e\TJ)[/$+;Ů(@ͦYd2p9P(]g"^II4*<@'ܼsӧ@*r[fևj@ \+0#V={!r1ꆊQW鷝;̑#瓕5k֬͛7o޼Rll['@ Iwt|66T3Z[:XeJYjl.,l5cFqƍ7vQ*kĢηΧg`B8ݤ`H$ 'ɓTmp8o޼W?{iٱVӠhiLBt]Qe0 *$ iƣG\'Nz;x͛o3B}V***.\p… vbʉu:q!#4tД)!p$T*uuާeۏ2WLLLLLLzQڏ==aAHU-XPRo5v-=4jP$H 4&SSS Ǐ?~xy_4TI@z4/ Ba~jiNKvg/ik u8)ԗ+1DBf~;ngl!4itY%$'/wsCd|04&'ۘ.TMMɦCUtiLT1 : x#2϶bRVۭ>s6: H0l~Ӌ <ۺڊ ?2<qp??1CVU8p]Srssׯ_'v1O’HXR'πXuuh8t aSѧگ펜MMM]]];&s0%Mg: H/1x@=@ $ u|p-0aôuGҘ릘`ᰅ%%ɭ7pPh$ Ȣ+&kH<77w/_ܽ{r*ZN\W'kv@@'tݔw$L5 [85D+t-O{Z): HK}PAUt4:å8[6L{ذWXo Yfv_Acyُ|64N<ݷBc<6(: Ha:i+3 U@4Gm@>pL&N~[ɘᾍ_^NBӅ@'! +IN3))R"z,&PêƯu<RY _&QSRtt:xh9 Q?{v_O ~NNNNKKSEGʼD*J%P4* /: H+:^>sLg___www+wmk 9u:dB(8MM^yj.n疧}L/o2|f H$DjPIR^ݽx%$q]2-16-CiN;=Pypg3FPm@ :5=Xdef2]M]I"OwmySO^Vfi?~/KO,v[ctih8[t wwWD9|1P3J&g{qACﴚlΝqwwz">> g*xtwH!I@zIUg%eϟT_罘Tj5*N2dȐ!CzL6$ I@zV8]>^$EB/+֭_a>qHS3f̘1=S+]@+@'5\U8y8.ذ^O>|KD"'u䕗$" #bFxy)N3=ų?@ѱ3bΉdI$SnnjSY!I@ڊt9`Y״bŊ$SUU:tСC{1A'CtS?B"5šޯ%$`ѣG6ot@Z'A+@'5(2q-Zkl6/^xE(r1D"`ᰅ%%J!I@ rJmmmbbbEE`0P!t )4Cwoد̵پ}+ K[DuSѧBXH23B<˙Aɠo7'/K"5namUR]RZS paIJJIJ< eϗf߿ߓ1fzN "&''WTTdddddd@@ IG콽O[~Rίjkk|˗wkYLVfk󸋷J!I@z mKҚR9~;|+9>C2hwԶL-IV NқxNǹU4&[1 VM ΁V NiΙ3VVҘꁘOw $<3: Ho"瑉^'cAnnP$ r ֶȏHI(ú~Xi 555%%%%%%%pbE: Hmeme|T[WPVF(֭{C:[b( I@ b2t+ݻ...>|p{UH0}@@'M&O̬̔aluq.Ж-k# F4Qtބ@ 99 ̦M']1ލIH _rZ)ׁ'kMz]*AC]7mڔd2i4Z78%&X[3Y̪eAƜ]e虘7<< I@z)'N[׻2\xwa2͛fДPF(: Hob0jTǏ^`ղ*dyPEZZN "H4F'1F#jh$ }[V["s'z5kV``````w|tJ{[i[Yi[]OM[K%P*TE!]AUNkhie}t7Sg>I?WTBCMVvB,Vӎlf/lhfcIt=f2II"Q=`36Ϙt?ޟ1xFϔU՛OWR{'3:Sv8i#6B AJ!&&$$5R WWQZt3y\LP"߿/RSK<%=W,cc&Bhi7nDDdmp0##uNBf\9bN%¹ݳn-^ڽ-W ۼs޽BFa2<9 `ޗw;"w$(֭c̱;G^ ̀cM &e2|x+֋uSW N.ou722zƍeUT4 EEUpBxtVFhIIrG#h4jh(N?xp:DC!45qvMܵk?뙚g[(YQBƪ>f泋mtlPJSS;b[:dOfggW>z8xeXJ*0VD#E- b&N4VSNl$=HH(ڶ-r￷8;sk&XYY,>=\3gh5kt.M7^.AjꭲrJ?}9mZ."i_Pk#tcdɓ2SRJ\]<V,Gcǎ;@$Hhkkkk+ӶݱȑD"N>vRFF W+9L2$dƤI.Ybo37e#WNsf[TUTY[9d@/I&'MPPȑ#e`DL TU%_#޵#GxWSǣ#GН}:&&F1 na!bzSH u|}Gw"O].Q70Niks JSS.l%E ff\H%%%>oll<\f};͔[p( PTYcFp8)qqH$6IȒ\vrd0/]J(,V4vvYdfe؜E 0 '<X3Yݹ#=Fxmq<<88=&yS%-cεڲ%b`ҝCںK[{?+PlbmmtҥKv11iwo2ں[vB=5}lOoNtvI$d̐!Z'O[oS@ MQ\}aC/wx~ʧOǑ8t+Aa 7ywp9sn}TYU%S1VbQzzDZf[14G%Bs+g5 yIc1_;v쭑1ͧMVqbq D][5i4oxa!zȐ{v"&gg۷*+#Mv!\U11]w)J5Aff&p}c ۷zy^^-:;7QQWWQWn 5qQ:DGG?~L_YY{LO.dDBzhU7v<$ Uvcdzwv}?psXjj޼dm'rƠAlYϹ=Q]]}Μ9>|[NȲݺulOϟ89)=:F%Pŝf>Ɉ7n<~aa!mO_ښ2oĉk߀Ҿ5[?r}Vűco԰Ӧ\%uKeafaI/[f;q_2AXXhI>"<=麺D ) ĂX0H.Q'K|)Sx5.'\iγ  )n+ή͛g 6x8M͞!z{}8.ٕ'*Ս]].^oΜwpH찷׫;9xz_3XY[0=dʽ%(iJ.܇+ Ǘh7Ku\{[mdz0;'Ъmt7ّ-yqe+d$D"f~?pI[uK>sW Q ii3g"BnRbrOYlPquܼB1h'hblgbb ̶mc;f=C42g) J PL+;-T DQ(ǙMgt*vXTVVl۾$xMddVbbqHͭ' a{{4ygTkeƅwgocoIC I ^7V6 J5V AvZ~WWSuulFFűcoׯ lg%ښʲʲW"ׯ_/K&LГ۟hg 82,% Ҷ?X<ϑm-hhҜ?N;K}svc]ɶ8%%ۛH$"9_>!!AlÇ4MSS]"̞}s޼[55vfrF&.]tҥذݚW)MGj,ۧkQǫvw>\S7.OGjzOښn<,,l<,o ZKypAw,b,BBBnnW^}ϫvz *S<4tً7 6JӧVf02BBBzHW\UR0@zQ(x (-Ϗή| IDATCc*4"sZ빶-:lZVaaaݲZ1ΥI߁I,J<sLPfD;3Le;,,Bhb-֘-m-7 ;l={>8DZ6kĒ.|MĤ;\8Prf7,,,Y\---L5VCdGFݴ:lˊ4Wt:ZVl(>>~Z㕺k uu--UD'1h+:lѻ:lwS[# movW}# wfZ>t+"AS|ȶ+w ō N?|_.:rD%'|2U.]jxOkXė}b'䍦qyVY&[O*bmMNtCWiiia0=N ?ѸV,puW'b깠 @AN)v 0iiit:=((ãCE<ѭ o+(}Nw[:? N {׀rt-["lltt:j ;20>驢.,끱s?5ٶh]d>vh(#:jɩ2; 5uv')+D99;&$-[PtVbc >@m4: 3z2۷;9]/oy+@]}U^h5g4o`899ZjժUаY{{Tt NBwxμ9s.+o{]X:cLXw.3G613?!`oXP&m!Jھ$;'d ѭ&~DXظ,/2<<}3Wb}\V]?hd )r&)yL|2Ukҡs+W߿/}#pccc Hr%}=epR-eϳW%r"ۼߗ[Gژk>kl4HcРΜSeTBI,xIK[o׾;w/2m"ufGjժ%kUƌ&껯1zجbt9!,{X(c$EqGoI8e4vx*{L6~  _a}At]ş^abj!X,׉I%Ǒ{FfdTȃl ŢWOY ZU"U|A݊+deoyy찰~{f׊Dv /%Kjq썠NT___'_[/JHxjH FgjawYQBQ}}pךw ?S'FG3edTu}>yl@S s#*%s'bƟĊ54C pX%& 䤊~uq1]~_ְ(PB+J8ُ hM~t4ɞ큀W()f,.?ߑ*{vg$I"hݗ%_E2|ʤ`y:66H4'Q@()ɕO<&UKꕔP9lvrG3#Fr/r#/}>ցjԽ,z]za˰PUe%ɡZ(VqH̅{Cw|E7sÁȜbEb``?U+(8E w'NfT Kʸ!ڿ[?~\{Q-;Qt?N[@q``O? cW/_]7o\v,'/b)OTMebii:fpmEIq1v/l1 /W;F H l;ͪUw*<-[F먇H$WWW}}}4Biϧ"K$"Z5YnĚ93cGxxXT::^Z y7&!l6ͮj>'dGi2|ԡCh4&F>aUU]xzz_,v@Iɕɓ{qX786CJI^"쏝F o1%%՝DcIht9h Pw@=*M]o93|q_Ԇ!|sz6[9DEUV uSTTPl9|8ӓN&tlM_HK}GvMAv.^]7;γr( Ν|m4m &ȃ3X4IDꏝ&=ɬڽԩ6RX]`VὌX,=f( H}7f͚r@Vp8~{?E2~ji{ĸs;oB.W FI|q|)`q{B Ao_""**I΍kku0`jx^ݻi7n`PH,WX?y򤾾5=߱uuuG iNL,w"Q}mHWiv|) 6gSIIu``҇e}l~sŽqIb=Ngrj VÆQCκV'\ii˗~QqV?}z$mmMI7'NMy.NNN?zحikkoڴ)##ã+WN &6}dV B'<4588?vDA>Pdt={2L'u`IK+c޻@UD^?lA~JR vvii徾˖ HXraLBNi߼xPX+i4~E"be^TZZ{#B CX{`ee/xC4I?xSYɯ55%˹b!fr볙L6p:N{Dn֎zˉL&wǎ {8xuuuL&鿲?//iiiO?-J t3~~]/y$ ee4VIx]dd+LM-%(+Dm+⤤?޿xx# ڃK~~ⲳLtO̰0ԡx;gsAQOOzRRC15TNH5I LIIիmm#E;wOR\ɰa#[aefV>ڻ4[q mm48d0*&L 0gۏTȩSo[-v0dEDM#3Lflݴirt}jm#"Q>qes^vl>_ Ϟb5QQ|K|~nn.UYOsX!wAQy?V~  %Svr&4&0 FI G-عs"7״n]b̑f[NwyڹqC_OяϚub˖(^<~u֝[V}[Y$퓗psZajja=<59z󙙽h9z}֭|x{,ZGXw˻{wњ5}233LO?WIO{j0?Fnj;@K}}~fO>]t:L7vza!QQ7l^a95,: I;)9'8pz=rRKM#'TWWwC^?z޼ᱱ\׉x/8e˰iӰ_*xK?l_nh|?  z\9R[d߾r~OR!tO;vfxdܸٳg :@@6n9۷W>MrrѣƏ8qk!` ڄ+O*ڽ[ӿa)^_\\,Xrs=y~;hP3z$??_e65wԩ'L2!fļwppOشinBxxqwKJ];ʕ҈#뤤xNhPxxٱ`JXoh:.TUw gʄNrKTj4oh@:tᆱ>sf_r"bO.G22:sܖ Zm h蓆BݻvGYRnKFs{+<5!|||\P"$tt5qĠH $wt"e :nI.R&1sL2 &E$""""""(@feeP&s86l6f 2 @2`W_}`ܹd# M)Φ Mh'ebP@I2 Эh4F 0l޼… )))I.۶mKLLL7NL7z8p8lmVwHZIX-W.R"] GPt$drƋےݎ$r۲mfhfkFcǝg7L.w8D[ih!W(kʭVN|. }{jux+}rBY|ࡣ*fsm$! $M9s__RZGJK|UjI{i!R(Ue&6 ǯniIvB׿ڡC$gu :J&nʙC9s+*B nu&nG)IDAT&+Tjg-¡ jnmOw5mK@PHkKsʁ!C:&}_mv[60H|!8<ݮT*Ja9;sڬγL$FtK)7@b5 !dӣ4Qkժ:D`7IENDB`lybniz-1.3.2/doc/lybniz.xml0000644000175000017500000002033710730464223013752 0ustar samsam Lybniz"> ]>
&app; User Manual Thomas Führinger Sam Tygier 2005 Thomas Führinger Sam Tygier 2006-09-12 Sam Tygier 2005-10-11 Thomas Führinger Lybniz &app; is a simple mathematical function graph plotter. Using &app; Enter functions in Python syntax with x as the dependent variable. Press the Plot button to see the graph.
&app; Window Shows &app; main window displaying 3 graphs.
Constants and functions of the math module are available. Examples: x**3 - 2 * x 2 * cos(x) e ** (x / -5) * sin(x) xMin, xMax, yMin, yMax define the boundaries of the range on the abszissa and ordinate to be displayed. To zoom in, activate the Zoom In tool button. It divides the range boundaries by half. Zoom out does the opposite. To closer inspect a specific section, drag the mouse cursor over an area. After release of the button the area thus marked will be displayed. The scale automatically adjusts as you zoom in and out. To switch between decimal and radian styles, use GraphScale StyleDecimal or GraphScale StyleRadians. If you wish to use a custom scale select GraphScale StyleCustom. You can then use the xScale, yScale entries to input the intervals at which marks are displayed on the respective axis. They can also be stated as expressions. Examples: xMin = pi * -2 xMax = pi * 2 xScale = pi / 2 To save the graph in PNG format choose FileSave. Using GraphEvaluate you get a dialog box that allows input of an x value and calculates y values.
Accelerator Keys Accelerator Function CtrlL Plot graph Ctrl+ Zoom in Ctrl- Zoom out CtrlR Reset zoom CtrlS Save graph CtrlE Evaluate functions CtrlQ Quit &app;
Operators and Functions Expressions are entered in python syntax. The following operators can be used. Note: multiplication is not implied (use "2*x" not "2x") Operator Description +,-,*,/ Plus, minus, multiply, divide // Integer divide. (eg 3/2 = 1) **, ^ Raise to the power of % Remainder
Lybniz has all the math functions of the python standard library available. acos() asin() atan() atan2() ceil() cos() cosh() degrees() exp() fabs() floor() fmod() frexp() hypot() ldexp() log() log10() modf() pow() radians() sin() sinh() sqrt() tan() tanh()
These are documented at Python Library Reference - Math. There are also a few extra functions that may be useful. Function Description fac(x) Factorial of x (or x!). Note: only works with positive integers. sinc(x) sin(x)/x.
The constants pi and e can be used.
About &app; &app; was originally written by Thomas Führinger (ThomasFuhringer@Yahoo.com). It is now maintained by Sam Tygier (samtygier@yahoo.co.uk). To find more information about &app;, please visit the &app; Web page. This program is distributed under the revised BSD license.
lybniz-1.3.2/po/0000755000175000017500000000000010730465750011573 5ustar samsamlybniz-1.3.2/PKG-INFO0000644000175000017500000000041510730465750012252 0ustar samsamMetadata-Version: 1.0 Name: lybniz Version: 1.3.2 Summary: Graph Plotter Home-page: http://lybniz2.sourceforge.net/ Author: Thomas Führinger, Sam Tygier Author-email: ThomasFuhringer@Yahoo.com, samtygier@yahoo.co.uk License: BSD Description: UNKNOWN Platform: UNKNOWN lybniz-1.3.2/lybniz.desktop0000644000175000017500000000026010730464223014047 0ustar samsam[Desktop Entry] Name=Lybniz Graph Plotter Comment=Plot graphs and functions Exec=lybniz.py Terminal=false StartupNotify=true Type=Application Categories=Education; Icon=lybniz lybniz-1.3.2/setup.py0000755000175000017500000000125310730465112012663 0ustar samsam#!/usr/bin/env python # -*- coding: UTF-8 -*- from distutils.core import setup data_files = [('share/applications',['lybniz.desktop']),('share/pixmaps',['images/lybniz.png']),('share/gnome/help/lybniz/C',['doc/lybniz.xml']),('share/gnome/help/lybniz/C/figures',['doc/figures/lybniz_colour_graph_small.png'])] setup( name = 'lybniz', version = '1.3.2', description = 'Graph Plotter', author = 'Thomas Führinger, Sam Tygier', author_email = 'ThomasFuhringer@Yahoo.com, samtygier@yahoo.co.uk', contact = 'Sam Tygier', contact_email = 'samtygier@yahoo.co.uk', url = 'http://lybniz2.sourceforge.net/', scripts = ['lybniz.py'], data_files = data_files, license = 'BSD', ) lybniz-1.3.2/images/0000755000175000017500000000000010730465750012422 5ustar samsamlybniz-1.3.2/images/lybniz.png0000644000175000017500000000531510730464223014435 0ustar samsamPNG  IHDR@@iqsBIT|dtEXtSoftwarewww.inkscape.org< _IDATx[{P\νw_d!&!dBLDvyTm:6fdlkFmqњT[GN:4ZCcK$% Bo]q޻`X:#̝R 9@98RkYx( ǔR"F@)ύȂU& 7VX@nrcU ȍU& 7VS4Q2ߑR lVg(//,?S=JٯN?Q^ҫR[[;DW PUU^rJTndfOy,'+ٙ;?S(//׳,*Bn,֜!Rxge]zCǧeA3^![Ȣ xRz0ZtPB#1PbȳVA =xC"+~sõp C@ݦA`d'@C{"6㧲8***E4@(g*|MT%"AOukz5,IŲjӹȶ@lw`ݨAc_#nII@Tlnhh\.,TA٫B҈vPRoc2XVVVI?jMo<\ =طoS6 1$|۵;KɧkyꌶgוqE#i/YTرcGg.^^{0rR+) tnb9o浞:~js̎GjoI۩\(VsSPPBs+:*?T*`*ox Eez㯏M5.0]YYhƓHII1S=Uյo_Lq0xjn\<ϿRuZ7t$/ ؖIq9ދm< @WqY҄&koJ>l8vKӡV?^җP[=}S RnydrWB(pwN 殺5F ᛆّC*O)#0XI"1vBg\bƖd2yNJF5e e Sڡ<(&$:FA)֙ȵ]7_ByA\u.HFghԩjťۉooNoeS]Ɖ4s `~?{U (GTQ+oCA vY M>bR J)FGG>nSP|$-#:' `CCHm2Ea0crI@oG/F?]H3E͟tJy SCz [ ٌzx48ki&0TNt#x-*o }4a#lk۶mOr yNO3 CX{47A˘9DI'ӏJ4Lةڨӗ }&I>]Vbh4tٜ¼H`U)M%xy!y|\iL3glXngey65lgԹr8Ɵqvn B+=ޢ j̵RrKJQaCgSߟ)w8HVq @) {IKpD+wu+6^|ٿH-ZQpО;kjjpܹ 2enL6I 욞wTXPM9mrG,:~fbkjH $@t8]jlltJ^>1b7:Z<5iq `0N$\*X<`wl/w~2^Na$_JLOtצ10Ahj-@uu5Ol' vr~<2CA S`-bg^4v|)6hkn^;a444"u4{P-Bߗ$Qznťo)E@ #IgҼ>NT[KRJ OȘ8&#v~7F?0d,n0j$JWl>s&WƄ?mx{b()8y䧬ޝz/l2HYi^ՀpӉ{\I,&V]R d1A C63/vx%b)+++bYE:lslls+e{9HjU ȍU& 7VX@nrCNw\$dRzRyGƿmIENDB`lybniz-1.3.2/images/lybniz.svg0000644000175000017500000001167010730464223014451 0ustar samsam image/svg+xml lybniz-1.3.2/ChangeLog0000644000175000017500000000227510730464647012741 0ustar samsamCurrent Version 1.3.2 Changes since 1.3.1 * Version number needs to be a string if it has multiple decimal places - thanks Sebastian Pająk Changes since 1.3 * [ 1807003 ] Error when saving * [ 1726426 ] "evaluate" doenst recognise "^" power sign * [ 1829857 ] Two start entries for lybniz - thanks Mario Bonino Changes since 1.2 * Translatable * fac(), and sinc() functions added. ^ can be used for powers. * Improve documentation * Bug fixes Changes since 1.1 * Coloured plotting * Auto Scaling * Scale labelling * Fix rounding error bugs in drawing code Changes since 1.0 * Moved to sourceforge * Optimise drawing code (typically ~50% reduction in drawing time) This was by compiling the function outside of the drawing loop There are additional savings when only plotting 1 or 2 functions * Safer evaluation of expressions The eval statement now runs with a restricted namespace. This prevents a user being able to call other functions within the program. * Using "math." before a function name (eg math.sin(x)) is optional * Preserve center when zooming * Setup.py install script * Pressing enter in input boxes refreshes plot * Make division always use floats (unless you use the // operator) lybniz-1.3.2/README0000644000175000017500000000050610730464223012030 0ustar samsamLybniz Lybniz is an easy to use mathematical function graph plotter using pyGTK. The main place to get information about Lybniz is https://sourceforge.net/projects/lybniz2/ Requirements Python >= 2.4 PyGTK >= 2.6 Running Lybniz Lybniz can be started with the command ./lybniz.py in the directory you downloaded it to. lybniz-1.3.2/lybniz.py0000755000175000017500000007315610730464465013057 0ustar samsam#!/usr/bin/env python # -*- coding: UTF-8 -*- """ Simple Function graph Plotter © Thomas Führinger, Sam Tygier 2005-2007 http://lybniz2.sourceforge.net/ Version 1.3.2 Requires PyGtk 2.6 Released under the terms of the revised BSD license Modified: 2007-12-14 """ from __future__ import division import gtk, pango import sys import math from math import * app_version = "1.3.2" try: import gnome props = {gnome.PARAM_APP_DATADIR : '/usr/share'} prog = gnome.program_init("lybniz", str(app_version), properties=props) except: print "Gnome not found" import gettext gettext.install('lybniz') # profiling enable_profiling = False if enable_profiling: from time import time app_win = None actions = gtk.ActionGroup("General") graph = None connect_points = True x_res = 1 x_max = "5.0" x_min = "-5.0" x_scale = "1.0" y_max = "3.0" y_min = "-3.0" y_scale = "1.0" y1 = "sin(x)" y2 = "" y3 = "" icon_file = "/usr/share/pixmaps/lybniz.png" # some extra maths functions def fac(x): if type(x) != int or x < 0: raise ValueError if x==0: return 1 for n in range(2,x): x = x*n return x def sinc(x): if x == 0: return 1 return sin(x)/x # create a safe namespace for the eval()s in the graph drawing code def sub_dict(somedict, somekeys, default=None): return dict([ (k, somedict.get(k, default)) for k in somekeys ]) # a list of the functions from math that we want. safe_list = ['math','acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh','fac','sinc'] safe_dict = sub_dict(locals(), safe_list) #add any needed builtins back in. safe_dict['abs'] = abs def marks(min_val,max_val,minor=1): "yield positions of scale marks between min and max. For making minor marks, set minor to the number of minors you want between majors" try: min_val = float(min_val) max_val = float(max_val) except: print "needs 2 numbers" raise ValueError if(min_val >= max_val): print "min bigger or equal to max" raise ValueError a = 0.2 # tweakable control for when to switch scales # big a value results in more marks a = a + log10(minor) width = max_val - min_val log10_range = log10(width) interval = 10 ** int(floor(log10_range - a)) lower_mark = min_val - fmod(min_val,interval) if lower_mark < min_val: lower_mark += interval a_mark = lower_mark while a_mark <= max_val: if abs(a_mark) < interval / 2: a_mark = 0 yield a_mark a_mark += interval class GraphClass: def __init__(self): # Create backing pixmap of the appropriate size def configure_event(widget, event): x, y, w, h = widget.get_allocation() self.pix_map = gtk.gdk.Pixmap(widget.window, w, h) # make colors self.gc = dict() for name, color in (('black',(0,0,0)),('red',(32000,0,0)),('blue',(0,0,32000)),('green',(0,32000,0))): self.gc[name] =self.pix_map.new_gc() self.gc[name].set_rgb_fg_color(gtk.gdk.Color(red=color[0],green=color[1],blue=color[2])) self.layout = pango.Layout(widget.create_pango_context()) self.canvas_width = w self.canvas_height = h self.x_max = eval(x_max,{"__builtins__":{}},safe_dict) self.x_min = eval(x_min,{"__builtins__":{}},safe_dict) self.x_scale = eval(x_scale,{"__builtins__":{}},safe_dict) self.y_max = eval(y_max,{"__builtins__":{}},safe_dict) self.y_min = eval(y_min,{"__builtins__":{}},safe_dict) self.y_scale = eval(y_scale,{"__builtins__":{}},safe_dict) self.plot() return True # Redraw the screen from the backing pixmap def expose_event(widget, event): x, y, w, h = event.area widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pix_map, x, y, x, y, w, h) return False # Start marking selection def button_press_event(widget, event): global x_sel, y_sel if event.button == 1: self.selection[0][0], self.selection[0][1] = int(event.x), int(event.y) self.selection[1][0], self.selection[1][1] = None, None # End of selection def button_release_event(widget, event): if event.button == 1 and event.x != self.selection[0][0] and event.y != self.selection[0][1]: xmi, ymi = min(self.graph_x(self.selection[0][0]), self.graph_x(event.x)), min(self.graph_y(self.selection[0][1]), self.graph_y(event.y)) xma, yma = max(self.graph_x(self.selection[0][0]), self.graph_x(event.x)), max(self.graph_y(self.selection[0][1]), self.graph_y(event.y)) self.x_min, self.y_min, self.x_max, self.y_max = xmi, ymi, xma, yma parameter_entries_repopulate() graph.plot() self.selection[1][0] = None self.selection[0][0] = None # Draw rectangle during mouse movement def motion_notify_event(widget, event): if event.is_hint: x, y, state = event.window.get_pointer() else: x = event.x y = event.y state = event.state if state & gtk.gdk.BUTTON1_MASK and self.selection[0][0] is not None: gc = self.drawing_area.get_style().black_gc gc.set_function(gtk.gdk.INVERT) if self.selection[1][0] is not None: x0 = min(self.selection[1][0], self.selection[0][0]) y0 = min(self.selection[1][1], self.selection[0][1]) w = abs(self.selection[1][0] - self.selection[0][0]) h = abs(self.selection[1][1] - self.selection[0][1]) self.pix_map.draw_rectangle(gc, False, x0, y0, w, h) x0 = min(self.selection[0][0], int(x)) y0 = min(self.selection[0][1], int(y)) w = abs(int(x) - self.selection[0][0]) h = abs(int(y) - self.selection[0][1]) self.pix_map.draw_rectangle(gc, False, x0, y0, w, h) self.selection[1][0], self.selection[1][1] = int(x), int(y) self.draw_drawable() self.prev_y = [None, None, None] # Marked area point[0, 1][x, y] self.selection = [[None, None], [None, None]] self.drawing_area = gtk.DrawingArea() self.drawing_area.connect("expose_event", expose_event) self.drawing_area.connect("configure_event", configure_event) self.drawing_area.connect("button_press_event", button_press_event) self.drawing_area.connect("button_release_event", button_release_event) self.drawing_area.connect("motion_notify_event", motion_notify_event) self.drawing_area.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.LEAVE_NOTIFY_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK |gtk.gdk.POINTER_MOTION_HINT_MASK) self.scale_style = "dec" def draw_drawable(self): x, y, w, h = self.drawing_area.get_allocation() self.drawing_area.window.draw_drawable(self.drawing_area.get_style().fg_gc[gtk.STATE_NORMAL], self.pix_map, 0, 0, 0, 0, w, h) def plot(self): self.pix_map.draw_rectangle(self.drawing_area.get_style().white_gc, True, 0, 0, self.canvas_width, self.canvas_height) if (self.scale_style == "cust"): #draw cross self.pix_map.draw_lines(self.gc['black'], [(int(round(self.canvas_x(0))),0),(int(round(self.canvas_x(0))),self.canvas_height)]) self.pix_map.draw_lines(self.gc['black'], [(0,int(round(self.canvas_y(0)))),(self.canvas_width,int(round(self.canvas_y(0))))]) # old style axis marks iv = self.x_scale * self.canvas_width / (self.x_max - self.x_min) # pixel interval between marks os = self.canvas_x(0) % iv # pixel offset of first mark # loop over each mark. for i in xrange(int(self.canvas_width / iv + 1)): #multiples of iv, cause adding of any error in iv, so keep iv as float # use round(), to get to closest pixel, int() to prevent warning self.pix_map.draw_lines(self.gc['black'], [(int(round(os + i * iv)), int(round(self.canvas_y(0) - 5))), (int(round(os + i * iv)), int(round(self.canvas_y(0) + 5)))]) # and the y-axis iv = self.y_scale * self.canvas_height / (self.y_max - self.y_min) os = self.canvas_y(0) % iv for i in xrange(int(self.canvas_height / iv + 1)): self.pix_map.draw_lines(self.gc['black'], [(int(round(self.canvas_x(0) - 5)), int(round(i * iv + os))), (int(round(self.canvas_x(0) + 5)), int(round(i * iv + os)))]) else: #new style factor = 1 if (self.scale_style == "rad"): factor = pi # where to put the numbers numbers_x_pos = -10 numbers_y_pos = 10 # where to center the axis center_x_pix = int(round(self.canvas_x(0))) center_y_pix = int(round(self.canvas_y(0))) if (center_x_pix < 5): center_x_pix = 5 if (center_x_pix < 20):numbers_x_pos = 10 if (center_y_pix < 5): center_y_pix = 5 if (center_x_pix > self.canvas_width - 5): center_x_pix = self.canvas_width - 5 if (center_y_pix > self.canvas_height -5): center_y_pix = self.canvas_height - 5; if (center_y_pix > self.canvas_height -20): numbers_y_pos = - 10 # draw cross self.pix_map.draw_lines(self.gc['black'], [(center_x_pix,0),(center_x_pix,self.canvas_height)]) self.pix_map.draw_lines(self.gc['black'], [(0,center_y_pix),(self.canvas_width,center_y_pix)]) for i in marks(self.x_min / factor, self.x_max / factor): label = '%g' % i if (self.scale_style == "rad"): label += '\xCF\x80' i = i * factor self.pix_map.draw_lines(self.gc['black'], [(int(round(self.canvas_x(i))), center_y_pix - 5), (int(round(self.canvas_x(i))), center_y_pix + 5)]) self.layout.set_text(label) extents = self.layout.get_pixel_extents()[1] if (numbers_y_pos < 0): adjust = extents[3] else: adjust = 0 self.pix_map.draw_layout(self.gc['black'],int(round(self.canvas_x(i))), center_y_pix + numbers_y_pos - adjust,self.layout) for i in marks(self.y_min,self.y_max): label = '%g' % i self.pix_map.draw_lines(self.gc['black'], [(center_x_pix - 5, int(round(self.canvas_y(i)))), (center_x_pix + 5, int(round(self.canvas_y(i))))]) self.layout.set_text(label) extents = self.layout.get_pixel_extents()[1] if (numbers_x_pos < 0): adjust = extents[2] else: adjust = 0 self.pix_map.draw_layout(self.gc['black'],center_x_pix +numbers_x_pos - adjust,int(round(self.canvas_y(i))),self.layout) # minor marks for i in marks(self.x_min / factor, self.x_max / factor, minor=10): i = i * factor self.pix_map.draw_lines(self.gc['black'], [(int(round(self.canvas_x(i))), center_y_pix - 2), (int(round(self.canvas_x(i))), center_y_pix +2)]) for i in marks(self.y_min, self.y_max, minor=10): label = '%g' % i self.pix_map.draw_lines(self.gc['black'], [(center_x_pix - 2, int(round(self.canvas_y(i)))), (center_x_pix +2, int(round(self.canvas_y(i))))]) plots = [] # precompile the functions try: compiled_y1 = compile(y1.replace("^","**"),"",'eval') plots.append((compiled_y1,0,self.gc['blue'])) except: compiled_y1 = None try: compiled_y2 = compile(y2.replace("^","**"),"",'eval') plots.append((compiled_y2,1,self.gc['red'])) except: compiled_y2 = None try: compiled_y3 = compile(y3.replace("^","**"),"",'eval') plots.append((compiled_y3,2,self.gc['green'])) except: compiled_y3 = None self.prev_y = [None, None, None] if enable_profiling: start_graph = time() if len(plots) != 0: for i in xrange(0,self.canvas_width,x_res): x = self.graph_x(i + 1) for e in plots: safe_dict['x']=x try: y = eval(e[0],{"__builtins__":{}},safe_dict) y_c = int(round(self.canvas_y(y))) if y_c < 0 or y_c > self.canvas_height: raise ValueError if connect_points and self.prev_y[e[1]] is not None: self.pix_map.draw_lines(e[2], [(i, self.prev_y[e[1]]), (i + x_res, y_c)]) else: self.pix_map.draw_points(e[2], [(i + x_res, y_c)]) self.prev_y[e[1]] = y_c except: #print "Error at %d: %s" % (x, sys.exc_value) self.prev_y[e[1]] = None if enable_profiling: print "time to draw graph:", (time() - start_graph) * 1000, "ms" self.draw_drawable() def canvas_x(self, x): "Calculate position on canvas to point on graph" return (x - self.x_min) * self.canvas_width / (self.x_max - self.x_min) def canvas_y(self, y): return (self.y_max - y) * self.canvas_height / (self.y_max - self.y_min) def canvas_point(self, x, y): return (self.canvas_x(x), self.canvas_y(y)) def graph_x(self, x): "Calculate position on graph from point on canvas" return x * (self.x_max - self.x_min) / self.canvas_width + self.x_min def graph_y(self, y): return self.y_max - (y * (self.y_max - self.y_min) / self.canvas_height) def menu_toolbar_create(): app_win.menu_main = gtk.MenuBar() menu_file = gtk.Menu() menu_item_file = gtk.MenuItem(_("_File")) menu_item_file.set_submenu(menu_file) actions.save = gtk.Action("Save", _("_Save"), _("Save graph as bitmap"), gtk.STOCK_SAVE) actions.save.connect ("activate", save) actions.add_action(actions.save) menu_item_save = actions.save.create_menu_item() menu_item_save.add_accelerator("activate", app_win.accel_group, ord("S"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menu_item_save) actions.quit = gtk.Action("Quit", _("_Quit"), _("Quit Application"), gtk.STOCK_QUIT) actions.quit.connect ("activate", quit_dlg) actions.add_action(actions.quit) menuItem_quit = actions.quit.create_menu_item() menuItem_quit.add_accelerator("activate", app_win.accel_group, ord("Q"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuItem_quit) menu_graph = gtk.Menu() menu_item_graph = gtk.MenuItem(_("_Graph")) menu_item_graph.set_submenu(menu_graph) actions.plot = gtk.Action("Plot", _("P_lot"), _("Plot Functions"), gtk.STOCK_REFRESH) actions.plot.connect ("activate", plot) actions.add_action(actions.plot) menu_item_plot = actions.plot.create_menu_item() menu_item_plot.add_accelerator("activate", app_win.accel_group, ord("l"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_graph.append(menu_item_plot) actions.evaluate = gtk.Action("Evaluate", _("_Evaluate"), _("Evaluate Functions"), gtk.STOCK_EXECUTE) actions.evaluate.connect ("activate", evaluate) actions.add_action(actions.evaluate) menu_item_evaluate = actions.evaluate.create_menu_item() menu_item_evaluate.add_accelerator("activate", app_win.accel_group, ord("e"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_graph.append(menu_item_evaluate) actions.zoom_in = gtk.Action("zoom_in", _("Zoom _In"), _("Zoom In"), gtk.STOCK_ZOOM_IN) actions.zoom_in.connect ("activate", zoom_in) actions.add_action(actions.zoom_in) menu_item_zoomin = actions.zoom_in.create_menu_item() menu_item_zoomin.add_accelerator("activate", app_win.accel_group, ord("+"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_graph.append(menu_item_zoomin) actions.zoom_out = gtk.Action("zoom_out", _("Zoom _Out"), _("Zoom Out"), gtk.STOCK_ZOOM_OUT) actions.zoom_out.connect ("activate", zoom_out) actions.add_action(actions.zoom_out) menu_item_zoomout = actions.zoom_out.create_menu_item() menu_item_zoomout.add_accelerator("activate", app_win.accel_group, ord("-"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_graph.append(menu_item_zoomout) actions.zoom_reset = gtk.Action("zoom_reset", _("Zoom _Reset"), _("Zoom Reset"), gtk.STOCK_ZOOM_100) actions.zoom_reset.connect ("activate", zoom_reset) actions.add_action(actions.zoom_reset) menu_item_zoomreset = actions.zoom_reset.create_menu_item() menu_item_zoomreset.add_accelerator("activate", app_win.accel_group, ord("r"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_graph.append(menu_item_zoomreset) menu_item_toggle_connect = gtk.CheckMenuItem(_("_Connect Points")) menu_item_toggle_connect.set_active(True) menu_item_toggle_connect.connect ("toggled", toggle_connect) menu_graph.append(menu_item_toggle_connect) menu_scale_style = gtk.Menu() menu_item_scale_style = gtk.MenuItem(_("Scale Style")) menu_item_scale_style.set_submenu(menu_scale_style) menu_graph.append(menu_item_scale_style) actions.dec = gtk.Action("Dec", _("Decimal"), _("Set style to decimal"),None) actions.dec.connect ("activate", scale_dec) actions.add_action(actions.dec) menu_item_dec = actions.dec.create_menu_item() menu_scale_style.append(menu_item_dec) actions.rad = gtk.Action("Rad", _("Radians"), _("Set style to radians"),None) actions.rad.connect ("activate", scale_rad) actions.add_action(actions.rad) menu_item_rad = actions.rad.create_menu_item() menu_scale_style.append(menu_item_rad) actions.cust = gtk.Action("Cust", _("Custom"), _("Set style to custom"),None) actions.cust.connect ("activate", scale_cust) actions.add_action(actions.cust) menu_item_cust = actions.cust.create_menu_item() menu_scale_style.append(menu_item_cust) menu_help = gtk.Menu() menu_item_help = gtk.MenuItem(_("_Help")) menu_item_help.set_submenu(menu_help) actions.Help = gtk.Action("Help", _("_Contents"), _("Help Contents"), gtk.STOCK_HELP) actions.Help.connect ("activate", show_yelp) actions.add_action(actions.Help) menu_item_contents = actions.Help.create_menu_item() menu_item_contents.add_accelerator("activate", app_win.accel_group, gtk.gdk.keyval_from_name("F1"), 0, gtk.ACCEL_VISIBLE) menu_help.append(menu_item_contents) actions.about = gtk.Action("About", _("_About"), _("About Box"), gtk.STOCK_ABOUT) actions.about.connect ("activate", show_about_dialog) actions.add_action(actions.about) menu_item_about = actions.about.create_menu_item() menu_help.append(menu_item_about) app_win.menu_main.append(menu_item_file) app_win.menu_main.append(menu_item_graph) app_win.menu_main.append(menu_item_help) app_win.tool_bar = gtk.Toolbar() app_win.tool_bar.insert(actions.plot.create_tool_item(), -1) app_win.tool_bar.insert(actions.evaluate.create_tool_item(), -1) app_win.tool_bar.insert(gtk.SeparatorToolItem(), -1) app_win.tool_bar.insert(actions.zoom_in.create_tool_item(), -1) app_win.tool_bar.insert(actions.zoom_out.create_tool_item(), -1) app_win.tool_bar.insert(actions.zoom_reset.create_tool_item(), -1) app_win.tool_bar.insert(gtk.SeparatorToolItem(), -1) app_win.tool_bar.insert(actions.quit.create_tool_item(), -1) def plot(widget, event=None): global x_max, x_min, x_scale, y_max, y_min, y_scale, y1, y2, y3 x_max = app_win.x_max_entry.get_text() x_min = app_win.x_min_entry.get_text() x_scale = app_win.x_scale_entry.get_text() y_max = app_win.y_max_entry.get_text() y_min = app_win.y_min_entry.get_text() y_scale = app_win.y_scale_entry.get_text() graph.x_max = eval(x_max,{"__builtins__":{}},safe_dict) graph.x_min = eval(x_min,{"__builtins__":{}},safe_dict) graph.x_scale = eval(x_scale,{"__builtins__":{}},safe_dict) graph.y_max = eval(y_max,{"__builtins__":{}},safe_dict) graph.y_min = eval(y_min,{"__builtins__":{}},safe_dict) graph.y_scale = eval(y_scale,{"__builtins__":{}},safe_dict) y1 = app_win.y1_entry.get_text() y2 = app_win.y2_entry.get_text() y3 = app_win.y3_entry.get_text() graph.plot() def evaluate(widget, event=None): "Evaluate a given x for the three functions" def entry_changed(self): for e in ((y1, dlg_win.y1_entry), (y2, dlg_win.y2_entry), (y3, dlg_win.y3_entry)): try: x = float(dlg_win.x_entry.get_text()) safe_dict['x']=x e[1].set_text(str(eval(e[0].replace("^","**"),{"__builtins__":{}},safe_dict))) except: if len(e[0]) > 0: e[1].set_text("Error: %s" % sys.exc_value) else: e[1].set_text("") def close(self): dlg_win.destroy() dlg_win = gtk.Window(gtk.WINDOW_TOPLEVEL) dlg_win.set_title(_("Evaluate")) dlg_win.connect("destroy", close) dlg_win.x_entry = gtk.Entry() dlg_win.x_entry.set_size_request(200, 24) dlg_win.x_entry.connect("changed", entry_changed) dlg_win.y1_entry = gtk.Entry() dlg_win.y1_entry.set_size_request(200, 24) dlg_win.y1_entry.set_sensitive(False) dlg_win.y2_entry = gtk.Entry() dlg_win.y2_entry.set_size_request(200, 24) dlg_win.y2_entry.set_sensitive(False) dlg_win.y3_entry = gtk.Entry() dlg_win.y3_entry.set_size_request(200, 24) dlg_win.y3_entry.set_sensitive(False) table = gtk.Table(2, 5) label = gtk.Label("x = ") label.set_alignment(0, .5) table.attach(label, 0, 1, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(dlg_win.x_entry, 1, 2, 0, 1) label = gtk.Label("y1 = ") label.set_alignment(0, .5) label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("blue")) table.attach(label, 0, 1, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(dlg_win.y1_entry, 1, 2, 1, 2) label = gtk.Label("y2 = ") label.set_alignment(0, .5) label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red")) table.attach(label, 0, 1, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(dlg_win.y2_entry, 1, 2, 2, 3) label = gtk.Label("y3 = ") label.set_alignment(0, .5) label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("DarkGreen")) table.attach(label, 0, 1, 3, 4, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(dlg_win.y3_entry, 1, 2, 3, 4) table.set_border_width(24) dlg_win.add(table) dlg_win.show_all() def zoom_in(widget, event=None): "Narrow the plotted section by half" center_x = (graph.x_min + graph.x_max) / 2 center_y = (graph.y_min + graph.y_max) / 2 range_x = (graph.x_max - graph.x_min) range_y = (graph.y_max - graph.y_min) graph.x_min = center_x - (range_x / 4) graph.x_max = center_x + (range_x / 4) graph.y_min = center_y - (range_y / 4) graph.y_max = center_y +(range_y / 4) parameter_entries_repopulate() graph.plot() def zoom_out(widget, event=None): "Double the plotted section" center_x = (graph.x_min + graph.x_max) / 2 center_y = (graph.y_min + graph.y_max) / 2 range_x = (graph.x_max - graph.x_min) range_y = (graph.y_max - graph.y_min) graph.x_min = center_x - (range_x) graph.x_max = center_x + (range_x) graph.y_min = center_y - (range_y) graph.y_max = center_y +(range_y) parameter_entries_repopulate() graph.plot() def zoom_reset(widget, event=None): "Set the range back to the user's input" graph.x_min = eval(x_min,{"__builtins__":{}},safe_dict) graph.y_min = eval(y_min,{"__builtins__":{}},safe_dict) graph.x_max = eval(x_max,{"__builtins__":{}},safe_dict) graph.y_max = eval(y_max,{"__builtins__":{}},safe_dict) parameter_entries_populate() graph.plot() def scale_dec(widget, event=None): graph.scale_style = "dec" app_win.scale_box.hide() plot(None) def scale_rad(widget, event=None): graph.scale_style = "rad" app_win.scale_box.hide() plot(None) def scale_cust(widget, event=None): graph.scale_style = "cust" app_win.scale_box.show() plot(None) def toggle_connect(widget, event=None): "Toggle between a graph that connects points with lines and one that does not" global connect_points connect_points = not connect_points graph.plot() def save(widget, event=None): "Save graph as .png" file_dialog = gtk.FileChooserDialog(_("Save as..."), app_win, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) file_dialog.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.add_mime_type("image/png") filter.add_pattern("*.png") file_dialog.add_filter(filter) file_dialog.set_filename("FunctionGraph.png") response = file_dialog.run() if response == gtk.RESPONSE_OK: x, y, w, h = graph.drawing_area.get_allocation() pix_buffer = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h) pix_buffer.get_from_drawable(graph.pix_map, graph.pix_map.get_colormap(), 0, 0, 0, 0, w, h) pix_buffer.save(file_dialog.get_filename(), "png") file_dialog.destroy() def quit_dlg(widget, event=None): gtk.main_quit() def show_yelp(widget): #import os #os.system("yelp /usr/share/gnome/help/lybniz/C/lybniz-manual.xml") try: gnome.help_display("lybniz") except: print _("Can't Show help") def show_about_dialog(widget): about_dialog = gtk.AboutDialog() about_dialog.set_name("Lybniz") about_dialog.set_version(str(app_version)) #about_dialog.set_copyright(u"© 2005 by Thomas Führinger") about_dialog.set_authors([u"Thomas Führinger","Sam Tygier"]) about_dialog.set_comments(_("Function graph Plotter")) about_dialog.set_license("Revised BSD") about_dialog.set_website("http://lybniz2.sourceforge.net/") try: lybniz_icon = gtk.gdk.pixbuf_new_from_file(icon_file) about_dialog.set_logo(lybniz_icon) except: print "icon not found at", icon_file about_dialog.connect ("response", lambda d, r: d.destroy()) about_dialog.run() def parameter_entries_create(): # create text entries for parameters table = gtk.Table(6, 3) app_win.y1_entry = gtk.Entry() app_win.y1_entry.set_size_request(300, 24) app_win.y2_entry = gtk.Entry() app_win.y3_entry = gtk.Entry() app_win.x_min_entry = gtk.Entry() app_win.x_min_entry.set_size_request(90, 24) app_win.x_min_entry.set_alignment(1) app_win.x_max_entry = gtk.Entry() app_win.x_max_entry.set_size_request(90, 24) app_win.x_max_entry.set_alignment(1) app_win.x_scale_entry = gtk.Entry() app_win.x_scale_entry.set_size_request(90, 24) app_win.x_scale_entry.set_alignment(1) app_win.y_min_entry = gtk.Entry() app_win.y_min_entry.set_size_request(90, 24) app_win.y_min_entry.set_alignment(1) app_win.y_max_entry = gtk.Entry() app_win.y_max_entry.set_size_request(90, 24) app_win.y_max_entry.set_alignment(1) app_win.y_scale_entry = gtk.Entry() app_win.y_scale_entry.set_size_request(90, 24) app_win.y_scale_entry.set_alignment(1) parameter_entries_populate() app_win.y1_entry.connect("key-press-event", key_press_plot) app_win.y2_entry.connect("key-press-event", key_press_plot) app_win.y3_entry.connect("key-press-event", key_press_plot) app_win.x_min_entry.connect("key-press-event", key_press_plot) app_win.y_min_entry.connect("key-press-event", key_press_plot) app_win.x_max_entry.connect("key-press-event", key_press_plot) app_win.y_max_entry.connect("key-press-event", key_press_plot) app_win.x_scale_entry.connect("key-press-event", key_press_plot) app_win.y_scale_entry.connect("key-press-event", key_press_plot) app_win.scale_box = gtk.HBox() label = gtk.Label("y1 = ") label.set_alignment(0, .5) label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("blue")) table.attach(label, 0, 1, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(app_win.y1_entry, 1, 2, 0, 1) label = gtk.Label(_("X min")) label.set_alignment(1, .5) table.attach(label, 2, 3, 0, 1, xpadding=5, ypadding=7, xoptions=gtk.FILL) table.attach(app_win.x_min_entry, 3, 4, 0, 1, xoptions=gtk.FILL) label = gtk.Label(_("Y min")) label.set_alignment(1, .5) table.attach(label, 4, 5, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(app_win.y_min_entry, 5, 6, 0, 1, xpadding=5, xoptions=gtk.FILL) label = gtk.Label("y2 = ") label.set_alignment(0, .5) label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red")) table.attach(label, 0, 1, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(app_win.y2_entry, 1, 2, 1, 2) label = gtk.Label(_("X max")) label.set_alignment(1, .5) table.attach(label, 2, 3, 1, 2, xpadding=5, ypadding=7, xoptions=gtk.FILL) table.attach(app_win.x_max_entry, 3, 4, 1, 2, xoptions=gtk.FILL) label = gtk.Label(_("Y max")) label.set_alignment(1, .5) table.attach(label, 4, 5, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(app_win.y_max_entry, 5, 6, 1, 2, xpadding=5, xoptions=gtk.FILL) label = gtk.Label("y3 = ") label.set_alignment(0, .5) label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("DarkGreen")) table.attach(label, 0, 1, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL) table.attach(app_win.y3_entry, 1, 2, 2, 3) label = gtk.Label(_("X scale")) label.set_alignment(0, .5) app_win.scale_box.add(label) #table.attach(label, 2, 3, 2, 3, xpadding=5, ypadding=7, xoptions=gtk.FILL) #table.attach(app_win.x_scale_entry, 3, 4, 2, 3, xoptions=gtk.FILL) app_win.scale_box.add(app_win.x_scale_entry) label = gtk.Label(_("Y scale")) label.set_alignment(0, .5) app_win.scale_box.add(label) #table.attach(label, 4, 5, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL) #table.attach(app_win.y_scale_entry, 5, 6, 2, 3, xpadding=5, xoptions=gtk.FILL) app_win.scale_box.add(app_win.y_scale_entry) table.attach(app_win.scale_box, 2, 6, 2, 3, xpadding=5, xoptions=gtk.FILL) return table def parameter_entries_populate(): # set text in entries for parameters with user's input app_win.y1_entry.set_text(y1) app_win.y2_entry.set_text(y2) app_win.y3_entry.set_text(y3) app_win.x_min_entry.set_text(x_min) app_win.x_max_entry.set_text(x_max) app_win.x_scale_entry.set_text(x_scale) app_win.y_min_entry.set_text(y_min) app_win.y_max_entry.set_text(y_max) app_win.y_scale_entry.set_text(y_scale) def parameter_entries_repopulate(): # set text in entries for parameters app_win.y1_entry.set_text(y1) app_win.y2_entry.set_text(y2) app_win.y3_entry.set_text(y3) app_win.x_min_entry.set_text(str(graph.x_min)) app_win.x_max_entry.set_text(str(graph.x_max)) app_win.x_scale_entry.set_text(str(graph.x_scale)) app_win.y_min_entry.set_text(str(graph.y_min)) app_win.y_max_entry.set_text(str(graph.y_max)) app_win.y_scale_entry.set_text(str(graph.y_scale)) def key_press_plot(widget, event): if event.keyval == 65293: plot(None) return True else: return False def main(): global app_win, graph app_win = gtk.Window(gtk.WINDOW_TOPLEVEL) app_win.set_title("Lybniz") app_win.set_default_size(800, 600) app_win.connect("delete-event", quit_dlg) try: app_win.set_icon_from_file(icon_file) except: print "icon not found at", icon_file app_win.accel_group = gtk.AccelGroup() app_win.add_accel_group(app_win.accel_group) app_win.v_box = gtk.VBox(False, 1) app_win.v_box.set_border_width(1) app_win.add(app_win.v_box) app_win.status_bar = gtk.Statusbar() app_win.status_bar.ContextId = app_win.status_bar.get_context_id("Dummy") menu_toolbar_create() app_win.v_box.pack_start(app_win.menu_main, False, True, 0) handle_box = gtk.HandleBox() handle_box.add(app_win.tool_bar) app_win.v_box.pack_start(handle_box, False, True, 0) app_win.v_box.pack_start(parameter_entries_create(), False, True, 4) graph = GraphClass() app_win.v_box.pack_start(graph.drawing_area, True, True, 0) app_win.v_box.pack_start(app_win.status_bar, False, True, 0) app_win.show_all() app_win.scale_box.hide() gtk.main() # Start it all if __name__ == '__main__': main()