public static void startValueSetAnimation(final Pane parent) {
    final javafx.scene.shape.Rectangle rectangle = new javafx.scene.shape.Rectangle();
    Insets margin = BorderPane.getMargin(parent);
    if (margin == null) {
      margin = new Insets(0);
    }
    rectangle
        .widthProperty()
        .bind(parent.widthProperty().subtract(margin.getLeft() + margin.getRight()));
    rectangle
        .heightProperty()
        .bind(parent.heightProperty().subtract(margin.getTop() + margin.getBottom()));
    rectangle.setFill(Color.rgb(0, 150, 201));
    parent.getChildren().add(rectangle);

    BoxBlur bb = new BoxBlur();
    bb.setWidth(5);
    bb.setHeight(5);
    bb.setIterations(3);
    rectangle.setEffect(bb);

    FadeTransition ft = new FadeTransition(Duration.millis(250), rectangle);
    ft.setFromValue(0.2);
    ft.setToValue(0.8);
    ft.setCycleCount(2);
    ft.setAutoReverse(true);
    ft.play();
    ft.setOnFinished(
        new EventHandler<ActionEvent>() {
          @Override
          public void handle(ActionEvent event) {
            parent.getChildren().remove(rectangle);
          }
        });
  }
    @Override
    protected void layoutChildren() {
      final Insets insets = getInsets();
      final double left = insets.getLeft();
      final double width = getWidth() - left - insets.getRight();
      final double labelWidth = computeLabelWidth();
      final double valueWidth = width - labelWidth - GAP;
      final double valueStartX = left + labelWidth + GAP;

      double y = insets.getTop();
      double labelHeight = eventTitle.prefHeight(width);
      eventTitle.resizeRelocate(left, y, width, labelHeight);
      y += labelHeight + GAP;

      labelHeight = item1Label.prefHeight(-1);
      double valueHeight = item1Value.prefHeight(valueWidth);
      item1Value.resizeRelocate(valueStartX, y, valueWidth, valueHeight);
      item1Label.resizeRelocate(
          left, y + ((valueHeight - labelHeight) / 2), labelWidth, labelHeight);

      if (item2Label != null) {
        y += valueHeight + GAP;
        labelHeight = item2Label.prefHeight(-1);
        valueHeight = item2Value.prefHeight(valueWidth);
        item2Value.resizeRelocate(valueStartX, y, valueWidth, valueHeight);
        item2Label.resizeRelocate(
            left, y + ((valueHeight - labelHeight) / 2), labelWidth, labelHeight);
      }

      if (item3Label != null) {
        y += valueHeight + GAP;
        labelHeight = item3Label.prefHeight(-1);
        valueHeight = item3Value.prefHeight(valueWidth);
        item3Value.resizeRelocate(valueStartX, y, valueWidth, valueHeight);
        item3Label.resizeRelocate(
            left, y + ((valueHeight - labelHeight) / 2), labelWidth, labelHeight);
      }

      if (desc != null) {
        y += valueHeight + GAP;
        valueHeight = desc.prefHeight(width);
        desc.resizeRelocate(left, y, width, valueHeight);
      }

      if (button != null) {
        y += valueHeight + GAP;
        valueHeight = button.prefHeight(width);
        button.resizeRelocate(left, y, width, valueHeight);
      }
    }
