@Override
  public void paintComponent(final Graphics g) {
    super.paintComponent(g);

    // skip if view is unavailable
    if (tdata.rows == null) return;

    gui.painting = true;
    g.setFont(GUIConstants.font);

    final int w = getWidth() - scroll.getWidth();
    final int h = getHeight();
    final int fsz = gui.gprop.num(GUIProp.FONTSIZE);

    final Context context = tdata.context;
    final Data data = context.data();
    final int focus = gui.context.focused;
    final int rfocus = tdata.getRoot(data, focus);
    int mpos = 0;

    final int nCols = tdata.cols.length;
    final int nRows = tdata.rows.size();
    final int rowH = tdata.rowH;

    final TableIterator ti = new TableIterator(data, tdata);
    final TokenBuilder[] tb = new TokenBuilder[nCols];
    for (int i = 0; i < nCols; ++i) tb[i] = new TokenBuilder();

    focusedString = null;
    final Nodes marked = context.marked;
    int l = scroll.pos() / rowH - 1;
    int posY = -scroll.pos() + l * rowH;

    while (++l < nRows && marked != null) {
      // skip when all visible rows have been painted or if data has changed
      if (posY > h || l >= tdata.rows.size()) break;
      posY += rowH;

      final int pre = tdata.rows.get(l);
      while (mpos < marked.size() && marked.list[mpos] < pre) ++mpos;

      // draw line
      g.setColor(GUIConstants.color2);
      g.drawLine(0, posY + rowH - 1, w, posY + rowH - 1);
      g.setColor(Color.white);
      g.drawLine(0, posY + rowH, w, posY + rowH);

      // verify if current node is marked or focused
      final boolean rm = mpos < marked.size() && marked.list[mpos] == pre;
      final boolean rf = pre == rfocus;
      final int col = rm ? rf ? 5 : 4 : 3;
      if (rm || rf) {
        g.setColor(GUIConstants.color(col));
        g.fillRect(0, posY - 1, w, rowH);
        g.setColor(GUIConstants.color(col + 4));
        g.drawLine(0, posY - 1, w, posY - 1);
      }
      g.setColor(Color.black);

      // skip drawing of text during animation
      if (rowH < fsz) continue;

      // find all row contents
      ti.init(pre);
      int fcol = -1;
      while (ti.more()) {
        final int c = ti.col;
        if (ti.pre == focus || data.parent(ti.pre, data.kind(ti.pre)) == focus) fcol = c;

        // add content to column (skip too long contents)...
        if (tb[c].size() < 100) {
          if (tb[c].size() != 0) tb[c].add("; ");
          tb[c].add(data.text(ti.pre, ti.text));
        }
      }

      // add dots if content is too long
      for (final TokenBuilder t : tb) if (t.size() > 100) t.add(DOTS);

      // draw row contents
      byte[] focusStr = null;
      int fx = -1;
      double x = 1;
      for (int c = 0; c < nCols; ++c) {
        // draw single column
        final double cw = w * tdata.cols[c].width;
        final double ce = x + cw;

        if (ce != 0) {
          final byte[] str = tb[c].size() != 0 ? tb[c].finish() : null;
          if (str != null) {
            if (tdata.mouseX > x && tdata.mouseX < ce || fcol == c) {
              fx = (int) x;
              focusStr = str;
            }
            BaseXLayout.chopString(g, str, (int) x + 1, posY + 2, (int) cw - 4, fsz);
            tb[c].reset();
          }
        }
        x = ce;
      }

      // highlight focused entry
      if (rf || fcol != -1) {
        if (focusStr != null) {
          final int sw = BaseXLayout.width(g, focusStr) + 8;
          if (fx > w - sw - 2) fx = w - sw - 2;
          g.setColor(GUIConstants.color(col + 2));
          g.fillRect(fx - 2, posY, sw, rowH - 1);
          g.setColor(Color.black);
          BaseXLayout.chopString(g, focusStr, fx + 1, posY + 2, sw, fsz);

          // cache focused string
          focusedString = string(focusStr);
          final int i = focusedString.indexOf("; ");
          if (i != -1) focusedString = focusedString.substring(0, i);
        }
      }
    }
    gui.painting = false;
  }
Example #2
0
  @Override
  void drawRectangles(final Graphics g, final MapRects rects, final float scale) {
    // some additions to set up borders
    final MapRect l = view.layout.layout;
    l.x = (int) scale * l.x;
    l.y = (int) scale * l.y;
    l.w = (int) scale * l.w;
    l.h = (int) scale * l.h;
    final int ww = view.getWidth();
    final int hh = view.getWidth();

    final Data data = view.gui.context.data();
    final int fsz = GUIConstants.fontSize;

    final int off = gopts.get(GUIOptions.MAPOFFSETS);
    final int rs = rects.size;
    for (int ri = 0; ri < rs; ++ri) {
      // get rectangle information
      final MapRect r = rects.get(ri);
      final int pre = r.pre;

      // level 1: next context node, set marker pointer to 0
      final int lvl = r.level;

      final boolean full = r.w == ww && r.h == hh;
      Color col = color(rects, ri);
      final boolean mark = col != null;

      r.pos =
          view.gui.context.marked.ftpos != null
              ? view.gui.context.marked.ftpos.get(data, pre)
              : null;
      g.setColor(mark ? col : GUIConstants.color(lvl));

      if (r.w < l.x + l.w || r.h < l.y + l.h || off < 2 || ViewData.leaf(gopts, data, pre)) {
        g.fillRect(r.x, r.y, r.w, r.h);
      } else {
        // painting only border for non-leaf nodes..
        g.fillRect(r.x, r.y, l.x, r.h);
        g.fillRect(r.x, r.y, r.w, l.y);
        g.fillRect(r.x + r.w - l.w, r.y, l.w, r.h);
        g.fillRect(r.x, r.y + r.h - l.h, r.w, l.h);
      }

      if (!full) {
        col = mark ? GUIConstants.colormark3 : GUIConstants.color(lvl + 2);
        g.setColor(col);
        g.drawRect(r.x, r.y, r.w, r.h);
        col = mark ? GUIConstants.colormark4 : GUIConstants.color(Math.max(0, lvl - 2));
        g.setColor(col);
        g.drawLine(r.x + r.w, r.y, r.x + r.w, r.y + r.h);
        g.drawLine(r.x, r.y + r.h, r.x + r.w, r.y + r.h);
      }

      // skip drawing of string if there is no space
      if (r.w <= 3 || r.h < GUIConstants.fontSize) continue;

      r.x += 3;
      r.w -= 3;

      final int kind = data.kind(pre);
      if (kind == Data.ELEM || kind == Data.DOC) {
        g.setColor(Color.black);
        g.setFont(GUIConstants.font);
        BaseXLayout.chopString(g, ViewData.name(gopts, data, pre), r.x, r.y, r.w, fsz);
      } else {
        g.setColor(GUIConstants.color(r.level * 2 + 8));
        g.setFont(GUIConstants.mfont);
        final byte[] text = ViewData.content(data, pre, false);

        r.thumb = MapRenderer.calcHeight(g, r, text, fsz) >= r.h;
        if (r.thumb) {
          MapRenderer.drawThumbnails(g, r, text, fsz);
        } else {
          MapRenderer.drawText(g, r, text, fsz);
        }
      }
      r.x -= 3;
      r.w += 3;
    }
  }