SourcePawn [SourcePawn] Урок 7 - Панели и Меню

Pushistik↯❤

Команда форума
Регистрация
6 Июл 2017
Сообщения
393
Реакции
97
Баллы
28
[SourcePawn] Урок 7 - Панели и Меню
<= К содержанию
SourceMod имеет 2 стиля меню:
  • Valve Style - так же называемое "ESC" меню; 8 пунктов на странице, нельзя добавить текст без занятия слота или спрятать (отключить) текст. Это меню, которое отображается в меню игры при нажатии на ESC.
  • Radio Style - так же называемый "AMX" меню; 10 пунктов на странице (в CS:GO 9), можно добавить любой текст. Это обычное привычное всем меню админки и отправки радиокоманд.

В SourceMod существует 2 вида меню: Панели и Меню.
В чем же разница?

  • Панель - более простой инструмент для создания меню. Может иметь как пункты так и простой текст. Панель считается временным объектом, хотя хранится может столько, сколько понадобится. Образный вызов для панели вызывается только при нажатии на пункт и при закрытии. Нумерация пунктов от 1 до 10.
  • Меню - является более сложным инструментом. Содержит пункты и их описание. Позволяет изменять заглавие, текст отображаемый в пунктах и их стиль. Обратный вызов может быть вызван при уничтожении меню, при закрытии, отображении меню и пунктов. Нумерация пунктов от 0 до N.

Panel - производный тип от Handle.
Методы типа
Panel:
  • Panel - Создает объект типа Panel
    PHP:
    Panel hPanel = new Panel();
  • SetTitle - Добавляет заглавие к панели
    PHP:
    hPanel.SetTitle("Заглавие");
  • DrawItem - Добавляет пункт в панель и возвращает его позицию
    PHP:
    hPanel.DrawItem("Пункт 1");
    hPanel.DrawItem("Пункт 2");
    hPanel.DrawItem("Пункт 3");
  • DrawText - Добавляет строку текста в панель. Она не имеет номера.
    PHP:
    hPanel.DrawText("Текст 1");
    hPanel.DrawText("Текст 2");
  • CanDrawFlags - Возвращает поддерживает ли эта панель указанный стиль пунктов
    PHP:
    if(hPanel.CanDrawFlags(ITEMDRAW_DEFAULT))
    {
    // ...
    }
  • Send - Отправляется панель игроку
    PHP:
    hPanel.Send(iClient, MenuHandler_MyPanel, 20);
Свойства типа Panel:
  • TextRemaining - Возвращает сколько текста еще может содержать панель.
  • CurrentKey - Возвращает/Устанавливает текущую позицию для добавления пункта
  • Style - Возвращает текущий стиль панели.
