Commit 2dd8ca4b authored by Daniel Dreibrodt's avatar Daniel Dreibrodt

Toolbar update, save toolbar position between sessions

parent fe595b14
......@@ -2,6 +2,10 @@ VLC Skin Editor release 0.8.1
-----------------------------------------------------------
Changelog:
-----------------------------------------------------------
0.8.5 - Various bugfixes and technical improvements
- A toolbar was added
- Sliders can be edited in the preview window
0.8.1 - Font rendering bugfix
- Anchor points saving bugfix
......@@ -90,8 +94,19 @@ approximately at least 256MB RAM and a 1GHz CPU
-----------------------------------------------------------
Usage:
-----------------------------------------------------------
To run the skin editor simply open the jar file.
Or manually run "java -jar VLCSkinEditor.jar".
On Windows launch the VLCSkinEditor executable.
On Linux run the VLCSkinEditor launch script.
Also you can run the skin editor by launching the jar file.
You can do this by running "java -jar VLCSkinEditor.jar".
Make sure that you run
-----------------------------------------------------------
Support:
-----------------------------------------------------------
There exists an online help & documentation at
http://www.videolan.org/vlc/skinedhlp
Furthermore you can ask questions in the VideoLAN forum at
http://forum.videolan.org/viewforum.php?f=15
-----------------------------------------------------------
Copyright:
-----------------------------------------------------------
......
......@@ -22,6 +22,7 @@
package vlcskineditor;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
......@@ -39,6 +40,7 @@ public class Config {
private static Hashtable<String, String> strings = new Hashtable<String, String>();
private static File configFile;
private static Main mainInstance;
static {
//Default values
......@@ -62,6 +64,11 @@ public class Config {
strings.put("win.items.height","200");
strings.put("swing.laf","System");
strings.put("toolbar","true");
strings.put("toolbar.floating", "false");
strings.put("toolbar.constraints", BorderLayout.PAGE_START);
strings.put("toolbar.x","0");
strings.put("toolbar.y","0");
strings.put("toolbar.orientation", String.valueOf(JToolBar.HORIZONTAL));
//Locate the config file
if(System.getProperty("os.name").indexOf("Windows")!=-1) {
......@@ -195,8 +202,14 @@ public class Config {
strings.put("autoupdate", String.valueOf(update_cb.isSelected()));
strings.put("language", ((Language)lang_cb.getSelectedItem()).getCode());
strings.put("swing.laf", (String)laf_cb.getSelectedItem());
strings.put("toolbar", String.valueOf(update_cb.isSelected()));
boolean toolbar = Boolean.parseBoolean(get("toolbar"));
strings.put("toolbar", String.valueOf(tbar_cb.isSelected()));
if(!toolbar && Boolean.parseBoolean(get("toolbar"))) {
mainInstance.showToolbar();
}
if(toolbar && !Boolean.parseBoolean(get("toolbar"))) {
mainInstance.hideToolbar();
}
frame.setVisible(false);
frame.dispose();
}
......@@ -273,5 +286,9 @@ public class Config {
frame.setResizable(false);
frame.setVisible(true);
}
public static void setMainInstance(Main m) {
mainInstance = m;
}
}
\ No newline at end of file
......@@ -35,6 +35,7 @@ import java.util.zip.*;
import vlcskineditor.items.*;
import com.ice.tar.*;
import com.ice.jni.registry.*;
import javax.swing.plaf.basic.BasicToolBarUI;
import javax.swing.plaf.metal.*;
import vlcskineditor.history.*;
import vlcskineditor.resources.Bitmap;
......@@ -60,6 +61,9 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
/** The directory from which VLC loads its skins */
private String vlc_skins_dir = "";
/** The main window layout */
BorderLayout layout;
/** The menu bar */
private JMenuBar mbar;
/** The menus */
......@@ -160,7 +164,9 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
* @param args Command line arguments passed by the console.
* If there exist one or more arguments, the first argument is intepreted as a file locator for a skin to be loaded.
*/
public Main(String[] args) {
public Main(String[] args) {
Config.setMainInstance(this);
setTitle("VLC Skin Editor "+VERSION);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(this);
......@@ -300,54 +306,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
mbar.add(m_edit);
mbar.add(m_help);
setJMenuBar(mbar);
//Toolbar
if(Boolean.parseBoolean(Config.get("toolbar"))) {
tbar = new JToolBar();
//tbar.setFloatable(false);
//Toolbar elements
tbar_open_btn = new JButton();
tbar_open_btn.setIcon(createIcon("icons/tbar_open.png"));
tbar_open_btn.setToolTipText(Language.get("TOOLBAR_OPEN"));
tbar_open_btn.addActionListener(this);
tbar.add(tbar_open_btn);
tbar_save_btn = new JButton();
tbar_save_btn.setIcon(createIcon("icons/tbar_save.png"));
tbar_save_btn.setToolTipText(Language.get("TOOLBAR_SAVE"));
tbar_save_btn.addActionListener(this);
tbar.add(tbar_save_btn);
JToolBar.Separator tbar_sep_1 = new JToolBar.Separator(new Dimension(10,22));
tbar_sep_1.setOrientation(JSeparator.VERTICAL);
tbar.add(tbar_sep_1);
tbar_undo_btn = new JButton();
tbar_undo_btn.setIcon(createIcon("icons/tbar_undo.png"));
tbar_undo_btn.setToolTipText(Language.get("TOOLBAR_UNDO"));
tbar_undo_btn.addActionListener(this);
tbar.add(tbar_undo_btn);
tbar_redo_btn = new JButton();
tbar_redo_btn.setIcon(createIcon("icons/tbar_redo.png"));
tbar_redo_btn.setToolTipText(Language.get("TOOLBAR_REDO"));
tbar_redo_btn.addActionListener(this);
tbar.add(tbar_redo_btn);
JToolBar.Separator tbar_sep_2 = new JToolBar.Separator(new Dimension(10,22));
tbar_sep_2.setOrientation(JSeparator.VERTICAL);
tbar.add(tbar_sep_2);
tbar_move_btn = new JButton();
tbar_move_btn.setIcon(createIcon("icons/tbar_move.png"));
tbar_move_btn.setToolTipText(Language.get("TOOLBAR_MOVE"));
tbar_move_btn.addActionListener(this);
tbar_move_btn.setSelected(true);
tbar.add(tbar_move_btn);
tbar_path_btn = new JButton();
tbar_path_btn.setIcon(createIcon("icons/tbar_path.png"));
tbar_path_btn.setToolTipText(Language.get("TOOLBAR_PATH"));
tbar_path_btn.addActionListener(this);
tbar.add(tbar_path_btn);
add(tbar);
}
setJMenuBar(mbar);
//Resources, window and item windows
......@@ -670,21 +629,17 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
items_add_pu_video = new JMenuItem(Language.get("VIDEO"));
items_add_pu_video.addActionListener(this);
items_add_pu.add(items_add_pu_video);
jdesk.add(items_add_pu);
add(jdesk);
jdesk.add(items_add_pu);
//Main window layout
layout = new BorderLayout();
setLayout(layout);
add(jdesk, BorderLayout.CENTER);
if(Boolean.parseBoolean(Config.get("toolbar"))) {
SpringLayout layout = new SpringLayout();
layout.putConstraint(SpringLayout.NORTH, tbar, 0, SpringLayout.NORTH, getContentPane());
layout.putConstraint(SpringLayout.WEST, tbar, 0, SpringLayout.WEST, getContentPane());
layout.putConstraint(SpringLayout.EAST, tbar, 0, SpringLayout.EAST, getContentPane());
layout.putConstraint(SpringLayout.NORTH, jdesk, 0, SpringLayout.SOUTH, tbar);
layout.putConstraint(SpringLayout.WEST, jdesk, 0, SpringLayout.WEST, getContentPane());
layout.putConstraint(SpringLayout.EAST, getContentPane(), 0, SpringLayout.EAST, jdesk);
layout.putConstraint(SpringLayout.SOUTH, getContentPane(), 0, SpringLayout.SOUTH, jdesk);
setLayout(layout);
showToolbar();
} else {
hideToolbar();
}
setMinimumSize(new Dimension(800,600));
......@@ -736,6 +691,101 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
else base_fc.setCurrentDirectory(new File(Config.get("open.folder")));
}
public void showToolbar() {
if(tbar!=null) remove(tbar);
else initToolbar();
tbar.setOrientation(Config.getInt("toolbar.orientation"));
add(tbar, Config.get("toolbar.constraints"));
layout.layoutContainer(getContentPane());
tbar.doLayout();
if(Boolean.parseBoolean(Config.get("toolbar.floating"))) {
((BasicToolBarUI)tbar.getUI()).setFloating(true, new Point(Config.getInt("toolbar.x"), Config.getInt("toolbar.y")));
Component c = tbar;
while( !c.getClass().toString().endsWith("ToolBarDialog") ) {
c = c.getParent();
}
c.setLocation(Config.getInt("toolbar.x"), Config.getInt("toolbar.y"));
}
}
public void hideToolbar() {
if(tbar==null) return;
saveToolbarState();
if(((BasicToolBarUI)tbar.getUI()).isFloating()) {
((BasicToolBarUI)tbar.getUI()).setFloating(false, new Point(0,0));
}
remove(tbar);
layout.layoutContainer(getContentPane());
}
private void initToolbar() {
tbar = new JToolBar();
//tbar.setFloatable(false);
//Toolbar elements
tbar_open_btn = new JButton();
tbar_open_btn.setIcon(createIcon("icons/tbar_open.png"));
tbar_open_btn.setToolTipText(Language.get("TOOLBAR_OPEN"));
tbar_open_btn.addActionListener(this);
tbar.add(tbar_open_btn);
tbar_save_btn = new JButton();
tbar_save_btn.setIcon(createIcon("icons/tbar_save.png"));
tbar_save_btn.setToolTipText(Language.get("TOOLBAR_SAVE"));
tbar_save_btn.addActionListener(this);
tbar.add(tbar_save_btn);
JToolBar.Separator tbar_sep_1 = new JToolBar.Separator(/*new Dimension(10,22)*/);
tbar_sep_1.setOrientation(JSeparator.VERTICAL);
tbar.add(tbar_sep_1);
tbar_undo_btn = new JButton();
tbar_undo_btn.setIcon(createIcon("icons/tbar_undo.png"));
tbar_undo_btn.setToolTipText(Language.get("TOOLBAR_UNDO"));
tbar_undo_btn.addActionListener(this);
tbar.add(tbar_undo_btn);
tbar_redo_btn = new JButton();
tbar_redo_btn.setIcon(createIcon("icons/tbar_redo.png"));
tbar_redo_btn.setToolTipText(Language.get("TOOLBAR_REDO"));
tbar_redo_btn.addActionListener(this);
tbar.add(tbar_redo_btn);
JToolBar.Separator tbar_sep_2 = new JToolBar.Separator(/*new Dimension(10,22)*/);
tbar_sep_2.setOrientation(JSeparator.VERTICAL);
tbar.add(tbar_sep_2);
tbar_move_btn = new JButton();
tbar_move_btn.setIcon(createIcon("icons/tbar_move.png"));
tbar_move_btn.setToolTipText(Language.get("TOOLBAR_MOVE"));
tbar_move_btn.addActionListener(this);
tbar_move_btn.setSelected(true);
tbar.add(tbar_move_btn);
tbar_path_btn = new JButton();
tbar_path_btn.setIcon(createIcon("icons/tbar_path.png"));
tbar_path_btn.setToolTipText(Language.get("TOOLBAR_PATH"));
tbar_path_btn.addActionListener(this);
tbar.add(tbar_path_btn);
}
private void saveToolbarState() {
if(tbar!=null && layout.getConstraints(tbar)!=null && !layout.getConstraints(tbar).equals("null"))
Config.set("toolbar.constraints", layout.getConstraints(tbar));
Config.set("toolbar.orientation", tbar.getOrientation());
if(((BasicToolBarUI)tbar.getUI()).isFloating()) {
Component c = tbar;
while( !c.getClass().toString().endsWith("ToolBarDialog") ) {
c = c.getParent();
}
System.out.println(c.getClass().toString());
System.out.println(c.getBounds());
System.out.println(c.getX()+":"+c.getY());
System.out.println(c.getParent().getClass().toString());
System.out.println(c.getParent().getBounds());
Config.set("toolbar.floating", true);
Config.set("toolbar.x", c.getX());
Config.set("toolbar.y", c.getY());
} else {
Config.set("toolbar.floating", false);
}
}
/**
* Shows a dialog from which the user can choose to either create a new skin, open an existing skin or quit the skin editor.
*/
......@@ -754,6 +804,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
exit();
}
}
/**
* Shows the "Open File" dialog.
*/
......@@ -794,6 +845,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
}
}
/**
* Opens the given file as a skin.
* @param f The skin file.
......@@ -913,6 +965,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
hist = new History(this);
s.gvars.sendUpdate();
}
/**
* Shows a dialog to specify the new skin's location and creates an empty skin.
*/
......@@ -936,6 +989,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
hist = new History(this);
}
}
/**
* Reacts to GUI actions
* @param e The performed action
......@@ -1790,20 +1844,23 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
/** Sets the activity state of the undo menu item to the given argument
* @param enabled Activity state
*/
public void setUndoEnabled(boolean enabled) {
m_edit_undo.setEnabled(enabled);
tbar_undo_btn.setEnabled(enabled);
if(tbar_undo_btn!=null) tbar_undo_btn.setEnabled(enabled);
}
/** Sets the activity state of the redo menu item to the given argument
* @param enabled Activity state
*/
public void setRedoEnabled(boolean enabled) {
m_edit_redo.setEnabled(enabled);
tbar_redo_btn.setEnabled(enabled);
if(tbar_redo_btn!=null) tbar_redo_btn.setEnabled(enabled);
}
/** Sets the action description that can be undone
* @param s Action description
*/
......@@ -1811,6 +1868,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
if(s.isEmpty()) m_edit_undo.setText(Language.get("MENU_EDIT_UNDO"));
else m_edit_undo.setText(Language.get("MENU_EDIT_UNDO")+": "+s);
}
/** Sets the action description that can be redone
* @param s Action description
*/
......@@ -1818,6 +1876,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
if(s.isEmpty()) m_edit_redo.setText(Language.get("MENU_EDIT_REDO"));
else m_edit_redo.setText(Language.get("MENU_EDIT_REDO")+": "+s);
}
/**
* Creates an ImageIcon of an image included in the JAR
* @param filename The path to the image file inside the JAR
......@@ -1995,6 +2054,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
Config.set("win.items.width",items.getWidth());
Config.set("win.items.height",items.getHeight());
if(base_fc!=null) Config.set("open.folder",base_fc.getCurrentDirectory().getAbsolutePath());
saveToolbarState();
Config.save();
System.exit(0);
}
......@@ -2038,7 +2098,7 @@ public class Main extends JFrame implements ActionListener, TreeSelectionListene
JFrame.setDefaultLookAndFeelDecorated(true);
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("com.apple.mrj.application.apple.menu.about.name", "VLC Skin Editor");
new Main(args);
new Main(args);
}
/**
......
/*****************************************************************************
* ToolbarButton.java
*****************************************************************************
* Copyright (C) 2009 Daniel Dreibrodt
*
* This file is part of VLC Skin Editor
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
package vlcskineditor;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
/**
* A toolbar image button, with hover effects
* @author Daniel Dreibrodt
*/
public class ToolbarButton extends JButton implements MouseListener {
/** The normal state image */
ImageIcon normal;
/** The mouse-over state image */
ImageIcon over;
/** The mouse-clicked state image */
ImageIcon down;
/** The isPressed state image */
ImageIcon pressed;
/** Indicates whether the mouse is currently hovering the button */
boolean hover = false;
/** Indicates whether this button is running under a Mac system, which implements its own hovering and clicking effects */
boolean mac = System.getProperty("os.name").indexOf("Mac") != -1;
/** Indicates that this button is in a isPressed state, e.g. a button setting a certain mode, if the mode is set than the button is in a isPressed state */
boolean isPressed = false;
/**
* Creates a new toolbar button
* @param img The button's icon
*/
public ToolbarButton(Image img) {
try {
normal = new ImageIcon(img);
BufferedImage icon = new BufferedImage(normal.getIconWidth(), normal.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
icon.getGraphics().drawImage(normal.getImage(), 0, 0, this);
if(!mac) {
BufferedImage ovbi = new BufferedImage(icon.getWidth(this), icon.getHeight(this), BufferedImage.TYPE_INT_ARGB);
for(int x = 0; x < icon.getWidth(this); x++) {
for(int y = 0; y < icon.getHeight(this); y++) {
Graphics g = ovbi.getGraphics();
int argb = icon.getRGB(x, y);
int red = (argb >> 16) & 0xff;
int green = (argb >> 8) & 0xff;
int blue = argb & 0xff;
int alpha = (argb >> 24) & 0xff;
g.setColor(brighter(new Color(red, green, blue, alpha), 0.92));
g.fillRect(x, y, 1, 1);
}
}
over = new ImageIcon(ovbi);
BufferedImage dobi = new BufferedImage(icon.getWidth(this), icon.getHeight(this), BufferedImage.TYPE_INT_ARGB);
for(int x = 0; x < icon.getWidth(this); x++) {
for(int y = 0; y < icon.getHeight(this); y++) {
Graphics g = dobi.getGraphics();
int argb = icon.getRGB(x, y);
int red = (argb >> 16) & 0xff;
int green = (argb >> 8) & 0xff;
int blue = argb & 0xff;
int alpha = (argb >> 24) & 0xff;
g.setColor(darker(new Color(red, green, blue, alpha), 0.92));
g.fillRect(x, y, 1, 1);
}
}
down = new ImageIcon(dobi);
BufferedImage prbi = new BufferedImage(icon.getWidth(this), icon.getHeight(this), BufferedImage.TYPE_INT_ARGB);
for(int x = 0; x < icon.getWidth(this); x++) {
for(int y = 0; y < icon.getHeight(this); y++) {
Graphics g = prbi.getGraphics();
int argb = icon.getRGB(x, y);
int red = (argb >> 16) & 0xff;
int green = (argb >> 8) & 0xff;
int blue = argb & 0xff;
int alpha = (argb >> 24) & 0xff;
g.setColor(darker(new Color(red, green, blue, alpha), 0.7));
g.fillRect(x, y, 1, 1);
}
}
pressed = new ImageIcon(prbi);
}
setIcon(normal);
setBorderPainted(false);
setContentAreaFilled(false);
setFocusPainted(false);
addMouseListener(this);
setPreferredSize(new Dimension(normal.getIconWidth() + 8, normal.getIconHeight() + 8));
} catch(Exception ex) {
ex.printStackTrace();
setText(" ");
}
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
if(mac||isPressed) {
return;
}
setIcon(down);
repaint();
}
public void mouseReleased(MouseEvent e) {
if(mac||isPressed) {
return;
}
if(hover) {
setIcon(over);
} else {
setIcon(normal);
}
repaint();
}
public void mouseEntered(MouseEvent e) {
if(mac||isPressed) {
return;
}
hover = true;
setIcon(over);
repaint();
}
public void mouseExited(MouseEvent e) {
if(mac||isPressed) {
return;
}
hover = false;
setIcon(normal);
repaint();
}
/**
* Calculates a brighter color which also supports alpha values
* Based upon java.awt.Color.brighter()
* @param c The source color
* @param factor The brightening factor
* @return The brighter color
*/
public Color brighter(Color c, double factor) {
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
int a = c.getAlpha();
/* From 2D group:
* 1. black.brighter() should return grey
* 2. applying brighter to blue will always return blue, brighter
* 3. non pure color (non zero rgb) will eventually return white
*/
int i = (int) (1.0 / (1.0 - factor));
if(r == 0 && g == 0 && b == 0) {
return new Color(i, i, i, a);
}
if(r > 0 && r < i) {
r = i;
}
if(g > 0 && g < i) {
g = i;
}
if(b > 0 && b < i) {
b = i;
}
return new Color(Math.min((int) (r / factor), 255),
Math.min((int) (g / factor), 255),
Math.min((int) (b / factor), 255),
a);
}
/**
* Calculates a darker color which also supports alpha values
* Based upon java.awt.Color.darker()
* @param c The source color
* @param factor The darkening factor (0-1), the closer to zero, the darker
* @return The darker color
*/
public Color darker(Color c, double factor) {
return new Color(Math.max((int) (c.getRed() * factor), 0),
Math.max((int) (c.getGreen() * factor), 0),
Math.max((int) (c.getBlue() * factor), 0),
c.getAlpha());
}
public void setPressed(boolean p) {
isPressed = p;
if(isPressed) setIcon(pressed);
else {
if(hover) setIcon(over);
else setIcon(normal);
}
repaint();
}
public boolean isPressed() {
return isPressed;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment