• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

HoverOriginButtonV1.3

Introduction


HoverOriginButton is a system (vjass or Lua) for Warcraft 3 V1.31 or higher. It tells when the local player is hovering an origin button like command, item buttons and provides a way to run code in that moment.

I created this because, the Tooltip approach to detect hovering originbuttons can only be done once per map. And so that systems don't have to fight over that feature, that fighting would break other systems.

This System can not run GUI triggers, because of its async nature.

How to Install:


Copy Paste into your map the appropriated one, either from the map or taking it from the Code Section below.
HoverOringButton vjass
HoverOriginButton Lua​

HoverOriginButton V1.3+ is not compatible with HoverOriginButton V1.2 and lower because of api interface changes. The vjass version was revamped and upgraded. For Lua the everyTime parameter HoverOriginButton.Add was pushed to the last spot.

Code:


JASS:
library HoverOriginButton initializer Init requires optional FrameLoader
/* HoverOriginButtonV1.3 by Tasyen
 This System gives a easy way to setup callbacks when a Origin-SimpleButton is hovered. It uses Tooltips hence the executed callbacks are async.
 I created this because one can do this Tooltip approach only once per map so that systems don't have to fight over that feature but use it.

function HoverOriginButtonAdd takes code action returns triggercondition
    the action happens when the user starts hovering a button
    action the callback
    use HoverOriginButton_ActionButtonIndex, HoverOriginButton_ActionOFrameType & HoverOriginButton_ActionNewHovered to know the current hovered Button
    function()
        yourCode
        yourCode
    end
    returns the new objects can be used for HoverOriginButtonRemove
function HoverOriginButtonAddClose takes code action returns triggercondition
    add a callback that happens when the user stops hoveringer a Command/Item Button, async.
    function()
        yourCode
        yourCode
    end
function HoverOriginButtonRemove takes triggercondition action returns nothing
    removes the table from the callback List

*/
globals
    //System Globals
    public framehandle array Frames
    public timer Timer
    public integer SectionSize = 30    //Size Given to each originFrameType
    public integer LastFrameIndex = 0
    public integer LastSelectedIndex = -1
    public real timeOut = 1/32.0 // How Fast is the Syste,m

    // Custom ActionIntegerFace
    public integer ActionButtonIndex = -1
    public originframetype ActionOFrameType
    public boolean ActionNewHovered
    public trigger Actions
    public trigger ActionsClose
endglobals
// ===========
// Custom Action Interface
// ===========
// default is setuped to push functions Actions & ActionsClose
private function HoverAction takes originframetype oFrameType, integer buttonIndex, boolean newHovered returns nothing    
    set ActionOFrameType = oFrameType
    set ActionButtonIndex = buttonIndex
    set ActionNewHovered = newHovered
    call TriggerEvaluate(Actions)
endfunction
private function HoverActionClose takes originframetype oFrameType returns nothing
    set ActionOFrameType = oFrameType
    call TriggerEvaluate(ActionsClose)
endfunction

function HoverOriginButtonAdd takes code action returns triggercondition
    return TriggerAddCondition(Actions, Condition(action) )
 endfunction
 function HoverOriginButtonAddClose takes code action returns triggercondition
    return TriggerAddCondition(ActionsClose, Condition(action) )
 endfunction
 function HoverOriginButtonRemove takes triggercondition action returns nothing
    call TriggerRemoveCondition(Actions, action)
    call TriggerRemoveCondition(ActionsClose, action)
 endfunction
// ===========
// System Code
// ===========

private function CreateTooltipForOrigin takes originframetype oFrameType, integer first, integer last returns nothing
    local integer i = first
    local integer baseIndex = GetHandleId(oFrameType)*SectionSize
    local framehandle oFrame
    local framehandle newFrame
    loop
        exitwhen i > last        
        set oFrame  = BlzGetOriginFrame(oFrameType, i)
        set newFrame = BlzCreateFrameByType("SIMPLEFRAME", "", oFrame, "", 0)
        call BlzFrameSetTooltip(oFrame, newFrame)
        call BlzFrameSetVisible(newFrame, false)
        set Frames[baseIndex + i] = newFrame
        set i = i + 1
    endloop
    if LastFrameIndex < baseIndex + i then
        set LastFrameIndex = baseIndex + i
    endif
