diff --git a/projects/robodj/src/java/robodj/chooser/EntryController.java b/projects/robodj/src/java/robodj/chooser/EntryController.java index 2eeccfbd..c0bc6b08 100644 --- a/projects/robodj/src/java/robodj/chooser/EntryController.java +++ b/projects/robodj/src/java/robodj/chooser/EntryController.java @@ -169,6 +169,9 @@ public abstract class EntryController extends ItemController plist = new PlaylistEntry[0]; } for (int i = 0; i < songs.length; i++) { + if (songs[i].isHated()) { + continue; + } PlaylistEntry entry = new PlaylistEntry( songs[i].entryid, songs[i].songid, songs[i].title); plist = (PlaylistEntry[])ArrayUtil.append(plist, entry); diff --git a/projects/robodj/src/java/robodj/chooser/ItemController.java b/projects/robodj/src/java/robodj/chooser/ItemController.java index 990f4add..21bf7bca 100644 --- a/projects/robodj/src/java/robodj/chooser/ItemController.java +++ b/projects/robodj/src/java/robodj/chooser/ItemController.java @@ -32,23 +32,20 @@ public abstract class ItemController extends Controller public boolean handleAction (ActionEvent e) { String cmd = e.getActionCommand(); - if (cmd.equals(SongItem.ADD_VOTE)) { + if (cmd.equals(SongItem.TOGGLE_VOTE)) { JButton button = (JButton)e.getSource(); SongItem item = (SongItem)button.getParent(); _song = item.getSong(); - if (_song.addVote(Chooser.frame.getUser(true))) { - item.update(); - TaskMaster.invokeMethodTask("updateSong", this, this); - } - } else if (cmd.equals(SongItem.CLEAR_VOTE)) { - JButton button = (JButton)e.getSource(); - SongItem item = (SongItem)button.getParent(); - _song = item.getSong(); - if (_song.clearVote(Chooser.frame.getUser(true))) { - item.update(); - TaskMaster.invokeMethodTask("updateSong", this, this); + String who = Chooser.frame.getUser(true); + switch (_song.hasVoted(who)) { + case -1: _song.addVote(who, true); break; + case 1: _song.clearVote(who); break; + default: + case 0: _song.addVote(who, false); break; } + item.update(); + TaskMaster.invokeMethodTask("updateSong", this, this); } else { Log.warning("Unknown action event: " + cmd); diff --git a/projects/robodj/src/java/robodj/chooser/SongItem.java b/projects/robodj/src/java/robodj/chooser/SongItem.java index f3d2f619..4e91fc56 100644 --- a/projects/robodj/src/java/robodj/chooser/SongItem.java +++ b/projects/robodj/src/java/robodj/chooser/SongItem.java @@ -33,8 +33,7 @@ public class SongItem extends Item public static final String PLAY = "song:play"; // ubiquitous actions - public static final String ADD_VOTE = "song:add_vote"; - public static final String CLEAR_VOTE = "song:clear_vote"; + public static final String TOGGLE_VOTE = "song:toggle_vote"; /** Used depending on where this song is being displayed. */ public Object extra; @@ -85,7 +84,7 @@ public class SongItem extends Item // add a vote button _voteButton = ButtonUtil.createControlButton( - ADD_VOTE_TIP, ADD_VOTE, _addVoteIcon, true); + TOGGLE_VOTE_TIP, TOGGLE_VOTE, _noVoteIcon, true); _voteButton.putClientProperty(SONG_PROP, song); add(_voteButton, HGroupLayout.FIXED); @@ -106,22 +105,22 @@ public class SongItem extends Item { if (!StringUtil.blank(_song.votes)) { _trackLabel.setFont(_hasVotesFont); - _trackLabel.setToolTipText("" + _song.title + - "
Votes: " + _song.votes); + _trackLabel.setToolTipText( + "" + + "" + + "
" + _song.title + "
Votes: " + _song.votes + "
"); } else { _trackLabel.setFont(_nameFont); _trackLabel.setToolTipText(_song.title); } - if (_song.hasVoted(Chooser.frame.getUser(false))) { - _voteButton.setIcon(_clearVoteIcon); - _voteButton.setActionCommand(CLEAR_VOTE); - _voteButton.setToolTipText(CLEAR_VOTE_TIP); - } else { - _voteButton.setIcon(_addVoteIcon); - _voteButton.setActionCommand(ADD_VOTE); - _voteButton.setToolTipText(ADD_VOTE_TIP); + switch (_song.hasVoted(Chooser.frame.getUser(false))) { + case -1: _voteButton.setIcon(_nayVoteIcon); break; + case 1: _voteButton.setIcon(_yeaVoteIcon); break; + default: + case 0: _voteButton.setIcon(_noVoteIcon); break; } + repaint(); } @@ -149,18 +148,18 @@ public class SongItem extends Item protected static final String PLAY_SONG_TIP = "Append this song to the playlist"; - protected static final String ADD_VOTE_TIP = - "Add your vote for this song"; - protected static final String CLEAR_VOTE_TIP = - "Remove your vote for this song"; + protected static final String TOGGLE_VOTE_TIP = + "Toggle your vote for this song"; protected static ImageIcon _skipToIcon = ButtonUtil.getIcon(ICON_ROOT + "skip.png"); protected static ImageIcon _removeIcon = ButtonUtil.getIcon(ICON_ROOT + "remove_song.png"); - protected static ImageIcon _addVoteIcon = - ButtonUtil.getIcon(ICON_ROOT + "add_vote.png"); - protected static ImageIcon _clearVoteIcon = - ButtonUtil.getIcon(ICON_ROOT + "clear_vote.png"); + protected static ImageIcon _yeaVoteIcon = + ButtonUtil.getIcon(ICON_ROOT + "yea_vote.png"); + protected static ImageIcon _nayVoteIcon = + ButtonUtil.getIcon(ICON_ROOT + "nay_vote.png"); + protected static ImageIcon _noVoteIcon = + ButtonUtil.getIcon(ICON_ROOT + "no_vote.png"); } diff --git a/projects/robodj/src/java/robodj/chooser/images/add_vote.png b/projects/robodj/src/java/robodj/chooser/images/add_vote.png deleted file mode 100644 index 1f6d2b50..00000000 Binary files a/projects/robodj/src/java/robodj/chooser/images/add_vote.png and /dev/null differ diff --git a/projects/robodj/src/java/robodj/chooser/images/clear_vote.png b/projects/robodj/src/java/robodj/chooser/images/clear_vote.png deleted file mode 100644 index 6888f317..00000000 Binary files a/projects/robodj/src/java/robodj/chooser/images/clear_vote.png and /dev/null differ diff --git a/projects/robodj/src/java/robodj/chooser/images/nay_vote.png b/projects/robodj/src/java/robodj/chooser/images/nay_vote.png new file mode 100644 index 00000000..667e10c9 Binary files /dev/null and b/projects/robodj/src/java/robodj/chooser/images/nay_vote.png differ diff --git a/projects/robodj/src/java/robodj/chooser/images/no_vote.png b/projects/robodj/src/java/robodj/chooser/images/no_vote.png new file mode 100644 index 00000000..7a046635 Binary files /dev/null and b/projects/robodj/src/java/robodj/chooser/images/no_vote.png differ diff --git a/projects/robodj/src/java/robodj/chooser/images/yea_vote.png b/projects/robodj/src/java/robodj/chooser/images/yea_vote.png new file mode 100644 index 00000000..777c38ef Binary files /dev/null and b/projects/robodj/src/java/robodj/chooser/images/yea_vote.png differ diff --git a/projects/robodj/src/java/robodj/repository/Song.java b/projects/robodj/src/java/robodj/repository/Song.java index 62e63884..ed5c99a1 100644 --- a/projects/robodj/src/java/robodj/repository/Song.java +++ b/projects/robodj/src/java/robodj/repository/Song.java @@ -49,25 +49,36 @@ public class Song * Adds a voter to the votes string for this entry, not including a * voter that already exists in the voter set. * + * @param yea true if this is a positive vote, false if it is a + * negative vote. + * * @return true if the voter set was changed as a result of this * addition, false if not. */ - public boolean addVote (String voter) + public boolean addVote (String voter, boolean yea) { - // handle our first vote separately - if (StringUtil.blank(votes)) { - votes = voter; - _votes = null; // clear our cached votes - return true; + if (voter.indexOf("-") != -1) { + throw new IllegalArgumentException("Voter must not contain '-'."); } // make sure this voter has not already cast their ballot - if (hasVoted(voter)) { - return false; + clearVote(voter); + + // mark the vote as nay if appropriate + if (!yea) { + voter = "-" + voter; + } + + // clear our cached votes + _votes = null; + + // handle our first vote separately + if (StringUtil.blank(votes)) { + votes = voter; + return true; } votes = (votes + "," + voter); - _votes = null; // clear our cached votes return true; } @@ -79,11 +90,13 @@ public class Song */ public boolean clearVote (String voter) { + String nvoter = "-" + voter; String[] votes = getVotes(); StringBuffer nvotes = new StringBuffer(); boolean saw = false; for (int ii = 0; ii < votes.length; ii++) { - if (votes[ii].equalsIgnoreCase(voter)) { + if (votes[ii].equalsIgnoreCase(voter) || + votes[ii].equalsIgnoreCase(nvoter)) { saw = true; } else { if (nvotes.length() > 0) { @@ -116,19 +129,51 @@ public class Song } /** - * Returns true if the specified user has voted. + * Returns true if this song has at least one positive vote. */ - public boolean hasVoted (String voter) + public boolean isLoved () { String[] votes = getVotes(); for (int ii = 0; ii < votes.length; ii++) { - if (votes[ii].equalsIgnoreCase(voter)) { + if (!votes[ii].startsWith("-")) { return true; } } return false; } + /** + * Returns true if this song has at least one negative vote. + */ + public boolean isHated () + { + String[] votes = getVotes(); + for (int ii = 0; ii < votes.length; ii++) { + if (votes[ii].startsWith("-")) { + return true; + } + } + return false; + } + + /** + * Returns +1, -1, or 0 to indicate whether the specified user has + * voted positively, negatively or not at all. + */ + public int hasVoted (String voter) + { + String nvoter = "-" + voter; + String[] votes = getVotes(); + for (int ii = 0; ii < votes.length; ii++) { + if (votes[ii].equals(voter)) { + return 1; + } else if (votes[ii].equals(nvoter)) { + return -1; + } + } + return 0; + } + /** * Returns a string representation of this instance. */