Основы Интерфейса

Содержание:
SimpleButton - это интерактивный Simpleframe. Это довольно мощный инструмент для Simpleframe.
Перечислим все факты:
  • можно триггерами переместить за пределы экрана 4:3
  • по нему можно щелкнуть, запустив FRAMEEVENT_CONTROL_CLICK. К сожалению, это единственное событие, которое доступно этому simple button. А еще нельзя повесить на эту кнопку несколько событий, при регистре событий старое событие заменяется на новое
  • при нажатии на simple button фокус не удерживается, короче не происходит залипания клавиатуры.
  • simple button контролирует пространство на экране, поэтому в этом месте нельзя заказывать / выбирать юнитов
  • каждая SIMPLEBUTTON может иметь только одно событие FRAMEEVENT_CONTROL_CLICK, когда одно регистрирует другое (для того же SimpleButton) предыдущее событие больше не срабатывает.
  • Для simple frame всплывающей подсказкой (tooltip) может быть только другие главные simpleframes. Хорошим выбором является SIMPLEFRAME. Внутри тела SIMPLEFRAME в fdf можно запихать потомков, которые будут появляться при наведении мыши на simple frame или исчезать.

Нельзя динамично изменять функциональные дочерние элементы

У SIMPLEBUTTON могут быть функциональные дочерние элементы, которые имеют текстуры для разных состояний, и разные строки для этих состояний.
списки fdf-настроек для SIMPLEBUTTON
NormalTexture <активная текстура>
DisabledTexture <отключенная текстура>
PushedTexture <текстура при нажатии>
CheckedTexture <галочка/флаг для Checkbox>
UseHighlight <текстура при наводке курсора>
NormalText <активный string>
DisabledText <string при отключении>
HighlightText <string при наводке курсора>
Эти функциональные дочерние элементы статичны и недоступны для BlzGetFrameByName, что делает их плохими для динамических кнопок с иконками. Вот с обычными кнопками button, gluebutton такое не будет происходить. Это только SimpleButton так.

Что значит статичны и недоступны?

Пример, есть fdf-file:
Texture "MyNormalTexture" {
   File "ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp",
}
Frame "SIMPLEBUTTON" "MySimpleButton" {
   Width 0.039,
   Height 0.039,
   NormalTexture "MyNormalTexture",
}
Я решил создать триггерно фрейм MySimpleButton, и изменить изображение MyNormalTexture. Но изображение не меняется. Причиной как мне кажется является то, что текстура MySimpleButton не является дочерним элементом, и мы не можем изменять текстуру. Как было указано в fdf, так и осталось. Вот пример триггеров:
код
//Create "HeroSelectorButton", for game UI
local framehandle buttonFrame = BlzCreateSimpleFrame("MySimpleButton", BlzGetOriginFrame ( ORIGIN_FRAME_GAME_UI, 0 ), 0)
//By Having created "HeroSelectorButton" also its children are created, this children are accessed using BlzGetFrameByName right after the creation or later one if the slots were not taken by other frames.
local framehandle buttonIconFrame = BlzGetFrameByName("MyNormalTexture", 0)
//Set a Texture
call BlzFrameSetTexture(buttonIconFrame, "ReplaceableTextures\\CommandButtons\\BTNPeasant.blp", 0, true)
// Place the buttonFrame to the center of the screen
    call BlzFrameSetAbsPoint(buttonFrame, FRAMEPOINT_CENTER, 0.7, 0.3)
// Give that buttonFrame a size
    call BlzFrameSetSize(buttonFrame, 0.039, 0.039)

Изменение текстуры кнопки

