Package com.polysfactory.glassremote.ui

Source Code of com.polysfactory.glassremote.ui.MainFrame

/*
* Copyright (C) 2009-2013 adakoda
* Copyright (C) 2013 Poly's Factory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.polysfactory.glassremote.ui;

import java.awt.Dimension;
import java.awt.Insets;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.prefs.Preferences;

import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.SwingUtilities;

import com.google.glass.companion.CompanionMessagingUtil;
import com.google.glass.companion.Proto.CompanionInfo;
import com.google.glass.companion.Proto.Envelope;
import com.google.glass.companion.Proto.GlassInfoResponse;
import com.google.glass.companion.Proto.MotionEvent;
import com.google.glass.companion.Proto.ScreenShot;
import com.polysfactory.glassremote.App;
import com.polysfactory.glassremote.model.Device;
import com.polysfactory.glassremote.model.GlassConnection;
import com.polysfactory.glassremote.model.GlassConnection.GlassConnectionListener;
import com.polysfactory.glassremote.ui.ScreencastPanel.ScreencastMouseEventListener;
import com.polysfactory.glassremote.util.GlassMessagingUtil;
import com.polysfactory.glassremote.util.SwingUtil;

@SuppressWarnings("serial")
public class MainFrame extends JFrame implements GlassConnectionListener, ScreencastMouseEventListener {

    private static final String TITLE = App.NAME;

    private ScreencastPanel mScreencastPanel;
    private JPopupMenu mPopupMenu;

    private Preferences mPrefs;
    private double mZoom = 1.0;

    private Device mDevice;

    private GlassConnection mGlassConnection;

    private DeviceDialog mDialog;

    private ControlPanel mControlPanel;

    private InfoPanel mInfoPanel;

    public MainFrame() {
        setFocusable(true);

        mGlassConnection = new GlassConnection();
        mGlassConnection.registerListener(this);

        initializePrefs();
        initializeFrame();
        initializePanel();
        initializeMenu();

        addMouseListener(mMouseListener);
        addWindowListener(mWindowListener);
        KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        keyboardFocusManager.addKeyEventDispatcher(mKeyEventDispatcher);

        pack();
        setImage(null);
    }

    public void selectDevice() {
        mGlassConnection.close();

        DefaultListModel deviceListModel = SwingUtil.list2ListModel(mGlassConnection.getBondedDevices());
        // mDeviceListModel = new DefaultListModel();
        mDialog = new DeviceDialog(this, deviceListModel, mGlassConnection);
        mGlassConnection.registerListener(mDialog);

        mGlassConnection.scan();

        mDialog.setLocationRelativeTo(this);
        mDialog.setVisible(true);
        if (mDialog.isOK()) {
            int selectedIndex = mDialog.getSelectedIndex();
            if (selectedIndex >= 0) {
                mDevice = (Device) deviceListModel.get(selectedIndex);
                mGlassConnection.connect(mDevice);
                setImage(null);
            }
        }

        mGlassConnection.unregisterListener(mDialog);
        deviceListModel = null;
        mDialog = null;
    }

    private void setZoom(double zoom) {
        if (mZoom != zoom) {
            mZoom = zoom;
            mScreencastPanel.setZoom(mZoom);
            savePrefs();
            updateSize();
        }
    }

    private void about() {
        AboutDialog dialog = new AboutDialog(this, true);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }

    private void updateSize() {
        // int width = mRawImageWidth;
        // int height = mRawImageHeight;
        int width = mScreencastPanel.getWidth();
        width = Math.max(width, mControlPanel.getWidth());
        width = Math.max(width, mInfoPanel.getWidth());

        int height = mScreencastPanel.getHeight() + mControlPanel.getHeight() + mInfoPanel.getHeight();
        Insets insets = getInsets();

        // System.out.println("size inside:" + width + "," + height);

        // int newWidth = (int) (width * mZoom) + insets.left + insets.right;
        // int newHeight = (int) (height * mZoom) + insets.top + insets.bottom;
        int newWidth = width + insets.left + insets.right;
        int newHeight = height + insets.top + insets.bottom;

        // Known bug
        // If new window size is over physical window size, cannot update window
        // size...
        // FIXME
        if ((getWidth() != newWidth) || (getHeight() != newHeight)) {
            // System.out.println("set new size:" + newWidth + "," + newHeight);
            Dimension d = new Dimension(newWidth, newHeight);
            setPreferredSize(d);
            setSize(d);
        }
    }

    private void setImage(BufferedImage image) {
        mScreencastPanel.setImage(image);
        updateSize();
    }

    private void savePrefs() {
        if (mPrefs != null) {
            mPrefs.putInt("PrefVer", 1);
            mPrefs.putDouble("Zoom", mZoom);
        }
    }

    private void initializePrefs() {
        mPrefs = Preferences.userNodeForPackage(this.getClass());
        if (mPrefs != null) {
            int prefVer = mPrefs.getInt("PrefVer", 1);
            if (prefVer == 1) {
                mZoom = mPrefs.getDouble("Zoom", 1.0);
            }
        }
    }

    private void initializeFrame() {
        setTitle(TITLE);
        // setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("icon.png")));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
    }

    private void initializePanel() {

        JPanel panel = new JPanel();
        GroupLayout layout = new GroupLayout(panel);
        panel.setLayout(layout);

        mInfoPanel = new InfoPanel();

        mScreencastPanel = new ScreencastPanel();
        mScreencastPanel.setZoom(mZoom);
        mScreencastPanel.setScreencastMouseEventListener(this);

        mControlPanel = new ControlPanel(mGlassConnection);

        layout.setHorizontalGroup(layout.createParallelGroup().addComponent(mInfoPanel).addComponent(mScreencastPanel)
                .addComponent(mControlPanel));
        layout.setVerticalGroup(layout.createSequentialGroup().addComponent(mInfoPanel).addComponent(mScreencastPanel)
                .addComponent(mControlPanel));

        add(panel);
    }

    private void initializeMenu() {
        mPopupMenu = new JPopupMenu();
        initializeSelectDeviceMenu();
        mPopupMenu.addSeparator();
        initializeZoomMenu();
        mPopupMenu.addSeparator();
        initializeAbout();
    }

    private void initializeSelectDeviceMenu() {
        JMenuItem menuItemSelectDevice = new JMenuItem("Select Device...");
        menuItemSelectDevice.setMnemonic(KeyEvent.VK_D);
        menuItemSelectDevice.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                selectDevice();
            }
        });
        mPopupMenu.add(menuItemSelectDevice);
    }

    private void initializeZoomMenu() {
        JMenu menuZoom = new JMenu("Zoom");
        menuZoom.setMnemonic(KeyEvent.VK_Z);
        mPopupMenu.add(menuZoom);

        ButtonGroup buttonGroup = new ButtonGroup();

        addRadioButtonMenuItemZoom(menuZoom, buttonGroup, 0.5, "50%", KeyEvent.VK_5, mZoom);
        addRadioButtonMenuItemZoom(menuZoom, buttonGroup, 0.75, "75%", KeyEvent.VK_7, mZoom);
        addRadioButtonMenuItemZoom(menuZoom, buttonGroup, 1.0, "100%", KeyEvent.VK_1, mZoom);
        addRadioButtonMenuItemZoom(menuZoom, buttonGroup, 1.5, "150%", KeyEvent.VK_0, mZoom);
        addRadioButtonMenuItemZoom(menuZoom, buttonGroup, 2.0, "200%", KeyEvent.VK_2, mZoom);
    }

    private void addRadioButtonMenuItemZoom(JMenu menuZoom, ButtonGroup buttonGroup, final double zoom, String caption,
            int nemonic, double currentZoom) {
        JRadioButtonMenuItem radioButtonMenuItemZoom = new JRadioButtonMenuItem(caption);
        if (nemonic != -1) {
            radioButtonMenuItemZoom.setMnemonic(nemonic);
        }
        radioButtonMenuItemZoom.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setZoom(zoom);
            }
        });
        if (currentZoom == zoom) {
            radioButtonMenuItemZoom.setSelected(true);
        }
        buttonGroup.add(radioButtonMenuItemZoom);
        menuZoom.add(radioButtonMenuItemZoom);
    }

    private void initializeAbout() {
        JMenuItem menuItemAbout = new JMenuItem("About " + App.NAME);
        menuItemAbout.setMnemonic(KeyEvent.VK_A);
        menuItemAbout.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                about();
            }
        });
        mPopupMenu.add(menuItemAbout);
    }

    private MouseListener mMouseListener = new MouseListener() {
        public void mouseReleased(MouseEvent e) {
        }

        public void mousePressed(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseClicked(MouseEvent e) {
            if (SwingUtilities.isRightMouseButton(e)) {
                mPopupMenu.show(e.getComponent(), e.getX(), e.getY());
            }
        }
    };

    private WindowListener mWindowListener = new WindowListener() {
        public void windowOpened(WindowEvent arg0) {
        }

        public void windowIconified(WindowEvent arg0) {
        }

        public void windowDeiconified(WindowEvent arg0) {
        }

        public void windowDeactivated(WindowEvent arg0) {
        }

        public void windowClosing(WindowEvent arg0) {
            mGlassConnection.close();
        }

        public void windowClosed(WindowEvent arg0) {
        }

        public void windowActivated(WindowEvent arg0) {
        }
    };

    private KeyEventDispatcher mKeyEventDispatcher = new KeyEventDispatcher() {
        @Override
        public boolean dispatchKeyEvent(KeyEvent e) {
            if (e.getID() != KeyEvent.KEY_PRESSED) {
                return false;
            }
            if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) {
                return false;
            }
            switch (e.getKeyCode()) {
            case KeyEvent.VK_LEFT:
                mGlassConnection.writeAsync(GlassMessagingUtil.getSwipeLeftEvents());
                break;
            case KeyEvent.VK_RIGHT:
                mGlassConnection.writeAsync(GlassMessagingUtil.getSwipeRightEvents());
                break;
            case KeyEvent.VK_DOWN:
                mGlassConnection.writeAsync(GlassMessagingUtil.getSwipeDownEvents());
                break;
            case KeyEvent.VK_ENTER:
                mGlassConnection.writeAsync(GlassMessagingUtil.getTapEvents());
                break;
            default:
                break;
            }
            return false;
        }
    };

    @Override
    public void onReceivedEnvelope(Envelope envelope) {
        if (envelope.screenshot != null) {
            if (envelope.screenshot.screenshotBytesG2C != null) {
                InputStream in = new ByteArrayInputStream(envelope.screenshot.screenshotBytesG2C);
                try {
                    final BufferedImage image = ImageIO.read(in);
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            setImage(image);
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        if (envelope.glassInfoResponseG2C != null) {
            GlassInfoResponse response = envelope.glassInfoResponseG2C;
            String info = "";
            info += "Device name: " + response.deviceName;
            info += " Battery: " + response.batteryLevel + "%";
            info += " Software: " + response.softwareVersion;
            info += "\n";
            info += "Storage: " + response.externalStorageAvailableBytes + "/" + response.externalStorageTotalBytes
                    + " bytes available";
            mInfoPanel.setText(info);
        }
        if (envelope.companionInfo != null) {
            CompanionInfo companionInfo = envelope.companionInfo;
            String log = companionInfo.responseLog;
            System.out.println(log);
        }
    }

    @Override
    public void onDeviceDiscovered(Device device) {
    }

    @Override
    public void onServiceNotFound() {
        JOptionPane.showMessageDialog(this, "Companion service not found.", App.NAME, JOptionPane.ERROR_MESSAGE);
    }

    @Override
    public void onServiceSearchError() {
        JOptionPane.showMessageDialog(this, "Error happend while searching companion service.", App.NAME,
                JOptionPane.ERROR_MESSAGE);
    }

    @Override
    public void onConnectionOpened() {
        Envelope envelope = CompanionMessagingUtil.newEnvelope();
        ScreenShot screenShot = new ScreenShot();
        screenShot.startScreenshotRequestC2G = true;
        envelope.screenshot = screenShot;
        mGlassConnection.write(envelope);
    }

    @Override
    public void onDeviceScanCompleted() {
        // TODO Auto-generated method stub
    }

    @Override
    public void onMouseEvent(int action, int x, int y, long downTime) {
        MotionEvent glassMotionEvent = GlassMessagingUtil.convertMouseEvent2MotionEvent(action, 100.0f * (float) x
                / (float) mScreencastPanel.getWidth(), 100.0f * (float) y / (float) mScreencastPanel.getHeight(),
                downTime);
        Envelope envelope = CompanionMessagingUtil.newEnvelope();
        envelope.motionC2G = glassMotionEvent;
        mGlassConnection.writeAsync(envelope);
    }
}
TOP

Related Classes of com.polysfactory.glassremote.ui.MainFrame

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.