001 package de.deepamehta.plugins.topicmaps.model; 002 003 import de.deepamehta.core.JSONEnabled; 004 import de.deepamehta.core.model.TopicModel; 005 import de.deepamehta.core.util.DeepaMehtaUtils; 006 007 import org.codehaus.jettison.json.JSONObject; 008 009 import java.awt.Point; 010 011 import java.util.List; 012 import java.util.logging.Logger; 013 014 015 016 /** 017 * A topicmap viewmodel: a collection of topics and associations plus their view properties. 018 * <p> 019 * Features: 020 * - Serialization to JSON. 021 */ 022 public class TopicmapViewmodel implements JSONEnabled { 023 024 // ---------------------------------------------------------------------------------------------- Instance Variables 025 026 private TopicModel topicmapTopic; 027 private List<TopicViewmodel> topics; 028 private List<AssociationViewmodel> assocs; 029 030 private Logger logger = Logger.getLogger(getClass().getName()); 031 032 // ---------------------------------------------------------------------------------------------------- Constructors 033 034 public TopicmapViewmodel(TopicModel topicmapTopic, List<TopicViewmodel> topics, List<AssociationViewmodel> assocs) { 035 this.topicmapTopic = topicmapTopic; 036 this.topics = topics; 037 this.assocs = assocs; 038 } 039 040 // -------------------------------------------------------------------------------------------------- Public Methods 041 042 public long getId() { 043 return topicmapTopic.getId(); 044 } 045 046 // --- 047 048 public Iterable<TopicViewmodel> getTopics() { 049 return topics; 050 } 051 052 public Iterable<AssociationViewmodel> getAssociations() { 053 return assocs; 054 } 055 056 // --- 057 058 @Override 059 public JSONObject toJSON() { 060 try { 061 JSONObject topicmap = new JSONObject(); 062 topicmap.put("info", topicmapTopic.toJSON()); 063 topicmap.put("topics", DeepaMehtaUtils.objectsToJSON(topics)); 064 topicmap.put("assocs", DeepaMehtaUtils.objectsToJSON(assocs)); 065 return topicmap; 066 } catch (Exception e) { 067 throw new RuntimeException("Serialization failed (" + this + ")", e); 068 } 069 } 070 071 @Override 072 public String toString() { 073 return "topicmap " + getId(); 074 } 075 076 // -------------------------------------------------------------------------------------------- Public Inner Classes 077 078 // Note: there is a client-side equivalent in canvas_view.js (deepamehta-webclient plugin) 079 public class GridPositioning { 080 081 // Settings 082 private final int GRID_DIST_X = 220; // MAX_TOPIC_LABEL_WIDTH + 20 pixel padding 083 private final int GRID_DIST_Y = 80; 084 private final int START_X; 085 private final int START_Y = 50; 086 private final int MIN_Y = -9999; 087 088 private final int canvasWidth; 089 private final int transX; 090 091 private int gridX; 092 private int gridY; 093 094 // --- Constructors --- 095 096 public GridPositioning(int canvasWidth, int transX) { 097 this.canvasWidth = canvasWidth; 098 this.transX = transX; 099 START_X = 50 - transX; 100 // 101 Point startPos = findStartPostition(); 102 gridX = startPos.x; 103 gridY = startPos.y; 104 } 105 106 // --- Public Methods --- 107 108 public Point nextPosition() { 109 Point pos = new Point(gridX, gridY); 110 advancePosition(); 111 return pos; 112 } 113 114 // --- Private Methods --- 115 116 private Point findStartPostition() { 117 int maxY = MIN_Y; 118 for (TopicViewmodel topic : topics) { 119 if (topic.getY() > maxY) { 120 maxY = topic.getY(); 121 } 122 } 123 int x = START_X; 124 int y = maxY != MIN_Y ? maxY + GRID_DIST_Y : START_Y; 125 return new Point(x, y); 126 } 127 128 private void advancePosition() { 129 if (gridX + GRID_DIST_X + transX > canvasWidth) { 130 gridX = START_X; 131 gridY += GRID_DIST_Y; 132 } else { 133 gridX += GRID_DIST_X; 134 } 135 } 136 } 137 }