Package com.google.testing.testify.risk.frontend.client.view.widgets

Source Code of com.google.testing.testify.risk.frontend.client.view.widgets.CapabilitiesGridWidget

// Copyright 2010 Google Inc. All Rights Reseved.
//
// Licensed 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 com.google.testing.testify.risk.frontend.client.view.widgets;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.Label;
import com.google.testing.testify.risk.frontend.model.Attribute;
import com.google.testing.testify.risk.frontend.model.Capability;
import com.google.testing.testify.risk.frontend.model.Component;
import com.google.testing.testify.risk.frontend.model.Pair;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* A widget for displaying a set of capabilities in a Grid.
*
* @author jimr@google.com (Jim Reardon)
*/
public class CapabilitiesGridWidget extends Composite
    implements HasValueChangeHandlers<Pair<Component, Attribute>> {

  private final List<Attribute> attributes = Lists.newArrayList();
  private final List<Component> components = Lists.newArrayList();

  // Map from intersection key to capability list.
  private final Multimap<Integer, Capability> capabilityMap = HashMultimap.create();
  // Map from intersection key to table cell.
  private final Map<Integer, HTML> cellMap = Maps.newHashMap();

  private final Grid grid = new Grid();

  private int highlightedCellRow = -1;
  private int highlightedCellColumn = -1;

  public CapabilitiesGridWidget() {
    grid.addStyleName("tty-ComponentAttributeGrid");
    grid.addStyleName("tty-CapabilitiesGrid");

    initWidget(grid);
  }

  /**
   * Adds a single capability without clearing out prior capabilities.
   *
   * @param capability capability to add.
   */
  public void addCapability(Capability capability) {
    Integer key = capability.getCapabilityIntersectionKey();

    // Add the capability.
    addCapabilityWithoutUpdate(capability);

    // Update relevant UI field.
    updateGridCell(key);
  }

  public void deleteCapability(Capability capability) {
    for (Integer key : capabilityMap.keySet()) {
      Collection<Capability> c = capabilityMap.get(key);
      if (c.contains(capability)) {
        c.remove(capability);
        updateGridCell(key);
      }
    }
  }

  public void updateCapability(Capability capability) {
    deleteCapability(capability);
    addCapability(capability);
  }

  public void setAttributes(List<Attribute> attributes) {
    this.attributes.clear();
    this.attributes.addAll(attributes);
    redrawGrid();
  }

  public void setComponents(List<Component> components) {
    this.components.clear();
    this.components.addAll(components);
    redrawGrid();
  }

  public void setCapabilities(List<Capability> capabilities) {
    capabilityMap.clear();
    for (Capability capability : capabilities) {
      addCapabilityWithoutUpdate(capability);
    }

    updateGridCells();
  }

  private void addCapabilityWithoutUpdate(Capability capability) {
    Integer key = capability.getCapabilityIntersectionKey();
    capabilityMap.put(key, capability);
  }

  /**
   * Completely recreates the grid then calls updateGridCells() to update contents of grid.
   * This should be called if the list of components or attributes changes.
   */
  private void redrawGrid() {
    grid.clear();
    cellMap.clear();

    if (components.size() < 1 || attributes.size() < 1) {
      return;
    }

    grid.resize(components.size() + 1, attributes.size() + 1);
    grid.getCellFormatter().setStyleName(0, 0, "tty-GridXHeaderCell");

    // Add component headers.
    for (int i = 0; i < components.size(); i++) {
      Label label = new Label(components.get(i).getName());
      grid.getCellFormatter().setStyleName(i + 1, 0, "tty-GridXHeaderCell");
      grid.setWidget(i + 1, 0, label);
    }

    // Add attribute headers.
    for (int i = 0; i < attributes.size(); i++) {
      Label label = new Label(attributes.get(i).getName());
      grid.getCellFormatter().setStyleName(0, i + 1, "tty-GridYHeaderCell");
      grid.setWidget(0, i + 1, label);
    }

    // Fill up the rest of the grid with labels.
    for (int cIndex = 0; cIndex < components.size(); cIndex++) {
      for (int aIndex = 0; aIndex < attributes.size(); aIndex++) {
        int row = cIndex + 1;
        int column = aIndex + 1;

        Component component = components.get(cIndex);
        Attribute attribute = attributes.get(aIndex);
        Integer key = Capability.getCapabilityIntersectionKey(component, attribute);

        grid.getCellFormatter().setStyleName(row, column, "tty-GridCell");
        if (row == highlightedCellRow && column == highlightedCellColumn) {
          grid.getCellFormatter().addStyleName(row, column, "tty-GridCellSelected");
        }

        HTML cell = new HTML();
        cell.addClickHandler(cellClickHandler(row, column));

        cell.addMouseOverHandler(createMouseOverHandler(row, column));
        cell.addMouseOutHandler(createMouseOutHandler(row, column));

        cellMap.put(key, cell);
        grid.setWidget(row, column, cell);
      }
    }

    updateGridCells();
  }

  /**
   * Creates a mouse over handler for a specific row and column.
   *
   * @param row the row number.
   * @param column the column number.
   * @return the mouse over handler.
   */
  private MouseOverHandler createMouseOverHandler(final int row, final int column) {
    return new MouseOverHandler() {
      @Override
      public void onMouseOver(MouseOverEvent event) {
        mouseOver(row, column);
      }
    };
  }

  /**
   * Generates a mouse out handler for a specific row and column.
   *
   * @param row the row.
   * @param column the column.
   * @return a mouse out handler.
   */
  private MouseOutHandler createMouseOutHandler(final int row, final int column) {
    return new MouseOutHandler() {
      @Override
      public void onMouseOut(MouseOutEvent event) {
        mouseOut(row, column);
      }
    };
  }

  /**
   * Handles a mouse out event by removing the formatting on cells that were once highlighted due
   * to a mouse over event.
   *
   * @param row the row that lost mouse over.
   * @param column the column that lost mouse over.
   */
  private void mouseOut(int row, int column) {
    CellFormatter formatter = grid.getCellFormatter();
    // Remove highlighting from cell.
    formatter.removeStyleName(row, column, "tty-GridCellHighlighted");

    // Remove column highlighting.
    for (int i = 1; i < grid.getRowCount(); i++) {
      formatter.removeStyleName(i, column, "tty-GridColumnHighlighted");
    }

    // Remove row highlighting.
    for (int j = 1; j < grid.getColumnCount(); j++) {
      formatter.removeStyleName(row, j, "tty-GridRowHighlighted");
    }
  }

  /**
   * Handles a mouse over event by highlighting the moused over cell and adding style to the
   * row and column that is also to be highlighted.
   *
   * @param row the row that gained mouse over.
   * @param column the column that gained mouse over.
   */
  private void mouseOver(int row, int column) {
    CellFormatter formatter = grid.getCellFormatter();
    // Add highlighting to cell.
    formatter.addStyleName(row, column, "tty-GridCellHighlighted");

    // Add column highlighting.
    for (int i = 1; i < grid.getRowCount(); i++) {
      if (i != row) {
        formatter.addStyleName(i, column, "tty-GridColumnHighlighted");
      }
    }

    // Add row highlighting.
    for (int j = 1; j < grid.getColumnCount(); j++) {
      if (j != column) {
        formatter.addStyleName(row, j, "tty-GridRowHighlighted");
      }
    }
  }

  /**
   * This updates the contents of the grid based off the current capability data.
   */
  private void updateGridCells() {
    for (Integer key : cellMap.keySet()) {
      updateGridCell(key);
    }
  }

  private void updateGridCell(Integer key) {
    int size = capabilityMap.get(key).size();

    String text = "&nbsp;";

    if (size > 0) {
      text = Integer.toString(size);
    }

    cellMap.get(key).setHTML(text);
  }

  private ClickHandler cellClickHandler(final int row, final int column) {
    final HasValueChangeHandlers<Pair<Component, Attribute>> self = this;
    return new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        cellClicked(row, column);
      }
    };
  }

  private void cellClicked(int row, int column) {
    final Component component = components.get(row - 1);
    final Attribute attribute = attributes.get(column - 1);

    if (highlightedCellRow != -1 && highlightedCellColumn != -1) {
      grid.getCellFormatter().removeStyleName(
          highlightedCellRow, highlightedCellColumn, "tty-GridCellSelected");
    }
    grid.getCellFormatter().addStyleName(row, column, "tty-GridCellSelected");
    highlightedCellRow = row;
    highlightedCellColumn = column;
    ValueChangeEvent.fire(this, new Pair<Component, Attribute>(component, attribute));
  }

  @Override
  public HandlerRegistration addValueChangeHandler(
      ValueChangeHandler<Pair<Component, Attribute>> handler) {
    return addHandler(handler, ValueChangeEvent.getType());
  }
}
TOP

Related Classes of com.google.testing.testify.risk.frontend.client.view.widgets.CapabilitiesGridWidget

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.