Exemplo n.º 1
0
  @Override
  public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {

    int offs = -1;

    if (!isAllocationValid()) {
      Rectangle alloc = a.getBounds();
      setSize(alloc.width, alloc.height);
    }

    // Get the child view for the line at (x,y), and ask it for the
    // specific offset.
    Rectangle alloc = getInsideAllocation(a);
    View v = getViewAtPoint((int) x, (int) y, alloc);
    if (v != null) {
      offs = v.viewToModel(x, y, alloc, bias);
    }

    // Code folding may have hidden the last line.  If so, return the last
    // visible offset instead of the last offset.
    if (host.isCodeFoldingEnabled()
        && v == getView(getViewCount() - 1)
        && offs == v.getEndOffset() - 1) {
      offs = host.getLastVisibleOffset();
    }

    return offs;
  }
 /**
  * Gives notification that something was inserted into the document in a location that this view
  * is responsible for. This is implemented to simply update the children.
  *
  * @param changes The change information from the associated document.
  * @param a the current allocation of the view
  * @param f the factory to use to rebuild if the view has children
  * @see View#insertUpdate
  */
 public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
   updateChildren(changes, a);
   Rectangle alloc = ((a != null) && isAllocationValid()) ? getInsideAllocation(a) : null;
   int pos = changes.getOffset();
   View v = getViewAtPosition(pos, alloc);
   if (v != null) v.insertUpdate(changes, alloc, f);
 }
Exemplo n.º 3
0
 private boolean contains(View logicalView, View v) {
   int n = logicalView.getViewCount();
   for (int i = 0; i < n; i++) {
     if (logicalView.getView(i) == v) {
       return true;
     }
   }
   return false;
 }
Exemplo n.º 4
0
 /**
  * Forwards the <code>DocumentEvent</code> to the give child view. This simply messages the view
  * with a call to <code>insertUpdate</code>, <code>removeUpdate</code>, or <code>changedUpdate
  * </code> depending upon the type of the event. This is called by <a
  * href="#forwardUpdate">forwardUpdate</a> to forward the event to children that need it.
  *
  * @param v the child view to forward the event to
  * @param e the change information from the associated document
  * @param a the current allocation of the view
  * @param f the factory to use to rebuild if the view has children
  * @see #forwardUpdate
  * @since 1.3
  */
 protected void forwardUpdateToView(View v, DocumentEvent e, Shape a, ViewFactory f) {
   DocumentEvent.EventType type = e.getType();
   if (type == DocumentEvent.EventType.INSERT) {
     v.insertUpdate(e, a, f);
   } else if (type == DocumentEvent.EventType.REMOVE) {
     v.removeUpdate(e, a, f);
   } else {
     v.changedUpdate(e, a, f);
   }
 }
Exemplo n.º 5
0
    /**
     * Update the flow on the given FlowView. By default, this causes all of the rows (child views)
     * to be rebuilt to match the given constraints for each row. This is called by a
     * FlowView.layout to update the child views in the flow.
     *
     * @param fv the view to reflow
     */
    public void layout(FlowView fv) {
      int p0 = fv.getStartOffset();
      int p1 = fv.getEndOffset();

      // we want to preserve all views from the logicalView from being
      // removed
      View lv = getLogicalView(fv);
      int n = lv.getViewCount();
      for (int i = 0; i < n; i++) {
        View v = lv.getView(i);
        v.setParent(lv);
      }
      fv.removeAll();
      for (int rowIndex = 0; p0 < p1; rowIndex++) {
        View row = fv.createRow();
        fv.append(row);

        // layout the row to the current span.  If nothing fits,
        // force something.
        int next = layoutRow(fv, rowIndex, p0);
        if (row.getViewCount() == 0) {
          row.append(createView(fv, p0, Integer.MAX_VALUE, rowIndex));
          next = row.getEndOffset();
        }
        if (next <= p0) {
          throw new StateInvariantError("infinite loop in formatting");
        } else {
          p0 = next;
        }
      }
    }
Exemplo n.º 6
0
 private void recursiveReparent(View v, View logicalView) {
   int n = v.getViewCount();
   for (int i = 0; i < n; i++) {
     View tmpView = v.getView(i);
     if (contains(logicalView, tmpView)) {
       tmpView.setParent(logicalView);
     } else {
       recursiveReparent(tmpView, logicalView);
     }
   }
 }
