Skip to content

Commit

Permalink
Topicmaps: client-side viewmodel customizer (#505)
Browse files Browse the repository at this point in the history
Nomenclature change: The concept of "Topicmap Renderer Customizer" is renamed to "View Customizer". In correspondence to "Viewmodel Customizer".

Viewmodel Customizers also have a client-side part now. At client-side a plugin can register a Viewmodel Customizer at the Canvas Renderer:
{{{
canvas_renderer.add_viewmodel_customizer(customizer_func)
}}}
A (client-side) Viewmodel Customizer is a constructor function with 1 method:
{{{
modify_view_properties(topic, view_props)
}}}
The Canvas Renderer calls this method each time a topic is added to a topicmap. The customizer then have the opportunity to add custom view properties to the "view_props" object. Typically these custom view properties are accessed then by a compatible View Customizer to do custom rendering.

As an example see the Box Renderer plugin:
https://github.com/jri/dm4-box-renderer

Note: for the moment a Viewmodel Customizer is only applicable to the Canvas Renderer (and its default TopicmapViewmodel), not to the Geomap Renderer.

BREAKING CHANGES

CanvasRenderer:
    - add_view_customizer() replaces add_customizer()
    - add_viewmodel_customizer() is new method

See #505.
  • Loading branch information
jri committed Oct 10, 2013
1 parent a5afc6d commit c97181b
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 37 deletions.
Expand Up @@ -122,10 +122,7 @@ public void addTopicToTopicmap(@PathParam("id") long topicmapId, @PathParam("top
dms.createAssociation(new AssociationModel(TOPIC_MAPCONTEXT,
new TopicRoleModel(topicmapId, ROLE_TYPE_TOPICMAP),
new TopicRoleModel(topicId, ROLE_TYPE_TOPIC),
new CompositeValueModel()
.put("dm4.topicmaps.x", viewProps.getInt("dm4.topicmaps.x"))
.put("dm4.topicmaps.y", viewProps.getInt("dm4.topicmaps.y"))
.put("dm4.topicmaps.visibility", viewProps.getBoolean("dm4.topicmaps.visibility"))
viewProps
), null); // FIXME: clientState=null
}

Expand Down
Expand Up @@ -141,7 +141,7 @@ dm4c.add_plugin("de.deepamehta.topicmaps", function() {
/**
* Displays the initial topicmap.
*
* Note: plugins are supposed to register their topicmap renderer customizers at init_2.
* Note: plugins are supposed to register their view customizers and viewmodel customizers at init_2.
* Displaying the initial topicmap at init_3 ensures all customizers are registered already.
*/
dm4c.add_listener("init_3", function() {
Expand Down
Expand Up @@ -3,6 +3,10 @@
* - loading a topicmap from DB
* - manipulating the topicmap by e.g. adding/removing topics and associations
*
* @param config an object with 2 properties:
* "is_writable" (boolean) -- indicates weather changes to this model are supposed to be persistent.
* "customizers" (array of viewmodel customer instances) -- the registered viewmodel customizers.
*
* ### TODO: introduce common base class for TopicmapViewmodel and GeomapViewmodel (see dm4-geomaps module)
*/
function TopicmapViewmodel(topicmap_id, config) {
Expand Down Expand Up @@ -88,11 +92,13 @@ function TopicmapViewmodel(topicmap_id, config) {
}

function default_view_props() {
return {
var view_props = {
"dm4.topicmaps.x": x,
"dm4.topicmaps.y": y,
"dm4.topicmaps.visibility": true
}
invoke_customizers("modify_view_properties", [topic, view_props])
return view_props
}
}

Expand Down Expand Up @@ -429,6 +435,19 @@ function TopicmapViewmodel(topicmap_id, config) {



// === Customization ===

/**
* @param args array of arguments
*/
function invoke_customizers(func_name, args) {
for (var i = 0, customizer; customizer = config.customizers[i]; i++) {
customizer[func_name] && customizer[func_name].apply(undefined, args)
}
}



// ------------------------------------------------------------------------------------------------- Private Classes

/**
Expand Down
Expand Up @@ -11,8 +11,8 @@ function CanvasRenderer() {
var canvas = new CanvasView()

// Viewmodel
var topicmap // the topicmap currently rendered (a TopicmapViewmodel).
// Initialized by display_topicmap().
var topicmap // the topicmap currently rendered (a TopicmapViewmodel). Initialized by display_topicmap().
var viewmodel_customizers = []

// ------------------------------------------------------------------------------------------------------ Public API

Expand All @@ -30,6 +30,7 @@ function CanvasRenderer() {
// ---

this.load_topicmap = function(topicmap_id, config) {
config.customizers = viewmodel_customizers
return new TopicmapViewmodel(topicmap_id, config)
}

Expand Down Expand Up @@ -271,12 +272,18 @@ function CanvasRenderer() {

// === End of interface implementations ===

this.get_topic_associations = function(topic_id) {
return topicmap.get_topic_associations(topic_id)
this.add_view_customizer = function(customizer_func) {
canvas.add_view_customizer(customizer_func)
}

this.add_viewmodel_customizer = function(customizer_func) {
viewmodel_customizers.push(new customizer_func())
}

this.add_customizer = function(customizer) {
canvas.add_customizer(customizer)
// ---

this.get_topic_associations = function(topic_id) {
return topicmap.get_topic_associations(topic_id)
}

// ----------------------------------------------------------------------------------------------- Private Functions
Expand Down
Expand Up @@ -23,7 +23,7 @@ function CanvasView() {

// Customization
var canvas_default_configuration = new CanvasDefaultConfiguration()
var customizers = []
var view_customizers = []

// Short-term interaction state
var topic_move_in_progress // true while topic move is in progress (boolean)
Expand Down Expand Up @@ -202,8 +202,8 @@ function CanvasView() {

// ---

this.add_customizer = function(customizer_func) {
customizers.push(new customizer_func({
this.add_view_customizer = function(customizer_func) {
view_customizers.push(new customizer_func({
iterate_topics: iterate_topics
}))
}
Expand All @@ -227,7 +227,7 @@ function CanvasView() {
*/
function add_topic(topic) {
var topic_view = new TopicView(topic)
invoke_customizer("update_topic", [topic_view, ctx])
invoke_customizers("update_topic", [topic_view, ctx])
canvas_topics[topic.id] = topic_view
}

Expand Down Expand Up @@ -370,17 +370,17 @@ function CanvasView() {
// === Customization ===

function customize_draw_topic(ct) {
invoke_customizer("draw_topic", [ct, ctx])
invoke_customizers("draw_topic", [ct, ctx])
}

// ---

/**
* @param args array of arguments
*/
function invoke_customizer(func_name, args) {
function invoke_customizers(func_name, args) {
var do_default = true
for (var i = 0, customizer; customizer = customizers[i]; i++) {
for (var i = 0, customizer; customizer = view_customizers[i]; i++) {
if (!(customizer[func_name] && customizer[func_name].apply(undefined, args))) {
do_default = false
}
Expand All @@ -390,19 +390,6 @@ function CanvasView() {
}
}

/* ### needed?
function invoke_single_customizer(func_name, args) {
var ret_value
for (var i = 0, customizer; customizer = customizers[i]; i++) {
var ret = customizer[func_name] && customizer[func_name].apply(undefined, args)
if (ret_value) {
throw "CanvasViewError: more than one customizer feel responsible for \"" + func_name + "\""
}
ret_value = ret
}
return ret_value || canvas_default_configuration[func_name].apply(undefined, args)
} */



// **********************
Expand Down Expand Up @@ -450,7 +437,7 @@ function CanvasView() {
tmp_x = canvas_pos.x
tmp_y = canvas_pos.y
//
invoke_customizer("on_mousedown", [
invoke_customizers("on_mousedown", [
{canvas: canvas_pos, topicmap: topicmap_pos},
{shift: event.shiftKey}
])
Expand Down Expand Up @@ -694,7 +681,7 @@ function CanvasView() {
/**
* Detects the topic that is located at a given position.
* Detection relies on the topic view's bounding box ("x1", "y1", "x2", "y2" properties).
* Note: Topicmap Renderer Customizers are responsible for adding these properties to the topic view.
* Note: View Customizers are responsible for adding these properties to the topic view.
*
* @param pos an object with "x" and "y" properties. Coord.TOPICMAP space.
*
Expand Down Expand Up @@ -940,7 +927,7 @@ function CanvasView() {
// ---

/**
* The generic topic view, to be enriched by customizers.
* The generic topic view, to be enriched by view customizers.
*
* Properties:
* id, type_uri, label
Expand All @@ -966,7 +953,7 @@ function CanvasView() {
this.x += dx
this.y += dy
//
invoke_customizer("move_topic", [this])
invoke_customizers("move_topic", [this])
}

/**
Expand All @@ -975,7 +962,7 @@ function CanvasView() {
this.update = function(topic) {
init(topic)
//
invoke_customizer("update_topic", [this, ctx])
invoke_customizers("update_topic", [this, ctx])
}

// ---
Expand Down

0 comments on commit c97181b

Please sign in to comment.