All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.editor.BaseView Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.editor;

import java.awt.Insets;
import java.awt.Graphics;
import java.awt.Shape;
import java.awt.Rectangle;
import javax.swing.text.View;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.BadLocationException;
import org.netbeans.modules.editor.lib.drawing.DrawGraphics;

/**
* Base abstract view serves as parent for both
* leaf and branch views.
*
* @author  Miloslav Metelka
* @version 1.00
*/

public abstract class BaseView extends View {

    /** Top insets paint type. */
    protected static final int INSETS_TOP = 1;

    /** Main area paint type. */
    protected static final int MAIN_AREA = 2;

    /** Bottom insets paint type. */
    protected static final int INSETS_BOTTOM = 4;

    /** Is this view packed */
    protected boolean packed;

    /** Index of this view as child view in its parent.
    * This gives the parent view a hint at which index it should
    * search for this view. If this index is incorrect, the parent
    * view searches the whole array of children. However this gives
    * good optimization of child views search process.
    */
    protected int helperInd;

    /** JTextComponent hosting this view */
    private JTextComponent component;

    /** Border insets of this view. Can be null */
    protected Insets insets;

    /** Start y coord. for this view */
    private int startY = -1;

    /** Construct new base view */
    BaseView(Element elem) {
        super(elem);
    }

    /** Getter for packed flag */
    public boolean isPacked() {
        return packed;
    }

    /** Setter for packed flag */
    public void setPacked(boolean packed) {
        this.packed = packed;
    }

    /** Get aligment along an X_AXIS or Y_AXIS */
    public @Override float getAlignment(int axis) {
        return 0f;
    }

    /* package */ abstract void modelToViewDG(int pos, DrawGraphics dg) throws BadLocationException;

    /** Get y-coord value from position */
    protected abstract int getYFromPos(int pos) throws BadLocationException;

    /** Get position when knowing y-coord */
    protected abstract int getPosFromY(int y);

    protected abstract int getBaseX(int y);

    /** Returns binary composition of regions that should be painted.
    * It can be binary composition of INSETS_TOP, MAIN_AREA and INSETS_BOTTOM.
    *
    * @param g Graphics to paint through
    * @param clip clipping area of graphics object
    *
    */
    protected abstract int getPaintAreas(Graphics g, int clipY, int clipHeight);

    /** Paint either top insets, main area, or bottom insets.
    *
    * @param g Graphics to paint through
    * @param clip clipping area of graphics object
    * @param paintAreas binary composition of paint areas
    */
    protected abstract void paintAreas(Graphics g, int clipY, int clipHeight, int paintAreas);

    /** It divides painting into three areas:
    * INSETS_TOP, MAIN_AREA, INSETS_BOTTOM. It paints them sequentially
    * using paintArea() method until it returns false.
    * This implementation also supposes that allocation is
    * instance of Rectangle to save object creations. The root
    * view in TextUI implementation will take care to ensure child views will
    * get rectangle instances.
    */
    public void paint(Graphics g, Shape allocation) {
        Rectangle clip = g.getClipBounds();
        if (clip.height < 0 || clip.width < 0) {
            return;
        }
        int paintAreas = getPaintAreas(g, clip.y, clip.height);
        if (paintAreas != 0) {
            paintAreas(g, clip.y, clip.height, paintAreas);
        }
    }

    /** Get component hosting this view. */
    public JTextComponent getComponent() {
        if (component == null) {
            component = (JTextComponent)getContainer();
        }
        return component;
    }

    /** Get insets of this view. */
    public Insets getInsets() {
        return insets;
    }

    /** This function is used to correct information
    * about which index this child view occupies in parent view's
    * array of children. It is called by parent view.
    */
    protected void setHelperInd(int ind) {
        helperInd = ind;
    }

    /** Get child view's y base value. This function is called by children
    * of this view to get its y offset.
    * @param view is child view of this view for which
    *   the offset should be computed.
    * @param helperInd is index that child view has cached to ease
    *   the parent view to search for it in its children array.
    *   If this index is correct, parent uses it. If it's incorrect
    *   parent view searches through the whole array of its children
    *   to find the child. It then calls children's
    *   setParentInd() to correct its location index.
    */
    protected abstract int getViewStartY(BaseView view, int helperInd);

    /** Informs the view that if it had cached start y of itself
    * it should invalidate it as it is no longer valid and it should call
    * getViewStartY() to get updated value.
    */
    protected void invalidateStartY() {
        startY = -1;
    }

    /** Get y base value for this view. */
    protected int getStartY() {
        if (startY == -1) { // the value is invalid
            BaseView v = (BaseView)getParent();
            if (v != null) {
                startY = v.getViewStartY(this, helperInd);
            }
        }
        return startY;
    }

    /** Get height of the view */
    public abstract int getHeight();

    /** Update height of main area as result of some important change.
    * Propagate to child views if necessary.
    */
    public abstract void updateMainHeight();

    /** Get preferred span over axis */
    public float getPreferredSpan(int axis) {
        switch (axis) {
        case Y_AXIS:
            return getHeight();
        }
        return 0f;
    }

    /** Get editor UI */
    protected EditorUI getEditorUI() {
        return ((BaseTextUI)getComponent().getUI()).getEditorUI();
    }

    /** Display view hierarchy on console. Current view is marked with asterisk. */
    public void displayHierarchy() {
        // find the root view
        BaseView v = this;
        while (v.getParent() != null) {
            v = (BaseView)v.getParent();
        }
        v.displayHierarchyHelper(this, 0, 0);
    }

    /** Helper for displaying hierarchy - called recursively.
    * @param origView view for which the displayHierarchy method was originally
    *  called. It is marked by asterisk.
    * @param col column offset
    * @param index index of this view in parent children[] array
    */
    private void displayHierarchyHelper(View origView, int col, int index) {
        StringBuffer buf = new StringBuffer();
        buf.append(((this == origView) ? "*" : " ")); // NOI18N
        for (int i = 0; i < col; i++) {
            buf.append(' ');
        }
        buf.append('[');
        buf.append(Integer.toString(index));
        buf.append("] "); // NOI18N
        buf.append(this.toString());
        System.out.println(buf);
        int childrenCnt = getViewCount();
        if (childrenCnt > 0) {
            for (int i = 0; i < childrenCnt; i++) {
                ((BaseView)getView(i)).displayHierarchyHelper(origView, col + 1, i);
            }
        }

    }

    public @Override String toString() {
        return "BaseView=" + System.identityHashCode(this) // NOI18N
               + ", elem=" + getElement() + ", parent=" // NOI18N
               + System.identityHashCode(getParent());
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy