use of com.cpjd.roblu.models.metrics.RMetric in project Roblu by wdavies973.
the class MetricEditor method buildConfigLayout.
/**
* Adds the config text fields below the metric preview
*/
private void buildConfigLayout() {
// clear old config items (don't clear toolbar, preview metric, or metric type selector)
for (int i = 3; i < this.layout.getChildCount(); i++) {
this.layout.removeViewAt(i);
}
RelativeLayout layout = new RelativeLayout(this);
layout.addView(getConfigField("Title", layout, 0));
if (metric instanceof RCheckbox || metric instanceof RChooser) {
layout.addView(getConfigField("Comma separated list", layout, 1));
} else if (metric instanceof RCounter) {
final TextInputLayout til = getConfigField("Increment", layout, 1);
til.setId(Utils.generateViewId());
layout.addView(til);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, til.getId());
CheckBox checkBox = new CheckBox(getApplicationContext());
checkBox.setId(Utils.generateViewId());
checkBox.setLayoutParams(params);
checkBox.setHighlightColor(rui.getAccent());
checkBox.setTextColor(rui.getText());
checkBox.setText("Verbose input");
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
((RCounter) metric).setVerboseInput(isChecked);
addMetricPreviewToToolbar();
}
});
ColorStateList colorStateList = new ColorStateList(new int[][] { // unchecked
new int[] { -android.R.attr.state_checked }, // checked
new int[] { android.R.attr.state_checked } }, new int[] { rui.getButtons(), rui.getAccent() });
CompoundButtonCompat.setButtonTintList(checkBox, colorStateList);
layout.addView(checkBox);
} else if (metric instanceof RSlider) {
layout.addView(getConfigField("Minimum", layout, 1));
layout.addView(getConfigField("Maximum", layout, 2));
} else if (metric instanceof RCalculation) {
final TextInputLayout til = getConfigField("Calculation", layout, 1);
layout.addView(til);
// Also add a button for inputting metric names
Button b = new Button(getApplicationContext());
b.setText("Add metric");
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, til.getId());
b.setLayoutParams(params);
layout.addView(b);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Dialog d = new Dialog(MetricEditor.this);
d.setTitle("Pick metric:");
d.setContentView(R.layout.metric_chooser);
final Spinner spinner = d.findViewById(R.id.type);
String[] values;
final ArrayList<RMetric> metrics;
if (tab == 0)
metrics = form.getPit();
else
metrics = form.getMatch();
// Remove all but counters, stopwatches, and sliders
for (int i = 0; i < metrics.size(); i++) {
if (!(metrics.get(i) instanceof RCounter) && !(metrics.get(i) instanceof RStopwatch && !(metrics.get(i) instanceof RSlider)) && !(metrics.get(i) instanceof RCalculation)) {
metrics.remove(i);
i--;
}
}
values = new String[metrics.size()];
for (int i = 0; i < metrics.size(); i++) {
values[i] = metrics.get(i).getTitle();
}
ArrayAdapter<String> adp = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, values);
adp.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adp);
Button button = d.findViewById(R.id.button7);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
RMetric m = new ArrayList<>(metrics).get(spinner.getSelectedItemPosition());
til.getEditText().setText(til.getEditText().getText().toString() + " " + m.getTitle());
} catch (Exception e) {
Log.d("RBS", "Failed to select metric");
} finally {
d.dismiss();
}
}
});
if (d.getWindow() != null)
d.getWindow().getAttributes().windowAnimations = new IO(getApplicationContext()).loadSettings().getRui().getAnimation();
d.show();
}
});
}
this.layout.addView(getCardView(layout));
}
use of com.cpjd.roblu.models.metrics.RMetric in project Roblu by wdavies973.
the class Match method changeMade.
/**
* This method is called when a change is made to a metric
* @param metric the modified metric
*/
@Override
public void changeMade(RMetric metric) {
/*
* Notify any calculation metrics that a change was made
*/
for (int i = 0; i < layout.getChildCount(); i++) {
CardView cv = (CardView) layout.getChildAt(i);
if (cv.getTag() != null && cv.getTag().toString().split(":")[0].equals("CALC")) {
// We've discovered a calculation metric, we have access to the ID, so acquire a new copy of the view
int ID = Integer.parseInt(cv.getTag().toString().split(":")[1]);
for (RMetric m : TeamViewer.team.getTabs().get(position).getMetrics()) {
if (m.getID() == ID) {
// Get the calculation
String value = m.getTitle() + "\nValue: " + ((RCalculation) m).getValue(TeamViewer.team.getTabs().get(position).getMetrics());
// Set the text
RelativeLayout rl = (RelativeLayout) cv.getChildAt(0);
TextView tv = (TextView) rl.getChildAt(0);
tv.setText(value);
break;
}
}
}
}
// set the metric as modified - this is a critical line, otherwise scouting data will get deleted
metric.setModified(true);
/*
* Check the team name and team number metrics to see if the action bar needs to be updated
*/
// since team name and team number are updated from the team model
boolean init = false;
// without the user's control, make sure not to update team's timestamp if it's only the team name or number metric
if (metric instanceof RTextfield) {
if (((RTextfield) metric).isOneLine() && ((RTextfield) metric).isNumericalOnly() && !((RTextfield) metric).getText().equals("")) {
TeamViewer.team.setNumber(Integer.parseInt(((RTextfield) metric).getText()));
((TeamViewer) getActivity()).setActionBarSubtitle("#" + TeamViewer.team.getNumber());
init = true;
}
if (((RTextfield) metric).isOneLine() && !((RTextfield) metric).isNumericalOnly() && !((RTextfield) metric).getText().equals("")) {
TeamViewer.team.setName(((RTextfield) metric).getText());
((TeamViewer) getActivity()).setActionBarTitle(TeamViewer.team.getName());
init = true;
}
}
if (!init) {
TeamViewer.team.setLastEdit(System.currentTimeMillis());
// Add local device to edit history list
if (event.isCloudEnabled()) {
LinkedHashMap<String, Long> edits = TeamViewer.team.getTabs().get(position).getEdits();
if (edits == null)
TeamViewer.team.getTabs().get(position).setEdits(new LinkedHashMap<String, Long>());
TeamViewer.team.getTabs().get(position).getEdits().put("me", System.currentTimeMillis());
}
}
// save the team
new IO(view.getContext()).saveTeam(event.getID(), TeamViewer.team);
}
use of com.cpjd.roblu.models.metrics.RMetric in project Roblu by wdavies973.
the class Overview method onCreateView.
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_tab, container, false);
Bundle bundle = this.getArguments();
layout = view.findViewById(R.id.overview_layout);
REvent event = (REvent) getArguments().getSerializable("event");
RTeam team = new IO(getActivity()).loadTeam(event.getID(), TeamViewer.team.getID());
rMetricToUI = new RMetricToUI(getActivity(), new IO(getActivity()).loadSettings().getRui(), true);
try {
/*
* Do statistics generation, this will generate graphs for certain metrics
*/
// Stores pie chart values, with the sub linked hash map <item,occurrences>, this will need to be processed later into a percent
LinkedHashMap<String, LinkedHashMap<String, Double>> pieValues = new LinkedHashMap<>();
// Stores line chart values, with the sub linked hash map <matchName,value>
LinkedHashMap<String, LinkedHashMap<String, Double>> lineValues = new LinkedHashMap<>();
// This isn't directly related, more of a side project
ArrayList<RGallery> galleries = new ArrayList<>();
for (RTab tab : team.getTabs()) {
// Rule out disallowed tabs
if (tab.getTitle().equalsIgnoreCase("PIT"))
continue;
// Start processing metrics
for (RMetric metric : tab.getMetrics()) {
if (metric instanceof RGallery) {
galleries.add((RGallery) metric);
}
if (!metric.isModified())
continue;
// Pie graph metrics, scan these here
if (metric instanceof RBoolean) {
LinkedHashMap<String, Double> temp = pieValues.get(metric.getTitle());
if (temp == null)
temp = new LinkedHashMap<>();
String key = ((RBoolean) metric).isValue() ? "Yes" : "No";
if (temp.get(key) == null)
temp.put(key, 1.0);
else
temp.put(key, temp.get(key) + 1);
pieValues.put(metric.getTitle(), temp);
} else if (metric instanceof RCheckbox) {
if (((RCheckbox) metric).getValues() != null) {
for (Object key : ((RCheckbox) metric).getValues().keySet()) {
LinkedHashMap<String, Double> temp = pieValues.get(metric.getTitle());
if (temp == null)
temp = new LinkedHashMap<>();
if (temp.get(key.toString()) == null)
temp.put(key.toString(), 1.0);
else
temp.put(key.toString(), temp.get(key.toString()) + 1);
pieValues.put(metric.getTitle(), temp);
}
}
} else if (metric instanceof RChooser) {
LinkedHashMap<String, Double> temp = pieValues.get(metric.getTitle());
if (temp == null)
temp = new LinkedHashMap<>();
if (temp.get(metric.toString()) == null)
temp.put(metric.toString(), 1.0);
else
temp.put(metric.toString(), temp.get(metric.toString()) + 1);
pieValues.put(metric.getTitle(), temp);
} else // Line chart metrics
if (metric instanceof RCounter || metric instanceof RSlider || metric instanceof RStopwatch || metric instanceof RCalculation) {
LinkedHashMap<String, Double> temp = lineValues.get(metric.getTitle());
if (temp == null)
temp = new LinkedHashMap<>();
temp.put(tab.getTitle(), Double.parseDouble(metric.toString()));
lineValues.put(metric.getTitle(), temp);
}
}
}
// Add the divider metrics by position, -1 if no metric after it, or at the end
ArrayList<RDivider> addedDividers = new ArrayList<>();
/*
* Add the charts!
*/
for (Object key : lineValues.keySet()) {
if (lineValues.get(key.toString()).size() >= 2) {
loop: for (RTab tab : team.getTabs()) {
for (int i = 0; i < tab.getMetrics().size(); i++) {
if (tab.getMetrics().get(i).getTitle().equals(key.toString())) {
// See if there is a RDivider hiding above this metric
for (int j = i; j >= 0; j--) {
if (tab.getMetrics().get(j) instanceof RDivider && !addedDividers.contains(tab.getMetrics().get(j))) {
layout.addView(rMetricToUI.getDivider((RDivider) tab.getMetrics().get(j)));
addedDividers.add((RDivider) tab.getMetrics().get(j));
break loop;
}
}
}
}
}
layout.addView(rMetricToUI.generateLineChart(key.toString(), lineValues.get(key.toString())));
}
}
// Process the pie charts
for (Object key : pieValues.keySet()) {
if (pieValues.get(key.toString()).size() <= 1)
continue;
int metricID = 0;
loop: for (RTab tab : team.getTabs()) {
for (int i = 0; i < tab.getMetrics().size(); i++) {
if (tab.getMetrics().get(i).getTitle().equals(key.toString())) {
metricID = tab.getMetrics().get(i).getID();
// See if there is a RDivider hiding above this metric
for (int j = i; j >= 0; j--) {
if (tab.getMetrics().get(j) instanceof RDivider && !addedDividers.contains(tab.getMetrics().get(j))) {
layout.addView(rMetricToUI.getDivider((RDivider) tab.getMetrics().get(j)));
addedDividers.add((RDivider) tab.getMetrics().get(j));
break loop;
}
}
}
}
}
for (Object key2 : pieValues.get(key.toString()).keySet()) {
if (numModified(team.getTabs(), metricID) != 0)
pieValues.get(key.toString()).put(key2.toString(), pieValues.get(key.toString()).get(key2.toString()) / (double) numModified(team.getTabs(), metricID));
}
layout.addView(rMetricToUI.generatePieChart(key.toString(), pieValues.get(key.toString())));
}
/*
* Find the image with the most entropy, and add
* it as the "featured" image
*/
galleryLoop: for (int j = galleries.size() - 1; j >= 0; j--) {
if (galleries.get(j).getImages() != null && galleries.get(j).getImages().size() > 0) {
for (int i = galleries.get(j).getImages().size() - 1; i >= 0; i--) {
try {
layout.addView(rMetricToUI.getImageView("Featured image", BitmapFactory.decodeByteArray(galleries.get(j).getImages().get(i), 0, galleries.get(j).getImages().get(i).length)));
break galleryLoop;
} catch (Exception e) {
Log.d("RBS", "Failed to load featured image: " + e.getMessage());
}
}
}
}
} catch (Exception e) {
Log.d("RBS", "Failed to generate graphs for this team profile.");
}
/*
* Attempt to download TBA info for this team
*/
if (!team.hasTBAInfo()) {
if (event.getKey() != null && event.getKey().length() >= 4)
new TBATeamInfoTask(view.getContext(), team.getNumber(), event.getKey().substring(0, 4), this);
} else {
// TBA info card
layout.addView(rMetricToUI.getInfoField("TBA.com information", TeamViewer.team.getTbaInfo(), TeamViewer.team.getWebsite(), TeamViewer.team.getNumber()), 0);
if (TeamViewer.team.getImage() != null) {
// Image view
Bitmap bitmap = BitmapFactory.decodeByteArray(TeamViewer.team.getImage(), 0, TeamViewer.team.getImage().length);
layout.addView(rMetricToUI.getImageView("Robot", bitmap));
}
}
/*
* Add UI cards to the layout
*/
// "Other" card
layout.addView(rMetricToUI.getInfoField("Other", "Last edited: " + Utils.convertTime(team.getLastEdit()) + "\nSize on disk: " + new IO(view.getContext()).getTeamSize(bundle.getInt("eventID"), team.getID()) + " KB", "", 0));
return view;
}
use of com.cpjd.roblu.models.metrics.RMetric in project Roblu by wdavies973.
the class UnpackTBAEvent method doInBackground.
protected Void doInBackground(Void... params) {
/*
* No teams were contained within the event, so exit, nothing here is relevant
* to a TBA event that doesn't contain any team models
*/
if (event.teams == null || event.teams.length == 0)
return null;
/*
* Create an array of team models from the ones contained in the event
*/
ArrayList<RTeam> teams = new ArrayList<>();
for (int i = 0; i < event.teams.length; i++) {
// i can be used as the ID because we are creating a fresh event, io.getNewTeamID is irrelevant
teams.add(new RTeam(event.teams[i].nickname, (int) event.teams[i].team_number, i));
}
/*
* Sort the matches in the event
*/
Collections.sort(Arrays.asList(event.matches));
/*
* Add the matches to the respective team models
*/
IO io = new IO(activityWeakReference.get());
RForm form = io.loadForm(eventID);
int result;
for (RTeam t : teams) {
t.verify(form);
for (int j = 0; j < event.matches.length; j++) {
result = event.matches[j].doesMatchContainTeam(t.getNumber());
if (result > 0) {
String name = "Match";
// process the correct match name
switch(event.matches[j].comp_level) {
case "qm":
name = "Quals " + event.matches[j].match_number;
break;
case "qf":
name = "Quarters " + event.matches[j].set_number + " Match " + event.matches[j].match_number;
break;
case "sf":
name = "Semis " + event.matches[j].set_number + " Match " + event.matches[j].match_number;
break;
case "f":
name = "Finals " + event.matches[j].match_number;
}
boolean isRed = result == com.cpjd.main.Constants.CONTAINS_TEAM_RED;
// add the match to the team, make sure to multiple the Event model's matches times by 1000 (seconds to milliseconds, Roblu works with milliseconds!)
RTab tab = new RTab(t.getNumber(), name, Utils.duplicateRMetricArray(form.getMatch()), isRed, event.matches[j].isOnWinningAlliance(t.getNumber()), event.matches[j].time * 1000);
// set the match position, if possible
tab.setAlliancePosition(event.matches[j].getTeamPosition(t.getNumber()));
// Check for FieldData metrics
if (tab.getMetrics() != null) {
for (RMetric metric : tab.getMetrics()) {
if (metric instanceof RFieldData) {
if (((RFieldData) metric).getData() == null)
((RFieldData) metric).setData(new LinkedHashMap<String, ArrayList<RMetric>>());
for (int i = 0; i < event.matches[j].scorableItems.length; i++) {
Log.d("RBS", "Metric name: " + event.matches[j].scorableItems[i] + ", " + "Red value: " + event.matches[j].redValues[i] + ", Blue value: " + event.matches[j].blueValues[i]);
ArrayList<RMetric> metrics = new ArrayList<>();
try {
metrics.add(new RCounter(0, "", 0, Double.parseDouble(event.matches[j].redValues[i])));
} catch (Exception e) {
metrics.add(new RTextfield(0, "", (event.matches[j].redValues[i])));
}
try {
metrics.add(new RCounter(0, "", 0, Double.parseDouble(event.matches[j].blueValues[i])));
} catch (Exception e) {
metrics.add(new RTextfield(0, "", (event.matches[j].blueValues[i])));
}
if (event.matches[j].scorableItems[i] != null && metrics.size() > 0)
((RFieldData) metric).getData().put(event.matches[j].scorableItems[i], metrics);
}
}
}
}
t.addTab(tab);
}
}
/*
* This is where the merge decision comes into play
*/
if (randomize) {
t.setLastEdit(System.currentTimeMillis());
Utils.randomizeTeamMetrics(t.getTabs());
}
io.saveTeam(eventID, t);
}
return null;
}
use of com.cpjd.roblu.models.metrics.RMetric in project Roblu by wdavies973.
the class FormRecyclerTouchHelper method onSwiped.
/**
* Called when a form card is swiped in a certain direction
* @param viewHolder the view holder containing the swiped card
* @param direction the direction the card was swiped in
*/
@Override
public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
final RMetric metric = mMetricsAdapter.getMetrics().get(viewHolder.getAdapterPosition());
/*
* User wants to delete the RMetric
*/
if (direction == ItemTouchHelper.LEFT) {
/*
* Decide which delete message to display, if the user is deleting a form metric that contains scouting data somewhere else,
* we'll want to notify them a bit more
*/
if (metric.getID() <= mMetricsAdapter.getInitID()) {
new FastDialogBuilder().setTitle("Warning").setMessage("Deleting this metric will remove it and all its associated scouting data from ALL team profiles.").setPositiveButtonText("Delete").setNegativeButtonText("Cancel").setFastDialogListener(new FastDialogBuilder.FastDialogListener() {
@Override
public void accepted() {
mMetricsAdapter.getMetrics().remove(viewHolder.getAdapterPosition());
mMetricsAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
}
@Override
public void denied() {
mMetricsAdapter.reAdd(metric);
mMetricsAdapter.notifyDataSetChanged();
}
@Override
public void neutral() {
}
}).build(mMetricsAdapter.getContext());
} else {
mMetricsAdapter.getMetrics().remove(viewHolder.getAdapterPosition());
mMetricsAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
}
} else /*
* User wants to edit the RMetric, we can't actually handle that here, so pass it back tot he FormViewer activity
*/
if (direction == ItemTouchHelper.RIGHT) {
/*
* One quick thing - Intents have a payload maximum, galleries will trigger this easily
* because of their size, so if the user requested a RGallery edit, remove all picture information
* from the reference.
*/
if (metric instanceof RGallery)
((RGallery) metric).setImages(null);
mMetricsAdapter.getListener().metricEditRequested(metric);
}
}
Aggregations