Skip to main content
// .sgui 打开

@Command(name="sgui", description="open script clickgui")
void openExec(args) { me.openScreen("script_clickgui"); }

@OnLoad void onLoad() { me.registerScreen("script_clickgui"); }

// ─── 布局参数 ────────────────────────────────────────────
String[] CATS = new String[]{ "COMBAT", "EXPLOIT", "MOVE", "PLAYER", "VISUAL", "WORLD" };
int PANEL_W   = 110;
int HEADER_H  = 18;
int ROW_H     = 14;
int MAX_BODY  = 240;
int CORNER_R  = 3;

// ─── 颜色 ────────────────────────────────────────────────
long C_HEADER  = 0xFF1E2430L;
long C_BG      = 0xE0101418L;
long C_ROW     = 0xFF1A1F28L;
long C_HOVER   = 0xFF2A3340L;
long C_ROW_ON  = 0xFF3F8DFFL;
long C_TEXT    = 0xFFFFFFFFL;
long C_DIM     = 0xFFAAAAAAL;

// ─── 状态 ────────────────────────────────────────────────
Map panelX       = null;   // category -> Integer
Map panelY       = null;
Map panelScroll  = null;
Map panelModules = null;   // category -> List<Module>

int screenW = 854;
int screenH = 480;

String draggingCat = null;
double dragOffX    = 0;
double dragOffY    = 0;

// ───────────────────────────────────────────────────────────
// init:屏幕打开时,每次重新读模块列表 + 默认布局
// ───────────────────────────────────────────────────────────
@EventTarget(events="init")
void onInit(event) {
    screenW = event.getInt("width");
    screenH = event.getInt("height");

    panelX       = new LinkedHashMap();
    panelY       = new LinkedHashMap();
    panelScroll  = new LinkedHashMap();
    panelModules = new LinkedHashMap();

    int x = 16;
    int y = 30;
    for (cat : CATS) {
        panelX.put(cat, x);
        panelY.put(cat, y);
        panelScroll.put(cat, 0);
        panelModules.put(cat, moduleManager.byCategory(cat));
        x += PANEL_W + 6;
    }

    draggingCat = null;
}

// ───────────────────────────────────────────────────────────
// 渲染
// ───────────────────────────────────────────────────────────
@EventTarget(events="render_screen")
void onRender(event) {
    if (!render.isActive()) return;
    if (panelModules == null) return;

    mx = event.getNumber("mouse_x");
    my = event.getNumber("mouse_y");

    for (cat : CATS) drawPanel(cat, mx, my);
}

void drawPanel(cat, mx, my) {
    px = panelX.get(cat);
    py = panelY.get(cat);
    scroll = panelScroll.get(cat);
    list = panelModules.get(cat);
    if (list == null) return;

    bodyTotalH   = list.size() * ROW_H;
    bodyVisibleH = bodyTotalH > MAX_BODY ? MAX_BODY : bodyTotalH;

    // header(圆顶)
    render.round(px, py, PANEL_W, HEADER_H, CORNER_R, C_HEADER, true, true, false, false);
    titleY = py + (HEADER_H - render.fontHeight()) / 2.0;
    render.text(cat, px + 8, titleY, C_TEXT);

    if (bodyVisibleH <= 0) return;

    // body 背景
    render.round(px, py + HEADER_H, PANEL_W, bodyVisibleH, CORNER_R, C_BG, false, false, true, true);

    // 用 scissor 把超出可视区的行剪掉
    render.pushScissor(px, py + HEADER_H, PANEL_W, bodyVisibleH);

    rowY = py + HEADER_H - scroll;
    for (h : list) {
        if (rowY + ROW_H < py + HEADER_H || rowY > py + HEADER_H + bodyVisibleH) {
            rowY += ROW_H;
            continue;
        }
        hover = mx >= px && mx < px + PANEL_W && my >= rowY && my < rowY + ROW_H;
        bg = h.isEnabled() ? C_ROW_ON : (hover ? C_HOVER : C_ROW);
        render.rect(px, rowY, PANEL_W, ROW_H, bg);
        render.text(h.getName(), px + 8, rowY + (ROW_H - render.fontHeight()) / 2.0, C_TEXT);
        rowY += ROW_H;
    }

    render.popScissor();

    // 滚动条提示(只在能滚的时候画)
    if (bodyTotalH > bodyVisibleH) {
        // 比例条
        ratio = (double) bodyVisibleH / bodyTotalH;
        scrollH = (int) (bodyVisibleH * ratio);
        scrollOffsetY = (int) ((double) scroll / bodyTotalH * bodyVisibleH);
        render.rect(px + PANEL_W - 2, py + HEADER_H + scrollOffsetY, 2, scrollH, C_DIM);
    }
}

