diff --git a/src/main/java/com/group_finity/mascotnative/shared/SwingPopupUtil.java b/src/main/java/com/group_finity/mascotnative/shared/SwingPopupUtil.java index 38e40b6..7f99d54 100644 --- a/src/main/java/com/group_finity/mascotnative/shared/SwingPopupUtil.java +++ b/src/main/java/com/group_finity/mascotnative/shared/SwingPopupUtil.java @@ -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 diff --git a/src/main/java/com/group_finity/mascotnative/virtualdesktop/NativeFactoryImpl.java b/src/main/java/com/group_finity/mascotnative/virtualdesktop/NativeFactoryImpl.java new file mode 100644 index 0000000..f08bf62 --- /dev/null +++ b/src/main/java/com/group_finity/mascotnative/virtualdesktop/NativeFactoryImpl.java @@ -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; + } +} diff --git a/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualEnvironment.java b/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualEnvironment.java new file mode 100644 index 0000000..0236fd5 --- /dev/null +++ b/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualEnvironment.java @@ -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 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()); + } +} diff --git a/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualImage.java b/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualImage.java new file mode 100644 index 0000000..3d78d44 --- /dev/null +++ b/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualImage.java @@ -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 { +} diff --git a/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualWindowPanel.java b/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualWindowPanel.java new file mode 100644 index 0000000..9191025 --- /dev/null +++ b/src/main/java/com/group_finity/mascotnative/virtualdesktop/VirtualWindowPanel.java @@ -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(); + } + }); + } +} diff --git a/src/main/java/com/group_finity/mascotnative/virtualdesktop/display/VirtualEnvironmentDisplay.java b/src/main/java/com/group_finity/mascotnative/virtualdesktop/display/VirtualEnvironmentDisplay.java new file mode 100644 index 0000000..1a4424b --- /dev/null +++ b/src/main/java/com/group_finity/mascotnative/virtualdesktop/display/VirtualEnvironmentDisplay.java @@ -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 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); + }); + } + +}