I have two windows, one main window which lies behind second window.
How can i move the second window along with main window, when ever the main window
moves. And second window is ordinary window, it will have reference to main window.
Regards,
iSight
I saw this question when I tried to answer this one: How do you save a gui to file in GtkD?
The demo code is modified to answer your question, and here it is:
#!/usr/bin/env python3
from gi.repository import Gtk
import json
import os
class Demo():
def __init__(self):
self.conf_name = 'demo.json'
self.read_config()
self.init_widgets()
self.init_window_position()
def init_widgets(self):
self.window = Gtk.Window()
self.window.set_title('window 1')
self.window.connect('check-resize', self.on_window_check_resize)
self.window.connect('configure-event',
self.on_window_configure_event)
self.window.connect('destroy', self.on_app_exit)
label = Gtk.Label('hello, world')
self.window.add(label)
self.window2 = Gtk.Window()
self.window2.set_title('window 2')
self.window2.connect('configure-event',
self.on_window2_configure_event)
def init_window_position(self):
# restore window size and position.
# we need to read these values from app configuration.
self.window.move(self.conf['window_x'], self.conf['window_y'])
self.window2.move(self.conf['window_x'] + self.conf['pos_diff_x'],
self.conf['window_y'] + self.conf['pos_diff_y'])
self.window.set_default_size(self.conf['window_width'],
self.conf['window_height'])
def read_config(self):
if os.path.isfile(self.conf_name):
with open(self.conf_name) as fh:
self.conf = json.loads(fh.read())
else:
# default configuration.
self.conf = {
'window_x': 100,
'window_y': 100,
'window_width': 320,
'window_height': 240,
# distance between window1 and window2 in x dimention.
'pos_diff_x': 120,
# distance between window1 and window2 in y dimention.
'pos_diff_y': 120,
}
def write_config(self):
with open(self.conf_name, 'w') as fh:
fh.write(json.dumps(self.conf))
def run(self):
self.window.show_all()
self.window2.show_all()
Gtk.main()
def on_app_exit(self, widget):
# new setting is dumped when app exits.
self.write_config()
Gtk.main_quit()
def on_window_check_resize(self, window):
print('check resize')
width, height = self.window.get_size()
print('size: ', width, height)
self.conf['window_width'] = width
self.conf['window_height'] = height
def on_window_configure_event(self, window, event):
print('configure event')
x, y = self.window.get_position()
print('position:', x, y)
self.conf['window_x'] = x
self.conf['window_y'] = y
# now move window2.
self.window2.move(x + self.conf['pos_diff_x'],
y + self.conf['pos_diff_y'])
def on_window2_configure_event(self, window, event):
'''
If window2 is moved by user, pos_diff_x and pos_diff_y need to be
recalculated.
'''
print('window2 configure event')
x2, y2 = self.window2.get_position()
print('position: ', x2, y2)
self.conf['pos_diff_x'] = x2 - self.conf['window_x']
self.conf['pos_diff_y'] = y2 - self.conf['window_y']
if __name__ == '__main__':
demo = Demo()
demo.run()
And a screenshot:
you can connect to the configure-event of your first window and change position of the second window accordingly to x and y coordinates which are coming via GdkEvent structure. Below is a small example:
void configure_callback(GtkWindow *window, GdkEvent *event, gpointer data)
{
int x = event->configure.x;
int y = event->configure.y;
gtk_widget_set_uposition(GTK_WIDGET(data), x+220, y);
}
int main(int argc, char * argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window0 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window0), "Window 0");
gtk_widget_set_uposition(window0, 20, 40);
GtkWidget *window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window1), "Window 1");
gtk_widget_set_uposition(window1, 240, 40);
g_signal_connect_swapped(G_OBJECT(window0), "destroy",
G_CALLBACK(gtk_main_quit), G_OBJECT(window0));
g_signal_connect(G_OBJECT(window0), "configure-event",
G_CALLBACK(configure_callback), window1);
gtk_widget_show_all(window0);
gtk_widget_show_all(window1);
gtk_main();
return 0;
}
once you move "window 0", "window 1" should change its position accordingly.
hope this helps, regards
Related
I want to make a linear regression program which visualizes the data to user. I'm using EJML for calculations and ScalaFX for front end. Everything is going fine but when I plot the data using Scatter Chart, the line drawn from the data is set to be rectangles which cover up the original data points. I would like to know how I can change the size, shape and transparency etc. of the plotted points.
Almost all of guides around JavaFX say that I should modify the CSS file (which doesn't automatically exist) in order to style my chart. I don't know how to do that in ScalaFX or even that is it possible to do that way. My result of searching every possible tutorial has been fruitless.
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.chart.ScatterChart
import scalafx.collections.ObservableBuffer
import scalafx.scene.chart.NumberAxis
import scalafx.scene.chart.XYChart
import scalafx.scene.shape.Line
import org.ejml.simple.SimpleMatrix
import scala.math.pow
import scala.collection.mutable.Buffer
object Plotting extends JFXApp {
/*
* Below are some arbitrary x and y values for a regression line
*/
val xValues = Array(Array(1.0, 1.0, 1.0, 1.0, 1.0, 1.0), Array(14.0, 19.0, 22.0, 26.0, 31.0, 43.0))
val yValues = Array(Array(51.0, 57.0, 66.0, 71.0, 72.0, 84.0))
val temp = yValues.flatten
val wrapper = xValues(1).zip(temp)
/*
* In the lines before stage what happens is that matrices for the x and y values are created, coefficients
* for the regression line are calculated with matrix operations and (x, y) points are calculated for the
* regression line.
*/
val X = new SimpleMatrix(xValues).transpose
val Y = new SimpleMatrix(yValues).transpose
val secondX = new SimpleMatrix(xValues(0).size, 2)
for (i <- 0 until xValues(0).size) {
secondX.set(i, 0, xValues(0)(i))
secondX.set(i, 1, xValues(1)(i))
}
val invertedSecondX = secondX.pseudoInverse()
val B = invertedSecondX.mult(Y)
val graphPoints = Buffer[(Double, Double)]()
for (i <- 0 to xValues(1).max.toInt) {
graphPoints.append((i.toDouble, B.get(0, 0) + i * B.get(1, 0)))
}
stage = new JFXApp.PrimaryStage {
title = "Demo"
scene = new Scene(400, 400) {
val xAxis = NumberAxis()
val yAxis = NumberAxis()
val pData = XYChart.Series[Number, Number](
"Data",
ObservableBuffer(wrapper.map(z => XYChart.Data[Number, Number](z._1, z._2)): _*))
val graph = XYChart.Series[Number, Number](
"RegressionLine",
ObservableBuffer(graphPoints.map(z => XYChart.Data[Number, Number](z._1, z._2)): _*))
val plot = new ScatterChart(xAxis, yAxis, ObservableBuffer(graph, pData))
root = plot
}
}
}
This certainly isn't as well documented as it might be... :-(
Stylesheets are typically placed in your project's resource directory. If you're using SBT (recommended), this would be src/main/resources.
In this example, I've added a stylesheet called MyCharts.css to this directory with the following contents:
/* Blue semi-transparent 4-pointed star, using SVG path. */
.default-color0.chart-symbol {
-fx-background-color: blue;
-fx-scale-shape: true;
-fx-shape: "M 0.0 10.0 L 3.0 3.0 L 10.0 0.0 L 3.0 -3.0 L 0.0 -10.0 L -3.0 -3.0 L -10.0 0.0 L -3.0 3.0 Z ";
-fx-opacity: 0.5;
}
/* Default shape is a rectangle. Here, we round it to become a red circle with a white
* center. Change the radius to control the size.
*/
.default-color1.chart-symbol {
-fx-background-color: red, white;
-fx-background-insets: 0, 2;
-fx-background-radius: 3px;
-fx-padding: 3px;
}
color0 will be used for the first data series (the regression line), color1 for the second (your scatter data). All other series use the default, JavaFX style.
(For more information on using scalable vector graphics (SVG) paths to define custom shapes, refer to the relevant section of the SVG specification.)
To have this stylesheet used by ScalaFX (JavaFX), you have a choice of options. To have them apply globally, add it to the main scene (which is what I've done below). Alternatively, if each chart needs a different style, you can add different stylesheets to specific charts. (BTW, I also added the standard includes import as this prevents many JavaFX-ScalaFX element conversion issues; otherwise, I've made no changes to your sources.)
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.chart.ScatterChart
import scalafx.collections.ObservableBuffer
import scalafx.scene.chart.NumberAxis
import scalafx.scene.chart.XYChart
import scalafx.scene.shape.Line
import org.ejml.simple.SimpleMatrix
import scala.math.pow
import scala.collection.mutable.Buffer
object Plotting extends JFXApp {
/*
* Below are some arbitrary x and y values for a regression line
*/
val xValues = Array(Array(1.0, 1.0, 1.0, 1.0, 1.0, 1.0), Array(14.0, 19.0, 22.0, 26.0, 31.0, 43.0))
val yValues = Array(Array(51.0, 57.0, 66.0, 71.0, 72.0, 84.0))
val temp = yValues.flatten
val wrapper = xValues(1).zip(temp)
/*
* In the lines before stage what happens is that matrices for the x and y values are created, coefficients
* for the regression line are calculated with matrix operations and (x, y) points are calculated for the
* regression line.
*/
val X = new SimpleMatrix(xValues).transpose
val Y = new SimpleMatrix(yValues).transpose
val secondX = new SimpleMatrix(xValues(0).size, 2)
for (i <- 0 until xValues(0).size) {
secondX.set(i, 0, xValues(0)(i))
secondX.set(i, 1, xValues(1)(i))
}
val invertedSecondX = secondX.pseudoInverse()
val B = invertedSecondX.mult(Y)
val graphPoints = Buffer[(Double, Double)]()
for (i <- 0 to xValues(1).max.toInt) {
graphPoints.append((i.toDouble, B.get(0, 0) + i * B.get(1, 0)))
}
stage = new JFXApp.PrimaryStage {
title = "Demo"
scene = new Scene(400, 400) {
// Add our stylesheet.
stylesheets.add("MyCharts.css")
val xAxis = NumberAxis()
val yAxis = NumberAxis()
val pData = XYChart.Series[Number, Number](
"Data",
ObservableBuffer(wrapper.map(z => XYChart.Data[Number, Number](z._1, z._2)): _*))
val graph = XYChart.Series[Number, Number](
"RegressionLine",
ObservableBuffer(graphPoints.map(z => XYChart.Data[Number, Number](z._1, z._2)): _*))
val plot = new ScatterChart(xAxis, yAxis, ObservableBuffer(graph, pData))
root = plot
}
}
}
For further information in the CSS formatting options available (changing shapes, colors, transparency, etc.) refer to the JavaFX CSS Reference Guide.
The result looks like this:
I almost don't dare to add somethig to Mike Allens solution (wich is very good, as always), but this did not work out for me because I could not get my scala to find and/or process the .css file.
I would have done it this way if possible, but I just could not get it to work.
Here is what I came up with:
Suppose I have some data to display:
val xyExampleData: ObservableBuffer[(Double, Double)] = ObservableBuffer(Seq(
1 -> 1,
2 -> 4,
3 -> 9))
Then I convert this to a Series for the LineChart:
val DataPoints = ObservableBuffer(xyExampleData map { case (x, y) => XYChart.Data[Number, Number](x, y) })
val PointsToDisplay = XYChart.Series[Number, Number]("Points", DataPoints)
now I put this again into a Buffer, maybe with some other data from different series.
val lineChartBuffer = ObservableBuffer(PointsToDisplay, ...)
and finally I create my lineChart, wich I call (with lack of creativity) lineChart:
val lineChart = new LineChart(xAxis, yAxis, lineChartBuffer) {...}
The lines between data points can be recoloured now easily with:
lineChart.lookup(".default-color0.chart-series-line").setStyle("-fx-stroke: blue;")
This will change the Line-colour of the FIRST Dataset in the LineChartBuffer.
If you want to change the Line-Properties for the second you call
lineChart.lookup(".default-color1.chart-series-line")...
There is also "-fx-stroke-width: 3px;" to set the with of the line.
"-fx-opacity: 0.1;"
"-fx-stroke-dash-array: 10;"
-fx-fill: blue;"
are also usefull, but dont call the above line repeatedly, because the second call will override the first.
Instead concatenate all the strings into one:
lineChart.lookup(".default-color0.chart-series-line").setStyle("-fx-stroke: blue;-fx-opacity: 0.1;-fx-stroke-dash-array: 10;-fx-fill: blue;")
Now for the formatting of the Symbols at each data-Point:
unfortunately there seems to be no other way than to format each Symbol seperately:
lineChart.lookupAll(".default-color0.chart-line-symbol").asScala foreach { node => node.setStyle("-fx-background-color: blue, white;") }
for this to run you need import scala.collection.JavaConverters._
for the conversion from a java set to a scala set.
One can also make all data-poins from only one data-set invisible, for example:
lineChart.lookupAll(".default-color1.chart-line-symbol").asScala foreach { node => node.setVisible(false) }
To say this is a nice solution would be exaggerated.
And it has the big disadvantage, that you have to recolour or reformat every Symbol after adding a new Datapoint to one of the series in LineChartBuffer. If you don't, the new Symbols will have standard colours and settings.
The Lines stay, ones they are recoloured, I can't say why.
But the good side of it, one can always reformat curves in a Line Chart afterwards like this!
I'm not able to draw, i've already read tutorials, i can't find the problem.
I simply have a correct UI drawed by Glade. Then i want to draw, for example 50 drawing areas. So i create a Grid with 50 cells; for each cell there is a vertical box (with a drawing area and a label inside each one). But i can't seen anything drawed.
class collega_GUI:
def __init__(self):
try:
self.__builder = Gtk.Builder()
self.__builder.add_from_file('UI2.glade')
self.__Grid = Gtk.Grid()
self.__Grid.set_margin_left(20)
self.__Grid.set_margin_right(20)
self.__Grid.set_row_spacing(10)
self.__Grid.set_column_spacing(15)
self.__Grid.set_column_homogeneous(True)
self.__GridBox = self.__builder.get_object('box11')
self.__GridBox.pack_end(self.__Grid, 1, 1, 20)
indirizzi_ip = []
for i in range(50):
indirizzi_ip.append(str(i))
cpu_info = {}
for ip in indirizzi_ip:
cpu_info[ip] = dict()
left = 0
right = 0
for ip in indirizzi_ip:
cpu_info[ip]['drawing_area'] = Gtk.DrawingArea()
cpu_info[ip]['drawing_area'].set_size_request(100, 100)
cpu_info[ip]['drawing_area'].set_name(ip)
box = Gtk.VBox(False, 5)
box.add(cpu_info[ip]['drawing_area'])
label = Gtk.Label(ip)
box.add(label)
self.__Grid.attach(box, left, right, 1, 1) #object,left,right,top,bottom
cpu_info[ip]['drawing_area'].connect("draw", self.__draw)
label.show()
cpu_info[ip]['drawing_area'].show() #the draw should start now!
box.show()
# 5 drawing areas in a row
left += 1
if left == 5:
right += 1
left = 0
self.__builder.get_object('Azioni_Window').show()
Gtk.main()
except Exception as xe:
logging.error('%s' % str(xe))
sys.exit()
def __draw(self, widget, context):
context.set_source_rgb(0.9, 0, 0.1) #rosso
context.set_source_rgb(0.1, 0.9, 0) #verde
context.set_source_rgb(0.8, 0.7, 0) #giallo
context.set_source_rgb(0.8, 0.7, 0.8) #inattivo
context.rectangle(0, 0, widget.get_allocated_width(), widget.get_allocated_height())
context.fill()
if __name__=='__main__':
try:
UINX=collega_GUI()
except Exception:
sys.exit()
You're missing
self.__Grid.show()
And hence nothing in the grid is shown.
In general it's easier to just call show_all() on some top-level container rather than trying to remember to show() every individual widget.
What I'm trying to do is take numerous(up to 48) 1024x768 images that are color coded images(weather maps, the precip overlay) and add up the precip to fall over the course of time. When I run into non-precip I want to take a box 5x5 around the pixel in question and average the value and use that value as the value of the pixel in question.
I can do this but it takes a long time to accomplish it. I have heard numpy could improve the speed but I still haven't been able to wrap my mind around how it going to improve the speed given the sequence of events that have to take place. It seems like I would still have to do it pixel by pixel. I've included an idea of the code I'm using to accomplish this SLOWLY.
I have this actually as two separate program, one to download the images and the other does the image processing(working up toward merging the two programs in the near future, just trying to get all the bugs worked out before the merger.) Hence some of the download coding may look a little strange. I figure I could probably write the file straight to a variable but I haven't been doing it that way so I stuck with a bit longer approach.
Is there anyway of increasing the speed? I don't see anyway of avoiding pixel by pixel due to the color coding scheme in place(look at the color bar in the lower left it shows the full color scheme...I only included part of it for demo purposes in the coding below.) Some of the coding may be a bit rough since I chopped from the two programs and put the important parts in here...it shows what I'm currently doing and gives the full idea of how I'm going about doing it.
Also, if you happen to see this three to four or more days after it was posted you would need to change the date in the download link to the current date. The files are only kept on the server for 3-4 days before they are removed.
from PIL import Image
import time
import urllib
import os
pathstr = '/'
url = 'http://mag.ncep.noaa.gov/GemPakTier/MagGemPakImages/gfs/20140216/00/gfs_namer_006_1000_500_thick.gif'
urllib.urlretrieve(url,str(pathstr + '20140216006.gif'))
url = 'http://mag.ncep.noaa.gov/GemPakTier/MagGemPakImages/gfs/20140216/00/gfs_namer_012_1000_500_thick.gif'
urllib.urlretrieve(url,str(pathstr + '20140216012.gif'))
url = 'http://mag.ncep.noaa.gov/GemPakTier/MagGemPakImages/gfs/20140216/00/gfs_namer_018_1000_500_thick.gif'
urllib.urlretrieve(url,str(pathstr + '20140216018.gif'))
url = 'http://mag.ncep.noaa.gov/GemPakTier/MagGemPakImages/gfs/20140216/00/gfs_namer_024_1000_500_thick.gif'
urllib.urlretrieve(url,str(pathstr + '20140216024.gif'))
class Convert():
def __init__(self):
self.colorscale2 = [(255,255,255),(127,255,0),(0,205,0),(145,44,238),(16,78,139),
(30,144,255),(0,178,238),(0,238,238),(137,104,205),(0,139,0),
(139,0,139),(139,0,0),(205,0,0),(238,64,0),(255,127,0),(205,133,0),
(255,215,0),(238,238,0),(255,255,0),(139,71,38),(255,0,0),(0,0,255),(0,0,0)]
self.x = 0
self.y = 0
self.grid = 0
self.moist = 0
self.scan = 0
self.turn = 0
self.precip = {}
start = time.time()
for i in range(6, 30, 6):
if i < 10:
filename = '/2014021600' + str(i) + '.gif'
else:
filename = '/201402160' + str(i) + '.gif'
self.im1 = Image.open(filename).convert('RGB')
self.image = self.im1.getdata()
self.size = width, height = self.im1.size
self.coordinates = self.x,self.y = width, height
self.getprecip()
self.turn = 1
print (time.time()-start)
def getprecip(self):
for self.x in range(81, 950):
for self.y in range(29, 749):
if self.turn == 0:
self.moist = 0
else:
self.moist = self.precip[self.x,self.y]
self.coordinates = self.x,self.y
self.scan = 0
self.imagescan()
if self.turn == 0:
self.precip[self.x,self.y] = self.moist
else:
self.precip[self.x,self.y] += self.moist
def imagescan(self):
if self.image[(self.y * 1024) + self.x] == self.colorscale2[0]:
self.moist =0
self.grid -=1
elif self.image[(self.y * 1024) + self.x] == self.colorscale2[1]:
self.moist =.01
elif self.image[(self.y * 1024) + self.x] == self.colorscale2[2]:
self.moist =.1
elif self.image[(self.y * 1024) + self.x] == self.colorscale2[3]:
self.moist =.25
elif self.image[(self.y * 1024) + self.x] == self.colorscale2[4]:
self.moist =.5
#on and on through self.colorscale2[18]
if self.scan == 1:
self.grid += 1
if self.scan == 0:
x = self.x
y = self.y
self.deliso540()
self.x = x
self.y = y
def deliso540(self):
self.grid = 1
self.scan = 1
for p in range(self.x-2,self.x+2):
for q in range(self.y-2,self.y+2):
self.x = p
self.y = q
self.imagescan()
self.moist = self.moist / self.grid
This question continue the question on the link : wxPython Event for ScrolledPanel. I edited the code a little bit so that OnScroll function get the x position of the content's scrollbar and use that to set x position of the header's scrollbar.
My problem is I cannot decide when the horizontal scrollbar is rolled. So my program now has the header's horizontal scrollbar rolled whenever any of the content's scrollbars is rolled while I want the header's h-scrollbar rolled when the content's h-scrollbar is rolled. (Or if anyone can suggest an event triggering by only when scrolling the horizontal bar it will be very good). Thanks ahead.
import wx
from wx.lib.scrolledpanel import ScrolledPanel
header = """
col1 col2 col3 col4 col5"""
text = """
1336 733 1336 4732 1217
5968 4477 1217 5748 4477
1217 5635 4372 1217 5634
4369 1217 5633 4371 217"""
class Test(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, size=(300, 200))
self.panel=panel = wx.Panel(self, -1)
vbox = wx.BoxSizer(wx.VERTICAL)
vboxA = wx.BoxSizer(wx.VERTICAL)
hbox = wx.BoxSizer(wx.HORIZONTAL)
self.headerPanel = headerPanel = ScrolledPanel(panel, -1, size=(150,32))
hboxHeader = wx.BoxSizer(wx.HORIZONTAL)
self.headertc = headertc = wx.TextCtrl(headerPanel, -1, header,
size=(500,32),style= wx.TE_READONLY)
headertc.Unbind(wx.EVT_SCROLLWIN)
hboxHeader.Add(headertc,1)
headerPanel.SetSizer(hboxHeader)
headerPanel.SetAutoLayout(1)
headerPanel.SetupScrolling(scroll_y = False)
hbox.Add(headerPanel,1, wx.EXPAND | wx.ALL,0)
vboxA.Add(hbox, 0, wx.EXPAND)
self.textPanel = textPanel = ScrolledPanel(panel, -1, size = (150,150))
textPanel.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
hboxText = wx.BoxSizer(wx.HORIZONTAL)
self.tc = tc = wx.TextCtrl(textPanel, -1, text, size=(500,500),
style=wx.TE_MULTILINE|wx.TE_DONTWRAP| wx.TE_READONLY)
hboxText.Add(tc, 1)
textPanel.SetSizer(hboxText)
textPanel.SetAutoLayout(1)
textPanel.SetupScrolling(scroll_x=True, scroll_y=True)
vboxA.Add(textPanel,1, wx.EXPAND | wx.ALL,0)
vbox.Add(vboxA, 1, wx.EXPAND | wx.ALL)
panel.SetSizer(vbox)
self.Centre()
self.Show(True)
def OnScroll(self, event):
event.Skip()
x= event.GetPosition()
self.headerPanel.Scroll(x,0)
print event.GetEventType()
if __name__ == "__main__":
app = wx.App()
frame = wx.Frame(None, -1)
win = Test(frame, "Test scroll bar")
app.MainLoop()
Use the following condition to check for horizontal scrolling in your scroll handler.
if event.Orientation == wx.SB_HORIZONTAL:
I want to drag an image along a horizontal line. In other words, I want to ignore the Y value of the mouse movement. I also want to limit the range of the X values. Here is a CoffeeScript class that drags an image, but attempts unsuccessfully to constrain the image's Y value. The other problem with this code is that the image's X value seems to be twice what it should be.
class TripleSlider
circle = ""
# (#x,#y) is coordinate of upper left corner of component bounding box
constructor: (#editArea, #x, #y, #tsLabel, #showLimits=false) ->
dragger: (x, y) =>
x2 = Math.min(Math.max(x, 0), 127)
circle.attr({x: x2, y:0}) # does not do anything; I hoped it would constrain Y
drawRaphael: () =>
paper = Raphael(10, 50, 320, 200)
paper.fixNS()
paper.draggable.enable()
circle = paper.image("/assets/images/sliderTipDef.png", 0, 0, 13, 16).draggable.enable()
circle.drag(#dragger)
$ ->
tripleSlider = new TripleSlider($('#editArea'), 50, 100, "Attribute", true)
tripleSlider.draw()
BTW, I applied the patch to raphael.draggable.js by inserting the code below at line 13.
/** Fix from https://github.com/DmitryBaranovskiy/raphael/issues/409
* Just call it once after constructing paper:
*
* var paper = Raphael(0, 0, 300, 300);
* paper.fixNS();
* paper.draggable.enable();
*/
Raphael.fn.fixNS = function() {
var r = this;
for (var ns_name in Raphael.fn) {
var ns = Raphael.fn[ns_name];
if (typeof ns == 'object') for (var fn in ns) {
var f = ns[fn];
ns[fn] = function(){ return f.apply(r, arguments); }
}
}
};
Mike