Beispiel #3
0
  @Override
  protected void layoutChildren() {
    final Insets insets = getInsets();
    final double width = getWidth();
    final double height = getHeight();
    final double top = insets.getTop();
    final double left = insets.getLeft();
    final double bottom = insets.getBottom();
    final double right = insets.getRight();
    final double insideWidth = width - left - right;
    final double insideHeight = height - top - bottom;

    // REMIND(aim): need to figure out how to cache the runs to avoid over-calculation
    final List<Run> runs = getRuns(getOrientation() == HORIZONTAL ? insideWidth : insideHeight);

    // Now that the nodes are broken into runs, figure out alignments
    for (int i = 0, max = runs.size(); i < max; i++) {
      final Run run = runs.get(i);
      final double xoffset =
          left
              + computeXOffset(
                  insideWidth,
                  getOrientation() == HORIZONTAL ? run.width : computeContentWidth(runs),
                  getAlignmentInternal().getHpos());
      final double yoffset =
          top
              + computeYOffset(
                  insideHeight,
                  getOrientation() == VERTICAL ? run.height : computeContentHeight(runs),
                  getAlignmentInternal().getVpos());
      for (int j = 0; j < run.rects.size(); j++) {
        final LayoutRect lrect = run.rects.get(j);
        //              System.out.println("flowpane.layout: run="+i+" "+run.width+"x"+run.height+"
        // xoffset="+xoffset+" yoffset="+yoffset+" lrect="+lrect);
        final double x = xoffset + lrect.x;
        final double y = yoffset + lrect.y;
        layoutInArea(
            lrect.node,
            x,
            y,
            getOrientation() == HORIZONTAL ? lrect.width : run.width,
            getOrientation() == VERTICAL ? lrect.height : run.height,
            run.baselineOffset,
            getMargin(lrect.node),
            getColumnHalignmentInternal(),
            getRowValignmentInternal());
      }
    }
  }
 @Override
 protected void layoutChildren() {
   Insets controlInsets = control.getInsets();
   final double w = control.getWidth() - controlInsets.getLeft() - controlInsets.getRight();
   final double h = control.getHeight() - controlInsets.getTop() - controlInsets.getBottom();
   final double prefW = pathsG.prefWidth(-1);
   final double prefH = pathsG.prefHeight(-1);
   double scaleX = w / prefW;
   double scale = scaleX;
   if ((scaleX * prefH) > h) {
     scale = h / prefH;
   }
   double indicatorW = prefW * scale - 3;
   double indicatorH = prefH * scale - 3;
   pathsG.resizeRelocate((w - indicatorW) / 2, (h - indicatorH) / 2, indicatorW, indicatorH);
 }
Beispiel #5
0
 @Override
 protected double computeMinWidth(double height) {
   if (getContentBias() == HORIZONTAL) {
     double maxPref = 0;
     final List<Node> children = getChildren();
     for (int i = 0, size = children.size(); i < size; i++) {
       Node child = children.get(i);
       if (child.isManaged()) {
         maxPref = Math.max(maxPref, child.prefWidth(-1));
       }
     }
     final Insets insets = getInsets();
     return insets.getLeft() + snapSize(maxPref) + insets.getRight();
   }
   return computePrefWidth(height);
 }
Beispiel #6
0
 @Override
 protected double computeMinHeight(double width) {
   if (getContentBias() == VERTICAL) {
     double maxPref = 0;
     final List<Node> children = getChildren();
     for (int i = 0, size = children.size(); i < size; i++) {
       Node child = children.get(i);
       if (child.isManaged()) {
         maxPref = Math.max(maxPref, child.prefHeight(-1));
       }
     }
     final Insets insets = getInsets();
     return insets.getTop() + snapSize(maxPref) + insets.getBottom();
   }
   return computePrefHeight(width);
 }
  @Override
  protected void layoutChildren() {
    super.layoutChildren();

    mainIcon.relocate(getPadding().getLeft(), getPadding().getTop());
    mainIcon.resize(mainIcon.prefWidth(-1), mainIcon.prefHeight(-1));

    double titleX = mainIcon.getLayoutX() + mainIcon.getWidth() + 12;
    double titleY =
        mainIcon.getLayoutY() + (mainIcon.getHeight() - currentTitle.prefHeight(-1)) / 2;
    double titleWidth = getWidth() - titleX * 2;
    double titleHeight = currentTitle.prefHeight(-1);

    currentTitle.relocate(titleX, titleY);
    currentTitle.resize(titleWidth, titleHeight);

    actionBox.relocate(
        getWidth() - getPadding().getRight() - actionBox.prefWidth(-1), getPadding().getTop());
    actionBox.resize(actionBox.prefWidth(-1), actionBox.prefHeight(-1));

    changeViewAnimationTitle.relocate(titleX, titleY);
    changeViewAnimationTitle.resize(titleWidth, titleHeight);

    Insets borderInsets =
        Optional.ofNullable(getBorder()).map(border -> border.getInsets()).orElse(Insets.EMPTY);
    background.setX(borderInsets.getLeft());
    background.setY(borderInsets.getTop());
    background.setWidth(getWidth() - borderInsets.getLeft() - borderInsets.getRight());
    background.setHeight(getHeight() - borderInsets.getTop() - borderInsets.getBottom());

    changeViewAnimationCircle.setCenterX(mainIcon.getLayoutX() + mainIcon.getWidth() / 2);
    changeViewAnimationCircle.setCenterY(mainIcon.getLayoutY() + mainIcon.getHeight() / 2);
  }
 @Override
 protected void layoutChildren() {
   final Insets insets = getInsets();
   scrollPane.relocate(insets.getLeft(), insets.getTop());
   scrollPane.resize(
       getWidth() - insets.getLeft() - insets.getRight(),
       getHeight() - insets.getTop() - insets.getBottom());
 }
