Add basic UI skeleton to add/modify/delete annotation settings
UI currently consists of
1) column for field type which is a drop-box of enums
2) column for field name which is a text box.
No logic is implemented yet.
Test: None
Change-Id: I31e261fe19f53a609889985b6e36642350904f6f
diff --git a/src/tuningfork/tools/plugin/src/main/java/AnnotationTab.java b/src/tuningfork/tools/plugin/src/main/java/AnnotationTab.java
new file mode 100644
index 0000000..efb1b69
--- /dev/null
+++ b/src/tuningfork/tools/plugin/src/main/java/AnnotationTab.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ */
+
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.ui.ToolbarDecorator;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.ui.components.JBScrollPane;
+import com.intellij.ui.table.JBTable;
+import java.awt.Dimension;
+import java.awt.Font;
+import javax.swing.Box;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.table.TableColumn;
+import org.jdesktop.swingx.VerticalLayout;
+
+class AnnotationTab extends JPanel {
+ private JBScrollPane scrollPane;
+ private JBTable annotationTable;
+ private JPanel decoratorPanel;
+
+ private final JBLabel annotationLabel = new JBLabel("Annotation Settings");
+ private final JBLabel informationLabel =
+ new JBLabel("Annotation is used by tuning fork to mark the histograms being sent.");
+ private final Font mainFont = new Font(Font.SANS_SERIF, Font.BOLD, FONT_BIG);
+ private final Font secondaryLabel = new Font(Font.SANS_SERIF, Font.PLAIN, FONT_SMALL);
+ private static final int PANEL_MIN_WIDTH = 600;
+ private static final int PANEL_MIN_HEIGHT = 500;
+ private static final int TABLE_MIN_WIDTH = 500;
+ private static final int TABLE_MIN_HEIGHT = 230;
+ private static final int FONT_BIG = 18;
+ private static final int FONT_SMALL = 12;
+
+ public AnnotationTab() {
+ initVariables();
+ initComponents();
+ }
+
+ private void initVariables() {
+ scrollPane = new JBScrollPane();
+ annotationTable = new JBTable();
+ decoratorPanel =
+ ToolbarDecorator.createDecorator(annotationTable)
+ .setAddAction(it -> AnnotationTabController.addRowAction(annotationTable))
+ .setRemoveAction(it -> AnnotationTabController.removeRowAction(annotationTable))
+ .createPanel();
+ }
+
+ private void initComponents() {
+ // Initialize layout.
+ this.setLayout(new VerticalLayout());
+ this.setMinimumSize(new Dimension(PANEL_MIN_WIDTH, PANEL_MIN_HEIGHT));
+ this.setPreferredSize(new Dimension(PANEL_MIN_WIDTH, PANEL_MIN_HEIGHT));
+
+ // Add labels.
+ annotationLabel.setFont(mainFont);
+ informationLabel.setFont(secondaryLabel);
+ this.add(annotationLabel);
+ this.add(Box.createVerticalStrut(10));
+ this.add(informationLabel);
+
+ // Initialize toolbar and table.
+ AnnotationTableModel model = new AnnotationTableModel();
+ annotationTable.setModel(model);
+ decoratorPanel.setPreferredSize(new Dimension(TABLE_MIN_WIDTH, TABLE_MIN_HEIGHT));
+ decoratorPanel.setMinimumSize(new Dimension(TABLE_MIN_WIDTH, TABLE_MIN_HEIGHT));
+ annotationTable.setFillsViewportHeight(true);
+ scrollPane.setViewportView(decoratorPanel);
+ annotationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ annotationTable.getTableHeader().setReorderingAllowed(false);
+ annotationTable.setRowSelectionAllowed(true);
+ annotationTable.setSelectionBackground(null);
+
+ // Initialize field type column.
+ TableColumn typeColumn = annotationTable.getColumnModel().getColumn(0);
+ typeColumn.setCellEditor(getComboBoxModel());
+ typeColumn.setCellRenderer(new TableRenderer.ComboBoxRenderer());
+ typeColumn.setPreferredWidth(150);
+
+ // Initialize field name column.
+ TableColumn nameColumn = annotationTable.getColumnModel().getColumn(1);
+ nameColumn.setCellEditor(getTextFieldModel());
+ nameColumn.setCellRenderer(new TableRenderer.RoundedCornerRenderer());
+ nameColumn.setPreferredWidth(350);
+
+ // Table extra feature such as dynamic size and no grid lines.
+ annotationTable.getModel().addTableModelListener(tableModelEvent -> resizePanelToFit());
+ annotationTable.setIntercellSpacing(new Dimension(0, 0));
+
+ this.add(scrollPane);
+ }
+
+ private void resizePanelToFit() {
+ int oldWidth = scrollPane.getWidth();
+ int newHeight = Math.max(decoratorPanel.getMinimumSize().height + 2,
+ Math.min(AnnotationTab.this.getHeight() - 100,
+ annotationTable.getRowHeight() * annotationTable.getRowCount() + 30));
+ scrollPane.setSize(new Dimension(oldWidth, newHeight));
+ scrollPane.revalidate();
+ }
+
+ private DefaultCellEditor getTextFieldModel() {
+ JTextField textFieldModel = new JTextField();
+ textFieldModel.setBorder(new RoundedCornerBorder());
+ DefaultCellEditor textEditor = new DefaultCellEditor(textFieldModel);
+ textEditor.setClickCountToStart(1);
+ return textEditor;
+ }
+
+ private DefaultCellEditor getComboBoxModel() {
+ ComboBox<String> comboBoxModel = new ComboBox<>();
+ // TODO(mohanad): This will be replaced by enum values.
+ comboBoxModel.addItem("loadingState");
+ comboBoxModel.addItem("Scene");
+ comboBoxModel.addItem("bigBoss");
+ DefaultCellEditor boxEditor = new DefaultCellEditor(comboBoxModel);
+ boxEditor.setClickCountToStart(1);
+ return boxEditor;
+ }
+}
diff --git a/src/tuningfork/tools/plugin/src/main/java/AnnotationTabController.java b/src/tuningfork/tools/plugin/src/main/java/AnnotationTabController.java
new file mode 100644
index 0000000..aa9f77b
--- /dev/null
+++ b/src/tuningfork/tools/plugin/src/main/java/AnnotationTabController.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ */
+
+import javax.swing.JTable;
+
+public class AnnotationTabController {
+ public static void addRowAction(JTable jtable) {
+ AnnotationTableModel model = (AnnotationTableModel) jtable.getModel();
+ // TODO(mohanad): placeholder values used. Will be replaced later with default enum value.
+ model.addRow(new String[] {
+ "",
+ "",
+ });
+ }
+
+ public static void removeRowAction(JTable jtable) {
+ AnnotationTableModel model = (AnnotationTableModel) jtable.getModel();
+ int row = jtable.getSelectedRow();
+ if (jtable.getCellEditor() != null) {
+ jtable.getCellEditor().stopCellEditing();
+ }
+ model.removeRow(row);
+ }
+}
diff --git a/src/tuningfork/tools/plugin/src/main/java/AnnotationTableModel.java b/src/tuningfork/tools/plugin/src/main/java/AnnotationTableModel.java
new file mode 100644
index 0000000..5dae2bc
--- /dev/null
+++ b/src/tuningfork/tools/plugin/src/main/java/AnnotationTableModel.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.table.AbstractTableModel;
+
+public class AnnotationTableModel extends AbstractTableModel {
+ private final String[] columnNames = {"Type", "Name"};
+ private final List<String[]> data;
+
+ public AnnotationTableModel() {
+ data = new ArrayList<>();
+ }
+
+ @Override
+ public int getRowCount() {
+ return data.size();
+ }
+
+ @Override
+ public int getColumnCount() {
+ return columnNames.length;
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ return data.get(rowIndex)[columnIndex];
+ }
+
+ @Override
+ public String getColumnName(int column) {
+ return columnNames[column];
+ }
+
+ public void addRow(String[] row) {
+ data.add(row);
+ fireTableRowsInserted(getRowCount() - 1, getRowCount());
+ }
+
+ @Override
+ public boolean isCellEditable(int row, int column) {
+ return true;
+ }
+
+ @Override
+ public void setValueAt(Object value, int row, int column) {
+ data.get(row)[column] = value.toString();
+ fireTableCellUpdated(row, column);
+ }
+
+ public void removeRow(int row) {
+ data.remove(row);
+ fireTableDataChanged();
+ }
+}
diff --git a/src/tuningfork/tools/plugin/src/main/java/RoundedCornerBorder.java b/src/tuningfork/tools/plugin/src/main/java/RoundedCornerBorder.java
new file mode 100644
index 0000000..cf97167
--- /dev/null
+++ b/src/tuningfork/tools/plugin/src/main/java/RoundedCornerBorder.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ */
+
+import com.intellij.ui.JBColor;
+import com.intellij.util.ui.JBUI;
+import com.intellij.util.ui.UIUtil;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.Area;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import javax.swing.border.AbstractBorder;
+
+public final class RoundedCornerBorder extends AbstractBorder {
+ private final Color ALPHA_ZERO = UIUtil.getWindowColor();
+
+ @Override
+ public void paintBorder(
+ Component component, Graphics graphics, int x, int y, int width, int height) {
+ Graphics2D graphics2D = (Graphics2D) graphics.create();
+ graphics2D.setRenderingHint(
+ RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ Shape border = getBorderShape(x, y, width - 1, height - 1);
+ graphics2D.setPaint(ALPHA_ZERO);
+ Area corner = new Area(new Rectangle2D.Double(x, y, width, height));
+ corner.subtract(new Area(border));
+ graphics2D.fill(corner);
+ graphics2D.setPaint(JBColor.GRAY);
+ graphics2D.draw(border);
+ graphics2D.dispose();
+ }
+
+ public Shape getBorderShape(int x, int y, int width, int height) {
+ int arcWidth = height;
+ int arcHeight = height;
+ return new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight);
+ }
+
+ @Override
+ public Insets getBorderInsets(Component component) {
+ return JBUI.insets(4, 8);
+ }
+
+ @Override
+ public Insets getBorderInsets(Component component, Insets insets) {
+ insets.set(4, 8, 4, 8);
+ return insets;
+ }
+}
diff --git a/src/tuningfork/tools/plugin/src/main/java/TableRenderer.java b/src/tuningfork/tools/plugin/src/main/java/TableRenderer.java
new file mode 100644
index 0000000..1db9a6f
--- /dev/null
+++ b/src/tuningfork/tools/plugin/src/main/java/TableRenderer.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ */
+
+import java.awt.Component;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+
+public class TableRenderer {
+ public static final class RoundedCornerRenderer extends DefaultTableCellRenderer {
+ @Override
+ public Component getTableCellRendererComponent(JTable jTable, Object value,
+ boolean isSelected, boolean hasFocus, int row, int column) {
+ JComponent component = (JComponent) super.getTableCellRendererComponent(
+ jTable, value, isSelected, hasFocus, row, column);
+ component.setBorder(new RoundedCornerBorder());
+ return component;
+ }
+ }
+
+ public static final class ComboBoxRenderer
+ extends JComboBox<String> implements TableCellRenderer {
+ @Override
+ public Component getTableCellRendererComponent(
+ JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ removeAllItems();
+ addItem(value.toString());
+ return this;
+ }
+ }
+}