/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016–2017, 2019–2023, 2025 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package malik.emulator.microedition.lcdui;
import javax.microedition.lcdui.*;
import malik.emulator.application.*;
public final class SystemScrollBarStyle extends ScrollBarStyle
{
private static final int ELEMENT_NONE = 0;
private static final int ELEMENT_SLIDER = 1;
private static final int ELEMENT_PAGE_BACK = 2;
private static final int ELEMENT_PAGE_NEXT = 3;
private static final int ELEMENT_SCROLL_BACK = 4;
private static final int ELEMENT_SCROLL_NEXT = 5;
private static final int SLIDER_MINIMUM_LENGTH = 7;
private static int getHorizontalScrollBarFocusedElement(int page, int range, int position, int x, int y, int width, int height) {
if(y >= 0 && y < height)
{
if(width <= 32)
{
int center = width >> 1;
if(x >= 0 && x < center) return ELEMENT_SCROLL_BACK;
if(x >= center && x < width) return ELEMENT_SCROLL_NEXT;
}
if(x >= 0 && x < 16) return ELEMENT_SCROLL_BACK;
if(x >= width - 16 && x < width) return ELEMENT_SCROLL_NEXT;
if(width >= 32 + SLIDER_MINIMUM_LENGTH && page > 0 && range > page)
{
int sl = getSliderLength(page, range, width - 32, SLIDER_MINIMUM_LENGTH);
int x1 = getSliderPosition(page, range, position, width - 32, sl) + 16;
int x2 = sl + x1 - 1;
if(x >= 16 && x < x1) return ELEMENT_PAGE_BACK;
if(x >= x1 && x <= x2) return ELEMENT_SLIDER;
if(x > x2 && x < width - 16) return ELEMENT_PAGE_NEXT;
}
}
return ELEMENT_NONE;
}
private static int getVerticalScrollBarFocusedElement(int page, int range, int position, int x, int y, int width, int height) {
if(x >= 0 && x < width)
{
if(height <= 32)
{
int center = height >> 1;
if(y >= 0 && y < center) return ELEMENT_SCROLL_BACK;
if(y >= center && y < height) return ELEMENT_SCROLL_NEXT;
}
if(y >= 0 && y < 16) return ELEMENT_SCROLL_BACK;
if(y >= height - 16 && y < height) return ELEMENT_SCROLL_NEXT;
if(height >= 32 + SLIDER_MINIMUM_LENGTH && page > 0 && range > page)
{
int sl = getSliderLength(page, range, height - 32, SLIDER_MINIMUM_LENGTH);
int y1 = getSliderPosition(page, range, position, height - 32, sl) + 16;
int y2 = sl + y1 - 1;
if(y >= 16 && y < y1) return ELEMENT_PAGE_BACK;
if(y >= y1 && y <= y2) return ELEMENT_SLIDER;
if(y > y2 && y < height - 16) return ELEMENT_PAGE_NEXT;
}
}
return ELEMENT_NONE;
}
private int focused;
private int pressedHorz;
private int pressedVert;
public SystemScrollBarStyle() {
super(16);
}
public void horizontalScrollBarPointerEvent(ScrollBar scrollbar, PointerEvent event, int width, int height) {
int f;
int page = scrollbar.getPage();
int range = scrollbar.getRange();
switch(event.getAction())
{
case PointerEvent.ACTION_POINTER_PRESSED:
switch(focused = pressedHorz = getHorizontalScrollBarFocusedElement(page, range, scrollbar.getPosition(), event.getX(), event.getY(), width, height))
{
case ELEMENT_PAGE_BACK:
scrollbar.scroll(-page);
break;
case ELEMENT_PAGE_NEXT:
scrollbar.scroll(page);
break;
case ELEMENT_SCROLL_BACK:
scrollbar.scroll(-16);
break;
case ELEMENT_SCROLL_NEXT:
scrollbar.scroll(16);
break;
}
scrollbar.repaint();
break;
case PointerEvent.ACTION_BUTTON_PRESSED:
case PointerEvent.ACTION_POINTER_DRAGGED:
case PointerEvent.ACTION_BUTTON_RELEASED:
f = focused;
if(page > 0 && range > page && f == ELEMENT_SLIDER)
{
int x = event.getX();
int p = event.historicalX(1);
scrollbar.scroll((int) ((double) (x - p) * (double) range / (double) (width - 32)));
}
if(pressedHorz != (pressedHorz = getHorizontalScrollBarFocusedElement(page, range, scrollbar.getPosition(), event.getX(), event.getY(), width, height) != f ? 0 : f)) scrollbar.repaint();
break;
case PointerEvent.ACTION_POINTER_RELEASED:
if(page > 0 && range > page && focused == ELEMENT_SLIDER)
{
int x = event.getX();
int p = event.historicalX(1);
scrollbar.scroll((int) ((double) (x - p) * (double) range / (double) (width - 32)));
}
pressedHorz = focused = 0;
scrollbar.repaint();
break;
}
}
public void horizontalScrollBarPaintEvent(ScrollBar scrollbar, Graphics render, int width, int height) {
boolean enabled;
int sl;
int x1;
int x2;
int page = scrollbar.getPage();
int range = scrollbar.getRange();
int element = pressedHorz;
enabled = page > 0 && range > page;
if(width <= 32)
{
int center = width >> 1;
render.drawElement(10, 2, enabled ? element != ELEMENT_SCROLL_BACK ? 0 : 1 : 2, 0, 0, center, height);
render.drawElement(10, 3, enabled ? element != ELEMENT_SCROLL_NEXT ? 0 : 1 : 2, center, 0, width - center, height);
return;
}
render.drawElement(10, 2, enabled ? element != ELEMENT_SCROLL_BACK ? 0 : 1 : 2, 0, 0, 16, height);
render.drawElement(10, 3, enabled ? element != ELEMENT_SCROLL_NEXT ? 0 : 1 : 2, width - 16, 0, 16, height);
if(width < 32 + SLIDER_MINIMUM_LENGTH || !enabled)
{
render.drawElement(10, 6, enabled ? 0 : 2, 16, 0, width - 32, height);
return;
}
sl = getSliderLength(page, range, width - 32, SLIDER_MINIMUM_LENGTH);
x1 = getSliderPosition(page, range, scrollbar.getPosition(), width - 32, sl) + 16;
x2 = sl + x1;
render.drawElement(10, 6, element != ELEMENT_PAGE_BACK ? 0 : 1, 16, 0, x1 - 16, height);
render.drawElement(10, 7, element != ELEMENT_PAGE_NEXT ? 0 : 1, x2, 0, width - x2 - 16, height);
render.drawElement(10, 4, element != ELEMENT_SLIDER ? 0 : 1, x1, 0, x2 - x1, height);
}
public void verticalScrollBarPointerEvent(ScrollBar scrollbar, PointerEvent event, int width, int height) {
int f;
int page = scrollbar.getPage();
int range = scrollbar.getRange();
switch(event.getAction())
{
case PointerEvent.ACTION_POINTER_PRESSED:
switch(focused = pressedVert = getVerticalScrollBarFocusedElement(page, range, scrollbar.getPosition(), event.getX(), event.getY(), width, height))
{
case ELEMENT_PAGE_BACK:
scrollbar.scroll(-page);
break;
case ELEMENT_PAGE_NEXT:
scrollbar.scroll(page);
break;
case ELEMENT_SCROLL_BACK:
scrollbar.scroll(-16);
break;
case ELEMENT_SCROLL_NEXT:
scrollbar.scroll(16);
break;
}
scrollbar.repaint();
break;
case PointerEvent.ACTION_BUTTON_PRESSED:
case PointerEvent.ACTION_POINTER_DRAGGED:
case PointerEvent.ACTION_BUTTON_RELEASED:
f = focused;
if(page > 0 && range > page && f == ELEMENT_SLIDER)
{
int y = event.getY();
int p = event.historicalY(1);
scrollbar.scroll((int) ((double) (y - p) * (double) range / (double) (height - 32)));
}
if(pressedVert != (pressedVert = getVerticalScrollBarFocusedElement(page, range, scrollbar.getPosition(), event.getX(), event.getY(), width, height) != f ? 0 : f)) scrollbar.repaint();
break;
case PointerEvent.ACTION_POINTER_RELEASED:
if(page > 0 && range > page && focused == ELEMENT_SLIDER)
{
int y = event.getY();
int p = event.historicalY(1);
scrollbar.scroll((int) ((double) (y - p) * (double) range / (double) (height - 32)));
}
pressedVert = focused = 0;
scrollbar.repaint();
break;
}
}
public void verticalScrollBarPaintEvent(ScrollBar scrollbar, Graphics render, int width, int height) {
boolean enabled;
int sl;
int y1;
int y2;
int page = scrollbar.getPage();
int range = scrollbar.getRange();
int element = pressedVert;
enabled = page > 0 && range > page;
if(height <= 32)
{
int center = height >> 1;
render.drawElement(10, 0, enabled ? element != ELEMENT_SCROLL_BACK ? 0 : 1 : 2, 0, 0, width, center);
render.drawElement(10, 1, enabled ? element != ELEMENT_SCROLL_NEXT ? 0 : 1 : 2, 0, center, width, height - center);
return;
}
render.drawElement(10, 0, enabled ? element != ELEMENT_SCROLL_BACK ? 0 : 1 : 2, 0, 0, width, 16);
render.drawElement(10, 1, enabled ? element != ELEMENT_SCROLL_NEXT ? 0 : 1 : 2, 0, height - 16, width, 16);
if(height < 32 + SLIDER_MINIMUM_LENGTH || !enabled)
{
render.drawElement(10, 8, enabled ? 0 : 2, 0, 16, width, height - 32);
return;
}
sl = getSliderLength(page, range, height - 32, SLIDER_MINIMUM_LENGTH);
y1 = getSliderPosition(page, range, scrollbar.getPosition(), height - 32, sl) + 16;
y2 = sl + y1;
render.drawElement(10, 8, element != ELEMENT_PAGE_BACK ? 0 : 1, 0, 16, width, y1 - 16);
render.drawElement(10, 9, element != ELEMENT_PAGE_NEXT ? 0 : 1, 0, y2, width, height - y2 - 16);
render.drawElement(10, 5, element != ELEMENT_SLIDER ? 0 : 1, 0, y1, width, y2 - y1);
}
public void sizeGripPaintEvent(boolean sizeChangeAllowed, Graphics render, int width, int height) {
render.drawElement(10, sizeChangeAllowed ? 11 : 12, 0, 0, 0, width, height);
}
}