Beispiel #9
0
 public static Insets add(Insets insets1, Insets insets2) {
   if (insets1 == null) {
     return insets2;
   } else if (insets2 == null) {
     return insets1;
   }
   return new Insets(
       insets1.getTop() + insets2.getTop(),
       insets1.getRight() + insets2.getRight(),
       insets1.getBottom() + insets2.getBottom(),
       insets1.getLeft() + insets2.getLeft());
 }
 /*     */ protected void layoutChildren() {
   /*  50 */ super.layoutChildren();
   /*     */
   /*  52 */ if (((ProgressBar) getSkinnable()).isIndeterminate()) {
     /*  53 */ return;
     /*     */ }
   /*     */
   /*  56 */ StackPane track = (StackPane) getChildren().get(0);
   /*  57 */ StackPane bar = (StackPane) getChildren().get(1);
   /*     */
   /*  59 */ if (!bar.getChildren().contains(this.topGradient)) {
     /*  60 */ bar.getChildren().add(this.topGradient);
     /*     */ }
   /*     */
   /*  63 */ if (!bar.getChildren().contains(this.bottomGradient)) {
     /*  64 */ bar.getChildren().add(this.bottomGradient);
     /*     */ }
   /*     */
   /*  67 */ if (!getChildren().contains(this.verticalLines)) {
     /*  68 */ getChildren().add(this.verticalLines);
     /*     */ }
   /*     */
   /*  71 */ Insets insets = getInsets();
   /*  72 */ double x = insets.getLeft();
   /*  73 */ double y = insets.getTop();
   /*  74 */ double w = getWidth() - (insets.getLeft() + insets.getRight());
   /*  75 */ double h = getHeight() - (insets.getTop() + insets.getBottom());
   /*     */
   /*  78 */ double scale = Math.floor(w / 14.0D) * 14.0D / w;
   /*     */
   /*  80 */ double barWidth = bar.getWidth() * scale;
   /*  81 */ double barHeight = bar.getHeight();
   /*     */
   /*  83 */ track.resize(track.getWidth() * scale, track.getHeight());
   /*  84 */ bar.resize(barWidth, barHeight);
   /*     */
   /*  86 */ this.topGradient.setX(x + this.gradientMargin);
   /*  87 */ this.topGradient.setY(y + 0.5D);
   /*  88 */ this.topGradient.setWidth(barWidth - 2.0D * this.gradientMargin);
   /*  89 */ this.topGradient.setHeight(
       barHeight * 0.3D / this.gradientRadius * this.gradientTweak);
   /*     */
   /*  91 */ this.bottomGradient.setX(x + this.gradientMargin);
   /*  92 */ this.bottomGradient.setWidth(barWidth - 2.0D * this.gradientMargin);
   /*  93 */ double gh = barHeight * 0.21D / this.gradientRadius * this.gradientTweak;
   /*  94 */ this.bottomGradient.setY(barHeight - gh - 0.5D);
   /*  95 */ this.bottomGradient.setHeight(gh);
   /*     */
   /*  97 */ this.verticalLines.setX(x);
   /*  98 */ this.verticalLines.setY(y);
   /*  99 */ this.verticalLines.setWidth(w * scale);
   /* 100 */ this.verticalLines.setHeight(h);
   /*     */ }
    @Override
    protected double computePrefHeight(double width) {
      if (width == -1) width = 400;
      final Insets insets = getInsets();
      width = width - insets.getLeft() - insets.getRight();

      double h = eventTitle.prefHeight(width) + GAP;

      final double labelWidth = computeLabelWidth();
      final double valueWidth = width - labelWidth - GAP;

      // Add the heights of the 3 values, plus the 12 pixel gap between them
      h += item1Value.prefHeight(valueWidth);

      if (item2Value != null) {
        h += GAP;
        h += item2Value.prefHeight(valueWidth);
      }

      if (item3Value != null) {
        h += GAP;
        h += item3Value.prefHeight(valueWidth);
      }

      // Add the height of the desc plus padding
      if (desc != null) {
        h += GAP;
        h += desc.prefHeight(width);
      }

      // Add the height of the button plus padding
      if (button != null) {
        h += GAP;
        h += button.prefHeight(width);
      }

      return insets.getTop() + h + insets.getBottom();
    }
