Skip to content

Commit

Permalink
Farming plugin panel redesign
Browse files Browse the repository at this point in the history
Farming Plugin:
- Redid the layout, coloring and positioning on the FarmingTrackerPanel
to include my new MaterialTabs.
- Added section divider labels in the special and tree tabs.
- Hid the patch type indicator for some patches (explained in docs).
- Added patch names for all instances of FarmingPatch (previously only
a portion of them were written for a hack that is no longer necessary).
- Created getName() method in PatchImplementation that returns the patch
type's name in a formatted style (SPIRIT_TREE -> Spirit Tree).
- Created a new tab for bushes.

MaterialTabs:
- Added onSelectEvent runnable to MaterialTab.
- Added horizontal gap to the tabs.
- Added getTab() method that returns a tab on a given index.

CustomScrollBarUI:
- Added functionality to allow the ui colors to be changed from an
external call. (setters)

ColorScheme:
- Created color constants in the ColorScheme file for the progresss bar
backgrounds and used them in the CropState enum.
  • Loading branch information
psikoi authored and deathbeam committed May 19, 2018
1 parent 497d421 commit 6d331ae
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@
import java.awt.Color;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.runelite.client.ui.ColorScheme;

@RequiredArgsConstructor
@Getter
public enum CropState
{
HARVESTABLE(Color.GREEN),
GROWING(Color.GREEN),
DISEASED(Color.ORANGE),
DEAD(Color.RED);
HARVESTABLE(ColorScheme.PROGRESS_COMPLETE_COLOR),
GROWING(ColorScheme.PROGRESS_COMPLETE_COLOR),
DISEASED(ColorScheme.PROGRESS_INPROGRESS_COLOR),
DEAD(ColorScheme.PROGRESS_ERROR_COLOR);

private final Color color;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 Abex
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand All @@ -24,56 +25,88 @@
*/
package net.runelite.client.plugins.farmingtracker;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.GroupLayout;
import java.awt.GridLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.border.EmptyBorder;
import lombok.Getter;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.ThinProgressBar;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;

@Getter
class FarmingPatchPanel extends JPanel
{
private final FarmingPatch patch;
private final JLabel icon = new JLabel();
private final JLabel estimate = new JLabel();
private final JProgressBar progress = new JProgressBar();
private final ThinProgressBar progress = new ThinProgressBar();

FarmingPatchPanel(FarmingPatch patch)
{
this.patch = patch;

GroupLayout layout = new GroupLayout(this);
this.setLayout(layout);
setLayout(new BorderLayout());
setOpaque(false);
setBorder(new EmptyBorder(7, 0, 0, 0));

JPanel topContainer = new JPanel();
topContainer.setBorder(new EmptyBorder(7, 7, 6, 0));
topContainer.setLayout(new BorderLayout());
topContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);

final JLabel location = new JLabel(patch.getRegion().getName() + " " + patch.getName());
location.setFont(FontManager.getRunescapeSmallFont());
icon.setMinimumSize(new Dimension(36, 32));

layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addComponent(icon)
.addGroup(layout.createSequentialGroup()
.addGap(1)
.addComponent(location)
.addGap(1)
.addComponent(estimate)
)
)
.addComponent(progress, 8, 8, 8)
.addGap(4)
);
JPanel infoPanel = new JPanel();
infoPanel.setOpaque(false);
infoPanel.setLayout(new GridLayout(2, 1));
infoPanel.setBorder(new EmptyBorder(4, 4, 4, 0));

final JLabel location = new JShadowedLabel(patch.getRegion().getName()
+ (showFullTitle() ? " (" + patch.getName() + ")" : ""));
location.setFont(FontManager.getRunescapeSmallFont());
location.setForeground(Color.WHITE);

estimate.setFont(FontManager.getRunescapeSmallFont());
estimate.setForeground(Color.GRAY);

layout.setHorizontalGroup(layout.createParallelGroup()
.addGroup(layout.createSequentialGroup()
.addComponent(icon)
.addGroup(layout.createParallelGroup()
.addComponent(location)
.addComponent(estimate)
)
)
.addComponent(progress)
);
infoPanel.add(location);
infoPanel.add(estimate);

topContainer.add(icon, BorderLayout.WEST);
topContainer.add(infoPanel, BorderLayout.CENTER);

add(topContainer, BorderLayout.NORTH);
add(progress, BorderLayout.SOUTH);
}