Exemplo n.º 7
0
 /**
  * Fetches the child view index representing the given position in the model.
  *
  * @param pos the position >= 0
  * @return index of the view representing the given position, or -1 if no view represents that
  *     position
  */
 protected int getViewIndexAtPosition(int pos) {
   if (pos >= getStartOffset() && (pos < getEndOffset())) {
     for (int counter = getViewCount() - 1; counter >= 0; counter--) {
       View v = getView(counter);
       if (pos >= v.getStartOffset() && pos < v.getEndOffset()) {
         return counter;
       }
     }
   }
   return -1;
 }
  protected void doMoveAirspaceLaterally(
      WorldWindow wwd, Airspace airspace, Point mousePoint, Point previousMousePoint) {
    // Intersect a ray throuh each mouse point, with a geoid passing through the reference
    // elevation. Since
    // most airspace control points follow a fixed altitude, this will track close to the intended
    // mouse position.
    // If either ray fails to intersect the geoid, then ignore this event. Use the difference
    // between the two
    // intersected positions to move the control point's location.

    if (!(airspace instanceof Movable)) {
      return;
    }

    Movable movable = (Movable) airspace;
    View view = wwd.getView();
    Globe globe = wwd.getModel().getGlobe();

    Position refPos = movable.getReferencePosition();
    if (refPos == null) return;

    // Convert the reference position into a cartesian point. This assumes that the reference
    // elevation is defined
    // by the airspace's lower altitude.
    Vec4 refPoint = null;
    if (airspace.isTerrainConforming()[LOWER_ALTITUDE])
      refPoint = wwd.getSceneController().getTerrain().getSurfacePoint(refPos);
    if (refPoint == null) refPoint = globe.computePointFromPosition(refPos);

    // Convert back to a position.
    refPos = globe.computePositionFromPoint(refPoint);

    Line ray = view.computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY());
    Line previousRay =
        view.computeRayFromScreenPoint(previousMousePoint.getX(), previousMousePoint.getY());

    Vec4 vec = AirspaceEditorUtil.intersectGlobeAt(wwd, refPos.getElevation(), ray);
    Vec4 previousVec = AirspaceEditorUtil.intersectGlobeAt(wwd, refPos.getElevation(), previousRay);

    if (vec == null || previousVec == null) {
      return;
    }

    Position pos = globe.computePositionFromPoint(vec);
    Position previousPos = globe.computePositionFromPoint(previousVec);
    LatLon change = pos.subtract(previousPos);

    movable.move(new Position(change.getLatitude(), change.getLongitude(), 0.0));

    this.fireAirspaceMoved(new AirspaceEditEvent(wwd, airspace, this));
  }
Exemplo n.º 9
0
 /**
  * Determines the preferred span for this view along an axis.
  *
  * @param axis may be either View.X_AXIS or View.Y_AXIS
  * @return the span the view would like to be rendered into. Typically the view is told to
  *     render into the span that is returned, although there is no guarantee. The parent may
  *     choose to resize or break the view.
  * @see View#getPreferredSpan
  */
 public float getPreferredSpan(int axis) {
   float maxpref = 0;
   float pref = 0;
   int n = getViewCount();
   for (int i = 0; i < n; i++) {
     View v = getView(i);
     pref += v.getPreferredSpan(axis);
     if (v.getBreakWeight(axis, 0, Short.MAX_VALUE) >= ForcedBreakWeight) {
       maxpref = Math.max(maxpref, pref);
       pref = 0;
     }
   }
   maxpref = Math.max(maxpref, pref);
   return maxpref;
 }
Exemplo n.º 10
0
  /**
   * Forwards the given <code>DocumentEvent</code> to the child views that need to be notified of
   * the change to the model. If there were changes to the element this view is responsible for,
   * that should be considered when forwarding (i.e. new child views should not get notified).
   *
   * @param ec changes to the element this view is responsible for (may be <code>null</code> if
   *     there were no changes).
   * @param e the change information from the associated document
   * @param a the current allocation of the view
   * @param f the factory to use to rebuild if the view has children
   * @see #insertUpdate
   * @see #removeUpdate
   * @see #changedUpdate
   * @since 1.3
   */
  protected void forwardUpdate(
      DocumentEvent.ElementChange ec, DocumentEvent e, Shape a, ViewFactory f) {
    Element elem = getElement();
    int pos = e.getOffset();
    int index0 = getViewIndex(pos, Position.Bias.Forward);
    if (index0 == -1 && e.getType() == DocumentEvent.EventType.REMOVE && pos >= getEndOffset()) {
      // Event beyond our offsets. We may have represented this, that is
      // the remove may have removed one of our child Elements that
      // represented this, so, we should foward to last element.
      index0 = getViewCount() - 1;
    }
    int index1 = index0;
    View v = (index0 >= 0) ? getView(index0) : null;
    if (v != null) {
      if ((v.getStartOffset() == pos) && (pos > 0)) {
        // If v is at a boundary, forward the event to the previous
        // view too.
        index0 = Math.max(index0 - 1, 0);
      }
    }
    if (e.getType() != DocumentEvent.EventType.REMOVE) {
      index1 = getViewIndex(pos + e.getLength(), Position.Bias.Forward);
      if (index1 < 0) {
        index1 = getViewCount() - 1;
      }
    }
    int hole0 = index1 + 1;
    int hole1 = hole0;
    Element[] addedElems = (ec != null) ? ec.getChildrenAdded() : null;
    if ((addedElems != null) && (addedElems.length > 0)) {
      hole0 = ec.getIndex();
      hole1 = hole0 + addedElems.length - 1;
    }

    // forward to any view not in the forwarding hole
    // formed by added elements (i.e. they will be updated
    // by initialization.
    index0 = Math.max(index0, 0);
    for (int i = index0; i <= index1; i++) {
      if (!((i >= hole0) && (i <= hole1))) {
        v = getView(i);
        if (v != null) {
          Shape childAlloc = getChildAllocation(i, a);
          forwardUpdateToView(v, e, childAlloc, f);
        }
      }
    }
  }
 /**
  * Sets the parent of the view. This is reimplemented to provide the superclass behavior as well
  * as calling the <code>loadChildren</code> method if this view does not already have children.
  * The children should not be loaded in the constructor because the act of setting the parent may
  * cause them to try to search up the hierarchy (to get the hosting <code>Container</code> for
  * example). If this view has children (the view is being moved from one place in the view
  * hierarchy to another), the <code>loadChildren</code> method will not be called.
  *
  * @param parent the parent of the view, <code>null</code> if none
  */
 public void setParent(View parent) {
   super.setParent(parent);
   if ((parent != null) && (nchildren == 0)) {
     ViewFactory f = getViewFactory();
     loadChildren(f);
   }
 }
