<file_sep>/**
 * Created by <EMAIL> on 05.05.16.
 */
package com.vsu.nil.widgets

import java.awt.Dimension
import java.awt.Graphics
import java.util.*
import javax.swing.JComponent
import kotlin.concurrent.timer


fun TouchPanel.button(func: TouchButton.() -> Unit = {}) = addTouchableChild(TouchButton(), func)

class TouchButton : JComponent(), TouchableContent, KClickable {
    override val kClickHandlers: MutableList<() -> Unit> = ArrayList()

    override var activated: Boolean = false
        set(value) {
            size = if (value) parentActivatedSize else parentNormalSize
            field = value
        }
    override var parentActivatedSize = Dimension()
    override var parentNormalSize = Dimension()

    var isClicked = false

    override fun click() {
        super.click()

        isClicked = true
        repaint()
        timer(initialDelay = 1000, period = 666) {
            isClicked = false
            repaint()
            cancel()
        }
    }

    override fun paintComponent(g: Graphics?) {
        super.paintComponent(g)
        g?.drawLine(0, 0, width, height)
        if (isClicked) g?.drawLine(0, height, width, 0)
    }
}<file_sep>/**
 * Created by <EMAIL> on 24.04.16.
 */
package com.vsu.nil

import com.vsu.nil.widgets.button
import com.vsu.nil.widgets.touchPanel
import com.vsu.nil.wrappers.*
import java.awt.FlowLayout
import java.awt.GridLayout
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent

fun main(args: Array<String>) {
    window {
        layout = GridLayout(4, 1)
        extendedState = MAXIMIZED_BOTH

        label {
            text = "Buttons"
            horizontalAlignment = CENTER
        } to this
        val status = label {
            horizontalAlignment = CENTER
        }
        panel {
            layout = FlowLayout()
            button {
                text = "One"
                addActionListener { status.text = text }
            } to this
            button {
                text = "Two"
                addActionListener { status.text = text }
            } to this
            button {
                text = "Three"
                addActionListener { status.text = text }
            } to this
        } to this
        status to this

        panel {
            layout = null

            touchPanel { touchPanel ->
                normalWidth = 100
                normalHeight = 100

                events {
                    onMouseMoved = { activated = true }
                    onMouseExited = { activated = false }
                }

                val button = button { } to this
                val mouseAdapter = object : MouseAdapter() {
                    override fun mouseClicked(e: MouseEvent?) {
                        button.click()
                    }

                    override fun mouseMoved(e: MouseEvent?) {
                        touchPanel.dispatchEvent(e)
                    }

                    override fun mouseExited(e: MouseEvent?) {
                        touchPanel.dispatchEvent(e)
                    }
                }
                button.addMouseListener(mouseAdapter)
                button.addMouseMotionListener(mouseAdapter)
            } to this
        } to this

        events {
            onClosing = { System.exit(0) }
        }
    }
}<file_sep>/**
 * Created by <EMAIL> on 29.04.16.
 */
package com.vsu.nil.widgets

import com.vsu.nil.kinect.trackPanel
import com.vsu.nil.wrappers.KMouseAdapter
import com.vsu.nil.wrappers.addChild
import java.awt.BorderLayout
import java.awt.Color
import java.awt.Dimension
import java.awt.Point
import java.util.*
import javax.swing.JComponent
import javax.swing.JPanel
import javax.swing.border.LineBorder


fun touchPanel(func: TouchPanel.(TouchPanel) -> Unit = {}): TouchPanel {
    val panel = TouchPanel()
    trackPanel(panel)
    return addChild(panel, func)
}

fun <T> TouchPanel.addTouchableChild(child: T, func: T.() -> Unit): T
        where T : JComponent, T : TouchableContent {
    touchableChildren.add(child)
    child.parentNormalSize = normalSize
    child.parentActivatedSize = activatedSize
    child.func()

    return child
}

const val INITIAL_WIDTH = 100
const val INITIAL_HEIGHT = 100

class TouchPanel : JPanel, TouchableContainer {
    override val touchableChildren by lazy { ArrayList<TouchableContent>() }
    val events = KMouseAdapter()

    var normalWidth = INITIAL_WIDTH
        set(value) {
            field = value
            normalSize.width = value
            if (!activated) size = normalSize
        }
    var normalHeight = INITIAL_HEIGHT
        set(value) {
            field = value
            normalSize.height = value
            if (!activated) size = normalSize
        }
    override var normalSize = Dimension(normalWidth, normalHeight)

