-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactored AlphaImage into PictureButton
- Loading branch information
Showing
6 changed files
with
210 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package control | ||
|
||
import util.* | ||
import java.awt.Color | ||
import java.awt.Dimension | ||
import java.awt.Insets | ||
import java.awt.image.BufferedImage | ||
import java.io.File | ||
import javax.imageio.ImageIO | ||
import javax.swing.ImageIcon | ||
import javax.swing.JButton | ||
import javax.swing.SwingConstants | ||
|
||
/** | ||
* a container for an image source. To be used in `PicturePanel` | ||
* @param source the source for the image. This must be in one of the Dungeon Board folders | ||
* @author [email protected] | ||
* @since 3.0.1 | ||
*/ | ||
class PictureButton( | ||
private val source: File, | ||
private val listener: Listener | ||
) { | ||
interface Listener { | ||
|
||
/** | ||
* called when an image is selected or deselected | ||
* @param button the button that was clicked | ||
* @param isEnabled the new state of the button | ||
*/ | ||
fun onChange(button: PictureButton, isEnabled: Boolean) | ||
} | ||
|
||
companion object { | ||
|
||
/** | ||
* The size of the `ImageIcon` in each of the buttons | ||
*/ | ||
private val IMAGE_ICON_SIZE = Dimension(100, 60) | ||
} | ||
|
||
/** | ||
* the file used to load the image | ||
*/ | ||
private val mode = Settings.getFileMode(source) ?: throw IllegalArgumentException("invalid source") | ||
|
||
/** | ||
* the thumbnail file for this image | ||
*/ | ||
private val thumbnailSource = File(Settings.getDataFolder(mode), source.name) | ||
|
||
/** | ||
* whether the button is currently enabled or disabled | ||
*/ | ||
private var isEnabled = false | ||
|
||
/** | ||
* button that controls whether the image should be displayed | ||
*/ | ||
val button = JButton(source.nameWithoutExtension).also { button -> | ||
button.margin = Insets(0, 0, 0, 0) | ||
button.isFocusPainted = false | ||
button.verticalTextPosition = SwingConstants.TOP | ||
button.horizontalTextPosition = SwingConstants.CENTER | ||
button.background = Colors.DISABLE_COLOR | ||
|
||
button.addActionListener { | ||
val isEnabled = !isEnabled | ||
listener.onChange(this, isEnabled) | ||
setEnabled(isEnabled) | ||
} | ||
} | ||
|
||
init { | ||
if (!thumbnailSource.exists() || source.lastModified() > thumbnailSource.lastModified()) { | ||
try { | ||
val bufferedImage = BufferedImage( | ||
IMAGE_ICON_SIZE.width, | ||
IMAGE_ICON_SIZE.height, | ||
BufferedImage.TYPE_INT_RGB | ||
) | ||
bufferedImage.graphics.drawImage( | ||
ImageIO.read(source).getScaledInstance( | ||
IMAGE_ICON_SIZE.width, | ||
IMAGE_ICON_SIZE.height, | ||
BufferedImage.SCALE_SMOOTH | ||
), | ||
0, | ||
0, | ||
null | ||
) | ||
ImageIO.write(bufferedImage, "GIF", thumbnailSource) | ||
} catch (e: Exception) { | ||
Log.error(Labels.CANNOT_CREATE_THUMBNAIL, e) | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* changes the button's visual appearance | ||
* @param isEnabled whether the button should be enabled | ||
*/ | ||
fun setEnabled(isEnabled: Boolean) { | ||
this.isEnabled = isEnabled | ||
|
||
button.background = when(this.isEnabled) { | ||
true -> Colors.ENABLE_COLOR | ||
false -> Colors.DISABLE_COLOR | ||
} | ||
} | ||
|
||
/** | ||
* loads the thumbnail from file | ||
*/ | ||
fun load() { | ||
try { | ||
button.icon = ImageIcon(ImageIO.read(thumbnailSource)) | ||
} catch (e: Exception) { | ||
Log.error(Labels.CANNOT_LOAD_THUMBNAIL, e) | ||
} | ||
} | ||
|
||
/** | ||
* removes the thumbnail from local memory | ||
*/ | ||
fun unload() { | ||
button.icon = null | ||
} | ||
|
||
/** | ||
* the `BufferedImage` from the file | ||
*/ | ||
fun readImage(): BufferedImage { | ||
return try { | ||
ImageIO.read(source) | ||
} catch (e: Exception) { | ||
Log.error(String.format(Labels.CANNOT_LOAD_IMAGE, source), e) | ||
Resources.BLANK_CURSOR | ||
} | ||
} | ||
|
||
/** | ||
* the background color of the image by using the top left corner pixel | ||
*/ | ||
fun getBackgroundColor(): Color { | ||
return try { | ||
Color(ImageIO.read(thumbnailSource).getRGB(0, 0)) | ||
} catch (e: Exception) { | ||
Log.error(String.format(Labels.CANNOT_LOAD_IMAGE_RGB, thumbnailSource), e) | ||
Color.BLACK | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,20 @@ | ||
package control | ||
|
||
import util.Colors | ||
import util.Labels | ||
import util.Log | ||
import java.awt.Dimension | ||
import main.Mode | ||
import java.awt.GridLayout | ||
import java.awt.Insets | ||
import java.awt.image.BufferedImage | ||
import java.io.File | ||
import javax.imageio.ImageIO | ||
import javax.swing.* | ||
import javax.swing.BorderFactory | ||
import javax.swing.JPanel | ||
|
||
/** | ||
* a scroll menu to display images on as buttons | ||
* @param thumbnailFolder directory to hold thumbnail caches | ||
* @param mode directory to hold thumbnail caches | ||
* @author [email protected] | ||
* @since 1.0 | ||
*/ | ||
abstract class PicturePanel( | ||
private val thumbnailFolder: File | ||
) : JPanel() { | ||
private val mode: Mode | ||
) : JPanel(), PictureButton.Listener { | ||
|
||
companion object { | ||
|
||
|
@@ -29,114 +24,44 @@ abstract class PicturePanel( | |
* The number of picture per row of a picture panel | ||
*/ | ||
private const val GRID_WIDTH = 4 | ||
|
||
/** | ||
* The size of the `ImageIcon` in each of the buttons | ||
*/ | ||
private val IMAGE_ICON_SIZE = Dimension(100, 60) | ||
} | ||
|
||
protected val buttons = mutableListOf<PictureButton>() | ||
|
||
init { | ||
layout = GridLayout(0, GRID_WIDTH) | ||
border = BorderFactory.createEmptyBorder() | ||
} | ||
|
||
/** | ||
* creates a button for a `PicturePanel` by loading an image from file | ||
* @param file the file of an image to add | ||
* @return a button with the proper settings for a `PicturePanel` | ||
* creates a button for the `PicturePanel` by loading an image from file | ||
* @param source the file of an image to add | ||
*/ | ||
fun createPPButton(file: File): JButton { | ||
createThumbnail(file) | ||
|
||
return JButton(file.name).apply { | ||
margin = Insets(0, 0, 0, 0) | ||
isFocusPainted = false | ||
verticalTextPosition = SwingConstants.TOP | ||
horizontalTextPosition = SwingConstants.CENTER | ||
background = Colors.DISABLE_COLOR | ||
addActionListener { | ||
val button = it.source as JButton | ||
val name = button.text | ||
if (button.background === Colors.DISABLE_COLOR) { | ||
select(name) | ||
button.background = Colors.ENABLE_COLOR | ||
} else { | ||
deselect(name) | ||
button.background = Colors.DISABLE_COLOR | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* re-sizes an image and saves a lower quality version as a thumbnail | ||
* @param file the file input of the full size image | ||
*/ | ||
private fun createThumbnail(file: File) { | ||
val tFile = File(thumbnailFolder, file.name) | ||
if (!tFile.exists() || file.lastModified() > tFile.lastModified()) { | ||
try { | ||
val bufferedImage = BufferedImage( | ||
IMAGE_ICON_SIZE.width, | ||
IMAGE_ICON_SIZE.height, | ||
BufferedImage.TYPE_INT_RGB | ||
) | ||
bufferedImage.graphics.drawImage( | ||
ImageIO.read(file).getScaledInstance( | ||
IMAGE_ICON_SIZE.width, | ||
IMAGE_ICON_SIZE.height, | ||
BufferedImage.SCALE_SMOOTH | ||
), | ||
0, 0, null | ||
) | ||
ImageIO.write(bufferedImage, "GIF", tFile) | ||
} catch (e: Exception) { | ||
Log.error(Labels.CANNOT_CREATE_THUMBNAIL, e) | ||
} | ||
} | ||
} | ||
fun addPicture(source: File) { | ||
val pictureButton = PictureButton(source, this) | ||
|
||
/** | ||
* removes all images | ||
*/ | ||
fun clearButtons() { | ||
components.filterIsInstance<JButton>().forEach { | ||
remove(it) | ||
} | ||
buttons.add(pictureButton) | ||
} | ||
|
||
/** | ||
* called when an image is selected | ||
* @param name the name of the image | ||
*/ | ||
protected abstract fun select(name: String) | ||
|
||
/** | ||
* called when an image is deselected | ||
* @param name the name of the image | ||
*/ | ||
protected abstract fun deselect(name: String) | ||
|
||
/** | ||
* loads the thumbnails from file | ||
*/ | ||
fun rememberThumbnails() { | ||
components.filterIsInstance<JButton>().forEach { | ||
try { | ||
it.icon = ImageIcon(ImageIO.read(File(thumbnailFolder, it.text))) | ||
} catch (e: Exception) { | ||
Log.error(Labels.CANNOT_LOAD_THUMBNAIL, e) | ||
} | ||
fun loadButtons() { | ||
buttons.forEach { | ||
it.load() | ||
add(it.button) | ||
} | ||
} | ||
|
||
/** | ||
* removes the thumbnails from local memory | ||
*/ | ||
fun forgetThumbnails() { | ||
components.filterIsInstance<JButton>().forEach { | ||
it.icon = null | ||
fun unloadButtons() { | ||
buttons.forEach { | ||
it.unload() | ||
remove(it.button) | ||
} | ||
} | ||
|
||
abstract override fun onChange(button: PictureButton, isEnabled: Boolean) | ||
} |
Oops, something went wrong.