Exemplo n.º 12
0
 /**
  * Establishes the parent view for this view. Seize this moment to cache the AWT Container I'm in.
  */
 public void setParent(View parent) {
   super.setParent(parent);
   fContainer = parent != null ? getContainer() : null;
   if (parent == null && fComponent != null) {
     fComponent.getParent().remove(fComponent);
     fComponent = null;
   }
 }
Exemplo n.º 13
0
 /**
  * Determines the minimum span for this view along an axis. The is implemented to find the
  * minimum unbreakable span.
  *
  * @param axis may be either View.X_AXIS or View.Y_AXIS
  * @return the span the view would like to be rendered into. Typically the view is told to
  *     render into the span that is returned, although there is no guarantee. The parent may
  *     choose to resize or break the view.
  * @see View#getPreferredSpan
  */
 public float getMinimumSpan(int axis) {
   float maxmin = 0;
   float min = 0;
   boolean nowrap = false;
   int n = getViewCount();
   for (int i = 0; i < n; i++) {
     View v = getView(i);
     if (v.getBreakWeight(axis, 0, Short.MAX_VALUE) == BadBreakWeight) {
       min += v.getPreferredSpan(axis);
       nowrap = true;
     } else if (nowrap) {
       maxmin = Math.max(min, maxmin);
       nowrap = false;
       min = 0;
     }
   }
   maxmin = Math.max(maxmin, min);
   return maxmin;
 }
 /**
  * Provides a mapping from the document model coordinate space to the coordinate space of the view
  * mapped to it.
  *
  * @param pos the position to convert &gt;= 0
  * @param a the allocated region to render into
  * @param b a bias value of either <code>Position.Bias.Forward</code> or <code>
  *     Position.Bias.Backward</code>
  * @return the bounding box of the given position
  * @exception BadLocationException if the given position does not represent a valid location in
  *     the associated document
  * @see View#modelToView
  */
 public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
   boolean isBackward = (b == Position.Bias.Backward);
   int testPos = (isBackward) ? Math.max(0, pos - 1) : pos;
   if (isBackward && testPos < getStartOffset()) {
     return null;
   }
   int vIndex = getViewIndexAtPosition(testPos);
   if ((vIndex != -1) && (vIndex < getViewCount())) {
     View v = getView(vIndex);
     if (v != null && testPos >= v.getStartOffset() && testPos < v.getEndOffset()) {
       Shape childShape = getChildAllocation(vIndex, a);
       if (childShape == null) {
         // We are likely invalid, fail.
         return null;
       }
       Shape retShape = v.modelToView(pos, childShape, b);
       if (retShape == null && v.getEndOffset() == pos) {
         if (++vIndex < getViewCount()) {
           v = getView(vIndex);
           retShape = v.modelToView(pos, getChildAllocation(vIndex, a), b);
         }
       }
       return retShape;
     }
   }
   throw new BadLocationException("Position not represented by view", pos);
 }
  /**
   * Provides a mapping from the view coordinate space to the logical coordinate space of the model.
   *
   * @param x x coordinate of the view location to convert &gt;= 0
   * @param y y coordinate of the view location to convert &gt;= 0
   * @param a the allocated region to render into
   * @param bias either <code>Position.Bias.Forward</code> or <code>Position.Bias.Backward</code>
   * @return the location within the model that best represents the given point in the view &gt;= 0
   * @see View#viewToModel
   */
  public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
    Rectangle alloc = getInsideAllocation(a);
    if (isBefore((int) x, (int) y, alloc)) {
      // point is before the range represented
      int retValue = -1;

      try {
        retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward, a, EAST, bias);
      } catch (BadLocationException ble) {
      } catch (IllegalArgumentException iae) {
      }
      if (retValue == -1) {
        retValue = getStartOffset();
        bias[0] = Position.Bias.Forward;
      }
      return retValue;
    } else if (isAfter((int) x, (int) y, alloc)) {
      // point is after the range represented.
      int retValue = -1;
      try {
        retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward, a, WEST, bias);
      } catch (BadLocationException ble) {
      } catch (IllegalArgumentException iae) {
      }

      if (retValue == -1) {
        // NOTE: this could actually use end offset with backward.
        retValue = getEndOffset() - 1;
        bias[0] = Position.Bias.Forward;
      }
      return retValue;
    } else {
      // locate the child and pass along the request
      View v = getViewAtPoint((int) x, (int) y, alloc);
      if (v != null) {
        return v.viewToModel(x, y, alloc, bias);
      }
    }
    return -1;
  }
