I am currently converting my GIS application that needs two browser windows (one for the map, and one for the administrative data and functions), to a single window application using the netzke gems (which in turn rely on Sencha Ext js).
The netzke gems are extremely powerful, but there is a bit of learning curve for me, since both netzke and ext js are new. But netzke makes a lot of things a lot easier. It is not really rails-like, since it abstracts a lot away, and I am not yet completely convinced of the approach. But for my current goals it is ok.
I have a panel containing an openlayers map, and a toolbar with action buttons. The action buttons need to indicate state (drawing/measuring). So when clicked they have to be in a "pressed" state, and start with the action.
Although I found no example of this, achieving it was pretty easy. I defined my action buttons as follows:
action :measure_line do |c|
c.id = "measure_line"
c.icon = :ruler
c.text = ""
end
action :measure_area do |c|
c.id = "measure_area"
c.icon = :surface
c.text = ""
end
js_configure do |c|
c.layout = :fit
c.mixin
end
def configure(c)
c.desc = "Contains the openlayers map"
c.title = "Map"
c.tbar = [:draw_point, :draw_line, :draw_polygon, :measure_line, :measure_area, :navigation_history]
c.body_padding = 5
end
I am only showing the actions for :measure_line
and :measure_area
because these are now the relevant ones I want to show. I need to give explicit id
to the buttons, so that I can use Ext.ComponentManager.get
to find them later on.
Nice thing to know is that the action handler by default receives the pressed button (yes!). This will allow us to just toggle
it. So your mixed in javascript will look this:
{
onMeasureLine: function(btn) {
Map.toggleMeasuring(btn, 'line');
},
onMeasureArea: function(btn) {
Map.toggleMeasuring(btn, 'polygon');
},
}
Because I prefer to write coffeescript (not found how I can do that for the netzke mixins), I have a class Map
in map.js.coffee
containing all map-related functions. toggleMeasuring
needs the button and the measurement-action to activate/deactivate
toggleMeasuring: (button, measurement_type) ->
button.toggle()
if 'pressed' in button.uiCls
@measureControls[measurement_type].activate()
else
@measureControls[measurement_type].deactivate()
# make sure the other measuring is automatically switched off
for key of @measureControls
unless key == measurement_type
@measureControls[key].deactivate()
Ext.ComponentManager.get("measure_#{key}").toggle(false)
That is about the gist of it. I will be sharing more of my netzke experience and code soon. For the moment still impressed :)