
jcurses.system.Toolkit Maven / Gradle / Ivy
package jcurses.system; import java.awt.Point; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import jcurses.util.Rectangle; /** * This class is the 'work factory' of the jcurses library. It contains * methods for primitive input and output operations and is only interface * to platform dependend libraries. An developer must not usually call methods of this * class, these are used implementing widgets and in jcurses core. */ public class Toolkit { public static final short CORNER_UNDER_LINE = 0; public static final short CORNER_OVER_LINE = 1; public static final short LL_CORNER = 2; public static final short LR_CORNER = 3; public static final short UL_CORNER = 4; public static final short UR_CORNER = 5; static final int VERTICAL = 0; static final int HORIZONTAL = 1; private static long [] __attributes = {0,0,0}; private static short [] __basicColors = {0,0,0,0,0,0,0,0}; private static short [] [] __colorpairs = new short [8] [8]; static { NativeLibrary.load(); fillBasicColors(__basicColors); fillAttributes(__attributes); fillColorPairs(); initEncoding(); init(); } private static Map
*/ public static native void endPainting(); /** * The method returns the screen width * * @return the screen height */ public static native int getScreenWidth(); /** * The method returns the screen height * * @return the screen height */ public static native int getScreenHeight(); /** * @return> __clips = new HashMap >(); /** * The method sets the clippping rectangle for the current thread. * All the output operations, that are performed by this thread after a call of this * method, will paint only within the clip rectangle. If other clips were set before this, * then the used clip rectangle is the intersection of all clip rectangles set by current thread. * * @param clipRect clip rectangle to be set */ public static void setClipRectangle(Rectangle clipRect) { List clips = __clips.get(Thread.currentThread()); if (clips == null) { clips = new ArrayList (); __clips.put(Thread.currentThread(), clips); } clips.add(clipRect); } /** * Removes the evtl. before set clip rectangle */ public static void unsetClipRectangle() { ArrayList clips = (ArrayList)__clips.get(Thread.currentThread()); if (clips == null) { return; } if (clips.size()>0) { clips.remove(clips.size()-1); } if (clips.size() == 0) { __clips.remove(Thread.currentThread()); } } private static Rectangle getCurrentClipRectangle() { ArrayList clips = (ArrayList)__clips.get(Thread.currentThread()); if ((clips == null) || (clips.size()==0)) { return null; } Rectangle result = (Rectangle)clips.get(0); for (int i=1; i startPainting true
if the terminal can color painting,false
otherwise. */ public static boolean hasColors() { return (hasColorsAsInteger()!=0); } private static native int hasColorsAsInteger(); /** * The method initializes the jcurses library, must be called only one time before * all painting and input operations. */ public static native void init(); /** * The method shuts down the jcurses library and recovers the terminal to the state before * jcurses application start. */ public static native void shutdown(); //Painting methods /** * The method clears the screen and fills it with the backround color ofcolor
* * @param color the color to fill the screen, only backround part is used. */ public static void clearScreen(CharColor color) { clearScreen(getColorPairNumber(color), __attributes[color.getColorAttribute()]); } private static native void clearScreen(short colorPairNumber, long attributes); /** * The method draws a rectangle on the screen, filled with background part of
color
* * @param rect rectangle ( that is, bounds of rectangle) to be painted * @param color color to fill the rectangle, only background part is used */ public static void drawRectangle(Rectangle rect, CharColor color) { Rectangle clipRect = getCurrentClipRectangle(); if (clipRect!=null) { rect = rect.intersection(clipRect); } if (!rect.isEmpty()) { drawRectangle(rect.getX(),rect.getY(),rect.getWidth(),rect.getHeight(), getColorPairNumber(color), __attributes[color.getColorAttribute()]); } } /** * The method draws a rectangle on the screen, filled with background part ofcolor
* * @param x the x coordinate of the top left corner of the rectangle to be painted * @param y the y coordinate of the top left corner of the rectangle to be painted * @param width the width of the rectangle to be painted * @param heigtht the height of the rectangle to be painted * @param color color to fill the rectangle, only background part is used */ public static void drawRectangle(int x, int y, int width, int height, CharColor color) { Rectangle rect = new Rectangle(x,y,width,height); drawRectangle(rect, color); } private static native void drawRectangle(int x, int y, int width, int height, short colorPairNumber, long attribute); private static boolean between(int begin, int end, int pos) { return ((begin <= pos) && (end >=pos)); } private static LinePart getLinePart(int begin, int end, int alignment, int position, Rectangle clipRect) { LinePart result = null; if (begin > end) { int tmp = end; end = begin; begin = tmp; } if (clipRect == null) { result = new LinePart(begin,end,alignment); } else { if ((alignment == VERTICAL) && (!between(clipRect.getX(),clipRect.getX()+clipRect.getWidth()-1,position))) { result = new LinePart(); } else if ((alignment == HORIZONTAL) && (!between(clipRect.getY(),clipRect.getY()+clipRect.getHeight()-1,position))) { result = new LinePart(); } else { if (alignment == VERTICAL) { result = new LinePart(Math.max(clipRect.getY(),begin),Math.min(clipRect.getY()+clipRect.getHeight()-1,end),alignment); } else { result = new LinePart(Math.max(clipRect.getX(),begin),Math.min(clipRect.getX()+clipRect.getWidth()-1,end),alignment); } } } return result; } /** * The method draws a horizontal thick line * @param startX the x coordinate of the start point * @param startY the y coordinate of the start point * @param endX the x coordinate of the end point */ public static void drawHorizontalThickLine(int startX, int startY, int endX, CharColor color) { LinePart part = getLinePart(startX,endX,HORIZONTAL,startY,getCurrentClipRectangle()); if (!part.isEmpty()) { drawHorizontalThickLine(part._begin, startY, part._end, getColorPairNumber(color), __attributes[color.getColorAttribute()]); } } private static native void drawHorizontalThickLine(int startX, int startY, int endX, short colorPairNumber, long attr); /** * The method draws a vertical thick line * @param startX the x coordinate of the start point * @param startY the y coordinate of the start point * @param endY the y coordinate of the end point */ public static void drawVerticalThickLine(int startX, int startY, int endY, CharColor color) { LinePart part = getLinePart(startY,endY,VERTICAL,startX,getCurrentClipRectangle()); if (!part.isEmpty()) { drawVerticalThickLine(startX, part._begin, part._end, getColorPairNumber(color), __attributes[color.getColorAttribute()]); } } private static native void drawVerticalThickLine(int startX, int startY, int endY, short colorPairNumber, long attr); /** * The method draws a horizontal line * @param startX the x coordinate of the start point * @param startY the y coordinate of the start point * @param endX the x coordinate of the end point */ public static void drawHorizontalLine(int startX, int startY, int endX, CharColor color) { LinePart part = getLinePart(startX,endX,HORIZONTAL,startY,getCurrentClipRectangle()); if (!part.isEmpty()) { drawHorizontalLine(part._begin, startY, part._end, getColorPairNumber(color), __attributes[color.getColorAttribute()]); } } private static native void drawHorizontalLine(int startX, int startY, int endY, short colorPairNumber, long attr); /** * The method draws a vertical line * @param startX the x coordinate of the start point * @param startY the y coordinate of the start point * @param endY the y coordinate of the end point */ public static void drawVerticalLine(int startX, int startY, int endY, CharColor color) { LinePart part = getLinePart(startY,endY,VERTICAL,startX,getCurrentClipRectangle()); if (!part.isEmpty()) { drawVerticalLine(startX, part._begin, part._end, getColorPairNumber(color), __attributes[color.getColorAttribute()]); } } private static native void drawVerticalLine(int startX, int startY, int endX, short colorPairNumber, long attr); private static Point getCornerCenterPoint(int startX,int startY,int endX,int endY,short alignment) { int x = 0; int y = 0; y = (alignment == CORNER_UNDER_LINE)?Math.min(startY,endY):Math.max(startY,endY); x = (y == startY)?endX:startX; return new Point(x,y); } private static short getCornerChar(int startX,int startY,int endX,int endY,short alignment) { int cornerX = Math.min(startX,endX); int cornerY = (startX == cornerX)?startY:endY; // int otherX = (startX == cornerX)?endX:startX; int otherY = (startX == cornerX)?endY:startY; short result = 0; if (cornerY < otherY) { if (alignment == CORNER_UNDER_LINE) { result = UR_CORNER; } else { result = LL_CORNER; } } else { if (alignment == CORNER_UNDER_LINE) { result = UL_CORNER; } else { result = LR_CORNER; } } return result; } /** * * The method draws a corner. The corner cann't have only one long side and the othe side empty. * In such case drawLine must be user followed by painting a sidelos corner. * * @param startX the x coordinate of the start point * @param startY the y coordinate of the start point * @param endX the x coordinate of the end point * @param endY the y coordinate of the end point * @param alignment this parameter states, whether the line, that connects the start point with end point, liesUNDER * the corner point (alignment == 0 ) orOVER (alignment == 1), or the corner char, if the corner has no sides, it. * @color the color attributes for of the corner * */ public static void drawCorner(int startX, int startY, int endX, int endY, CharColor color, short alignment) { Rectangle clipRect = getCurrentClipRectangle(); if ((clipRect == null)) { drawCorner(startX, startY, endX, endY, getColorPairNumber(color), __attributes[color.getColorAttribute()], alignment); } else { Point center = getCornerCenterPoint(startX,startY,endX,endY,alignment); if ((alignment == CORNER_UNDER_LINE) || (alignment == CORNER_OVER_LINE)) { LinePart verticalPart = null; LinePart horizontalPart = null; if (startX == center.x) { int endY2 = (startY < center.y)?(center.y-1):(center.y+1); verticalPart = new LinePart(startY,endY2,center.x,VERTICAL); int endX2 = (endX < center.x)?(center.x-1):(center.x+1); horizontalPart = new LinePart(endX,endX2,center.y,HORIZONTAL); } else { int endY3 = (endY < center.y)?(center.y-1):(center.y+1); verticalPart = new LinePart(endY,endY3,center.x,VERTICAL); int endX3 = (startX < center.x)?(center.x-1):(center.x+1); horizontalPart = new LinePart(startX,endX3,center.y,HORIZONTAL); } drawHorizontalLine(horizontalPart._begin,horizontalPart._position,horizontalPart._end,color); drawVerticalLine(verticalPart._position,verticalPart._begin,verticalPart._end,color); } if (clipRect.inside(center.x,center.y)) { if ((alignment != CORNER_UNDER_LINE) && (alignment!=CORNER_OVER_LINE)) { drawCorner(center.x, center.y, center.x, center.y, getColorPairNumber(color), __attributes[color.getColorAttribute()], alignment); } else { short newAlignment = getCornerChar(startX,startY,endX,endY,alignment); drawCorner(center.x, center.y, center.x, center.y, getColorPairNumber(color), __attributes[color.getColorAttribute()], newAlignment); } } } return; } private static native void drawCorner(int startX, int startY, int endX, int endY, short colorPairNumber, long attr, short alignment); /** * The method draws a border ( empty rectangle ) * * @param rect bounds of the border to be painted * @param color color attributes of the border */ public static void drawBorder(Rectangle rect, CharColor color) { drawBorder((int)rect.getX(), (int)rect.getY(), (int)rect.getWidth(), (int)rect.getHeight(), color); } /** * The method draws a border on the screen. * * @param x the x coordinate of the top left corner of the border to be painted * @param y the y coordinate of the top left corner of the border to be painted * @param width the width of the border to be painted * @param heigtht the height of the border to be painted * @param color color attributes of the border */ public static void drawBorder(int x, int y, int width, int height, CharColor color) { drawCorner(x+1,y,x+width-1, y+height-2,color, CORNER_UNDER_LINE); drawCorner(x,y+1,x+width-2, y+height-1,color, CORNER_OVER_LINE); drawCorner(x,y,x,y,color, UL_CORNER); drawCorner(x+width-1,y+height-1,x+width-1,y+height-1,color, LR_CORNER); } private static String __encoding; /** * The method sets java encoding for string input and output operations * */ public static void setEncoding(String encoding) { __encoding = encoding; } /** * @return the java encoding used by sring input and output operations */ public static String getEncoding() { return __encoding; } private static void initEncoding() { if (isWindows()) { setEncoding("CP850"); } } private static boolean isWindows() { return (java.io.File.separatorChar == '\\'); } /** * The method prints a string on the screen * * @param text string to be printed * @param rectangle the rectangle, within which the string must lie. If the string * doesn't fit within the rectangle it will be broken. * @param colr attributes of the string */ public static void printString(String text, Rectangle rect, CharColor color) { Rectangle clipRect = getCurrentClipRectangle(); if (clipRect!=null) { Rectangle newRect = rect.intersection(clipRect); if (!newRect.isEmpty()) { printClippedString(rect, newRect, text, color); } } else { printStringWithoutClipping(text, rect,color); } } private static void printStringWithoutClipping(String text, Rectangle rect, CharColor color) { byte [] bytes = null; if (__encoding == null) { bytes = text.getBytes(); } else { try { bytes = text.getBytes(__encoding); } catch (java.io.UnsupportedEncodingException e) { __encoding = null; bytes = text.getBytes(); } } printString(bytes, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), getColorPairNumber(color), __attributes[color.getColorAttribute()]); } private static List getLines(String text, int maxWidth) { Listlist = new ArrayList (); StringBuffer buffer = new StringBuffer(); for (int i=0; i maxWidth) { list.add(line.substring(0,maxWidth)); list.add(line.substring(maxWidth,line.length())); } else { list.add(line); } buffer = new StringBuffer(); } else if (c == '\r') { //ignore } else { buffer.append(c); } } if (buffer.length() > 0) { list.add(buffer.toString()); } return list; } private static void printClippedString(Rectangle oldRect,Rectangle newRect, String text, CharColor color) { List lines = getLines(text, oldRect.getWidth()); int beginY = Math.max(oldRect.getY(), newRect.getY()); // int endY = Math.min(oldRect.getY()+oldRect.getHeight()-1,newRect.getY()+newRect.getHeight()-1); if (lines.size() > 0) { for (int i=0; i< lines.size(); i++) { if (((i+oldRect.getY())>=beginY) && ((i+oldRect.getY())>=beginY)) { String line = (String)lines.get(i); int beginPart = 0; if (oldRect.getX() < newRect.getX()) { beginPart = newRect.getX()-oldRect.getX(); } if (beginPart < line.length()) { line = line.substring(beginPart,line.length()); if (line.length() > newRect.getWidth()) { line = line.substring(0,newRect.getWidth()); } //Zeichnen Rectangle paintRect = new Rectangle(newRect.getX(),oldRect.getY()+i,line.length(),1); printStringWithoutClipping(line,paintRect,color); } } } } } /** * The method prints a string on the screen * * @param text string to be printed * @param x the x coordinate of the string start point * @param y the y coordinate of the string start point * @param color color attributes of the string */ public static void printString(String text, int x, int y, CharColor color) { printString(text,x,y,text.length(),1,color); } /** * The method prints a string on the screen. If the string doesn't fit within the rectangle bounds, * it wiil be broken. * * @param text string to be printed * @param x the x coordinate of the string start point * @param y the y coordinate of the string start point * @param width the width of bounds rectangle * @param height the width of bounds rectangle * @param color color attributes of the string */ public static void printString(String text, int x, int y, int width, int height, CharColor color) { Rectangle rect = new Rectangle(x,y,width,height); printString(text,rect,color); } private static native void printString(byte [] chars, int x, int y, int width, int height, short colorPairNumber, long attr); /** * The method reads the next code (ascii or control ) fro input stream an wraps it into an instance * of {@link jcurses.system.InputChar} * * @return the next read code */ public static synchronized InputChar readCharacter() { int code = readByte(); return new InputChar(code); } private static synchronized native int readByte(); static native int getSpecialKeyCode(int code); /** * The method change the background and the foreground colors of an given rectangle on the schreen * * @param rectangle rectangle, whose colors are to be changed * @param colors new colors */ public static void changeColors(Rectangle rect, CharColor color) { Rectangle clipRect = getCurrentClipRectangle(); if (clipRect!=null) { rect = rect.intersection(clipRect); } if (!rect.isEmpty()) { changeColors(rect.getX(),rect.getY(),rect.getWidth(),rect.getHeight(), getColorPairNumber(color), __attributes[color.getColorAttribute()]); } } private native static void changeColors(int x, int y, int width, int height, short colorPairNumber, long attr); /** * The method to make an audio alert. Works * only with terminals, that support 'beeps', * under windows currenty does nothing. */ public native static void beep(); } class LinePart { int _begin = -1; int _end = -2; int _alignment = -1; int _position = -1; public LinePart() { } LinePart(int begin, int end, int alignment) { _begin = begin; _end = end; _alignment = alignment; } LinePart(int begin, int end, int position, int alignment) { _begin = begin; _end = end; _position = position; _alignment = alignment; } boolean isEmpty() { return (_begin > _end); } public String toString() { return "[begin="+_begin+",end="+_end+",align="+_alignment+",isEmpty="+isEmpty(); } }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy