Добавлен , опубликован

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

Содержание:

Button без импорта, только кодом

кратко: здесь мы попытаемся использовать только jass / lua код без fdf-импорта. Есть такие люди, которым не очень нравится копаться в импорте
Fdf имеет приятные функции, но если бы я хотел, чтобы кнопка, показывающая изображение, могла быть создана только с помощью кода? Да, с помощью BlzCreateFrameByType можно создавать новые пустые фреймы на основе FrameType и давать им новые имена, и даже наследовать/копировать другие фреймы. Можно создать GLUEBUTTON с родительским GameUI и BACKDROP, используя созданную Button в качестве родителя. Также потребуется имитировать положение и размер, которые обрабатывает BlzFrameSetAllPoints. Каждая из них - это всего лишь одна строка кода
.
Короче, мы создали код, и использовали для этого фальшивое имя, которое нигде в варкрафте в файлах не указано. Нигде в fdf, мы создали пустышку.
код
 do
    local real = MarkGameStarted
    function MarkGameStarted()
        real()
--Create a "GLUEBUTTON" named "Facebutton", the clickable Button, for game UI
    local buttonFrame = BlzCreateFrameByType("GLUEBUTTON", "FaceButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
--Create a BACKDROP named "FaceButtonIcon", the visible image, for buttonFrame.
    local buttonIconFrame = BlzCreateFrameByType("BACKDROP", "FaceButtonIcon", buttonFrame, "", 0)
--buttonIconFrame will mimic buttonFrame in size and position
    BlzFrameSetAllPoints(buttonIconFrame, buttonFrame)
--Set a Texture
    BlzFrameSetTexture(buttonIconFrame, "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn", 0, true)
-- Place the buttonFrame to the center of the screen
    BlzFrameSetAbsPoint(buttonFrame, FRAMEPOINT_CENTER, 0.4, 0.3)
-- Give that buttonFrame a size
    BlzFrameSetSize(buttonFrame, 0.05, 0.05)
    end
end
И у нас получилась кнопка с изображением:
Однако, получилась лишь картинка. Нет ни эффектов нажатия клавиши, ни свечения. В триггерах события фреймов ловят и клик, и что мышь в фрейм и так далее. можно ли свечения сделать только с помощью кода?
Да, вы видите пустую строку после parentFrame в BlzCreateFrameByType, это имя мэйнфрейма, от которого наследуется новый фрейм. У нас в игре близзарды сделали кучу шаблонов всяких кнопок, и вы можете брать и копировать их значения. Вам не нужно залезать в fdf и изменять значения.

Образцы. Inherit (наследование)

Inherit - это метод в fdf-file, при котором копируются данные другого фрейма, следует копировать только знакомые типы фреймов. При использовании BlzCreateFrameByType можно наследовать данные / поведение от загруженного мэйнфрейма, фрейма с его заголовком вне тела фрейма, записав имя фрейма. Фрейм, который хочется унаследовать.
Для свечения нам нужен мэйнфрейм с ControlMouseOverHighlight или ControlFocusHighlight, в зависимости от желаемого поведения. Унаследованные childrenFrames недоступны с помощью BlzGetFrameByName и не получают handleId. С выпуском собственного BlzFrameGetChild в V1.32.6 можно получить унаследованные дочерние фреймы во время выполнения, в 1.32.6 этот собственный игнорирует String
По умолчанию загружены 2 КНОПКИ, которые могут быть унаследованы для свечения:
"IconButtonTemplate" (синий)
"ScoreScreenTabButtonTemplate" (yellow)
Можно посмотреть образцы кнопок вот здесь. Зачем эта ссылка нужна? чтобы не терять время и сразу посмотреть на эти Button. Есть конечно вот это, но вы убьете слишком много времени. Я именно так и поступал.
код
BlzCreateFrameByType("GLUEBUTTON", "MyFrameName", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "IconButtonTemplate", 0)
//или
BlzCreateFrameByType("GLUEBUTTON", "MyFrameName", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
Предыдущий пример с желтым свечением.
код
 do
    local real = MarkGameStarted
    function MarkGameStarted()
        real()
--Create a "GLUEBUTTON" named "Facebutton" inheriting "ScoreScreenTabButtonTemplate", the clickable Button, for game UI
    local buttonFrame = BlzCreateFrameByType("GLUEBUTTON", "FaceButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
--Create a BACKDROP named "FaceButtonIcon", the visible image, for buttonFrame.
    local buttonIconFrame = BlzCreateFrameByType("BACKDROP", "FaceButtonIcon", buttonFrame, "", 0)
--buttonIconFrame will mimic buttonFrame in size and position
    BlzFrameSetAllPoints(buttonIconFrame, buttonFrame)
--Set a Texture
    BlzFrameSetTexture(buttonIconFrame, "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn", 0, true)
-- Place the buttonFrame to the center of the screen
    BlzFrameSetAbsPoint(buttonFrame, FRAMEPOINT_CENTER, 0.4, 0.3)
-- Give that buttonFrame a size
    BlzFrameSetSize(buttonFrame, 0.05, 0.05)
    end
end
Button Action
В большинстве случаев, когда кто-то создает кнопку, эта кнопка должна что-то делать, когда пользователь нажимает на нее. В Warcraft 3 это делается через триггеры и события. Самый простой FrameEvent для кнопок - FRAMEEVENT_CONTROL_CLICK, он происходит, когда пользователь отпускает левую кнопку MouseButton, когда начальный щелчок мыши находился внутри кнопки, или когда кнопка находится в фокусе, а пользователь нажимает кнопку return / space.
Пример кода, который выводит сообщение на экран при нажатии кнопки, когда она была зарегистрирована с помощью ButtonAddAction:
код
function ButtonClickAction takes nothing returns nothing
    BJDebugMsg("Button Clicked")
endfunction

function ButtonAddAction takes framehandle buttonFrame returns nothing
    local trigger buttonEventTrigger = CreateTrigger()
    call TriggerAddAction(buttonEventTrigger, function ButtonClickAction)
    call BlzTriggerRegisterFrameEvent(buttonEventTrigger, buttonFrame, FRAMEEVENT_CONTROL_CLICK)
endfunction
Focus
кратко: это из серии фокуса
После того, как button была нажата (с помощью мыши), она сохранит фокус ввода щелкающего игрока. Блокирование большинства горячих клавиш и событий OSKEY, пока они находятся в фокусе, даже без привязанного триггера или FrameEvent. Вы можете удалить этот фокус с нажатой кнопки, отключив и включив нажатую кнопку внутри TriggerAction, после чего она теряет фокус при щелчке. Пользователь также может удалить фокус с помощью щелчка левой кнопкой мыши на игровой площадке.
код
function ButtonClickAction takes nothing returns nothing
    BJDebugMsg("Button Clicked")
    if GetLocalPlayer() == GetTriggerPlayer() then
      call BlzFrameSetEnable(BlzGetTriggerFrame(), false)
      call BlzFrameSetEnable(BlzGetTriggerFrame(), true)
   endif
endfunction
К сожалению, этот метод может привести к ошибке, когда при нажатии кнопки и отпускании нажатой клавиши со стрелкой почти одновременно с камерой будет продолжаться панорамирование даже без удерживания клавиши со стрелкой (обнаружено дядей), еще один щелчок мыши пользователем где-то останавливается. автоматическое панорамирование.

TextButton без импорта FDF

Многим нужна дополнительная кнопка, на которую можно щелкнуть, при нажатии на нее что-то должно произойти. Давайте создадим GLUETEXTBUTTON, похожий на кнопки в диалогах. Их имя - «ScriptDialogButton». Но в игре есть жестко запрограммированное поведение для «ScriptDialogButton» при использовании диалогов. Поэтому использование BlzCreateFrame может закончиться некоторыми проблемами. Этой проблемы можно избежать, если BlzCreateFrameByType присвоит нашим фреймам другое имя. Тогда нет коллизии с использованием Dialog. (Сабэ нашла эту проблему)
код
do
    local real = MarkGameStarted
 function MarkGameStarted()
        real()
    -- create a new Button which inherits from "ScriptDialogButton"
    local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
    -- place the Button to the center of the Screen
    BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
    -- set the Button's text
    BlzFrameSetText(button, "My Button Text")

    -- create the trigger handling the Button Clicking
    local trigger = CreateTrigger()
   
    -- register the Click event
    BlzTriggerRegisterFrameEvent(trigger, button, FRAMEEVENT_CONTROL_CLICK)

    -- this happens when the button is clicked
    TriggerAddAction(trigger, function()
        local frame = BlzGetTriggerFrame()
        print(BlzFrameGetName(frame),"was Clicked")
    end)
 end
end
Можно создать синюю кнопку с «DebugButton» вместо «ScriptDialogButton».

IconButton без импорта FDF

Еще одна распространенная вещь - создание кнопки, визуально представленной CommandButton-Icon. Здесь создается 2 фрейма: button, интерактивная часть и backdrop, показывающий изображение.
код
do
    local real = MarkGameStarted
 function MarkGameStarted()
        real()
    -- create a new BUTTON inheriting from "ScoreScreenTabButtonTemplate". With the inherit one gains a yellow on mouse hover glowing and blocks right clicks onto the button from reaching the ground below the button
    local button = BlzCreateFrameByType("BUTTON", "MyIconButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
    --create a BACKDROP for Button which displays the Texture
    local buttonIconFrame = BlzCreateFrameByType("BACKDROP", "MyIconButtonIcon", button, "", 0)
    -- buttonIcon will mimic buttonFrame in size and position
    BlzFrameSetAllPoints(buttonIconFrame, button)
    -- place the Button to the left center of the Screen
    BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.1, 0.3)
    -- set the Button's Size
    BlzFrameSetSize(button, 0.03, 0.03)
    -- set the texture
    BlzFrameSetTexture(buttonIconFrame, "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn", 0, false)
 

    -- create the trigger handling the Button Clicking
    local trigger = CreateTrigger()
   
    -- register the Click event
    BlzTriggerRegisterFrameEvent(trigger, button, FRAMEEVENT_CONTROL_CLICK)

    -- this happens when the button is clicked
    TriggerAddAction(trigger, function()
        local frame = BlzGetTriggerFrame()
        print(BlzFrameGetName(frame),"was Clicked")
    end)
 end
end
Есть еще одна загруженная опция наследования «IconButtonTemplate» (синий цвет).

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