    var activatedWidth = (normalWidth * 1.5).toInt()
        set(value) {
            field = value
            activatedSize.width = value
            if (activated) size = activatedSize
        }
    var activatedHeight = (normalHeight * 1.5).toInt()
        set(value) {
            field = value
            activatedSize.height = value
            if (activated) size = activatedSize
        }
    override var activatedSize = Dimension(activatedWidth, activatedHeight)

    var borderColor = Color.GREEN

    override var activated: Boolean = false
        set(value) {
            if (value xor field) {
                border = if (value) {
                    size = activatedSize
                    LineBorder(borderColor, 3)
                } else {
                    size = normalSize
                    null
                }
                touchableChildren.forEach { it.activated = value }
                field = value
            }
        }

    constructor() : super(BorderLayout()) {
        addMouseListener(events)
        addMouseMotionListener(events)
    }

    override fun isTouched(point: Point): Boolean {
        val width: Int
        val height: Int
        if (activated) {
            width = activatedWidth
            height = activatedHeight
        } else {
            width = normalWidth
            height = normalHeight
        }
        return x <= point.x && point.x <= x + width && y <= point.y && point.y <= y + height
    }
}


// TODO возможно это уже не понадобится
fun TouchPanel.content(func: TouchContent.() -> Unit = {}) {
    val child = TouchContent()
    addTouchableChild(child, func)
    add(child)
}

class TouchContent : JPanel(), TouchableContent {
    override var activated: Boolean = false
        set(value) {
            size = if (value) parentActivatedSize else parentNormalSize
            field = value
        }
    override var parentActivatedSize = Dimension()
    override var parentNormalSize = Dimension()
}<file_sep>/**
 * Created by <EMAIL> on 05.05.16.
 */
package com.vsu.nil.widgets

import java.awt.Dimension
import java.awt.Point


interface Touchable {
    var activated: Boolean
}

interface TouchableContainer : Touchable {
    val touchableChildren: MutableList<TouchableContent>
    var normalSize: Dimension
    var activatedSize: Dimension

    fun isTouched(point: Point): Boolean
}

interface TouchableContent : Touchable {
    var parentNormalSize: Dimension
    var parentActivatedSize: Dimension
}

interface KClickable {
    val kClickHandlers: MutableList<() -> Unit>
    fun click() {
        kClickHandlers.forEach { it() }
    }

    fun onKClicked(func: () -> Unit) {
        kClickHandlers.add(func)
    }
}<file_sep>/**
 * Created by <EMAIL> on 06.05.16.
 */
package com.vsu.nil.wrappers

import java.awt.event.MouseEvent
import java.awt.event.MouseListener
import java.awt.event.MouseMotionListener


class KMouseAdapter : MouseMotionListener, MouseListener {

    operator fun invoke(func: KMouseAdapter.() -> Unit) {
        this.func()
    }

    var onMouseEntered: (e: MouseEvent?) -> Unit = {}
    override fun mouseEntered(e: MouseEvent?) {
        onMouseEntered(e)
    }

    var onMouseClicked: (e: MouseEvent?) -> Unit = {}
    override fun mouseClicked(e: MouseEvent?) {
        onMouseClicked(e)
    }

    var onMouseReleased: (e: MouseEvent?) -> Unit = {}
    override fun mouseReleased(e: MouseEvent?) {
        onMouseReleased(e)
    }

    var onMouseExited: (e: MouseEvent?) -> Unit = {}
    override fun mouseExited(e: MouseEvent?) {
        onMouseExited(e)
    }

    var onMousePressed: (e: MouseEvent?) -> Unit = {}
    override fun mousePressed(e: MouseEvent?) {
        onMousePressed(e)
    }

    var onMouseMoved: (e: MouseEvent?) -> Unit = {}
    override fun mouseMoved(e: MouseEvent?) {
        onMouseMoved(e)
    }

    var onMouseDragged: (e: MouseEvent?) -> Unit = {}
    override fun mouseDragged(e: MouseEvent?) {
        onMouseDragged(e)
    }

}<file_sep>/**
 * Created by <EMAIL> on 29.04.16.
 */
package com.vsu.nil.wrappers

import java.awt.event.WindowEvent
import java.awt.event.WindowFocusListener
import java.awt.event.WindowListener
import java.awt.event.WindowStateListener
import java.util.*
import javax.swing.JFrame


private val windowAdapters by lazy { HashMap<JFrame, WindowAdapter>() }

