mirror of
https://gitlab.com/AutumnMeowMeow/jexer
synced 2024-09-19 11:50:19 -06:00
#83 underlay/overlay for windows
This commit is contained in:
parent
f513485b9e
commit
5339e760f5
8 changed files with 233 additions and 31 deletions
|
@ -46,6 +46,7 @@ import jexer.event.TMouseEvent;
|
|||
import jexer.event.TResizeEvent;
|
||||
import jexer.layout.LayoutManager;
|
||||
import jexer.menu.TMenu;
|
||||
import jexer.tackboard.Tackboard;
|
||||
import jexer.ttree.TTreeItem;
|
||||
import jexer.ttree.TTreeView;
|
||||
import jexer.ttree.TTreeViewWidget;
|
||||
|
@ -1427,6 +1428,12 @@ public abstract class TWidget implements Comparable<TWidget> {
|
|||
screen.setOffsetX(getAbsoluteX());
|
||||
screen.setOffsetY(getAbsoluteY());
|
||||
|
||||
// Hang onto these in case there is an overlay to draw
|
||||
int overlayClipRight = screen.getClipRight();
|
||||
int overlayClipBottom = screen.getClipBottom();
|
||||
int overlayOffsetX = screen.getOffsetX();
|
||||
int overlayOffsetY = screen.getOffsetY();
|
||||
|
||||
// Draw me
|
||||
draw();
|
||||
if (!isDrawable()) {
|
||||
|
@ -1452,6 +1459,20 @@ public abstract class TWidget implements Comparable<TWidget> {
|
|||
if (activeChild != null) {
|
||||
activeChild.drawChildren();
|
||||
}
|
||||
|
||||
// The TWindow overlay has to be here so that it can cover drawn
|
||||
// widgets.
|
||||
if (this instanceof TWindow) {
|
||||
Tackboard overlay = ((TWindow) this).overlay;
|
||||
if (overlay != null) {
|
||||
screen.setClipRight(overlayClipRight);
|
||||
screen.setClipBottom(overlayClipBottom);
|
||||
screen.setOffsetX(overlayOffsetX);
|
||||
screen.setOffsetY(overlayOffsetY);
|
||||
overlay.draw(getScreen(),
|
||||
getApplication().getBackend().isImagesOverText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,6 +41,8 @@ import jexer.event.TMenuEvent;
|
|||
import jexer.event.TMouseEvent;
|
||||
import jexer.event.TResizeEvent;
|
||||
import jexer.menu.TMenu;
|
||||
import jexer.tackboard.Tackboard;
|
||||
import jexer.tackboard.TackboardItem;
|
||||
import static jexer.TCommand.*;
|
||||
import static jexer.TKeypress.*;
|
||||
|
||||
|
@ -204,6 +206,18 @@ public class TWindow extends TWidget {
|
|||
*/
|
||||
protected String helpTopic = "Help";
|
||||
|
||||
/**
|
||||
* A means of drawing arbitrary items underneath all widgets on this
|
||||
* window.
|
||||
*/
|
||||
protected Tackboard underlay = null;
|
||||
|
||||
/**
|
||||
* A means of drawing arbitrary items on top of all widgets on this
|
||||
* window.
|
||||
*/
|
||||
protected Tackboard overlay = null;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constructors -----------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -925,7 +939,6 @@ public class TWindow extends TWidget {
|
|||
CellAttributes border = getBorder();
|
||||
CellAttributes background = getBackground();
|
||||
int borderType = getBorderType();
|
||||
|
||||
drawBox(0, 0, getWidth(), getHeight(), border, background, borderType,
|
||||
true);
|
||||
|
||||
|
@ -982,6 +995,15 @@ public class TWindow extends TWidget {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (underlay != null) {
|
||||
// This is a tad less slick that I want. I would prefer the
|
||||
// underlay to be fully contained within the window borders.
|
||||
// Putting it here means it can draw over the window edge.
|
||||
underlay.draw(getScreen(),
|
||||
getApplication().getBackend().isImagesOverText());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -1573,4 +1595,28 @@ public class TWindow extends TWidget {
|
|||
getX(), getY(), getWidth(), getHeight(), hidden, isModal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tackboard item to the underlay.
|
||||
*
|
||||
* @param item the item to add
|
||||
*/
|
||||
public void addUnderlay(final TackboardItem item) {
|
||||
if (underlay == null) {
|
||||
underlay = new Tackboard();
|
||||
}
|
||||
underlay.addItem(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tackboard item to the overlay.
|
||||
*
|
||||
* @param item the item to add
|
||||
*/
|
||||
public void addOverlay(final TackboardItem item) {
|
||||
if (overlay == null) {
|
||||
overlay = new Tackboard();
|
||||
}
|
||||
overlay.addItem(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -179,6 +179,15 @@ public class LogicalScreen implements Screen {
|
|||
this.offsetX = offsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get drawing offset for x.
|
||||
*
|
||||
* @return the drawing offset
|
||||
*/
|
||||
public int getOffsetX() {
|
||||
return offsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set drawing offset for y.
|
||||
*
|
||||
|
@ -188,6 +197,15 @@ public class LogicalScreen implements Screen {
|
|||
this.offsetY = offsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get drawing offset for y.
|
||||
*
|
||||
* @return the drawing offset
|
||||
*/
|
||||
public int getOffsetY() {
|
||||
return offsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get right drawing clipping boundary.
|
||||
*
|
||||
|
@ -299,7 +317,7 @@ public class LogicalScreen implements Screen {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the cell at one location.
|
||||
* Get the cell at one location in absolute coordinates.
|
||||
*
|
||||
* @param x column coordinate. 0 is the left-most column.
|
||||
* @param y row coordinate. 0 is the top-most row.
|
||||
|
@ -313,6 +331,41 @@ public class LogicalScreen implements Screen {
|
|||
return cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cell at one location, in either absolute or clipped
|
||||
* coordinates.
|
||||
*
|
||||
* @param x column coordinate. 0 is the left-most column.
|
||||
* @param y row coordinate. 0 is the top-most row.
|
||||
* @param clip if true, honor clipping/offset
|
||||
*
|
||||
* @return the character + attributes, or null if this position is
|
||||
* outside the clipping/offset region
|
||||
*/
|
||||
public Cell getCharXY(final int x, final int y, final boolean clip) {
|
||||
int X = x;
|
||||
int Y = y;
|
||||
|
||||
if (clip) {
|
||||
if ((x < clipLeft)
|
||||
|| (x >= clipRight)
|
||||
|| (y < clipTop)
|
||||
|| (y >= clipBottom)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
X += offsetX;
|
||||
Y += offsetY;
|
||||
}
|
||||
|
||||
if ((X >= 0) && (X < width) && (Y >= 0) && (Y < height)) {
|
||||
Cell cell = new Cell();
|
||||
cell.setTo(logical[X][Y]);
|
||||
return cell;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attributes at one location.
|
||||
*
|
||||
|
|
|
@ -81,6 +81,20 @@ public class MultiScreen implements Screen {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get drawing offset for x.
|
||||
*
|
||||
* @return the drawing offset
|
||||
*/
|
||||
public int getOffsetX() {
|
||||
synchronized (screens) {
|
||||
if (screens.size() > 0) {
|
||||
return screens.get(0).getOffsetX();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set drawing offset for y.
|
||||
*
|
||||
|
@ -94,6 +108,20 @@ public class MultiScreen implements Screen {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get drawing offset for y.
|
||||
*
|
||||
* @return the drawing offset
|
||||
*/
|
||||
public int getOffsetY() {
|
||||
synchronized (screens) {
|
||||
if (screens.size() > 0) {
|
||||
return screens.get(0).getOffsetY();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get right drawing clipping boundary.
|
||||
*
|
||||
|
@ -251,6 +279,26 @@ public class MultiScreen implements Screen {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cell at one location, in either absolute or clipped
|
||||
* coordinates.
|
||||
*
|
||||
* @param x column coordinate. 0 is the left-most column.
|
||||
* @param y row coordinate. 0 is the top-most row.
|
||||
* @param clip if true, honor clipping/offset
|
||||
*
|
||||
* @return the character + attributes, or null if this position is
|
||||
* outside the clipping/offset region
|
||||
*/
|
||||
public Cell getCharXY(final int x, final int y, final boolean clip) {
|
||||
synchronized (screens) {
|
||||
if (screens.size() > 0) {
|
||||
return screens.get(0).getCharXY(x, y, clip);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attributes at one location.
|
||||
*
|
||||
|
|
|
@ -44,6 +44,13 @@ public interface Screen {
|
|||
*/
|
||||
public void setOffsetX(final int offsetX);
|
||||
|
||||
/**
|
||||
* Get drawing offset for x.
|
||||
*
|
||||
* @return the drawing offset
|
||||
*/
|
||||
public int getOffsetX();
|
||||
|
||||
/**
|
||||
* Set drawing offset for y.
|
||||
*
|
||||
|
@ -51,6 +58,13 @@ public interface Screen {
|
|||
*/
|
||||
public void setOffsetY(final int offsetY);
|
||||
|
||||
/**
|
||||
* Get drawing offset for y.
|
||||
*
|
||||
* @return the drawing offset
|
||||
*/
|
||||
public int getOffsetY();
|
||||
|
||||
/**
|
||||
* Get right drawing clipping boundary.
|
||||
*
|
||||
|
@ -125,7 +139,7 @@ public interface Screen {
|
|||
public CellAttributes getAttrXY(final int x, final int y);
|
||||
|
||||
/**
|
||||
* Get the cell at one location.
|
||||
* Get the cell at one location in absolute coordinates.
|
||||
*
|
||||
* @param x column coordinate. 0 is the left-most column.
|
||||
* @param y row coordinate. 0 is the top-most row.
|
||||
|
@ -133,6 +147,19 @@ public interface Screen {
|
|||
*/
|
||||
public Cell getCharXY(final int x, final int y);
|
||||
|
||||
/**
|
||||
* Get the cell at one location, in either absolute or clipped
|
||||
* coordinates.
|
||||
*
|
||||
* @param x column coordinate. 0 is the left-most column.
|
||||
* @param y row coordinate. 0 is the top-most row.
|
||||
* @param clip if true, honor clipping/offset
|
||||
*
|
||||
* @return the character + attributes, or null if this position is
|
||||
* outside the clipping/offset region
|
||||
*/
|
||||
public Cell getCharXY(final int x, final int y, final boolean clip);
|
||||
|
||||
/**
|
||||
* Set the attributes at one location.
|
||||
*
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.awt.image.BufferedImage;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import javax.imageio.ImageIO;
|
||||
|
@ -49,7 +50,6 @@ import jexer.TWindow;
|
|||
import jexer.event.TCommandEvent;
|
||||
import jexer.layout.StretchLayoutManager;
|
||||
import jexer.tackboard.Bitmap;
|
||||
import jexer.tackboard.Tackboard;
|
||||
import jexer.tackboard.TackboardItem;
|
||||
import static jexer.TCommand.*;
|
||||
import static jexer.TKeypress.*;
|
||||
|
@ -113,11 +113,6 @@ public class DemoMainWindow extends TWindow {
|
|||
*/
|
||||
TProgressBar progressBar2;
|
||||
|
||||
/**
|
||||
* Tackboard can display pixels over text.
|
||||
*/
|
||||
Tackboard tackboard = new Tackboard();
|
||||
|
||||
/**
|
||||
* Direction for the bitmaps to move.
|
||||
*/
|
||||
|
@ -321,13 +316,20 @@ public class DemoMainWindow extends TWindow {
|
|||
loader = Thread.currentThread().getContextClassLoader();
|
||||
BufferedImage image;
|
||||
image = ImageIO.read(loader.getResource("trans_icon.png"));
|
||||
tackboard.addItem(new Bitmap(17, 41, 0, image));
|
||||
tackboard.addItem(new Bitmap(41, 97, 0, image));
|
||||
addUnderlay(new Bitmap(17, 33, 0, image));
|
||||
addOverlay(new Bitmap(41, 97, 0, image));
|
||||
|
||||
timer3 = getApplication().addTimer(100, true,
|
||||
new TAction() {
|
||||
public void DO() {
|
||||
List<TackboardItem> items = tackboard.getItems();
|
||||
List<TackboardItem> items;
|
||||
items = new ArrayList<TackboardItem>();
|
||||
if (underlay != null) {
|
||||
items.addAll(underlay.getItems());
|
||||
}
|
||||
if (overlay != null) {
|
||||
items.addAll(overlay.getItems());
|
||||
}
|
||||
int i = 0;
|
||||
for (TackboardItem item: items) {
|
||||
i++;
|
||||
|
@ -393,19 +395,6 @@ public class DemoMainWindow extends TWindow {
|
|||
// TWindow ----------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Show the bitmap(s) on the Tackboard.
|
||||
*/
|
||||
@Override
|
||||
public void draw() {
|
||||
super.draw();
|
||||
|
||||
// For this one, render to the entire screen, not to the window.
|
||||
getScreen().resetClipping();
|
||||
tackboard.draw(getScreen(),
|
||||
getApplication().getBackend().isImagesOverText());
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to override onClose so that the timer will no longer be called
|
||||
* after we close the window. TTimers currently are completely unaware
|
||||
|
|
|
@ -208,9 +208,13 @@ public class Tackboard {
|
|||
break;
|
||||
}
|
||||
|
||||
// This cell is visible on the screen.
|
||||
assert (sx + textX + left < screen.getWidth());
|
||||
assert (sy + textY + top < screen.getHeight());
|
||||
Cell oldCell = screen.getCharXY(sx + textX + left,
|
||||
sy + textY + top, true);
|
||||
if (oldCell == null) {
|
||||
// This image fragment would not be visible on the
|
||||
// screen.
|
||||
continue;
|
||||
}
|
||||
|
||||
BufferedImage newImage;
|
||||
newImage = image.getSubimage(sx * cellWidth,
|
||||
|
@ -224,8 +228,6 @@ public class Tackboard {
|
|||
// newImage has the image that needs to be overlaid on
|
||||
// (sx + textX + left, sy + textY + top)
|
||||
|
||||
Cell oldCell = screen.getCharXY(sx + textX + left,
|
||||
sy + textY + top);
|
||||
if (oldCell.isImage()) {
|
||||
// Blit this image over that one.
|
||||
BufferedImage oldImage = oldCell.getImage();
|
||||
|
|
|
@ -44,6 +44,11 @@ public class TackboardItem implements Comparable<TackboardItem> {
|
|||
// Variables --------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The board this item is on.
|
||||
*/
|
||||
private Tackboard tackboard;
|
||||
|
||||
/**
|
||||
* X pixel coordinate.
|
||||
*/
|
||||
|
@ -179,7 +184,8 @@ public class TackboardItem implements Comparable<TackboardItem> {
|
|||
return false;
|
||||
}
|
||||
TackboardItem that = (TackboardItem) rhs;
|
||||
return ((this.x == that.x)
|
||||
return ((this.tackboard == that.tackboard)
|
||||
&& (this.x == that.x)
|
||||
&& (this.y == that.y)
|
||||
&& (this.z == that.z));
|
||||
}
|
||||
|
@ -241,4 +247,14 @@ public class TackboardItem implements Comparable<TackboardItem> {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this item from its board.
|
||||
*/
|
||||
final public void remove() {
|
||||
if (tackboard != null) {
|
||||
tackboard.getItems().remove(this);
|
||||
}
|
||||
tackboard = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue