Skip to content

Commit

Permalink
[Virtual Desktop] Basic implementation
Browse files Browse the repository at this point in the history
    - Shows mascot inside a window for testing
    - No IE or multi-display support yet
  • Loading branch information
LavenderSnek committed Jul 18, 2023
1 parent 959f227 commit 1bbcca3
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import javax.swing.event.PopupMenuListener;
import java.awt.Container;

class SwingPopupUtil {
public class SwingPopupUtil {

static JPopupMenu createJPopupmenuFrom(TopLevelMenuRep topMenuRep) {
public static JPopupMenu createJPopupmenuFrom(TopLevelMenuRep topMenuRep) {
JPopupMenu mainPopup = new JPopupMenu(topMenuRep.getTitle());
mainPopup.addPopupMenuListener(new PopupMenuListener() {
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.group_finity.mascotnative.virtualdesktop;

import com.group_finity.mascot.NativeFactory;
import com.group_finity.mascot.environment.NativeEnvironment;
import com.group_finity.mascot.image.NativeImage;
import com.group_finity.mascot.window.TranslucentWindow;
import com.group_finity.mascotnative.virtualdesktop.display.VirtualEnvironmentDisplay;

import java.awt.image.BufferedImage;

@SuppressWarnings("unused")
public class NativeFactoryImpl extends NativeFactory {

static final VirtualEnvironmentDisplay display;
static final VirtualEnvironment environment;

static {
display = new VirtualEnvironmentDisplay();
environment = new VirtualEnvironment(display);
}

@Override
public NativeEnvironment getEnvironment() {
return environment;
}

@Override
public NativeImage newNativeImage(BufferedImage src) {
return new VirtualImage(src);
}

@Override
public TranslucentWindow newTransparentWindow() {
var panel = new VirtualWindowPanel();
display.addShimejiWindow(panel);
return panel;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.group_finity.mascotnative.virtualdesktop;

import com.group_finity.mascot.environment.*;
import com.group_finity.mascotnative.virtualdesktop.display.VirtualEnvironmentDisplay;

import java.awt.*;
import java.util.List;

public class VirtualEnvironment extends BaseNativeEnvironment {

private final VirtualEnvironmentDisplay display;

public VirtualEnvironment(VirtualEnvironmentDisplay display) {
this.display = display;
}

@Override
protected void updateIe(Area ieToUpdate) {
ieToUpdate.setVisible(false);
}

@Override
protected List<Rectangle> getNewDisplayBoundsList() {
return display.getDisplayBoundsList();
}

@Override
public void tick() {
super.tick();
updateDisplayBounds();
}

@Override
public String getActiveIETitle() {
return null;
}

@Override
public void moveActiveIE(Point point) {
}

@Override
public void restoreIE() {
}

@Override
protected Point getNewCursorLocation() {
return display.getCursorLocation(super.getNewCursorLocation());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.group_finity.mascotnative.virtualdesktop;

import com.group_finity.mascot.image.NativeImage;

import java.awt.image.BufferedImage;

public record VirtualImage(BufferedImage bufferedImage) implements NativeImage {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.group_finity.mascotnative.virtualdesktop;

import com.group_finity.mascot.image.NativeImage;
import com.group_finity.mascot.ui.contextmenu.TopLevelMenuRep;
import com.group_finity.mascot.window.TranslucentWindow;
import com.group_finity.mascot.window.TranslucentWindowEvent;
import com.group_finity.mascot.window.TranslucentWindowEventHandler;
import com.group_finity.mascotnative.shared.SwingPopupUtil;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class VirtualWindowPanel extends JPanel implements TranslucentWindow {

protected static final Color CLEAR = new Color(0, 0, 0, 0);

private TranslucentWindowEventHandler eventHandler = TranslucentWindowEventHandler.DEFAULT;

private VirtualImage image;

public VirtualWindowPanel() {
super();
setBounds(0,0,0,0);
setBackground(CLEAR);
setOpaque(false);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
showPopupMenu(e);
} else if (SwingUtilities.isLeftMouseButton(e)) {
getEventHandler().onDragBegin(new TranslucentWindowEvent(e.getPoint()));
}
}

@Override
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
getEventHandler().onDragEnd(new TranslucentWindowEvent(e.getPoint()));
}
}
});
}

protected void showPopupMenu(MouseEvent e) {
TopLevelMenuRep menuRep = getEventHandler().getContextMenuRep();
if (menuRep == null) {
return;
}
JPopupMenu popupMenu = SwingPopupUtil.createJPopupmenuFrom(menuRep);
SwingUtilities.invokeLater(() -> popupMenu.show(this, e.getX(), e.getY()));
}

@Override
protected void paintComponent(Graphics g) {
g.drawImage(image.bufferedImage(), 0, 0, null);
}

public TranslucentWindowEventHandler getEventHandler() {
return eventHandler;
}

@Override
public void setEventHandler(TranslucentWindowEventHandler eventHandler) {
this.eventHandler = eventHandler;
}

@Override
public void setImage(NativeImage image) {
if (image != null) {
this.image = (VirtualImage) image;
}
}

@Override
public void updateImage() {
repaint();
}

@Override
public void dispose() {
SwingUtilities.invokeLater(() -> {
var parent = getParent();
if (parent != null) {
parent.remove(this);
parent.repaint();
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.group_finity.mascotnative.virtualdesktop.display;

import com.group_finity.mascotnative.virtualdesktop.VirtualWindowPanel;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import java.awt.*;
import java.util.List;

public class VirtualEnvironmentDisplay {

private static final int INIT_WIDTH = 900;
private static final int INIT_HEIGHT = 600;
private static final Color BG_COLOR = Color.WHITE;

private final JFrame frame;

public VirtualEnvironmentDisplay() {
frame = new JFrame("Shimeji");
frame.getContentPane().setPreferredSize(new Dimension(INIT_WIDTH, INIT_HEIGHT));
frame.getContentPane().setLayout(null);
frame.getContentPane().setBackground(BG_COLOR);

SwingUtilities.invokeLater(() -> {
frame.pack();
frame.setVisible(true);
});
}

public List<Rectangle> getDisplayBoundsList() {
return List.of(frame.getContentPane().getBounds());
}

public Point getCursorLocation(Point screenCoordinates) {
var p = screenCoordinates.getLocation();
SwingUtilities.convertPointFromScreen(p, frame.getContentPane());
return p;
}

public void addShimejiWindow(VirtualWindowPanel panel) {
SwingUtilities.invokeLater(() -> {
frame.getContentPane().add(panel);
});
}

}

0 comments on commit 1bbcca3

Please sign in to comment.