endfunction

private function TimerAction takes nothing returns nothing
    local boolean selectedAnything  = false
    local integer int 
    local integer originFrameIndex
    local integer buttonIndex
    local boolean newOneHovered
    set int = 0
    loop
        exitwhen int > LastFrameIndex
        if BlzFrameIsVisible(Frames[int]) then
            set selectedAnything = true

            // the new selected is not the same as the current one?
            set newOneHovered = LastSelectedIndex != int
            set LastSelectedIndex = int
            set originFrameIndex = int/SectionSize
            set buttonIndex = int - originFrameIndex*SectionSize
            //if newOneHovered then
                //call BJDebugMsg("TotalIndex"+I2S(int)+ " Origin"+I2S(originFrameIndex) + " button"+I2S(buttonIndex))
            //endif
            call HoverAction(ConvertOriginFrameType(originFrameIndex), buttonIndex, newOneHovered)
            exitwhen true
        endif
        set int = int + 1
    endloop
       

    // now selects nothing?
    if not selectedAnything and LastSelectedIndex != - 1 then
        set originFrameIndex = LastSelectedIndex/SectionSize
        call HoverActionClose(ConvertOriginFrameType(originFrameIndex))
        set LastSelectedIndex = -1
    endif
       
endfunction
private function InitFrames takes nothing returns nothing
    call CreateTooltipForOrigin(ORIGIN_FRAME_COMMAND_BUTTON, 0, 11)
    call CreateTooltipForOrigin(ORIGIN_FRAME_ITEM_BUTTON, 0, 5)
    call CreateTooltipForOrigin(ORIGIN_FRAME_HERO_BUTTON, 0, 6)
    call CreateTooltipForOrigin(ORIGIN_FRAME_SYSTEM_BUTTON, 0, 3)
    call CreateTooltipForOrigin(ORIGIN_FRAME_MINIMAP_BUTTON, 0, 4)

    call TimerStart(Timer, timeOut, true, function TimerAction)
endfunction 
private function At0s takes nothing returns nothing
    call InitFrames()
endfunction
 private function Init takes nothing returns nothing
    set Timer = CreateTimer()
    set Actions = CreateTrigger()
    set ActionsClose = CreateTrigger()
    call TimerStart(Timer,0 ,false, function At0s)
    // Frame related code actions are not saved/Loaded, probably repeat them after Loading the game
    static if LIBRARY_FrameLoader then
        call FrameLoaderAdd(function InitFrames)
    endif
endfunction
 

endlibrary
Lua:
--[[ HoverOriginButton V1.3 by Tasyen
This System gives a easy way setup callbacks when a originframe Button is hovered. It uses Tooltips hence the executed callbacks are async.
I created this because one can do this Tooltip approach to know hovering only once per map so that systems don't have to fight over that feature but use it.

function HoverOriginButton.Add(originframeType, function(buttonIndex) end[, everyTime])
    originframeType ORIGIN_FRAME_COMMAND_BUTTON or ORIGIN_FRAME_HERO_BUTTON ...
    everyTime (false) only happens when the current Frame was not hovered lastTime.
    action the callback
    function(buttonIndex)
        yourCode
        yourCode
    end
    returns the new objects can be used for HoverOriginButton.Remove
function HoverOriginButton.AddClose(function() end)
    add a callback that happens when the user stops hoveringer a Command/Item Button, async.
    function()
        yourCode
        yourCode
    end
function HoverOriginButton.Remove(object)
    removes the table from the callback List
--]]
do
    HoverOriginButton = {}
    local SystemSpeed = 1/32.0 -- How Fast is the System
    local this = HoverOriginButton
    local function CreateTooltipForOrigin(originframeType, firstIndex, lastIndex)        
        for int = firstIndex, lastIndex do
            local button = BlzGetOriginFrame(originframeType, int)
            local frame = BlzCreateFrameByType("SIMPLEFRAME", "", button, "", 0)
            BlzFrameSetTooltip(button, frame)
            BlzFrameSetVisible(frame, false)
            this[frame] = {originframeType, int}
            table.insert(this.Frames, frame)
         end
    end
    local function CreateTooltipForBuffs(firstIndex, lastIndex)
        if ORIGIN_FRAME_UNIT_PANEL_BUFF_BAR then
            local parent = BlzGetOriginFrame(ORIGIN_FRAME_UNIT_PANEL_BUFF_BAR, 0)
            for int = firstIndex, lastIndex do
                local button = BlzFrameGetChild(parent, int)
                local frame = BlzCreateFrameByType("SIMPLEFRAME", "", button, "", 0)
                BlzFrameSetTooltip(button, frame)
                BlzFrameSetVisible(frame, false)
                this[frame] = {ORIGIN_FRAME_UNIT_PANEL_BUFF_BAR, int}
                table.insert(this.Frames, frame)
             end
        end
        
    end