Menu - производный тип от Handle.
Методы типа Menu:
  • Menu - Создает объект типа Menu
    PHP:
    Menu hMenu = new Menu(MenuHandler_MyMenu);
  • SetTitle - Добавляет заглавие к меню. Поддерживает форматирование текста
    PHP:
    hMenu.SetTitle("Заглавие");
  • GetTitle - Получает заглавие меню.
    PHP:
    char szTitle[128];
    hMenu.GetTitle(szTitle, sizeof(szTitle));
  • AddItem - Добавляет пункт в меню.
    PHP:
    hMenu.AddItem("описание", "название", стиль);
    hMenu.AddItem("item1", "Пункт 1");
    hMenu.AddItem("item2", "Пункт 2", ITEMDRAW_DISABLED);
  • InsertItem - Вставляет пункт на указанной позиции в меню.
    PHP:
    hMenu.InsertItem(позиция, "описание", "название", стиль);
    hMenu.InsertItem(3, "item4", "Пункт 4");
    hMenu.InsertItem(6, "item7", "Пункт 7", ITEMDRAW_DISABLED);
  • GetItem - Получает информацию о пункте (описание, название, стиль)
    PHP:
    hMenu.GetItem(int position, char[] infoBuf, int infoBufLen, int &style, char[] dispBuf, int dispBufLen)
    // position - позиция пункта
    // infoBuf - буфер для помещения описания пункта
    // infoBufLen - размер буфера для описания пункта
    // style -  буфер для помещения стиля пункта
    // dispBuf - буфер для помещения названия пункта
    // dispBufLen - размер буфера для названия пункта
    
    // Получаем всё
    char szInfo[128], szTitle[128];
    int iStyle;
    hMenu.GetItem(iItem, szInfo, sizeof(szInfo), iStyle, szTitle, sizeof(szTitle));
    
    // Получаем только описание
    char szInfo[128];
    hMenu.GetItem(iItem, szInfo, sizeof(szInfo));
    
    // Получаем только название
    char szTitle[128];
    hMenu.GetItem(iItem, _, _, _, szTitle, sizeof(szTitle));
    
    // Получаем только стиль
    int iStyle;
    hMenu.GetItem(iItem, _, _, iStyle);
    
    // Получаем только название и описание
    char szInfo[128], szTitle[128];
    hMenu.GetItem(iItem, szInfo, sizeof(szInfo), _, szTitle, sizeof(szTitle));
  • RemoveItem - Удаляет пункт из меню. При этом все пункты сдвигаются.
    PHP:
    hMenu.RemoveItem(номер_пункта);
    hMenu.RemoveItem(4);
  • RemoveAllItems - Удаляет все пункты из меню.
    PHP:
    hMenu.RemoveAllItems();
  • ToPanel - Создает объект типа Panel на основе меню.
    PHP:
    Panel hPanel = hMenu.ToPanel();
  • Display - Отправляет меню игроку
    PHP:
    hMenu.Display(iClient, 20); // 20 это количество секунд, по истечению которых меню будет закрыто. Чтобы убрать лимит по времени необходимо установить 0 или MENU_TIME_FOREVER
  • DisplayAt - Отправляет меню игроку, начиная с указанного пункта
    PHP:
    hMenu.DisplayAt(iClient, 4, 20); // 4 это номер пункта, который будет первым.
  • Cancel - Отменяет меню у всех игроков
    PHP:
    hMenu.Cancel();
Свойства типа Menu:
  • Pagination - Возвращает/Устанавливает количество пунктов на странице. Чтобы убрать разбиение на страницы установить MENU_NO_PAGINATION.
  • OptionFlags - Возвращает/Устанавливает флаги опций меню
  • ExitButton - Возвращает/Устанавливает наличие кнопки "Выход".
  • ExitBackButton - Возвращает/Устанавливает наличие кнопки "Назад".
  • ItemCount - Возвращает количество пунктов в меню.
  • Style - Возвращает стиль меню.
  • Selection - Возвращает номер первого пункта на странице с выбранным пунктом. Нужен для отправки меню с этого же места, где был выбран пункт.
Стили пунктов:
  • ITEMDRAW_DEFAULT - Нормальный пункт.
  • ITEMDRAW_DISABLED - Пункт, который нельзя выбрать (белого цвета).
  • ITEMDRAW_RAWLINE - Пункт, который не имеет слота и имеет только текст
  • ITEMDRAW_NOTEXT - Пункт, без текста
  • ITEMDRAW_SPACER - Пункт, для отступа
  • ITEMDRAW_IGNORE - Пункт, будет игнорироваться (rawline + notext)
  • ITEMDRAW_CONTROL - Пункт, который имеет функцию управления (назад / далее / выход)

Обратный вызов.
И меню и панели имею одинаковый обратный вызов:
PHP:
typedef MenuHandler = function int(Menu menu, MenuAction action, int param1, int param2)
  • Menu menu - Объект меню
  • MenuAction action - Тип события обратного вызова
  • int param1 - Параметр 1
  • int param2 - Параметр 2
События обратного вызова
  • MenuAction_Start - Меню было начато. Это гарантирует что будет вызвано событие завершения меню.
    • param1 - Всегда 0
    • param2 - Всегда 0
  • MenuAction_Display - Меню было отображено игроку.
    • param1 - Индекс игрока
    • param2 - MenuPanel Handle
  • MenuAction_Select - Игрок нажал на пункт.
    • param1 - Индекс игрока
    • param2 - Номер пункта
  • MenuAction_DisplayItem - Отображение содержимого пункта игроку.
    • param1 - Индекс игрока
    • param2 - Номер пункта
    Чтобы изменить отображение пункта вернуть RedrawMenuItem().
  • MenuAction_DrawItem - Отображение стиля пункта игроку.
    • param1 - Индекс игрока
    • param2 - Номер пункта
    Чтобы изменить - вернуть новый стиль.
  • MenuAction_Cancel - Меню было отменено.
    • param1 - Индекс игрока
    • param2 - Причина:
      • MenuCancel_Disconnected - Игрок был отключен от сервера
      • MenuCancel_Interrupted - Другое меню перебило наше
      • MenuCancel_Exit - Игрок нажал на кнопку "Выход"
      • MenuCancel_NoDisplay - Меню не может быть отображено игроку
      • MenuCancel_Timeout - Время отображения вышло
      • MenuCancel_ExitBack - Игрок нажал на кнопку "Назад"
  • MenuAction_End - Меню было полностью завершено. Именно в этом событии следует удалять его.
    • param1 - Причина:
      • MenuEnd_Selected - Игрок нажал на пункт
      • MenuEnd_Exit - Игрок нажал на кнопку "Выход"
      • MenuEnd_ExitBack - Игрок нажал на кнопку "Назад"
      • MenuEnd_Cancelled - Меню было отменено (Причин param2)
      • MenuEnd_VotingDone - Голосование завершено
      • MenuEnd_VotingCancelled - Голосование отменено
    • param2 - Либо 0, либо причина.