Exemplo n.º 16
0
  /**
   * Lays out the children. If the span along the flow axis has changed, layout is marked as invalid
   * which which will cause the superclass behavior to recalculate the layout along the box axis.
   * The FlowStrategy.layout method will be called to rebuild the flow rows as appropriate. If the
   * height of this view changes (determined by the perferred size along the box axis), a
   * preferenceChanged is called. Following all of that, the normal box layout of the superclass is
   * performed.
   *
   * @param width the width to lay out against >= 0. This is the width inside of the inset area.
   * @param height the height to lay out against >= 0 This is the height inside of the inset area.
   */
  protected void layout(int width, int height) {
    final int faxis = getFlowAxis();
    int newSpan;
    if (faxis == X_AXIS) {
      newSpan = (int) width;
    } else {
      newSpan = (int) height;
    }
    if (layoutSpan != newSpan) {
      layoutChanged(faxis);
      layoutChanged(getAxis());
      layoutSpan = newSpan;
    }

    // repair the flow if necessary
    if (!isLayoutValid(faxis)) {
      final int heightAxis = getAxis();
      int oldFlowHeight = (int) ((heightAxis == X_AXIS) ? getWidth() : getHeight());
      strategy.layout(this);
      int newFlowHeight = (int) getPreferredSpan(heightAxis);
      if (oldFlowHeight != newFlowHeight) {
        View p = getParent();
        if (p != null) {
          p.preferenceChanged(this, (heightAxis == X_AXIS), (heightAxis == Y_AXIS));
        }

        // PENDING(shannonh)
        // Temporary fix for 4250847
        // Can be removed when TraversalContext is added
        Component host = getContainer();
        if (host != null) {
          // nb idk 12/12/2001 host should not be equal to null. We need to add assertion here
          host.repaint();
        }
      }
    }

    super.layout(width, height);
  }
Exemplo n.º 17
0
    /**
     * Creates a view that can be used to represent the current piece of the flow. This can be
     * either an entire view from the logical view, or a fragment of the logical view.
     *
     * @param fv the view holding the flow
     * @param startOffset the start location for the view being created
     * @param spanLeft the about of span left to fill in the row
     * @param rowIndex the row the view will be placed into
     */
    protected View createView(FlowView fv, int startOffset, int spanLeft, int rowIndex) {
      // Get the child view that contains the given starting position
      View lv = getLogicalView(fv);
      int childIndex = lv.getViewIndex(startOffset, Position.Bias.Forward);
      View v = lv.getView(childIndex);
      if (startOffset == v.getStartOffset()) {
        // return the entire view
        return v;
      }

      // return a fragment.
      v = v.createFragment(startOffset, v.getEndOffset());
      return v;
    }
Exemplo n.º 18
0
  /** My attributes may have changed. */
  public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
    if (DEBUG) System.out.println("ImageView: changedUpdate begin...");
    super.changedUpdate(e, a, f);
    float align = getVerticalAlignment();

    int height = fHeight;
    int width = fWidth;

    initialize(getElement());

    boolean hChanged = fHeight != height;
    boolean wChanged = fWidth != width;
    if (hChanged || wChanged || getVerticalAlignment() != align) {
      if (DEBUG) System.out.println("ImageView: calling preferenceChanged");
      getParent().preferenceChanged(this, hChanged, wChanged);
    }
    if (DEBUG) System.out.println("ImageView: changedUpdate end; valign=" + getVerticalAlignment());
  }
  /**
   * Provides a mapping from the document model coordinate space to the coordinate space of the view
   * mapped to it.
   *
   * @param p0 the position to convert &gt;= 0
   * @param b0 the bias toward the previous character or the next character represented by p0, in
   *     case the position is a boundary of two views; either <code>Position.Bias.Forward</code> or
   *     <code>Position.Bias.Backward</code>
   * @param p1 the position to convert &gt;= 0
   * @param b1 the bias toward the previous character or the next character represented by p1, in
   *     case the position is a boundary of two views
   * @param a the allocated region to render into
   * @return the bounding box of the given position is returned
   * @exception BadLocationException if the given position does not represent a valid location in
   *     the associated document
   * @exception IllegalArgumentException for an invalid bias argument
   * @see View#viewToModel
   */
  public Shape modelToView(int p0, Position.Bias b0, int p1, Position.Bias b1, Shape a)
      throws BadLocationException {
    if (p0 == getStartOffset() && p1 == getEndOffset()) {
      return a;
    }
    Rectangle alloc = getInsideAllocation(a);
    Rectangle r0 = new Rectangle(alloc);
    View v0 = getViewAtPosition((b0 == Position.Bias.Backward) ? Math.max(0, p0 - 1) : p0, r0);
    Rectangle r1 = new Rectangle(alloc);
    View v1 = getViewAtPosition((b1 == Position.Bias.Backward) ? Math.max(0, p1 - 1) : p1, r1);
    if (v0 == v1) {
      if (v0 == null) {
        return a;
      }
      // Range contained in one view
      return v0.modelToView(p0, b0, p1, b1, r0);
    }
    // Straddles some views.
    int viewCount = getViewCount();
    int counter = 0;
    while (counter < viewCount) {
      View v;
      // Views may not be in same order as model.
      // v0 or v1 may be null if there is a gap in the range this
      // view contains.
      if ((v = getView(counter)) == v0 || v == v1) {
        View endView;
        Rectangle retRect;
        Rectangle tempRect = new Rectangle();
        if (v == v0) {
          retRect =
              v0.modelToView(p0, b0, v0.getEndOffset(), Position.Bias.Backward, r0).getBounds();
          endView = v1;
        } else {
          retRect =
              v1.modelToView(v1.getStartOffset(), Position.Bias.Forward, p1, b1, r1).getBounds();
          endView = v0;
        }

        // Views entirely covered by range.
        while (++counter < viewCount && (v = getView(counter)) != endView) {
          tempRect.setBounds(alloc);
          childAllocation(counter, tempRect);
          retRect.add(tempRect);
        }

        // End view.
        if (endView != null) {
          Shape endShape;
          if (endView == v1) {
            endShape = v1.modelToView(v1.getStartOffset(), Position.Bias.Forward, p1, b1, r1);
          } else {
            endShape = v0.modelToView(p0, b0, v0.getEndOffset(), Position.Bias.Backward, r0);
          }
          if (endShape instanceof Rectangle) {
            retRect.add((Rectangle) endShape);
          } else {
            retRect.add(endShape.getBounds());
          }
        }
        return retRect;
      }
      counter++;
    }
    throw new BadLocationException("Position not represented by view", p0);
  }