Beispiel #12
0
 @Override
 protected double computePrefHeight(double forWidth) {
   final Insets insets = getInsets();
   if (getOrientation() == HORIZONTAL) {
     // horizontal
     double maxRunWidth =
         forWidth != -1 ? forWidth - insets.getLeft() - insets.getRight() : getPrefWrapLength();
     List<Run> hruns = getRuns(maxRunWidth);
     return insets.getTop() + computeContentHeight(hruns) + insets.getBottom();
   } else {
     // vertical
     double maxRunHeight = getPrefWrapLength();
     List<Run> vruns = getRuns(maxRunHeight);
     double h = computeContentHeight(vruns);
     h = getPrefWrapLength() > h ? getPrefWrapLength() : h;
     return insets.getTop() + snapSize(h) + insets.getBottom();
   }
 }
    @Override
    protected void layoutChildren() {
      // Position and size the circular background
      // double doneTextHeight = doneText.getLayoutBounds().getHeight();
      final Insets controlInsets = control.getInsets();
      final double left = snapSize(controlInsets.getLeft());
      final double right = snapSize(controlInsets.getRight());
      final double top = snapSize(controlInsets.getTop());
      final double bottom = snapSize(controlInsets.getBottom());

      /*
       ** use the min of width, or height, keep it a circle
       */
      final double areaW = control.getWidth() - left - right;
      final double areaH = control.getHeight() - top - bottom /*- textGap - doneTextHeight*/;
      final double radiusW = areaW / 2;
      final double radiusH = areaH / 2;
      final double radius = Math.round(Math.min(radiusW, radiusH)); // use round instead of floor
      final double centerX = snapPosition(left + radiusW);
      final double centerY = snapPosition(top + radius);

      // find radius that fits inside radius - insetsPadding
      final Insets indicatorInsets = indicator.getInsets();
      final double iLeft = snapSize(indicatorInsets.getLeft());
      final double iRight = snapSize(indicatorInsets.getRight());
      final double iTop = snapSize(indicatorInsets.getTop());
      final double iBottom = snapSize(indicatorInsets.getBottom());
      final double progressRadius =
          snapSize(
              Math.min(
                  Math.min(radius - iLeft, radius - iRight),
                  Math.min(radius - iTop, radius - iBottom)));

      indicatorCircle.setRadius(radius);
      indicator.setLayoutX(centerX);
      indicator.setLayoutY(centerY);

      arcShape.setRadiusX(progressRadius);
      arcShape.setRadiusY(progressRadius);
      progress.setLayoutX(centerX);
      progress.setLayoutY(centerY);

      // find radius that fits inside progressRadius - progressInsets
      final Insets progressInsets = progress.getInsets();
      final double pLeft = snapSize(progressInsets.getLeft());
      final double pRight = snapSize(progressInsets.getRight());
      final double pTop = snapSize(progressInsets.getTop());
      final double pBottom = snapSize(progressInsets.getBottom());
      final double indicatorRadius =
          snapSize(
              Math.min(
                  Math.min(progressRadius - pLeft, progressRadius - pRight),
                  Math.min(progressRadius - pTop, progressRadius - pBottom)));

      // find size of spare box that fits inside indicator radius
      double squareBoxHalfWidth = Math.ceil(Math.sqrt((indicatorRadius * indicatorRadius) / 2));
      // double squareBoxHalfWidth2 = indicatorRadius * (Math.sqrt(2) / 2);

      tick.setLayoutX(centerX - squareBoxHalfWidth);
      tick.setLayoutY(centerY - squareBoxHalfWidth);
      tick.resize(squareBoxHalfWidth + squareBoxHalfWidth, squareBoxHalfWidth + squareBoxHalfWidth);
      tick.setVisible(control.getProgress() >= 1);
    }