Для панели действительны только 2 события: MenuAction_Cancel и MenuAction_Select.
Для меню действительны все события. Но чтобы они вызывались их необходимо указать при создании меню:
PHP:
Menu hMenu = new Menu(MenuHandler_MyMenu, События);

// Если события не указаны используется MENU_ACTIONS_DEFAULT, который равен MenuAction_Select|MenuAction_Cancel|MenuAction_End

// Запросим события отображения содержимого пунктов, отображения меню, выбора пункта и отмены:
Menu hMenu = new Menu(MenuHandler_MyMenu, MenuAction_Cancel|MenuAction_Select|MenuAction_Display|MenuAction_DisplayItem);
Обратный вызов со всеми доступными событиями (кроме Start) и примером их использования
PHP:
// Для удобства переименовал параметры
public int MenuHandler_MyMenu(Menu hMenu, MenuAction action, int iClient, int iItem)
{
    switch(action)
    {
        case MenuAction_End:    // Меню завершилось
        {
            // Оно нам больше не нужно. Удалим его
            delete hMenu;
        }
        case MenuAction_Cancel:    // Меню было отменено
        {
            if(iItem == MenuCancel_ExitBack)    // Если игрок нажал кнопку "Назад"
            {
                // Отправим ему сообщение что нет возможности вернуться назад.
                // Бывает же что конопку "Назад" назад добавили там, где это не нужно
                PrintToChat(iClient, "Извините, но назад вернуться нельзя!");
            }
        }
        case MenuAction_Display:    // Меню отображено игроку
        {
            // Изменим заглавие
            char szTitle[128];
            FormatEx(szTitle, sizeof(szTitle), "%T", "фраза_из_перевода", iClient);
            (view_as<Panel>(iItem)).SetTitle(szTitle); // iItem имеет тип int, его нужно привести к типу Panel и использовать метод SetTitle для установки заглавия.
        }
        case MenuAction_Select:    // Игрок выбрал пункт
        {
            char szInfo[64], szTitle[128];
            hMenu.GetItem(iItem, szInfo, sizeof(szInfo), _, szTitle, sizeof(szTitle));
            PrintToChat(iClient, "Вы выбрали пункт: %i (%s, инфо: %s)", iItem, szTitle, szInfo);
        }
        case MenuAction_DisplayItem:    // Пункт будет отображен игроку (его содержимое)
        {
            // Изменим его
            char szItem[128], szTitle[128];
            hMenu.GetItem(iItem, _, _, _, szTitle, sizeof(szTitle));    // Получим название пункта и используем его имя фразы в переводе
            FormatEx(szItem, sizeof(szItem), "%T", szTitle, iClient);
            return RedrawMenuItem(szItem); // Изменяем отображаемый текст пункта
        }
        case MenuAction_DrawItem:    // Пункт будет отображен игроку (его стиль)
        {
            // Давайте скроем пункты с описанием "hide" и сделаем недоступными пункты с описанием "block"
            char szInfo[64];
            hMenu.GetItem(iItem, szInfo, sizeof(szInfo));
            if(strcmp(szInfo, "hide") == 0)
            {
                return ITEMDRAW_RAWLINE;
            }

            if(strcmp(szInfo, "block") == 0)
            {
                return ITEMDRAW_DISABLED;
            }
        }
    }

    return 0;
}

<= К содержанию
 
Последнее редактирование:
Сверху Снизу