Exemplo n.º 20
0
    /**
     * Creates a row of views that will fit within the layout span of the row. This is called by the
     * layout method. This is implemented to fill the row by repeatedly calling the createView
     * method until the available span has been exhausted, a forced break was encountered, or the
     * createView method returned null. If the remaining span was exhaused, the adjustRow method
     * will be called to perform adjustments to the row to try and make it fit into the given span.
     *
     * @param rowIndex the index of the row to fill in with views. The row is assumed to be empty on
     *     entry.
     * @param pos The current position in the children of this views element from which to start.
     * @return the position to start the next row
     */
    protected int layoutRow(FlowView fv, int rowIndex, int pos) {
      View row = fv.getView(rowIndex);
      int x = fv.getFlowStart(rowIndex);
      int spanLeft = fv.getFlowSpan(rowIndex);
      int end = fv.getEndOffset();
      TabExpander te = (fv instanceof TabExpander) ? (TabExpander) fv : null;

      // Indentation.
      int preX = x;
      int availableSpan = spanLeft;
      preX = x;

      final int flowAxis = fv.getFlowAxis();
      boolean forcedBreak = false;
      while (pos < end && spanLeft > 0) {
        View v = createView(fv, pos, spanLeft, rowIndex);
        if (v == null) {
          break;
        }

        int chunkSpan;
        if ((flowAxis == X_AXIS) && (v instanceof TabableView)) {
          chunkSpan = (int) ((TabableView) v).getTabbedSpan(x, te);
        } else {
          chunkSpan = (int) v.getPreferredSpan(flowAxis);
        }

        // If a forced break is necessary, break
        if (v.getBreakWeight(flowAxis, pos, spanLeft) >= ForcedBreakWeight) {
          int n = row.getViewCount();
          if (n > 0) {
            /* If this is a forced break and it's not the only view
             * the view should be replaced with a call to breakView.
             * If it's it only view, it should be used directly.  In
             * either case no more children should be added beyond this
             * view.
             */
            v = v.breakView(flowAxis, pos, x, spanLeft);
            if (v != null) {
              if ((flowAxis == X_AXIS) && (v instanceof TabableView)) {
                chunkSpan = (int) ((TabableView) v).getTabbedSpan(x, te);
              } else {
                chunkSpan = (int) v.getPreferredSpan(flowAxis);
              }
            } else {
              chunkSpan = 0;
            }
          }
          forcedBreak = true;
        }

        spanLeft -= chunkSpan;
        x += chunkSpan;
        if (v != null) {
          row.append(v);
          pos = v.getEndOffset();
        }
        if (forcedBreak) {
          break;
        }
      }
      if (spanLeft < 0) {
        // This row is too long and needs to be adjusted.
        adjustRow(fv, rowIndex, availableSpan, preX);
      } else if (row.getViewCount() == 0) {
        // Impossible spec... put in whatever is left.
        View v = createView(fv, pos, Integer.MAX_VALUE, rowIndex);
        row.append(v);
      }
      return row.getEndOffset();
    }