int panelTotalH(cat) {
    list = panelModules.get(cat);
    if (list == null) return HEADER_H;
    bodyH = list.size() * ROW_H;
    if (bodyH > MAX_BODY) bodyH = MAX_BODY;
    return HEADER_H + bodyH;
}

// ───────────────────────────────────────────────────────────
// 点击:header 起拖 / row 切模块
// ───────────────────────────────────────────────────────────
@EventTarget(events="mouse_clicked")
void onClick(event) {
    if (event.getInt("button") != 0) return;
    if (panelModules == null) return;

    mx = event.getNumber("mouse_x");
    my = event.getNumber("mouse_y");

    for (cat : CATS) {
        px = panelX.get(cat);
        py = panelY.get(cat);
        if (mx < px || mx >= px + PANEL_W) continue;

        // header → 拖拽
        if (my >= py && my < py + HEADER_H) {
            draggingCat = cat;
            dragOffX = mx - px;
            dragOffY = my - py;
            return;
        }

        // body → 切模块
        totalH = panelTotalH(cat);
        if (my < py + HEADER_H || my >= py + totalH) continue;

        scroll = panelScroll.get(cat);
        list = panelModules.get(cat);
        rowY = py + HEADER_H - scroll;
        for (h : list) {
            if (my >= rowY && my < rowY + ROW_H) {
                // 行可能在 scroll 之外,hit 一下用 visible 范围二次校验
                if (rowY + ROW_H >= py + HEADER_H && rowY < py + totalH) {
                    h.toggle();
                }
                return;
            }
            rowY += ROW_H;
        }
        return;
    }
}

@EventTarget(events="mouse_released")
void onRelease(event) {
    if (event.getInt("button") == 0) draggingCat = null;
}

// ───────────────────────────────────────────────────────────
// 拖拽
// ───────────────────────────────────────────────────────────
@EventTarget(events="mouse_dragged")
void onDrag(event) {
    if (draggingCat == null) return;
    if (event.getInt("button") != 0) return;

    mx = event.getNumber("mouse_x");
    my = event.getNumber("mouse_y");

    newX = (int) (mx - dragOffX);
    newY = (int) (my - dragOffY);

    if (newX < 0) newX = 0;
    if (newY < 0) newY = 0;
    if (newX + PANEL_W > screenW) newX = screenW - PANEL_W;

    totalH = panelTotalH(draggingCat);
    if (newY + totalH > screenH) newY = screenH - totalH;

    panelX.put(draggingCat, newX);
    panelY.put(draggingCat, newY);
}

// ───────────────────────────────────────────────────────────
// 滚轮:在哪个面板上方就滚那个的模块列表
// ───────────────────────────────────────────────────────────
@EventTarget(events="mouse_scrolled")
void onScroll(event) {
    if (panelModules == null) return;

    mx = event.getNumber("mouse_x");
    my = event.getNumber("mouse_y");
    delta = event.getNumber("delta");

    for (cat : CATS) {
        px = panelX.get(cat);
        py = panelY.get(cat);
        totalH = panelTotalH(cat);
        if (mx < px || mx >= px + PANEL_W) continue;
        if (my < py || my >= py + totalH) continue;

        list = panelModules.get(cat);
        bodyTotalH = list.size() * ROW_H;
        bodyVisibleH = bodyTotalH > MAX_BODY ? MAX_BODY : bodyTotalH;
        maxScroll = bodyTotalH - bodyVisibleH;
        if (maxScroll < 0) maxScroll = 0;

        cur = panelScroll.get(cat);
        newScroll = ((int) cur) - (int) (delta * 20);
        if (newScroll < 0) newScroll = 0;
        if (newScroll > maxScroll) newScroll = maxScroll;
        panelScroll.put(cat, newScroll);
        return;
    }
}

@EventTarget(events="close")
void onClose(event) {
    draggingCat = null;
}