Переводчик: нашелся способ динамически изменять текстуру и строку в игре. Их в fdf-file не нужно прописывать в Control. Их нужно прописать внутри тела главного фрейма - simple button. Спасибо автору хайва
Для IconButton лучше создать SIMPLEBUTTON с дочерней текстурой, чтобы можно было изменять текстуру во время игры.
Это будет определение такой IconButton внутри fdf:
Frame "SIMPLEBUTTON" "MySimpleButton" {
    Width 0.039,
    Height 0.039,
    Texture "MySimpleButtonTexture" {
    }
} 
Во время игры можно было создать с помощью BlzCreateSimpleFrame «MySimpleButton» для этого фрейма и установить текстуру «MySimpleButtonTexture» с помощью BlzFrameSetTexture.
Код Lua, который создает эту кнопку со значком Паладина. Когда кнопка нажата, она печатает «Button Click»:
lua код
do
    local real = MarkGameStarted
  function MarkGameStarted()
        real()
    BlzLoadTOCFile("war3mapImported\\MySimpleButton.toc")

    local trigger = CreateTrigger()
    TriggerAddAction(trigger, function()
        print("Button Click")
        -- SimpleButton does not keep the focus.
    end)
    local button = BlzCreateSimpleFrame("MySimpleButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0)
    BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.9, 0.3)
    BlzFrameSetTexture(BlzGetFrameByName("MySimpleButtonTexture", 0), "ReplaceableTextures\\CommandButtons\\BTNHeroPaladin", 0, true)
    BlzTriggerRegisterFrameEvent(trigger, button, FRAMEEVENT_CONTROL_CLICK)
  end
end
Если кто-то хочет, чтобы при наведении курсора на кнопку он светился, можно добавить функциональный дочерний фрейм к SIMPLEBUTTON внутри fdf. Пример Highlight - это желтый свет, который отображается на экране результатов.
Texture "MySimpleButtonButtonHighlight" {
    File "UI\Glues\ScoreScreen\scorescreen-tab-hilight.blp",
    AlphaMode "ADD",
}
Frame "SIMPLEBUTTON" "MySimpleButtonGlowing" {
    Width 0.039,
    Height 0.039,
    UseHighlight "MySimpleButtonButtonHighlight",
    Texture "MySimpleButtonTexture" {
    }
}
Вывод:
если в fdf файле главному simple frame прописать потомков внутри тела. То они будут работать как единое целое. Если кнопка исчезнет, то и потомки исчезнут. Для Texture, String, Layer большего и не нужно, они все равно не могут как отдельные фреймы существовать.

Проваливается текстура кнопки в текстурах? Мини-недостаток и решение

К сожалению, добавление Texture внутри SimpleButton выявило новую ошибку. Это происходит не всегда, я это выявил в последний момент. По каким-то причинам видно бывает только часть текстуры, а другую часть закрывает темная полоса (см. скриншот ниже, тут все кнопки самодельные фреймы). Всегда по-разному закрывает, почему так происходит - загадка.
Методом тыка я это решал давно, недавно снова всплыла эта ошибка, и я так долго возился. И разобрался. Ответ: если присмотреться в fdf-file, то texture добавлена в SimpleButton как отдельный фрейм, и никак не связана с кнопкой. текстура словно "проваливается", и это происходит с верхними кнопками. Догадался, что там лежит консольная текстура, и мне нужно поднять уровень кнопки с1-level на 2, а с ней и текстура поднимется.

Снова проваливается текстура simplebutton во фреймах?

Хотел создать динамичный инвентарь. Была создать функция, в зависимости от заданных параметров (строки и столбцов), задается кол-во кнопок, и снизу по краям крайних кнопок натягивают фон.
Изначально, кнопки были обычными BUTTON. Но из-за залипании, решил переделать на simplebutton, а фон так и останется backdrop.
Но тут произошел шок. backdrop их закрыл, а simplebuttons остались внизу. По сути, их не видно. Все перепробовал, чтобы поднять их. И уровень менял, и родителей менял, совал в файл fdf backdrop. Итд. Ничего не помогало.
Hate: simpleframes всегда будут ниже обычных функциональных фреймов. Функциональные фреймы это же фреймы меню, когда открываешь меню, они всегда выше simpleframes создаются. Пп: До меня это было как литр воды
Решение:
попытаться создать simplebutton дополнительные фреймы: изображения (backdrops), свечения (hightlight). Чтобы была видна на фоне. Simplebutton можно сделать абсолютной пустышкой, главной размер и координаты задайте на экране.