Exemplo n.º 21
0
  /**
   * Draws a single view (i.e., a line of text for a wrapped view), wrapping the text onto multiple
   * lines if necessary. Any selected text is rendered with the editor's "selected text" color.
   *
   * @param painter The painter to use to render tokens.
   * @param g The graphics context in which to paint.
   * @param r The rectangle in which to paint.
   * @param view The <code>View</code> to paint.
   * @param fontHeight The height of the font being used.
   * @param y The y-coordinate at which to begin painting.
   * @param selStart The start of the selection.
   * @param selEnd The end of the selection.
   */
  protected void drawViewWithSelection(
      TokenPainter painter,
      Graphics2D g,
      Rectangle r,
      View view,
      int fontHeight,
      int y,
      int selStart,
      int selEnd) {

    float x = r.x;

    LayeredHighlighter h = (LayeredHighlighter) host.getHighlighter();

    RSyntaxDocument document = (RSyntaxDocument) getDocument();
    Element map = getElement();

    int p0 = view.getStartOffset();
    int lineNumber = map.getElementIndex(p0);
    int p1 = view.getEndOffset(); // - 1;

    setSegment(p0, p1 - 1, document, drawSeg);
    // System.err.println("drawSeg=='" + drawSeg + "' (p0/p1==" + p0 + "/" + p1 + ")");
    int start = p0 - drawSeg.offset;
    Token token = document.getTokenListForLine(lineNumber);

    // If this line is an empty line, then the token list is simply a
    // null token.  In this case, the line highlight will be skipped in
    // the loop below, so unfortunately we must manually do it here.
    if (token != null && token.getType() == Token.NULL) {
      h.paintLayeredHighlights(g, p0, p1, r, host, this);
      return;
    }

    // Loop through all tokens in this view and paint them!
    while (token != null && token.isPaintable()) {

      int p = calculateBreakPosition(p0, token, x);
      x = r.x;

      h.paintLayeredHighlights(g, p0, p, r, host, this);

      while (token != null && token.isPaintable() && token.getEndOffset() - 1 < p) { // <=p) {

        // Selection starts in this token
        if (token.containsPosition(selStart)) {

          if (selStart > token.getOffset()) {
            tempToken.copyFrom(token);
            tempToken.textCount = selStart - tempToken.getOffset();
            x = painter.paint(tempToken, g, x, y, host, this);
            tempToken.textCount = token.length();
            tempToken.makeStartAt(selStart);
            // Clone required since token and tempToken must be
            // different tokens for else statement below
            token = new TokenImpl(tempToken);
          }

          int selCount = Math.min(token.length(), selEnd - token.getOffset());
          if (selCount == token.length()) {
            x = painter.paintSelected(token, g, x, y, host, this);
          } else {
            tempToken.copyFrom(token);
            tempToken.textCount = selCount;
            x = painter.paintSelected(tempToken, g, x, y, host, this);
            tempToken.textCount = token.length();
            tempToken.makeStartAt(token.getOffset() + selCount);
            token = tempToken;
            x = painter.paint(token, g, x, y, host, this);
          }

        }

        // Selection ends in this token
        else if (token.containsPosition(selEnd)) {
          tempToken.copyFrom(token);
          tempToken.textCount = selEnd - tempToken.getOffset();
          x = painter.paintSelected(tempToken, g, x, y, host, this);
          tempToken.textCount = token.length();
          tempToken.makeStartAt(selEnd);
          token = tempToken;
          x = painter.paint(token, g, x, y, host, this);
        }

        // This token is entirely selected
        else if (token.getOffset() >= selStart && token.getEndOffset() <= selEnd) {
          x = painter.paintSelected(token, g, x, y, host, this);
        }

        // This token is entirely unselected
        else {
          x = painter.paint(token, g, x, y, host, this);
        }

        token = token.getNextToken();
      }

      // If there's a token that's going to be split onto the next line
      if (token != null && token.isPaintable() && token.getOffset() < p) {

        int tokenOffset = token.getOffset();
        Token orig = token;
        token =
            new TokenImpl(
                drawSeg, tokenOffset - start, p - 1 - start, tokenOffset, token.getType());

        // Selection starts in this token
        if (token.containsPosition(selStart)) {

          if (selStart > token.getOffset()) {
            tempToken.copyFrom(token);
            tempToken.textCount = selStart - tempToken.getOffset();
            x = painter.paint(tempToken, g, x, y, host, this);
            tempToken.textCount = token.length();
            tempToken.makeStartAt(selStart);
            // Clone required since token and tempToken must be
            // different tokens for else statement below
            token = new TokenImpl(tempToken);
          }

          int selCount = Math.min(token.length(), selEnd - token.getOffset());
          if (selCount == token.length()) {
            x = painter.paintSelected(token, g, x, y, host, this);
          } else {
            tempToken.copyFrom(token);
            tempToken.textCount = selCount;
            x = painter.paintSelected(tempToken, g, x, y, host, this);
            tempToken.textCount = token.length();
            tempToken.makeStartAt(token.getOffset() + selCount);
            token = tempToken;
            x = painter.paint(token, g, x, y, host, this);
          }

        }

        // Selection ends in this token
        else if (token.containsPosition(selEnd)) {
          tempToken.copyFrom(token);
          tempToken.textCount = selEnd - tempToken.getOffset();
          x = painter.paintSelected(tempToken, g, x, y, host, this);
          tempToken.textCount = token.length();
          tempToken.makeStartAt(selEnd);
          token = tempToken;
          x = painter.paint(token, g, x, y, host, this);
        }

        // This token is entirely selected
        else if (token.getOffset() >= selStart && token.getEndOffset() <= selEnd) {
          x = painter.paintSelected(token, g, x, y, host, this);
        }

        // This token is entirely unselected
        else {
          x = painter.paint(token, g, x, y, host, this);
        }

        token = new TokenImpl(orig);
        ((TokenImpl) token).makeStartAt(p);
      }

      p0 = (p == p0) ? p1 : p;
      y += fontHeight;
    } // End of while (token!=null && token.isPaintable()).

    // NOTE: We should re-use code from Token (paintBackground()) here,
    // but don't because I'm just too lazy.
    if (host.getEOLMarkersVisible()) {
      g.setColor(host.getForegroundForTokenType(Token.WHITESPACE));
      g.setFont(host.getFontForTokenType(Token.WHITESPACE));
      g.drawString("\u00B6", x, y - fontHeight);
    }
  }
