2014-07-27 20:11:10 -04:00

176 lines
4.7 KiB
Scala

package com.ianonavy.netflixsync
import scala.swing.GridBagPanel.Fill
import scala.swing._
import scala.swing.event.ButtonClicked
/**
* Main swing panel for the main frame.
*/
class MainPanel extends FlowPanel {
var socketEventPublisher: SocketEventPublisher = null
var client: Client = null
val SYNC_LABEL_DEFAULT_TEXT = "Please place me in the middle of your " +
"Netflix window"
val serverField = new TextField {
text = "localhost"
}
val roomField = new TextField
val nameField = new TextField
val registerButton = new Button {
text = "Register"
}
val setLocationButton = new Button {
text = "Set Location"
}
val setLocationLabel = new TextArea {
text = SYNC_LABEL_DEFAULT_TEXT
editable = false
opaque = false
focusable = false
cursor = null
lineWrap = true
wordWrap = true
}
/**
* @return A panel containing the elements relevant to registration
*/
def registerPanel: Panel = new BoxPanel(Orientation.Vertical) {
contents += new Label("Server:")
contents += serverField
contents += new Label("Room:")
contents += roomField
contents += new Label("Name:")
contents += nameField
contents += registerButton
border = Swing.EmptyBorder(30, 30, 30, 30)
}
/**
* @return A panel used for setting the location of the Netflix window
*/
def setLocationPanel: Panel = new GridBagPanel() {
val c = new Constraints
c.fill = Fill.Vertical
c.gridx = 0
c.gridy = 0
layout(setLocationLabel) = c
c.gridx = 0
c.gridy = 1
c.insets = new Insets(32, 0, 0, 0)
layout(setLocationButton) = c
border = Swing.EmptyBorder(30, 30, 30, 30)
}
/**
* The master control panel for a particular room. Shown only to the first
* user who registeres into a room.
* @param room The room to control
* @return The master control panel
*/
def masterPanel(room: String): Panel = new BoxPanel(Orientation.Vertical) {
val label = new Label {
text = "0 people have joined the room."
}
val clickButton = new Button {
text = "Send Click"
}
val spacebarButton = new Button {
text = "Send Spacebar"
}
val refreshButton = new Button {
text = "Refresh Count"
}
contents += label
contents += clickButton
contents += spacebarButton
contents += refreshButton
border = Swing.EmptyBorder(30, 30, 30, 30)
listenTo(clickButton)
listenTo(spacebarButton)
listenTo(refreshButton)
reactions += {
case ButtonClicked(`clickButton`) =>
label.text = "Sending..."
client.sendClick(room)
case ButtonClicked(`spacebarButton`) =>
label.text = "Sending..."
client.sendSpacebar(room)
case ButtonClicked(`refreshButton`) =>
val numPeople = client.getNumberRegistered(room)
label.text = s"$numPeople people have joined the room."
}
}
/**
* Frame for the master panel
* @param room The room to control
* @return The master frame
*/
def masterFrame(room: String) = new MainFrame {
title = "Netflix Sync"
contents = masterPanel(room)
}
/**
* Registers a user to a client at a particular server based on the results
* of the form elements usually contained in the registerPanel. Starts the
* socket event publisher, configures the Netflix Sync client and
* optionally spawns the master frame.
*/
def register() {
client = new Client(serverField.text, 10)
client.calculateAverageTime()
val room = roomField.text
val watcherName = nameField.text
contents.clear()
contents += setLocationPanel
revalidate()
repaint()
socketEventPublisher = new SocketEventPublisher(client, room, watcherName)
listenTo(socketEventPublisher)
val isMaster = client.registerName(roomField.text, nameField.text)
if (isMaster) {
masterFrame(room).open()
}
}
contents += registerPanel
listenTo(registerButton)
listenTo(setLocationButton)
// Netflix location
var (x, y) = (0, 0)
reactions += {
case ButtonClicked(`registerButton`) =>
register()
case ButtonClicked(`setLocationButton`) =>
socketEventPublisher.startPublishing()
val myLocation = self.getLocationOnScreen
x = myLocation.getX.toInt - 10
y = myLocation.getY.toInt - 10
setLocationLabel.text = "Netflix location set. You may now minimize this window."
case ServerSaidClick(delay) =>
client.synchronizedClick(delay.toLong, x, y)
setLocationLabel.text = SYNC_LABEL_DEFAULT_TEXT
case ServerSaidSpacebar(delay) =>
client.synchronizedClick(delay.toLong, x, y)
client.synchronizedSpacebar(delay.toLong)
setLocationLabel.text = SYNC_LABEL_DEFAULT_TEXT
}
}