You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OsdWindow.java 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.addons.osd;
  23. import com.dmdirc.Main;
  24. import com.dmdirc.addons.ui_swing.MainFrame;
  25. import com.dmdirc.config.IdentityManager;
  26. import com.dmdirc.ui.messages.ColourManager;
  27. import java.awt.Color;
  28. import java.awt.Point;
  29. import java.awt.event.MouseEvent;
  30. import java.awt.event.MouseListener;
  31. import java.awt.event.MouseMotionListener;
  32. import java.util.ArrayList;
  33. import java.util.List;
  34. import java.util.Timer;
  35. import java.util.TimerTask;
  36. import javax.swing.JDialog;
  37. import javax.swing.JLabel;
  38. import javax.swing.JPanel;
  39. import javax.swing.SwingConstants;
  40. import javax.swing.WindowConstants;
  41. import javax.swing.border.LineBorder;
  42. import net.miginfocom.swing.MigLayout;
  43. /**
  44. * The OSD Window is an always-on-top window designed to convey information
  45. * about events to the user.
  46. * @author chris
  47. */
  48. public final class OsdWindow extends JDialog implements MouseListener,
  49. MouseMotionListener {
  50. /**
  51. * A version number for this class. It should be changed whenever the class
  52. * structure is changed (or anything else that would prevent serialized
  53. * objects being unserialized with the new class).
  54. */
  55. private static final long serialVersionUID = 2;
  56. /** Gap between vertically stacked windows. */
  57. private static final int WINDOW_GAP = 5;
  58. /** A list of open OSD windows. */
  59. private static List<OsdWindow> windows = new ArrayList<OsdWindow>();
  60. /** Plugin this window belongs to. */
  61. private final OsdPlugin plugin;
  62. /** OSD Label. */
  63. private final JLabel label;
  64. /** OSD Panel. */
  65. private final JPanel panel;
  66. /** Starting positions of the mouse. */
  67. private int startX, startY;
  68. /** Is this a config instance? */
  69. private final boolean config;
  70. /**
  71. * Creates a new instance of OsdWindow.
  72. *
  73. * @param text The text to be displayed in the OSD window
  74. * @param config Is the window being configured (should it timeout and
  75. * allow itself to be moved)
  76. * @param plugin The plugin that owns this window
  77. */
  78. public OsdWindow(final String text, final boolean config, final OsdPlugin plugin) {
  79. this(text, config, IdentityManager.getGlobalConfig()
  80. .getOptionInt(plugin.getDomain(), "locationX"), getYPosition(plugin), plugin);
  81. }
  82. /**
  83. * Creates a new instance of OsdWindow.
  84. *
  85. * @param text The text to be displayed in the OSD window
  86. * @param config Is the window being configured (should it timeout and
  87. * allow itself to be moved)
  88. * @param x The x-axis position for the OSD Window
  89. * @param y The y-axis position for the OSD window
  90. * @param plugin Parent OSD Plugin
  91. */
  92. public OsdWindow(final String text, final boolean config, final int x,
  93. final int y, final OsdPlugin plugin) {
  94. super((MainFrame) Main.getUI().getMainWindow(), false);
  95. this.plugin = plugin;
  96. this.config = config;
  97. setFocusableWindowState(false);
  98. setAlwaysOnTop(true);
  99. setResizable(false);
  100. setUndecorated(true);
  101. setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
  102. setLocation(x, y);
  103. panel = new JPanel();
  104. panel.setBorder(new LineBorder(Color.BLACK));
  105. panel.setBackground(IdentityManager.getGlobalConfig().getOptionColour(plugin.getDomain(),
  106. "bgcolour"));
  107. final int width = IdentityManager.getGlobalConfig().getOptionInt(plugin.getDomain(),
  108. "width");
  109. setContentPane(panel);
  110. setLayout(new MigLayout("wmin " + width + ", wmax " + width + ", ins rel, fill"));
  111. label = new JLabel(text);
  112. label.setForeground(IdentityManager.getGlobalConfig().getOptionColour(plugin.getDomain(),
  113. "fgcolour"));
  114. label.setFont(label.getFont().deriveFont(
  115. (float) IdentityManager.getGlobalConfig().getOptionInt(plugin.getDomain(),
  116. "fontSize")));
  117. label.setHorizontalAlignment(SwingConstants.CENTER);
  118. add(label, "alignx center");
  119. setVisible(true);
  120. pack();
  121. if (config) {
  122. this.addMouseMotionListener(this);
  123. this.addMouseListener(this);
  124. } else {
  125. addMouseListener(this);
  126. new Timer("OSD Display Timer").schedule(new TimerTask() {
  127. /** {@inheritDoc} */
  128. @Override
  129. public void run() {
  130. setVisible(false);
  131. dispose();
  132. }
  133. }, IdentityManager.getGlobalConfig().getOptionInt(plugin.getDomain(),
  134. "timeout") * 1000);
  135. }
  136. }
  137. /**
  138. * Retrieves the y-axis position for a new OSD window, based on the user's
  139. * configured policy.
  140. *
  141. * @return The y-axis position for a new OSD window.
  142. */
  143. private static int getYPosition(final OsdPlugin plugin) {
  144. final String policy = IdentityManager.getGlobalConfig()
  145. .getOption(plugin.getDomain(), "newbehaviour");
  146. int y = IdentityManager.getGlobalConfig().getOptionInt(plugin.getDomain(),
  147. "locationY");
  148. if ("down".equals(policy)) {
  149. // Place our new window below old windows
  150. for (OsdWindow window : new ArrayList<OsdWindow>(windows)) {
  151. if (window.isVisible()) {
  152. y = Math.max(y, window.getY() + window.getHeight() + WINDOW_GAP);
  153. }
  154. }
  155. } else if ("up".equals(policy)) {
  156. // Place our new window above old windows
  157. for (OsdWindow window : new ArrayList<OsdWindow>(windows)) {
  158. if (window.isVisible()) {
  159. y = Math.min(y, window.getY() - window.getHeight() - WINDOW_GAP);
  160. }
  161. }
  162. } else if ("close".equals(policy)) {
  163. // Close existing windows and use their place
  164. closeAll();
  165. }
  166. return y;
  167. }
  168. /**
  169. * Closes all open OSD windows.
  170. */
  171. protected static void closeAll() {
  172. for (OsdWindow window : new ArrayList<OsdWindow>(windows)) {
  173. window.setVisible(false);
  174. window.dispose();
  175. }
  176. }
  177. /**
  178. * {@inheritDoc}
  179. *
  180. * @param e Mouse event
  181. */
  182. @Override
  183. public void mouseClicked(final MouseEvent e) {
  184. if (!config) {
  185. setVisible(false);
  186. dispose();
  187. }
  188. }
  189. /**
  190. * {@inheritDoc}
  191. *
  192. * @param e Mouse event
  193. */
  194. @Override
  195. public void mousePressed(final MouseEvent e) {
  196. if (config) {
  197. startX = e.getPoint().x;
  198. startY = e.getPoint().y;
  199. }
  200. }
  201. /**
  202. * {@inheritDoc}
  203. *
  204. * @param e Mouse event
  205. */
  206. @Override
  207. public void mouseReleased(final MouseEvent e) {
  208. // Do nothing
  209. }
  210. /**
  211. * {@inheritDoc}
  212. *
  213. * @param e Mouse event
  214. */
  215. @Override
  216. public void mouseEntered(final MouseEvent e) {
  217. // Do nothing
  218. }
  219. /**
  220. * {@inheritDoc}
  221. *
  222. * @param e Mouse event
  223. */
  224. @Override
  225. public void mouseExited(final MouseEvent e) {
  226. // Do nothing
  227. }
  228. /**
  229. * {@inheritDoc}
  230. *
  231. * @param e Mouse event
  232. */
  233. @Override
  234. public void mouseDragged(final MouseEvent e) {
  235. final Point p = e.getLocationOnScreen();
  236. p.translate(-1 * startX, -1 * startY);
  237. setLocation(p);
  238. }
  239. /**
  240. * {@inheritDoc}
  241. *
  242. * @param e Mouse event
  243. */
  244. @Override
  245. public void mouseMoved(final MouseEvent e) {
  246. // Do nothing
  247. }
  248. /**
  249. * Sets the font size that this OSD uses.
  250. *
  251. * @param size The new size of the font
  252. */
  253. public void setFontSize(final int size) {
  254. label.setFont(label.getFont().deriveFont((float) size));
  255. }
  256. /**
  257. * Sets the background colour for this OSD.
  258. *
  259. * @param colour The background colour to use
  260. */
  261. public void setBackgroundColour(final String colour) {
  262. panel.setBackground(ColourManager.parseColour(colour));
  263. }
  264. /**
  265. * Sets the foreground colour for this OSD.
  266. *
  267. * @param colour The foreground colour to use
  268. */
  269. public void setForegroundColour(final String colour) {
  270. label.setForeground(ColourManager.parseColour(colour));
  271. }
  272. /** {@inheritDoc} */
  273. @Override
  274. public void setVisible(final boolean b) {
  275. super.setVisible(b);
  276. if (b) {
  277. windows.add(this);
  278. transferFocusBackward();
  279. }
  280. }
  281. /** {@inheritDoc} */
  282. @Override
  283. public void dispose() {
  284. super.dispose();
  285. windows.remove(this);
  286. }
  287. }