Exemplo n.º 22
0
  /**
   * Draws a single view (i.e., a line of text for a wrapped view), wrapping the text onto multiple
   * lines if necessary.
   *
   * @param painter The painter to use to render tokens.
   * @param g The graphics context in which to paint.
   * @param r The rectangle in which to paint.
   * @param view The <code>View</code> to paint.
   * @param fontHeight The height of the font being used.
   * @param y The y-coordinate at which to begin painting.
   */
  protected void drawView(
      TokenPainter painter, Graphics2D g, Rectangle r, View view, int fontHeight, int y) {

    float x = r.x;

    LayeredHighlighter h = (LayeredHighlighter) host.getHighlighter();

    RSyntaxDocument document = (RSyntaxDocument) getDocument();
    Element map = getElement();

    int p0 = view.getStartOffset();
    int lineNumber = map.getElementIndex(p0);
    int p1 = view.getEndOffset(); // - 1;

    setSegment(p0, p1 - 1, document, drawSeg);
    // System.err.println("drawSeg=='" + drawSeg + "' (p0/p1==" + p0 + "/" + p1 + ")");
    int start = p0 - drawSeg.offset;
    Token token = document.getTokenListForLine(lineNumber);

    // If this line is an empty line, then the token list is simply a
    // null token.  In this case, the line highlight will be skipped in
    // the loop below, so unfortunately we must manually do it here.
    if (token != null && token.getType() == Token.NULL) {
      h.paintLayeredHighlights(g, p0, p1, r, host, this);
      return;
    }

    // Loop through all tokens in this view and paint them!
    while (token != null && token.isPaintable()) {

      int p = calculateBreakPosition(p0, token, x);
      x = r.x;

      h.paintLayeredHighlights(g, p0, p, r, host, this);

      while (token != null && token.isPaintable() && token.getEndOffset() - 1 < p) { // <=p) {
        x = painter.paint(token, g, x, y, host, this);
        token = token.getNextToken();
      }

      if (token != null && token.isPaintable() && token.getOffset() < p) {
        int tokenOffset = token.getOffset();
        tempToken.set(
            drawSeg.array, tokenOffset - start, p - 1 - start, tokenOffset, token.getType());
        painter.paint(tempToken, g, x, y, host, this);
        tempToken.copyFrom(token);
        tempToken.makeStartAt(p);
        token = new TokenImpl(tempToken);
      }

      p0 = (p == p0) ? p1 : p;
      y += fontHeight;
    } // End of while (token!=null && token.isPaintable()).

    // NOTE: We should re-use code from Token (paintBackground()) here,
    // but don't because I'm just too lazy.
    if (host.getEOLMarkersVisible()) {
      g.setColor(host.getForegroundForTokenType(Token.WHITESPACE));
      g.setFont(host.getFontForTokenType(Token.WHITESPACE));
      g.drawString("\u00B6", x, y - fontHeight);
    }
  }
Exemplo n.º 23
0
 /**
  * Forward the DocumentEvent to the given child view. This is implemented to reparent the child
  * to the logical view (the children may have been parented by a row in the flow if they fit
  * without breaking) and then execute the superclass behavior.
  *
  * @param v the child view to forward the event to.
  * @param e the change information from the associated document
  * @param a the current allocation of the view
  * @param f the factory to use to rebuild if the view has children
  * @see #forwardUpdate
  * @since 1.3
  */
 protected void forwardUpdateToView(View v, DocumentEvent e, Shape a, ViewFactory f) {
   v.setParent(this);
   super.forwardUpdateToView(v, e, a, f);
 }
Exemplo n.º 24
0
 /**
  * Fetches the <code>ViewFactory</code> implementation that is feeding the view hierarchy.
  * Normally the views are given this as an argument to updates from the model when they are most
  * likely to need the factory, but this method serves to provide it at other times.
  *
  * @return the factory, <code>null</code> if none
  */
 public ViewFactory getViewFactory() {
   View v = getParent();
   return (v != null) ? v.getViewFactory() : null;
 }
Exemplo n.º 25
0
 /**
  * Fetches the container hosting the view. This is useful for things like scheduling a repaint,
  * finding out the host components font, etc. The default implementation of this is to forward the
  * query to the parent view.
  *
  * @return the container, <code>null</code> if none
  */
 public Container getContainer() {
   View v = getParent();
   return (v != null) ? v.getContainer() : null;
 }
Exemplo n.º 26
0
 /**
  * Child views can call this on the parent to indicate that the preference has changed and should
  * be reconsidered for layout. By default this just propagates upward to the next parent. The root
  * view will call <code>revalidate</code> on the associated text component.
  *
  * @param child the child view
  * @param width true if the width preference has changed
  * @param height true if the height preference has changed
  * @see javax.swing.JComponent#revalidate
  */
 public void preferenceChanged(View child, boolean width, boolean height) {
   View parent = getParent();
   if (parent != null) {
     parent.preferenceChanged(this, width, height);
   }
 }