Шаблон. + эффект продавливания

Кратко: это просто бонус, можно кнопке всякие эффекты задавать.
Во всех fdf-files нашел только единственный пример использования текстур в "ui\framedef\ui\upperbuttonbar.fdf" содержит использование метелицей для этого. Я взял с шаблона UpperButtonBarButtonTemplate, и переписал тот код, еще немного изменив код PushedTexture, чтобы был эффект клика или продавливания:
fdf код
//IncludeFile "UI\FrameDef\UI\EscMenuTemplates.fdf", //подключаем файл

    Texture "MyNormalTexture" {
        File "ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp",
    }

    Texture "MyPushedTexture" {
//0.008-0.0010 если размер MyPushedTexture меньше от реального 0.039x0.039, то получается эффект продавливания. Только учтите, если триггерно задать размер кнопки MySimpleButton, то будет очень сильное продавливаться, что не очень хорошо. Триггерно размеры MyPushedTexture изменить нельзя
        Width 0.038,
        Height 0.038,
        File "ReplaceableTextures\CommandButtons\BTNSelectHeroOn.blp",
    }

    Texture "MyDisabledTexture" {
        File "ReplaceableTextures\CommandButtonsDisabled\DISBTNSelectHeroOn.blp",
    }

    Texture "MyButtonHighlight" {
        File "UI\Widgets\EscMenu\Orc\orc-options-button-highlight.blp",
        AlphaMode "ADD",
        //File "UI\Glues\ScoreScreen\scorescreen-tab-hilight.blp",
        //AlphaMode "ADD",
    }

Frame "SIMPLEBUTTON" "MySimpleButton" {
    Width 0.039,
    Height 0.039,
    //ButtonPushedTextOffset 0.001 -0.001, //<- эта строчка для текста, а не для иконок
    NormalTexture "MyNormalTexture",
    PushedTexture "MyPushedTexture",
    DisabledTexture "MyDisabledTexture",
    UseHighlight "MyButtonHighlight",
}
Но даже изменивший выше fdf-код, который я записал внутрь тела фрейма SimpleButton, не смог изменить текстуры в игре. Видимо, это происходит из-за функции, записывающие для кнопки текстуры для разных состоянии. Обычно изменить текстуру можно без этих функции, но тогда не работают некоторые эффекты.
Вывод: выше fdf-код не является динамичным, т.к. в игре для каждой текстуры придется прописывать свою SimpleButton со всеми Textures. Короче, нельзя изменить текстуры MyNormalTexture, MyPushedTexture, MyButtonHighlight, MyButtonHighlight (спецэффект можно оставить без изменений).
Можно обойти все ограничения SimpleButton с помощью других фреймов и костылей. Пример, вы можете кнопке задать какое-то одно изображение, пример В нормальное состояние он такой (NormalTexture). Для добавления подсказки Tooltip использовать помощью фрейма-пустышки. Можно ловить когда курсор входит в фрейм (событие входа), и создавать текстуру свечения эффекта, а при выходе (событие выхода) удалять/прятать (UseHighLight). В выключенном состоянии вы можете наложить затемненную полупрозрачную слой-текстуру с затемненными краями или просто заменить текстуру (DisabledTexture). А при клике вы можете на секунду таймером сплющить размер, и показать обратно (будет PushedTexture). Если нужно, еще и при клике звук отыграем. Но правда это очень неудобно, проще использовать GlueButton. Причин отказываться от GlueButton я не нашел.

Содержание
`
ОЖИДАНИЕ РЕКЛАМЫ...