Beispiel #14
0
  @Override
  public void handle(MouseEvent event) {
    if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
      if (dockNode.isFloating()
          && event.getClickCount() == 2
          && event.getButton() == MouseButton.PRIMARY) {
        dockNode.setMaximized(!dockNode.isMaximized());
      } else {
        // drag detected is used in place of mouse pressed so there is some threshold for the
        // dragging which is determined by the default drag detection threshold
        dragStart = new Point2D(event.getX(), event.getY());
      }
    } else if (event.getEventType() == MouseEvent.DRAG_DETECTED) {
      if (!dockNode.isFloating()) {
        // if we are not using a custom title bar and the user
        // is not forcing the default one for floating and
        // the dock node does have native window decorations
        // then we need to offset the stage position by
        // the height of this title bar
        if (!dockNode.isCustomTitleBar() && dockNode.isDecorated()) {
          dockNode.setFloating(true, new Point2D(0, DockTitleBar.this.getHeight()));
        } else {
          dockNode.setFloating(true);
        }

        // TODO: Find a better solution.
        // Temporary work around for nodes losing the drag event when removed from
        // the scene graph.
        // A possible alternative is to use "ghost" panes in the DockPane layout
        // while making DockNode simply an overlay stage that is always shown.
        // However since flickering when popping out was already eliminated that would
        // be overkill and is not a suitable solution for native decorations.
        // Bug report open: https://bugs.openjdk.java.net/browse/JDK-8133335
        DockPane dockPane = this.getDockNode().getDockPane();
        if (dockPane != null) {
          dockPane.addEventFilter(MouseEvent.MOUSE_DRAGGED, this);
          dockPane.addEventFilter(MouseEvent.MOUSE_RELEASED, this);
        }
      } else if (dockNode.isMaximized()) {
        double ratioX = event.getX() / this.getDockNode().getWidth();
        double ratioY = event.getY() / this.getDockNode().getHeight();

        // Please note that setMaximized is ruined by width and height changes occurring on the
        // stage and there is currently a bug report filed for this though I did not give them an
        // accurate test case which I should and wish I would have. This was causing issues in the
        // original release requiring maximized behavior to be implemented manually by saving the
        // restored bounds. The problem was that the resize functionality in DockNode.java was
        // executing at the same time canceling the maximized change.
        // https://bugs.openjdk.java.net/browse/JDK-8133334

        // restore/minimize the window after we have obtained its dimensions
        dockNode.setMaximized(false);

        // scale the drag start location by our restored dimensions
        dragStart = new Point2D(ratioX * dockNode.getWidth(), ratioY * dockNode.getHeight());
      }
      dragging = true;
      event.consume();
    } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
      if (dockNode.isFloating()
          && event.getClickCount() == 2
          && event.getButton() == MouseButton.PRIMARY) {
        event.setDragDetect(false);
        event.consume();
        return;
      }

      if (!dragging) return;

      Stage stage = dockNode.getStage();
      Insets insetsDelta = this.getDockNode().getBorderPane().getInsets();

      // dragging this way makes the interface more responsive in the event
      // the system is lagging as is the case with most current JavaFX
      // implementations on Linux
      stage.setX(event.getScreenX() - dragStart.getX() - insetsDelta.getLeft());
      stage.setY(event.getScreenY() - dragStart.getY() - insetsDelta.getTop());

      // TODO: change the pick result by adding a copyForPick()
      DockEvent dockEnterEvent =
          new DockEvent(
              this,
              DockEvent.NULL_SOURCE_TARGET,
              DockEvent.DOCK_ENTER,
              event.getX(),
              event.getY(),
              event.getScreenX(),
              event.getScreenY(),
              null);
      DockEvent dockOverEvent =
          new DockEvent(
              this,
              DockEvent.NULL_SOURCE_TARGET,
              DockEvent.DOCK_OVER,
              event.getX(),
              event.getY(),
              event.getScreenX(),
              event.getScreenY(),
              null);
      DockEvent dockExitEvent =
          new DockEvent(
              this,
              DockEvent.NULL_SOURCE_TARGET,
              DockEvent.DOCK_EXIT,
              event.getX(),
              event.getY(),
              event.getScreenX(),
              event.getScreenY(),
              null);

      EventTask eventTask =
          new EventTask() {
            @Override
            public void run(Node node, Node dragNode) {
              executions++;

              if (dragNode != node) {
                Event.fireEvent(node, dockEnterEvent.copyFor(DockTitleBar.this, node));

                if (dragNode != null) {
                  // fire the dock exit first so listeners
                  // can actually keep track of the node we
                  // are currently over and know when we
                  // aren't over any which DOCK_OVER
                  // does not provide
                  Event.fireEvent(dragNode, dockExitEvent.copyFor(DockTitleBar.this, dragNode));
                }

                dragNodes.put(node.getScene().getWindow(), node);
              }
              Event.fireEvent(node, dockOverEvent.copyFor(DockTitleBar.this, node));
            }
          };

      this.pickEventTarget(
          new Point2D(event.getScreenX(), event.getScreenY()), eventTask, dockExitEvent);
    } else if (event.getEventType() == MouseEvent.MOUSE_RELEASED) {
      dragging = false;

      DockEvent dockReleasedEvent =
          new DockEvent(
              this,
              DockEvent.NULL_SOURCE_TARGET,
              DockEvent.DOCK_RELEASED,
              event.getX(),
              event.getY(),
              event.getScreenX(),
              event.getScreenY(),
              null,
              this.getDockNode());

      EventTask eventTask =
          new EventTask() {
            @Override
            public void run(Node node, Node dragNode) {
              executions++;
              if (dragNode != node) {
                Event.fireEvent(node, dockReleasedEvent.copyFor(DockTitleBar.this, node));
              }
              Event.fireEvent(node, dockReleasedEvent.copyFor(DockTitleBar.this, node));
            }
          };

      this.pickEventTarget(new Point2D(event.getScreenX(), event.getScreenY()), eventTask, null);

      dragNodes.clear();

      // Remove temporary event handler for bug mentioned above.
      DockPane dockPane = this.getDockNode().getDockPane();
      if (dockPane != null) {
        dockPane.removeEventFilter(MouseEvent.MOUSE_DRAGGED, this);
        dockPane.removeEventFilter(MouseEvent.MOUSE_RELEASED, this);
      }
    }
  }
 @Override
 protected double computePrefHeight(double width) {
   final Insets insets = getInsets();
   return insets.getTop() + content.prefHeight(width) + insets.getBottom();
 }
 @Override
 protected double computePrefWidth(double height) {
   final Insets insets = getInsets();
   return insets.getLeft() + content.prefWidth(height) + insets.getRight();
 }
 @Override
 protected double computePrefHeight(double width) {
   final Insets controlInsets = control.getInsets();
   final double top = snapSize(controlInsets.getTop());
   final double bottom = snapSize(controlInsets.getBottom());
   final Insets indicatorInsets = indicator.getInsets();
   final double iLeft = snapSize(indicatorInsets.getLeft());
   final double iRight = snapSize(indicatorInsets.getRight());
   final double iTop = snapSize(indicatorInsets.getTop());
   final double iBottom = snapSize(indicatorInsets.getBottom());
   final double indicatorMax =
       snapSize(Math.max(Math.max(iLeft, iRight), Math.max(iTop, iBottom)));
   final Insets progressInsets = progress.getInsets();
   final double pLeft = snapSize(progressInsets.getLeft());
   final double pRight = snapSize(progressInsets.getRight());
   final double pTop = snapSize(progressInsets.getTop());
   final double pBottom = snapSize(progressInsets.getBottom());
   final double progressMax =
       snapSize(Math.max(Math.max(pLeft, pRight), Math.max(pTop, pBottom)));
   final Insets tickInsets = tick.getInsets();
   final double tTop = snapSize(tickInsets.getTop());
   final double tBottom = snapSize(tickInsets.getBottom());
   final double indicatorHeight =
       indicatorMax + progressMax + tTop + tBottom + progressMax + indicatorMax;
   return top + indicatorHeight /*+ textGap  + doneText.getLayoutBounds().getHeight()*/ + bottom;
 }
 @Override
 protected double computePrefWidth(double height) {
   final Insets controlInsets = control.getInsets();
   final double left = snapSize(controlInsets.getLeft());
   final double right = snapSize(controlInsets.getRight());
   final Insets indicatorInsets = indicator.getInsets();
   final double iLeft = snapSize(indicatorInsets.getLeft());
   final double iRight = snapSize(indicatorInsets.getRight());
   final double iTop = snapSize(indicatorInsets.getTop());
   final double iBottom = snapSize(indicatorInsets.getBottom());
   final double indicatorMax =
       snapSize(Math.max(Math.max(iLeft, iRight), Math.max(iTop, iBottom)));
   final Insets progressInsets = progress.getInsets();
   final double pLeft = snapSize(progressInsets.getLeft());
   final double pRight = snapSize(progressInsets.getRight());
   final double pTop = snapSize(progressInsets.getTop());
   final double pBottom = snapSize(progressInsets.getBottom());
   final double progressMax =
       snapSize(Math.max(Math.max(pLeft, pRight), Math.max(pTop, pBottom)));
   final Insets tickInsets = tick.getInsets();
   final double tLeft = snapSize(tickInsets.getLeft());
   final double tRight = snapSize(tickInsets.getRight());
   final double indicatorWidth =
       indicatorMax + progressMax + tLeft + tRight + progressMax + indicatorMax;
   return left
       + indicatorWidth
       + /*Math.max(indicatorWidth, doneText.getLayoutBounds().getWidth()) + */ right;
 }