Exemplo n.º 27
0
  private void invoke() {
    String cmd;
    if (popup != null) cmd = popup.list.getSelectedValue().toString();
    else {
      cmd = action.getText().trim();
      int index = cmd.indexOf('=');
      if (index != -1) {
        action.addCurrentToHistory();
        String propName = cmd.substring(0, index).trim();
        String propValue = cmd.substring(index + 1).trim();
        String code;

        if (propName.startsWith("buffer.")) {
          if (propName.equals("buffer.mode")) {
            code = "buffer.setMode(\"" + MiscUtilities.charsToEscapes(propValue) + "\");";
          } else {
            code =
                "buffer.setStringProperty(\""
                    + MiscUtilities.charsToEscapes(propName.substring("buffer.".length()))
                    + "\",\""
                    + MiscUtilities.charsToEscapes(propValue)
                    + "\");";
          }

          code += "\nbuffer.propertiesChanged();";
        } else if (propName.startsWith("!buffer.")) {
          code =
              "jEdit.setProperty(\""
                  + MiscUtilities.charsToEscapes(propName.substring(1))
                  + "\",\""
                  + MiscUtilities.charsToEscapes(propValue)
                  + "\");\n"
                  + "jEdit.propertiesChanged();";
        } else {
          code =
              "jEdit.setProperty(\""
                  + MiscUtilities.charsToEscapes(propName)
                  + "\",\""
                  + MiscUtilities.charsToEscapes(propValue)
                  + "\");\n"
                  + "jEdit.propertiesChanged();";
        }

        Macros.Recorder recorder = view.getMacroRecorder();
        if (recorder != null) recorder.record(code);
        BeanShell.eval(view, namespace, code);
        cmd = null;
      } else if (cmd.length() != 0) {
        String[] completions = getCompletions(cmd);
        if (completions.length != 0) {
          cmd = completions[0];
        }
      } else cmd = null;
    }

    if (popup != null) {
      popup.dispose();
      popup = null;
    }

    final String finalCmd = cmd;
    final EditAction act = (finalCmd == null ? null : jEdit.getAction(finalCmd));
    if (temp) view.removeToolBar(this);

    SwingUtilities.invokeLater(
        new Runnable() {
          public void run() {
            view.getTextArea().requestFocus();
            if (act == null) {
              if (finalCmd != null) {
                view.getStatus()
                    .setMessageAndClear(jEdit.getProperty("view.action.no-completions"));
              }
            } else {
              view.getInputHandler().setRepeatCount(repeatCount);
              view.getInputHandler().invokeAction(act);
            }
          }
        });
  }
Exemplo n.º 28
0
 /**
  * Fetches the attributes to use when rendering. This view isn't directly responsible for an
  * element so it returns the outer classes attributes.
  */
 public AttributeSet getAttributes() {
   View p = getParent();
   return (p != null) ? p.getAttributes() : null;
 }
Exemplo n.º 29
0
 @Override
 public void setSize(float width, float height) {
   super.setSize(width, height);
   updateMetrics();
 }
Exemplo n.º 30
0
    /**
     * Adjusts the given row if possible to fit within the layout span. By default this will try to
     * find the highest break weight possible nearest the end of the row. If a forced break is
     * encountered, the break will be positioned there.
     *
     * @param rowIndex the row to adjust to the current layout span.
     * @param desiredSpan the current layout span >= 0
     * @param x the location r starts at.
     */
    protected void adjustRow(FlowView fv, int rowIndex, int desiredSpan, int x) {
      final int flowAxis = fv.getFlowAxis();
      View r = fv.getView(rowIndex);
      int n = r.getViewCount();
      int span = 0;
      int bestWeight = BadBreakWeight;
      int bestSpan = 0;
      int bestIndex = -1;
      int bestOffset = 0;
      View v;
      for (int i = 0; i < n; i++) {
        v = r.getView(i);
        int spanLeft = desiredSpan - span;

        int w = v.getBreakWeight(flowAxis, x + span, spanLeft);
        if ((w >= bestWeight) && (w > BadBreakWeight)) {
          bestWeight = w;
          bestIndex = i;
          bestSpan = span;
          if (w >= ForcedBreakWeight) {
            // it's a forced break, so there is
            // no point in searching further.
            break;
          }
        }
        span += v.getPreferredSpan(flowAxis);
      }
      if (bestIndex < 0) {
        // there is nothing that can be broken, leave
        // it in it's current state.
        return;
      }

      // Break the best candidate view, and patch up the row.
      int spanLeft = desiredSpan - bestSpan;
      v = r.getView(bestIndex);
      v = v.breakView(flowAxis, v.getStartOffset(), x + bestSpan, spanLeft);
      View[] va = new View[1];
      va[0] = v;
      View lv = getLogicalView(fv);
      for (int i = bestIndex; i < n; i++) {
        View tmpView = r.getView(i);
        if (contains(lv, tmpView)) {
          tmpView.setParent(lv);
        } else if (tmpView.getViewCount() > 0) {
          recursiveReparent(tmpView, lv);
        }
      }
      r.replace(bestIndex, n - bestIndex, va);
    }