@Override
 protected void snapToPage(int whichPage) {
   if (mScrollMode == X_LARGE_MODE) {
     super.snapToPage(whichPage);
   } else {
     snapToPageWithVelocity(whichPage, 0, false);
   }
 }
 @Override
 protected void snapToDestination() {
   if (mScrollMode == X_LARGE_MODE) {
     super.snapToDestination();
   } else {
     snapToPageWithVelocity(getPageNearestToCenterOfScreen(), 0);
   }
 }
  /**
   * Validates this view.
   *
   * @param request the request
   * @throws ServiceVersionException the service version exception
   * @throws ServiceValidationException the service validation exception
   */
  @Override
  protected void internalValidate(ServiceRequestBase request)
      throws ServiceVersionException, ServiceValidationException {
    super.internalValidate(request);

    EwsUtilities.validateEnumVersionValue(
        this.traversal, request.getService().getRequestedServerVersion());
  }
  /** Initializes various states for this workspace. */
  @Override
  protected void init() {
    super.init();

    mScrollMode = getScrollMode();
    if (mScrollMode == DEFAULT_MODE) {
      mBaseLineFlingVelocity = 2500.0f;
      mFlingVelocityInfluence = 0.4f;
      mScrollInterpolator = new OvershootInterpolator();
      mScroller = new Scroller(getContext(), mScrollInterpolator);
    }
  }
  @Override
  public void computeScroll() {
    if (mScrollMode == X_LARGE_MODE) {
      super.computeScroll();
    } else {
      boolean scrollComputed = computeScrollHelper();

      if (!scrollComputed && mTouchState == TOUCH_STATE_SCROLLING) {
        final float now = System.nanoTime() / NANOTIME_DIV;
        final float e = (float) Math.exp((now - mSmoothingTime) / SMOOTHING_CONSTANT);

        final float dx = mTouchX - mUnboundedScrollX;
        scrollTo(Math.round(mUnboundedScrollX + dx * e), getScrollY());
        mSmoothingTime = now;

        // Keep generating points as long as we're more than 1px away from the target
        if (dx > 1.f || dx < -1.f) {
          invalidate();
        }
      }
    }
  }
 /**
  * Internals the write search settings to XML.
  *
  * @param writer the writer
  * @param groupBy the group by
  * @throws javax.xml.stream.XMLStreamException the xML stream exception
  * @throws ServiceXmlSerializationException the service xml serialization exception
  */
 @Override
 protected void internalWriteSearchSettingsToXml(EwsServiceXmlWriter writer, Grouping groupBy)
     throws XMLStreamException, ServiceXmlSerializationException {
   super.internalWriteSearchSettingsToXml(writer, groupBy);
 }
  public void layout(Launcher launcher) {
    FrameLayout.LayoutParams lp;
    Resources res = launcher.getResources();
    boolean hasVerticalBarLayout = isVerticalBarLayout();

    // Layout the search bar space
    View searchBar = launcher.getSearchBar();
    lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
    if (hasVerticalBarLayout) {
      // Vertical search bar space
      lp.gravity = Gravity.TOP | Gravity.LEFT;
      lp.width = searchBarSpaceHeightPx;
      lp.height = LayoutParams.WRAP_CONTENT;

      LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar);
      targets.setOrientation(LinearLayout.VERTICAL);
    } else {
      // Horizontal search bar space
      lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
      lp.width = searchBarSpaceWidthPx;
      lp.height = searchBarSpaceHeightPx;
    }
    searchBar.setLayoutParams(lp);

    // Layout the workspace
    PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace);
    lp = (FrameLayout.LayoutParams) workspace.getLayoutParams();
    lp.gravity = Gravity.CENTER;
    int orientation = isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT;
    Rect padding = getWorkspacePadding(orientation);
    workspace.setLayoutParams(lp);
    workspace.setPadding(padding.left, padding.top, padding.right, padding.bottom);
    workspace.setPageSpacing(getWorkspacePageSpacing(orientation));

    // Layout the hotseat
    View hotseat = launcher.findViewById(R.id.hotseat);
    lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams();
    if (hasVerticalBarLayout) {
      // Vertical hotseat
      lp.gravity = Gravity.END;
      lp.width = hotseatBarHeightPx;
      lp.height = LayoutParams.MATCH_PARENT;
      hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx);
    } else if (isTablet()) {
      // Pad the hotseat with the workspace padding calculated above
      lp.gravity = Gravity.BOTTOM;
      lp.width = LayoutParams.MATCH_PARENT;
      lp.height = hotseatBarHeightPx;
      hotseat.setPadding(
          edgeMarginPx + padding.left, 0, edgeMarginPx + padding.right, 2 * edgeMarginPx);
    } else {
      // For phones, layout the hotseat without any bottom margin
      // to ensure that we have space for the folders
      lp.gravity = Gravity.BOTTOM;
      lp.width = LayoutParams.MATCH_PARENT;
      lp.height = hotseatBarHeightPx;
      hotseat.findViewById(R.id.layout).setPadding(2 * edgeMarginPx, 0, 2 * edgeMarginPx, 0);
    }
    hotseat.setLayoutParams(lp);

    // Layout the page indicators
    View pageIndicator = launcher.findViewById(R.id.page_indicator);
    if (pageIndicator != null) {
      if (hasVerticalBarLayout) {
        // Hide the page indicators when we have vertical search/hotseat
        pageIndicator.setVisibility(View.GONE);
      } else {
        // Put the page indicators above the hotseat
        lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
        lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
        lp.width = LayoutParams.WRAP_CONTENT;
        lp.height = LayoutParams.WRAP_CONTENT;
        lp.bottomMargin = hotseatBarHeightPx;
        pageIndicator.setLayoutParams(lp);
      }
    }

    // Layout AllApps
    AppsCustomizeTabHost host =
        (AppsCustomizeTabHost) launcher.findViewById(R.id.apps_customize_pane);
    if (host != null) {
      // Center the all apps page indicator
      int pageIndicatorHeight =
          (int)
              (pageIndicatorHeightPx
                  * Math.min(1f, (allAppsIconSizePx / DynamicGrid.DEFAULT_ICON_SIZE_PX)));
      pageIndicator = host.findViewById(R.id.apps_customize_page_indicator);
      if (pageIndicator != null) {
        LinearLayout.LayoutParams lllp =
            (LinearLayout.LayoutParams) pageIndicator.getLayoutParams();
        lllp.width = LayoutParams.WRAP_CONTENT;
        lllp.height = pageIndicatorHeight;
        pageIndicator.setLayoutParams(lllp);
      }

      AppsCustomizePagedView pagedView =
          (AppsCustomizePagedView) host.findViewById(R.id.apps_customize_pane_content);

      FrameLayout fakePageContainer = (FrameLayout) host.findViewById(R.id.fake_page_container);
      FrameLayout fakePage = (FrameLayout) host.findViewById(R.id.fake_page);

      padding = new Rect();
      if (pagedView != null) {
        // Constrain the dimensions of all apps so that it does not span the full width
        int paddingLR =
            (availableWidthPx - (allAppsCellWidthPx * allAppsNumCols)) / (2 * (allAppsNumCols + 1));
        int paddingTB =
            (availableHeightPx - (allAppsCellHeightPx * allAppsNumRows))
                / (2 * (allAppsNumRows + 1));
        paddingLR = Math.min(paddingLR, (int) ((paddingLR + paddingTB) * 0.75f));
        paddingTB = Math.min(paddingTB, (int) ((paddingLR + paddingTB) * 0.75f));
        int maxAllAppsWidth = (allAppsNumCols * (allAppsCellWidthPx + 2 * paddingLR));
        int gridPaddingLR = (availableWidthPx - maxAllAppsWidth) / 2;
        // Only adjust the side paddings on landscape phones, or tablets
        if ((isTablet() || isLandscape) && gridPaddingLR > (allAppsCellWidthPx / 4)) {
          padding.left = padding.right = gridPaddingLR;
        }

        // The icons are centered, so we can't just offset by the page indicator height
        // because the empty space will actually be pageIndicatorHeight + paddingTB
        padding.bottom = Math.max(0, pageIndicatorHeight - paddingTB);

        pagedView.setWidgetsPageIndicatorPadding(pageIndicatorHeight);
        fakePage.setBackground(res.getDrawable(R.drawable.quantum_panel));

        // Horizontal padding for the whole paged view
        int pagedFixedViewPadding =
            res.getDimensionPixelSize(R.dimen.apps_customize_horizontal_padding);

        padding.left += pagedFixedViewPadding;
        padding.right += pagedFixedViewPadding;

        pagedView.setPadding(padding.left, padding.top, padding.right, padding.bottom);
        fakePageContainer.setPadding(padding.left, padding.top, padding.right, padding.bottom);
      }
    }

    // Layout the Overview Mode
    ViewGroup overviewMode = launcher.getOverviewPanel();
    if (overviewMode != null) {
      Rect r = getOverviewModeButtonBarRect();
      lp = (FrameLayout.LayoutParams) overviewMode.getLayoutParams();
      lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;

      int visibleChildCount = getVisibleChildCount(overviewMode);
      int totalItemWidth = visibleChildCount * overviewModeBarItemWidthPx;
      int maxWidth = totalItemWidth + (visibleChildCount - 1) * overviewModeBarSpacerWidthPx;

      lp.width = Math.min(availableWidthPx, maxWidth);
      lp.height = r.height();
      overviewMode.setLayoutParams(lp);

      if (lp.width > totalItemWidth && visibleChildCount > 1) {
        // We have enough space. Lets add some margin too.
        int margin = (lp.width - totalItemWidth) / (visibleChildCount - 1);
        View lastChild = null;

        // Set margin of all visible children except the last visible child
        for (int i = 0; i < visibleChildCount; i++) {
          if (lastChild != null) {
            MarginLayoutParams clp = (MarginLayoutParams) lastChild.getLayoutParams();
            if (isLayoutRtl) {
              clp.leftMargin = margin;
            } else {
              clp.rightMargin = margin;
            }
            lastChild.setLayoutParams(clp);
            lastChild = null;
          }
          View thisChild = overviewMode.getChildAt(i);
          if (thisChild.getVisibility() != View.GONE) {
            lastChild = thisChild;
          }
        }
      }
    }
  }