/** * Check if an element need to change from a style group to another. * * <p>When an element can have potentially changed style due to some of its attributes (ui.class * for example), instead of removing it then reading it, use this method to move the element from * its current style group to a potentially different style group. * * <p>Explanation of this method : checking the style of an element may be done by removing it * ({@link #removeElement(Element)}) and then re-adding it ( {@link #addElement(Element)}). This * must be done by the element since it knows when to check this. However you cannot only remove * and add, since the style group inside which the element is can have events occurring on it, and * these events must be passed from its old style to its new style. This method does all this * information passing. * * @param element The element to move. */ public void checkElementStyleGroup(Element element) { StyleGroup oldGroup = getGroup(getElementGroup(element)); // Get the old element "dynamic" status. boolean isDyn = oldGroup.isElementDynamic(element); // Get the old event set for the given element. StyleGroup.ElementEvents events = null; if (oldGroup != null) events = oldGroup.getEventsFor(element); // Remove the element from its old style and add it to insert it in the // correct style. removeElement(element); addElement_(element); // Eventually push the events on the new style group. StyleGroup newGroup = getGroup(getElementGroup(element)); if (newGroup != null && events != null) { for (String event : events.events) pushEventFor(element, event); } for (StyleGroupListener listener : listeners) listener.elementStyleChanged(element, oldGroup, newGroup); // Eventually set the element as dynamic, if it was. if (newGroup != null && isDyn) newGroup.pushElementAsDynamic(element); }
/** * Check each group that may have changed, for example to rebuild the Z index and the shadow set. * * @param oldRule The old rule that changed. * @param newRule The new rule that participated in the change. */ protected void checkZIndexAndShadow(Rule oldRule, Rule newRule) { if (oldRule != null) { if (oldRule.selector.getId() != null || oldRule.selector.getClazz() != null) { // We may accelerate things a bit when a class or id style is // modified, // since only the groups listed in the style are concerned (we // are at the // bottom of the inheritance tree). if (oldRule.getGroups() != null) for (String s : oldRule.getGroups()) { StyleGroup group = groups.get(s); zIndex.groupChanged(group); shadow.groupChanged(group); } } else { // For kind styles "NODE", "EDGE", "GRAPH", "SPRITE", we must // reset // the whole Z and shadows for the kind, since several styles // may // have changed. Selector.Type type = oldRule.selector.type; for (StyleGroup group : groups.values()) { if (group.getType() == type) { zIndex.groupChanged(group); shadow.groupChanged(group); } } } } }
@SuppressWarnings("unchecked") public E next() { String eid = elts.next(); String gid = elt2grp.get(eid); StyleGroup grp = groups.get(gid); return (E) grp.getElement(eid); }
/** * A new group appeared, put it in the z index. * * @param group The group to add. */ protected void groupAdded(StyleGroup group) { int z = convertZ(group.getZIndex()); if (zIndex.get(z) == null) zIndex.set(z, new HashSet<StyleGroup>()); zIndex.get(z).add(group); reverseZIndex.put(group.getId(), z); }
/** * Get an element. * * @param id The element id. * @param elt2grp The kind of element. * @return The element or null if not found. */ protected Element getElement(String id, HashMap<String, String> elt2grp) { String gid = elt2grp.get(id); if (gid != null) { StyleGroup group = groups.get(gid); return group.getElement(id); } return null; }
/** * Remove an element from the group set. If the group becomes empty after the element removal, * depending on the setting of {@link #areEmptyGroupRemoved()}, the group is deleted or kept. * Keeping groups allows to handle faster elements that constantly appear and disappear. * * @param element The element to remove. */ public void removeElement(Element element) { String gid = getElementGroup(element); StyleGroup group = groups.get(gid); if (group != null) { group.removeElement(element); removeElementFromReverseSearch(element); if (removeEmptyGroups && group.isEmpty()) removeGroup(group); } }
protected StyleGroup addElement_(Element element) { ArrayList<Rule> rules = stylesheet.getRulesFor(element); String gid = stylesheet.getStyleGroupIdFor(element, rules); StyleGroup group = groups.get(gid); if (group == null) group = addGroup(gid, rules, element); else group.addElement(element); addElementToReverseSearch(element, gid); return group; }
@Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(String.format("Style groups (%d) :%n", groups.size())); for (StyleGroup group : groups.values()) { builder.append(group.toString(1)); builder.append(String.format("%n")); } return builder.toString(); }
/** * Remove or keep groups that becomes empty, if true the groups are removed. If this setting was * set to false, and is now true, the group set is purged of the empty groups. * * @param on If true the groups will be removed. */ public void setRemoveEmptyGroups(boolean on) { if (removeEmptyGroups == false && on == true) { Iterator<? extends StyleGroup> i = groups.values().iterator(); while (i.hasNext()) { StyleGroup g = i.next(); if (g.isEmpty()) i.remove(); } } removeEmptyGroups = on; }
/** * A group was removed, remove it from the Z index. * * @param group The group to remove. */ protected void groupRemoved(StyleGroup group) { int z = convertZ(group.getZIndex()); HashSet<StyleGroup> map = zIndex.get(z); if (map != null) { map.remove(group); reverseZIndex.remove(group.getId()); if (map.isEmpty()) zIndex.set(z, null); } else { throw new RuntimeException("Inconsistency in Z-index"); } }
/** * A group eventually changed, check its location. * * @param group The group to check. */ protected void groupChanged(StyleGroup group) { int oldZ = reverseZIndex.get(group.getId()); int newZ = convertZ(group.getZIndex()); if (oldZ != newZ) { HashSet<StyleGroup> map = zIndex.get(oldZ); if (map != null) { map.remove(group); reverseZIndex.remove(group.getId()); if (map.isEmpty()) zIndex.set(oldZ, null); } groupAdded(group); } }
@Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.format("Z index :%n")); for (int i = 0; i < 256; i++) { if (zIndex.get(i) != null) { sb.append(String.format(" * %d -> ", i - 127)); HashSet<StyleGroup> map = zIndex.get(i); for (StyleGroup g : map) sb.append(String.format("%s ", g.getId())); sb.append(String.format("%n")); } } return sb.toString(); }
/** * Remove the given element from the subset of elements having dynamic style attribute values. * This is normally done automatically by the graphic element. * * @param element The element to remove from the dynamic subset. */ public void popElementAsDynamic(Element element) { StyleGroup group = getGroup(getElementGroup(element)); if (group != null) group.popElementAsDynamic(element); }
/** * Pop an event specifically for a given element. This is normally done automatically by the * graphic element. * * @param element The element considered. * @param event The event to pop. */ public void popEventFor(Element element, String event) { StyleGroup group = getGroup(getElementGroup(element)); if (group != null) group.popEventFor(element, event); }
/** * A group appeared, check its shadow status. * * @param group The group added. */ protected void groupAdded(StyleGroup group) { if (group.getShadowMode() != ShadowMode.NONE) shadowSet.add(group); }
/** * A group eventually changed, check its shadow status. * * @param group The group that changed. */ protected void groupChanged(StyleGroup group) { if (group.getShadowMode() == ShadowMode.NONE) shadowSet.remove(group); else shadowSet.add(group); }
protected void removeGroup(StyleGroup group) { zIndex.groupRemoved(group); shadow.groupRemoved(group); groups.remove(group.getId()); group.release(); }