val JFrame.events: WindowAdapter
    get() {
        var adapter = windowAdapters[this]
        if (adapter === null) {
            adapter = WindowAdapter()
            windowAdapters[this] = adapter

            addWindowStateListener(adapter)
            addWindowFocusListener(adapter)
            addWindowListener(adapter)
        }
        return adapter
    }


class WindowAdapter : WindowListener, WindowStateListener, WindowFocusListener {

    operator fun invoke(func: WindowAdapter.() -> Unit) {
        this.func()
    }

    var onDeiconified: (e: WindowEvent?) -> Unit = {}
    override fun windowDeiconified(e: WindowEvent?) {
        onDeiconified(e)
    }

    var onActivated: (e: WindowEvent?) -> Unit = {}
    override fun windowActivated(e: WindowEvent?) {
        onActivated(e)
    }

    var onDeactivated: (e: WindowEvent?) -> Unit = {}
    override fun windowDeactivated(e: WindowEvent?) {
        onDeactivated(e)
    }

    var onIconofied: (e: WindowEvent?) -> Unit = {}
    override fun windowIconified(e: WindowEvent?) {
        onIconofied(e)
    }

    var onClosing: (e: WindowEvent?) -> Unit = {}
    override fun windowClosing(e: WindowEvent?) {
        onClosing(e)
    }

    var onClosed: (e: WindowEvent?) -> Unit = {}
    override fun windowClosed(e: WindowEvent?) {
        onClosed(e)
    }

    var onOpened: (e: WindowEvent?) -> Unit = {}
    override fun windowOpened(e: WindowEvent?) {
        onOpened(e)
    }

    var onStateChanged: (e: WindowEvent?) -> Unit = {}
    override fun windowStateChanged(e: WindowEvent?) {
        onStateChanged(e)
    }

    var onLostFocus: (e: WindowEvent?) -> Unit = {}
    override fun windowLostFocus(e: WindowEvent?) {
        onLostFocus(e)
    }

    var onGainedFocus: (e: WindowEvent?) -> Unit = {}
    override fun windowGainedFocus(e: WindowEvent?) {
        onGainedFocus(e)
    }
}<file_sep>/**
 * Created by <EMAIL> on 25.04.16.
 */
package com.vsu.nil.wrappers

import java.awt.Component
import java.awt.Container
import javax.swing.JButton
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.JPanel


fun window(func: JFrame.(JFrame) -> Unit = {}): JFrame {
    val window = JFrame()
    window.func(window)
    window.setVisible(true)
    return window
}

fun panel(func: JPanel.(JPanel) -> Unit = {}) = addChild(JPanel(), func)
fun label(func: JLabel.(JLabel) -> Unit = {}) = addChild(JLabel(), func)
fun button(func: JButton.(JButton) -> Unit = {}) = addChild(JButton(), func)

fun <C : Component> addChild(child: C, func: C.(C) -> Unit = {}): C {
    child.func(child)
    return child
}

val CENTER = JLabel.CENTER
val MAXIMIZED_BOTH = JFrame.MAXIMIZED_BOTH

infix fun <C : Component> C.to(container: Container): C {
    container.add(this)
    return this
}<file_sep># Natural-Interaction-Library<file_sep>/**
 * Created by <EMAIL> on 03.05.16.
 */
package com.vsu.nil.kinect

import com.vsu.nil.widgets.TouchableContainer
import java.awt.Point
import java.util.*
import kotlin.concurrent.timer


private val trackedPanels = HashSet<TouchableContainer>()

fun trackPanel(panel: TouchableContainer) {
    trackedPanels.add(panel)
}

class HandTracker {

    val timer: Timer = Timer()

    /**
     * Координаты отслеживаемой руки.
     * null, если рука не отслеживается
     */
    var position: Point? = null

    fun updatePanels() {
        val pos = position
        pos?.let {
            for (panel in trackedPanels) {
                if (panel.activated) {
                    if (!panel.isTouched(pos)) {
                        var count = 0
                        timer(initialDelay = 250, period = 250) {
                            val newPos = position
                            pos?.let {
                                if (panel.isTouched(pos)) cancel()
                                if (count++ >= 2) {
                                    panel.activated = false
                                    cancel()
                                }
                            } ?: cancel()
                        }
                    }
                } else {
                    if (panel.isTouched(pos)) {
                        var count = 0
                        timer(initialDelay = 250, period = 250) {
                            val newPos = position
                            pos?.let {
                                if (!panel.isTouched(pos)) cancel()
                                if (count++ >= 2) {
                                    panel.activated = true
                                    cancel()
                                }
                            } ?: cancel()
                        }
                    }
                }
            }
        }
    }
}