/**
* This determines if the label should display location and type, ex:
* It makes sense to display:
* Catherby (North) <-- for allotment
* but not so much for herbs:
* Troll Stronghold
* as there are no other herb patches in that region.
*/
private boolean showFullTitle()
{
switch (patch.getImplementation())
{
case FLOWER:
case HOPS:
case BUSH:
case FRUIT_TREE:
case CALQUAT:
case SPIRIT_TREE:
case TREE:
case HERB:
return false;
default:
return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 Abex
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -29,6 +30,7 @@
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
Expand All @@ -37,17 +39,22 @@
import java.util.List;
import java.util.Locale;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.vars.Autoweed;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.game.AsyncBufferedImage;
import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.materialtabs.MaterialTab;
import net.runelite.client.ui.components.materialtabs.MaterialTabGroup;

@Slf4j
class FarmingTrackerPanel extends PluginPanel
Expand All @@ -61,6 +68,10 @@ class FarmingTrackerPanel extends PluginPanel

private List<FarmingPatchPanel> patchPanels = new ArrayList<>();

/* This is the panel the tabs' respective panels will be displayed on. */
private final JPanel display = new JPanel();
private final MaterialTabGroup tabGroup = new MaterialTabGroup(display);

FarmingTrackerPanel(
Client client,
ItemManager itemManager,
Expand All @@ -77,63 +88,105 @@ class FarmingTrackerPanel extends PluginPanel
this.config = config;

setLayout(new BorderLayout());
setBackground(ColorScheme.DARK_GRAY_COLOR);

display.setOpaque(false);
display.setBorder(new EmptyBorder(10, 10, 8, 10));

tabGroup.setBorder(new EmptyBorder(10, 1, 0, 0));

add(tabGroup, BorderLayout.NORTH);
add(display, BorderLayout.CENTER);

JTabbedPane tabs = new JTabbedPane();
farmingWorld.getTabs().forEach((tab, patches) ->
{
JPanel panel = new JPanel(new GridBagLayout())
JPanel container = new JPanel(new GridBagLayout())
{
@Override
public Dimension getPreferredSize()
{
return new Dimension(PluginPanel.PANEL_WIDTH, super.getPreferredSize().height);
}
};
panel.setBorder(new EmptyBorder(2, 6, 6, 6));
container.setBackground(ColorScheme.DARK_GRAY_COLOR);

GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;

PatchImplementation lastImpl = null;

boolean first = true;
for (FarmingPatch patch : patches)
{
FarmingPatchPanel p = new FarmingPatchPanel(patch);

/* Show labels to subdivide tabs into sections */
if ((tab == Tab.SPECIAL
&& patch.getImplementation().ordinal() > 2
&& patch.getImplementation() != lastImpl)
|| (tab == Tab.TREE
&& patch.getImplementation().ordinal() > 9
&& patch.getImplementation() != lastImpl))
{
JLabel groupLabel = new JLabel(patch.getImplementation().getName());
groupLabel.setBorder(new EmptyBorder(15, 0, 0, 0));
groupLabel.setFont(FontManager.getRunescapeSmallFont());

container.add(groupLabel, c);
c.gridy++;
lastImpl = patch.getImplementation();
}

patchPanels.add(p);
panel.add(p, c);
container.add(p, c);
c.gridy++;

/* This is a weird hack to remove the top border on the first tracker of every tab */
if (first)
{
p.setBorder(null);
first = false;
}
}

JPanel wrapped = new JPanel(new BorderLayout());
wrapped.add(panel, BorderLayout.NORTH);
wrapped.add(container, BorderLayout.NORTH);
wrapped.setBackground(ColorScheme.DARK_GRAY_COLOR);

JScrollPane scroller = new JScrollPane(wrapped);
scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroller.getVerticalScrollBar().setUnitIncrement(16);
scroller.getVerticalScrollBar().setPreferredSize(new Dimension(16, 0));
scroller.getVerticalScrollBar().setBorder(new EmptyBorder(0, 9, 0, 0));
scroller.setBackground(ColorScheme.DARK_GRAY_COLOR);

MaterialTab materialTab = new MaterialTab("", tabGroup, scroller);
materialTab.setName(tab.getName());

AsyncBufferedImage icon = itemManager.getImage(tab.getItemID());
tabs.addTab(null, null, scroller, tab.getName());
int idx = tabs.getTabCount() - 1;
Runnable resize = () ->
{
tabs.setIconAt(idx, new ImageIcon(icon.getScaledInstance(24, 21, Image.SCALE_SMOOTH)));
BufferedImage subIcon = icon.getSubimage(0, 0, 32, 32);
materialTab.setIcon(new ImageIcon(subIcon.getScaledInstance(24, 24, Image.SCALE_SMOOTH)));
materialTab.setHorizontalAlignment(SwingConstants.CENTER);
materialTab.setVerticalAlignment(SwingConstants.CENTER);
materialTab.setOpaque(true);
materialTab.setBackground(ColorScheme.DARKER_GRAY_COLOR);
materialTab.setPreferredSize(new Dimension(30, 27));
};
icon.onChanged(resize);
resize.run();

materialTab.setOnSelectEvent(() -> config.setPatch(tab));

tabGroup.addTab(materialTab);
if (config.patch() == tab)
{
tabs.setSelectedComponent(scroller);
tabGroup.select(materialTab);
}
tabs.addChangeListener(e ->
{
if (tabs.getSelectedComponent() == scroller)
{
config.setPatch(tab);
}
});
});
add(tabs, BorderLayout.CENTER);
}

void update()
Expand Down Expand Up @@ -178,10 +231,11 @@ void update()
PatchState state = unixTime <= 0 ? null : patch.getImplementation().forVarbitValue(value);
if (state == null)
{
panel.getIcon().setIcon(null);
itemManager.getImage(Produce.WEEDS.getItemID()).addTo(panel.getIcon());
panel.getIcon().setToolTipText("Unknown state");
panel.getProgress().setMaximum(0);
panel.getProgress().setMaximumValue(0);
panel.getProgress().setValue(0);
panel.getProgress().setVisible(false);
panel.getEstimate().setText("Unknown");
panel.getProgress().setBackground(null);
}
Expand Down Expand Up @@ -298,9 +352,20 @@ else if (config.estimateRelative())
}
}

panel.getProgress().setBackground(state.getCropState().getColor().darker());
panel.getProgress().setMaximum(stages - 1);
panel.getProgress().setValue(stage);
/* Hide any fully grown weeds' progress bar. */
if (state.getProduce() != Produce.WEEDS
|| (state.getProduce() == Produce.WEEDS && !autoweed && stage < stages - 1))
{
panel.getProgress().setVisible(true);
panel.getProgress().setForeground(state.getCropState().getColor().darker());
panel.getProgress().setMaximumValue(stages - 1);
panel.getProgress().setValue(stage);
panel.getProgress().update();
}
else
{
panel.getProgress().setVisible(false);
}
}
}
}
Expand Down
Loading

0 comments on commit 6d331ae

Please sign in to comment.