/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016, 2019 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package javax.microedition.lcdui;
import malik.emulator.media.graphics.*;
public class StringItem extends Item
{
private boolean controlFocused;
private boolean pointerFocused;
private boolean pointerPressed;
private int contentWidth;
private int contentHeight;
private int appearance;
private String text;
private Font font;
private TextOutputMultilined lines;
public StringItem(String label, String text)
{
this(LAYOUT_DEFAULT, -1, -1, label, null, null, null, text, null, PLAIN);
}
public StringItem(String label, String text, int appearance)
{
this(LAYOUT_DEFAULT, -1, -1, label, null, null, null, text, null, appearance);
}
public StringItem(int layout, int lockedWidth, int lockedHeight, String label,
Command[] commands, Command defaultCommand, ItemCommandListener listener,
String text, Font font, int appearance)
{
super(layout, lockedWidth, lockedHeight, label, commands, defaultCommand, listener);
Font f;
TextOutputMultilined lines;
if(appearance != PLAIN && appearance != HYPERLINK && appearance != BUTTON)
{
throw new IllegalArgumentException("StringItem: " +
"недопустимое значение параметра appearance.");
}
this.appearance = appearance;
this.text = text;
this.font = font != null ? font :
(appearance != HYPERLINK ? Font.getFont(Font.FONT_STATIC_TEXT) :
Font.getFont((f = Font.getFont(Font.FONT_STATIC_TEXT)).getFace(),
f.getStyle() | Font.STYLE_UNDERLINED, f.getSize()));
this.lines = lines = new TextOutputMultilinedExt(0);
lines.setText(text);
}
public void setText(String text)
{
TextOutputMultilined lines;
this.text = text;
synchronized(lines = this.lines)
{
lines.setText(text);
}
notifyUpdate();
}
public void setFont(Font font)
{
this.font = font == null ? Font.getFont(Font.FONT_STATIC_TEXT) : font;
notifyUpdate();
}
public int getAppearanceMode()
{
return appearance;
}
public String getText()
{
return text;
}
public Font getFont()
{
return font;
}
void paintContent(Graphics render, int contentWidth, int contentHeight)
{
boolean pressed;
int l;
int t;
int a;
int s;
int ct;
int cb;
int i;
int len;
char[] chars;
TextOutputMultilined lines;
Font font;
pressed = pointerPressed;
render.setFont(font = this.font);
synchronized(lines = this.lines)
{
lines.split(font, contentWidth - 8);
s = font.getHeight();
cb = (ct = render.getClipY()) + render.getClipHeight();
len = lines.getLinesCount();
chars = lines.getChars();
if(isMatchForButton())
{
render.drawElementOfGUI(4, a = pressed ? 1 : (controlFocused ? 3 : 0), 0,
0, 0, contentWidth, contentHeight);
render.setColor(RasterCanvas.getSystemColor(a + 0x24));
l = (contentWidth / 2) + (pressed ? 1 : 0);
t = ((contentHeight - len * s) / 2) + (pressed ? 1 : 0);
a = Graphics.HCENTER | Graphics.TOP;
}
else if(isMatchForHyperlink())
{
a = pressed ? 1 : (controlFocused ? 3 : 0);
render.setColor(RasterCanvas.getSystemColor(a + 0x24));
l = pressed ? 5 : 4;
t = pressed ? 5 : 4;
a = Graphics.LEFT | Graphics.TOP;
}
else
{
render.setColor(RasterCanvas.getSystemColor(0x28));
l = 4;
t = 4;
a = Graphics.LEFT | Graphics.TOP;
}
for(i = 0; i < len; t += s, i++)
{
if(t < cb && t + s > ct)
{
render.drawChars(chars, lines.getLineStart(i), lines.getLineLength(i),
l, t, a);
}
}
}
}
void onSizeChanged(int contentWidth, int contentHeight)
{
this.contentWidth = contentWidth;
this.contentHeight = contentHeight;
}
void onContentPointerPressed(int x, int y, int button)
{
if(button != MIDletProxy.BUTTON_MAIN ||
(!isMatchForButton()) && (!isMatchForHyperlink()))
{
return;
}
pointerFocused = true;
pointerPressed = true;
notifyPaint();
}
void onContentPointerDragged(int x, int y)
{
if((!pointerFocused) || pointerPressed == (pointerPressed =
x >= 0 && x < contentWidth &&
y >= 0 && y < contentHeight))
{
return;
}
notifyPaint();
}
void onContentPointerReleased(int x, int y, int button)
{
boolean pressed;
if(button != MIDletProxy.BUTTON_MAIN)
{
return;
}
pressed = pointerPressed;
pointerFocused = false;
pointerPressed = false;
if(!pressed)
{
return;
}
notifyPaint();
notifyCommandAction(getCommands().getDefaultCommand());
}
void onTraverseOut()
{
controlFocused = false;
if(isMatchForButton())
{
notifyPaint();
}
}
boolean onTraverseNeedStayOn(int direction, int viewportWidth, int viewportHeight,
int[] visibleRectangle)
{
boolean cfocused;
int tmp;
int size;
if((cfocused = controlFocused) != (controlFocused = true) && isMatchForButton())
{
notifyPaint();
}
if(pointerFocused)
{
return true;
}
switch(direction)
{
case Canvas.UP:
if(cfocused)
{
if((tmp = visibleRectangle[TOP]) > 0)
{
visibleRectangle[TOP] = Math.max(tmp - viewportHeight / 4, 0);
return true;
}
return false;
}
break;
case Canvas.LEFT:
if(cfocused)
{
if((tmp = visibleRectangle[LEFT]) > 0)
{
visibleRectangle[LEFT] = Math.max(tmp - viewportWidth / 4, 0);
return true;
}
return false;
}
break;
case Canvas.RIGHT:
size = super.getPreferredWidth() - visibleRectangle[WIDTH];
if(cfocused)
{
if((tmp = visibleRectangle[LEFT]) < size)
{
visibleRectangle[LEFT] = Math.min(tmp + viewportWidth / 4, size);
return true;
}
return false;
}
break;
case Canvas.DOWN:
size = super.getPreferredHeight() - visibleRectangle[HEIGHT];
if(cfocused)
{
if((tmp = visibleRectangle[TOP]) < size)
{
visibleRectangle[TOP] = Math.min(tmp + viewportHeight / 4, size);
return true;
}
return false;
}
break;
}
return true;
}
boolean isMatchForButton()
{
return appearance == BUTTON && super.isMatchForButton();
}
boolean isMatchForHyperlink()
{
return appearance == HYPERLINK && super.isMatchForHyperlink();
}
int getPreferredContentWidth(int contentHeight, int containerClientWidth)
{
int i;
int tmp;
int result;
char[] chars;
Font font;
TextOutputMultilined lines;
result = 0;
font = this.font;
synchronized(lines = this.lines)
{
chars = lines.getChars();
lines.split(font, Integer.MAX_VALUE - 8);
for(i = lines.getLinesCount(); i-- > 0; )
{
if(result < (tmp = font.charsWidth(chars,
lines.getLineStart(i), lines.getLineLength(i))))
{
result = tmp;
}
}
}
if((result += 8) > containerClientWidth)
{
result = containerClientWidth;
}
return result;
}
int getPreferredContentHeight(int contentWidth)
{
int result;
Font font;
TextOutputMultilined lines;
font = this.font;
if(contentWidth < 0)
{
contentWidth = Integer.MAX_VALUE;
}
synchronized(lines = this.lines)
{
lines.split(font, contentWidth - 8);
result = lines.getLinesCount() * font.getHeight() + 8;
}
return result;
}
}