local function InitFrames()
    this.Frames = {}
    local frame, button, CurrentSelectedButtonIndex, selectedAnything

    CreateTooltipForOrigin(ORIGIN_FRAME_COMMAND_BUTTON, 0, 11)
    CreateTooltipForOrigin(ORIGIN_FRAME_ITEM_BUTTON, 0, 5)
    CreateTooltipForOrigin(ORIGIN_FRAME_HERO_BUTTON, 0, 6)
    CreateTooltipForOrigin(ORIGIN_FRAME_SYSTEM_BUTTON, 0, 3)
    CreateTooltipForOrigin(ORIGIN_FRAME_MINIMAP_BUTTON, 0, 4)
    CreateTooltipForBuffs(0, 7)

    button = nil
    frame = nil
     -- saves the last selected Button, async
     CurrentSelectedButtonIndex = nil
    TimerStart(this.Timer, SystemSpeed, true, function()
       selectedAnything = false   
       -- loop all tooltips and check for the visible one
       for tooltipIndex, tooltip in ipairs(this.Frames) do
           if BlzFrameIsVisible(tooltip) then
               selectedAnything = true
                local actionType = this[tooltip][1]
                local buttonIndex = this[tooltip][2]
               -- the new selected is not the same as the current one?
               for _, v in ipairs(this.Actions[actionType]) do
                if CurrentSelectedButtonIndex ~= tooltipIndex or v[2] then
                    v[1](buttonIndex)
                end                 
               end
               CurrentSelectedButtonIndex = tooltipIndex        
           end
       end

       -- now selects nothing?
       if not selectedAnything and CurrentSelectedButtonIndex then
          for _, v in ipairs(this.ActionsClose) do v[1]() end
            CurrentSelectedButtonIndex = nil
       end
       
   end)
 end
 local function Init()
    this.Timer = CreateTimer()
    InitFrames()
    if FrameLoaderAdd then FrameLoaderAdd(InitFrames) end
    this.Actions = {}
    this.ActionsClose = {}
 end
 function HoverOriginButton.Add(originframeType, action, everyTime)
    if not this.Timer then Init() end
    if not everyTime then everyTime = false end
    local object = {action, everyTime}
    if not originframeType then  originframeType = ORIGIN_FRAME_COMMAND_BUTTON end
    if not this.Actions[originframeType] then this.Actions[originframeType] = {} end
    table.insert(this.Actions[originframeType], object)
    return object
 end
 function HoverOriginButton.AddClose(action)
    if not this.Timer then Init() end
    local object = {action}
    table.insert(this.ActionsClose, object)
    return object
 end
 function HoverOriginButton.Remove(object)
    for _, actions in pairs(this.Actions) do
        for i, v in ipairs(actions) do
            if v == object then
                table.remove(actions, i)
                return
            end
        end
    end
    for i, v in ipairs(this.ActionsClose) do
        if v == object then
            table.remove(this.ActionsClose, i)
            return
        end
    end
 end
end

Changelog


Changes:
V1.3
Changed api
(vjass) supports more originframetypes
Migrate from Code Archive
V1.1
V1.2 (lua) supports more originframetypes
V1.1 (lua) API functions became a table member of HoverOriginButton

Tags: UI, Custom UI, Hover, Tooltip​
Contents

HoverOriginButtonV1.3 (Map)

Reviews
Antares
Migrated resource from the Code Archive section. Approved by @Bribe : "Approved. API is a wrapper of sorts for the BlzOriginButton natives, which users can find more information on here: WC3 Modding Information Center - Jass documentation Database...
Top