lotrointerface.com
Search Downloads

LoTROInterface SVN SortPack

[/] [trunk/] [JackdawPlugins/] [SortPack/] [Bag.lua] - Rev 158

Go to most recent revision | Compare with Previous | Blame | View Log

--Needs a tidy!
--Check the bag datais valid.
if SB==nil then SB={} end
if SB.x==nil then                               SB.x=100                                                end     --}
if      SB.y==nil then                          SB.y=100                                                end     --}Position
if      SB.icx==nil then                        SB.icx=4                                                end     --]
if      SB.icy==nil then                        SB.icy=3                                                end     --]Size, in icons
if      SB.override==nil then   SB.override=false                       end     --Override default bags?
if      SB.labelwidth==nil then         SB.labelwidth=80                        end     --Width of the text label for the group.
if      SB.font==nil then                       SB.font="TrajanPro14"   end     --Label font
if      SB.ShowItem==nil then   SB.ShowItem=true                        end     --un-hide a group when an item is looted in it?


--font size
SB.fontsize=string.sub(SB.font,-2)
if SB.fontsize=="ed" then SB.fontsize=13-1 else SB.fontsize=tonumber(SB.fontsize)-1 end

--Frame padding
pad={top=30,side=15,bottom=10}

--Calculate width and maximum height for the bag.
SB.width=SB.labelwidth+36*SB.icx+2*pad.side
SB.maxheight=Turbine.UI.Display.GetHeight()

--Functions
        --Set the sizes of all the areas of the bag.
        function SortBagSetSize()
                SortBag.ListBox:SetSize( SB.labelwidth+SB.icx*36, SortBag:GetHeight()-(pad.top+pad.bottom)+1)
                SortBag.ScrollBar:SetPosition(SB.labelwidth+SB.icx*36+10,pad.top+5)
                SortBag.ScrollBar:SetHeight(SortBag:GetHeight()-(pad.top+pad.bottom)-10)
                SortBag.Resize:SetPosition(SB.width-10,pad.top+10)
                SortBag.Resize:SetSize(10,SortBag:GetHeight()-2*pad.top-10)
                SortBag.ResizeBack:SetSize(10,SortBag:GetHeight()-pad.top-pad.bottom)
                Search.label:SetSize(SB.labelwidth,SB.fontsize)
        end
        
        --Adjust the sizes of the GroupBoxes.
        function SetGroupBoxSize()
                if GroupBox==nil then return end
                local height=0
                for j=0,#Groups do
                        --Adjust GroupBox Widths
                        GroupBox[j]:SetMaxItemsPerLine(SB.icx)
                        GroupBox[j]:SetWidth(SB.icx*36)
                        
                        --Hide the slot, or adjust its height
                        if Groups[j].hide then 
                                GroupBox[j]:SetHeight(0) 
                                GroupBox[j].label:SetBackColor(Turbine.UI.Color( 1,0.4,0,0 )) 
                        else 
                                GroupBox[j]:SetHeight( math.ceil(GroupBox[j]:GetItemCount()/SB.icx)*36) 
                                GroupBox[j].label:SetBackColor(Turbine.UI.Color( 1,0,0,0.4 ))
                        end
                        
                        --Adjust Label Width,Height
                        GroupBox[j].label:SetWidth(SB.labelwidth)
                        if GroupBox[j]:GetItemCount()>0 then 
                                GroupBox[j].label:SetHeight(SB.fontsize) 
                        else 
                                GroupBox[j].label:SetHeight(0) 
                        end
                        
                        --Add to the height variable
                        height=height+math.max(GroupBox[j]:GetHeight(),GroupBox[j].label:GetHeight())

                end
                if height>SB.maxheight-(pad.top+pad.bottom) then height=SB.maxheight-(pad.top+pad.bottom) end

                --Resize the window to fit the new height NOTE: The SB.fontsize is to accomodate the "search" box
                        SortBag:SetHeight(height+pad.top+pad.bottom+SB.fontsize)
                        
                        --Change the title to show how many empty slots are left
                        SortBag:SetText(GroupBox[0]:GetItemCount().." empty slots left")
        end
        
--Search function now added to the bag!
        Search={}

        Search.label=Turbine.UI.Label()
                Search.label:SetBackColor( Turbine.UI.Color( 1,0.1,0.1,0.1 ) )
                Search.label:SetMultiline(true)
                Search.label:SetTextAlignment( Turbine.UI.ContentAlignment.MiddleCenter )
                Search.label:SetMouseVisible (true)
                Search.label:SetSize(SB.labelwidth,SB.fontsize)
                Search.label.MouseDown=function()
                        Search.Textbox:SetText("")
                        SearchBag()
                end
                
        Search.Textbox=Turbine.UI.TextBox()
                Search.Textbox:SetSize(200,SB.fontsize)
                
                
                --When focus is gained turn updating on so that the plugin will scan the text entered.
                Search.Textbox.FocusGained=function() 
                        Search.Textbox:SetWantsUpdates(true)
                        SearchString=Search.Textbox:GetText()
                end
                Search.Textbox.FocusLost=function() 
                        Search.Textbox:SetWantsUpdates(false)
                end
                Search.Textbox.Update = function()
                        SearchBag()
                end
                
        function SearchBag()
                if SearchString ~= Search.Textbox:GetText() then
                        SearchString = Search.Textbox:GetText()
                        --remove odd characters
                        txt1=string.lower(SearchString)
                        for i=1,size do
                                local item = backpack:GetItem(i)
                                if item~=nil then
                                        local itemInfo=item:GetItemInfo();
                                        local txt2=string.lower(itemInfo:GetName())
                                        if string.find(txt2,txt1) then 
                                                BackpackSlots[i]:SetVisible(true)
                                        else
                                                BackpackSlots[i]:SetVisible(false)
                                        end
                                end
                        end
                end
        end

        --populate the bag.
        function populatebag()          
                SortBag.ListBox:ClearItems()
                
                --Add the search section. Fonts applied here too.
                SortBag.ListBox:AddItem(Search.label)
                SortBag.ListBox:AddItem(Search.Textbox)
                
                Search.Textbox:SetFont(Turbine.UI.Lotro.Font[SB.font])
                Search.label:SetFont(Turbine.UI.Lotro.Font[SB.font])
                Search.label:SetText( "Search" )
                        
                
                GroupBox={}
                BackpackSlots=nil
                BackpackSlots={}
                
                --Check for font size errors
                if SB.labelwidth<SB.fontsize then SB.labelwidth=SB.fontsize end
                
                --Build VirtPack 
                
                VirtPack=analysepack()
                
                ---Build a box for this group of items. Box 0 is for empty slots.
                for i=0,#Groups do
                        GroupBox[i] = Turbine.UI.ListBox()
                        GroupBox[i]:SetOrientation( Turbine.UI.Orientation.Horizontal )
                        
                        GroupBox[i]:SetAllowDrop( true )
                        GroupBox[i].DragDrop = function( sender, args )
                                --Empty slots allow drag-drop. Hopefully!
                                local shortcut = args.DragDropInfo:GetShortcut();

                                if ( shortcut ~= nil ) then
                                        local item = GroupBox[i]:GetItemAt( args.X, args.Y );
                                        local index 
                                        if item==nil then index=1 else index= item.id end
                                        
                                        backpack:PerformShortcutDrop( shortcut, index, Turbine.UI.Control.IsShiftKeyDown() )
                                end
                        end
                end
                
                --Build the backpack Slots.
                for i=1,size do
                        item = backpack:GetItem(i)
                        if item~=nil then AddCallback(item, "QuantityChanged",  BagQuantityChanged) end
                        BackpackSlots[i]=Turbine.UI.Lotro.ItemControl( item )   
                        BackpackSlots[i].id=i --so it can be passed for item swopping.
                        BackpackSlots[i]:SetBackground( "JackdawPlugins/SortPack/Back.tga" )
                        BackpackSlots[i]:SetBlendMode( Turbine.UI.BlendMode.Overlay )
                end
                
                --Move the items into the boxes
                for i=1,#VirtPack do
                        --if i<10 then Turbine.Shell.WriteLine(VirtPack[i].id) end --Re-enable if the "not sorting correctly" bug rears its head again.
                        BackpackSlots[VirtPack[i].id].Group=VirtPack[i].Group
                        GroupBox[VirtPack[i].Group]:AddItem(BackpackSlots[VirtPack[i].id])
                end
                
                --Add the groups to the backpack
                for j=0,#Groups do
                        --Build a label
                        GroupBox[j].label=Turbine.UI.Label()
                                GroupBox[j].label:SetBackColor( Turbine.UI.Color( 1,0,0,0.4 ) )
                                GroupBox[j].label:SetFont(Turbine.UI.Lotro.Font[SB.font])
                                GroupBox[j].label:SetMultiline(true)
                                GroupBox[j].label:SetTextAlignment( Turbine.UI.ContentAlignment.MiddleCenter )
                                GroupBox[j].label:SetText( Groups[j].Name )
                                GroupBox[j].label:SetMouseVisible (true)
                                GroupBox[j].label:SetSize(SB.labelwidth,0)--Initially of height 0
                                GroupBox[j].label.label=true            
                        
                        if j~=0 then 
                                --Add the label and GroupBox, but not for empty slots
                                SortBag.ListBox:AddItem(GroupBox[j].label)                      
                                SortBag.ListBox:AddItem(GroupBox[j])
                        end
                        
                        --Click events for the labels.
                        GroupBox[j].label.MouseClick=function(sender,args)
                                if ( args.Button == Turbine.UI.MouseButton.Left ) then
                                        --Left Clicking the label collapses this group
                                        Groups[j].hide=not(Groups[j].hide)
                                else
                                        --Right clicking either collapses all groups, if this one is shown, or opens all groups if not.
                                                Groups[j].hide=not(Groups[j].hide)
                                        for i=0,#Groups do
                                                Groups[i].hide=Groups[j].hide
                                        end
                                end
                                SetGroupBoxSize()
                        end
                end
                        --Empty Slots group added last.
                        SortBag.ListBox:AddItem(GroupBox[0].label) 
                        SortBag.ListBox:AddItem(GroupBox[0])
                
                --Function refresh the heights of the group boxes               
                SetGroupBoxSize()
        end
        
        --Show the backpack
        function openbag()
                --Clear out any previous search
                Search.Textbox:SetText("")
                SearchString=""
                for i=1,size do BackpackSlots[i]:SetVisible(true) end
                --Show the bag!
                SortBag:SetVisible(true)
        end
        
        --Events here replace the default bags with this one.
        function SBOverride()
                        
                if SB.override then SortBag:SetWantsKeyEvents( true );

                        SortBag.KeyDown = function( sender, args )
                                if ( args.Action == Turbine.UI.Lotro.Action.Escape ) then
                                        SortBag:Close()
                                end

                                if ( args.Action == Turbine.UI.Lotro.Action.ToggleBags or
                                         args.Action == Turbine.UI.Lotro.Action.ToggleBag1 or
                                         args.Action == Turbine.UI.Lotro.Action.ToggleBag2 or
                                         args.Action == Turbine.UI.Lotro.Action.ToggleBag3 or
                                         args.Action == Turbine.UI.Lotro.Action.ToggleBag4 or
                                         args.Action == Turbine.UI.Lotro.Action.ToggleBag5 or
                                         args.Action == Turbine.UI.Lotro.Action.ToggleBag6) 
                                then
                                        if SortBag:IsVisible() then
                                                SortBag:Close()
                                        else
                                                openbag()
                                        end
                                end
                        end
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack1, false )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack2, false )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack3, false )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack4, false )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack5, false )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack6, false )
                else
                        SortBag:SetWantsKeyEvents( false )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack1, true )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack2, true )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack3, true )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack4, true )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack5, true )
                        Turbine.UI.Lotro.LotroUI.SetEnabled( Turbine.UI.Lotro.LotroUIElement.Backpack6, true )
                end
        end
        
        --Next three items update the bag if items are added or removed.


                BagAdd=function( sender, args )
                        --args.Index    = Bag slot
                        --args.Item             = Item object

                        --Remove the slot from the group it is in.
                        
                        for i=0,#Groups do
                                if GroupBox[i]:ContainsItem(BackpackSlots[args.Index]) then GroupBox[i]:RemoveItem(BackpackSlots[args.Index]) end
                        end
                        
                        --Determine which group it belongs to
                        local destination=ItemGroup[ItemCategory[GetCat(args.Item)]]
                        
                        if destination==nil then destination=0 end

                        --Insert the item in that group
                        BackpackSlots[args.Index]:SetItem(args.Item)
                        BackpackSlots[args.Index].Group=destination

                        GroupBox[destination]:InsertItem(position,BackpackSlots[args.Index])
                        
                        if destination~=0 then
                                --Remove every item from that groupbox one at a time and resort them.
                                local temp={}
                                --cycle through the elements checking for weights
                                for i=GroupBox[destination]:GetItemCount(),1,-1 do
                                        temp[i]=GroupBox[destination]:GetItem(i)
                                        temp[i].Weight=weight(temp[i].id)
                                        temp[i].Name=GroupBox[destination]:GetItem(i):GetItem():GetName()
                                end
                                
                                --Remove all the items
                                GroupBox[destination]:ClearItems()
                                
                                --Sort the items according to weight (ignoring alpha. I am happy with this compromise)
                                table.sort(temp, function (a,b) 
                                        if a.Weight == b.Weight then 
                                                --return a.Name < b.Name
                                                --return strip(a.Name)< strip(b.Name)
                                                if revorder then return strip(a.Name)> strip(b.Name) else return strip(a.Name)< strip(b.Name) end
                                        else  
                                                if revorder then return (a.Weight > b.Weight) else return (a.Weight < b.Weight) end
                                        end
                                 end) 
                                
                                --Put the items in the group
                                for i=1,#temp do
                                        GroupBox[destination]:AddItem(temp[i])
                                end             
                        end
                        
                        --Refresh heights
                        SetGroupBoxSize()
                        
                        --Add the quantity changed event
                        AddCallback(args.Item, "QuantityChanged",       BagQuantityChanged)
                        unhide(args.Item)
                end
                
                BagRemove=function( sender, args )
                        --Turbine.Shell.WriteLine("BagRemove "..args.Index)
                        --Note: this is sometimes called when looting *and no item is removed* causing the "empty slot" bug. Annoying, and not my fault!
                        
                        --Also called if a stack is merged.
                        --args.Index    = Bag slot
                        
                        --Remove the quantity changed callback
                        item = backpack:GetItem(args.Index)
                        RemoveCallback(item, "QuantityChanged",         BagQuantityChanged)

                        --Remove item from group
                        GroupBox[BackpackSlots[args.Index].Group]:RemoveItem(BackpackSlots[args.Index])
                        --Make the item for that slot nil
                        BackpackSlots[args.Index]:SetItem(nil)
                        BackpackSlots[args.Index].Group=0
                        --Add it to empty slots.
                        GroupBox[0]:AddItem(BackpackSlots[args.Index])
                        
                        --Refesh Heights
                        SetGroupBoxSize()
                end
                
                BagMove=function( sender, args )
                        --15/12/11 This has changed completely! The notes below are now false.

                        --Turbine.Shell.WriteLine("BagMove Old Index"..args.OldIndex.." New Index "..args.NewIndex)
                        --[[
                        1) If an item has just been moved to an empty slot then just this fires.
                        2) If an item has been swopped with another; Say A in slot n1 with B in slot n2
                                        ItemRemoved fires on slot n1
                                        ItemMoved fires with B from n2 to n1
                                        ItemAdded fires on slot n2 with item A
                        
                        Essentially, item A (the moved item) gets held "in hand" making the target slot empty.
                        
                        Recently I have come to the belief that it is this that causes the bug, and not ItemRemoved.
                        ]]
                                        
                        --args.Item             =Item object of the item that has been moved.
                        --args.NewIndex =Target Slot
                        --args.OldIndex =Destination Slot
                        
                        BackpackSlots[args.NewIndex],BackpackSlots[args.OldIndex]=BackpackSlots[args.OldIndex],BackpackSlots[args.NewIndex]
                        
                        --Refresh heights
                        SetGroupBoxSize()
                        
                end
                
                BagQuantityChanged=function(sender,args)
                        unhide(sender)
                end
                
        function unhide(item)
                if not(SB.ShowItem) then return end
                local destination=ItemGroup[ItemCategory[GetCat(item)]]
                
                if destination==nil then destination=0 end

                --Un-Hide this group
                if Groups[destination].hide then
                        Groups[destination].hide=false
                        SetGroupBoxSize()
                end
        end
                
        AddCallback(backpack, "ItemAdded",                      BagAdd)
        AddCallback(backpack, "ItemRemoved",            BagRemove)
        AddCallback(backpack, "ItemMoved",                      BagMove)
        
--Main Structure; Create the window to hold the backpack slots and populate it.

SortBag = Turbine.UI.Lotro.Window()
        SortBag:SetPosition( SB.x,SB.y )
        SortBag:SetText("SortBag")

SortBag.ListBox = Turbine.UI.ListBox()
        SortBag.ListBox:SetParent( SortBag )
        SortBag.ListBox:SetPosition( pad.side, pad.top )
        SortBag.ListBox:SetMaxItemsPerLine(2)
        SortBag.ListBox:SetOrientation( Turbine.UI.Orientation.Horizontal )
        
        SortBag.ScrollBar=Turbine.UI.Lotro.ScrollBar()
                SortBag.ScrollBar:SetOrientation( Turbine.UI.Orientation.Vertical )
                SortBag.ListBox:SetVerticalScrollBar( SortBag.ScrollBar )
                SortBag.ScrollBar:SetParent(SortBag)
                SortBag.ScrollBar:SetPosition(SB.labelwidth+SB.icx*36+10,pad.top+5)
                SortBag.ScrollBar:SetWidth(10)
        
        --Remove this control when Turbine fix the backpack bug. again.
        SortBag.Control=Turbine.UI.Control()
                SortBag.Control:SetParent(SortBag)
                SortBag.Control:SetMouseVisible(true)
                SortBag.Control:SetBackground(0x41007e26)
                SortBag.Control:SetSize(16,16)
                SortBag.Control:SetPosition(pad.side-15,pad.top-15)
                
        SortBag.Control.MouseClick=function()
                --This was, originally, in Button.lua. And is better there imho.
                local contextMenu = Turbine.UI.ContextMenu()
                contextMenu.items = contextMenu:GetItems()
                
                local option2=Turbine.UI.MenuItem("Re-stack the items - WARNING! EXPERIMENTAL!",true)
                        option2.Click = function () import "JackdawPlugins.SortPack.Stack"      Turbine.Shell.WriteLine("<rgb=#888888>Starting stack")  Stack() end

                local option3=Turbine.UI.MenuItem("Override default bags",true,SB.override)
                        option3.Click = function () SB.override=not(SB.override) SBOverride() end
                
                local option4=Turbine.UI.MenuItem("Open the sort order panel",true)
                        option4.Click = function () import"JackdawPlugins.SortPack.ListOption" ShowListOption() end
                
                local option6=Turbine.UI.MenuItem("Create/Edit custom Categories",true)
                        option6.Click = function () import"JackdawPlugins.SortPack.CustomOption" ShowCustomOption() end
                        
                local option7=Turbine.UI.MenuItem("Show a group on item gain.",true,SB.ShowItem)
                        option7.Click = function () SB.ShowItem=not(SB.ShowItem) end
                        
                local option5 = Turbine.UI.MenuItem("Select SortBag label font;")
                        contextMenu.SubMenuItems = option5:GetItems()
                        local suboption5={}
                        local font={}
                        j=1
                        for i in pairs(Turbine.UI.Lotro.Font) do 
                                font[j]=i
                                j=j+1
                        end
                        table.sort(font, function (a,b) 
                                        return (a < b) 
                         end)
                         for i=1,#font do
                                suboption5[i] = Turbine.UI.MenuItem(font[i],true,font[i]==SB.font)
                                suboption5[i].Click = function () 
                                        SB.font=font[i]
                                        SB.fontsize=string.sub(SB.font,-2)
                                        if SB.fontsize=="ed" then SB.fontsize=13-1 else SB.fontsize=tonumber(SB.fontsize)-1 end
                                        populatebag()
                                end

                                contextMenu.SubMenuItems:Add(suboption5[i])
                        end

                contextMenu.items:Add(option2)
                contextMenu.items:Add(option5)  
                contextMenu.items:Add(option3)
                contextMenu.items:Add(option7)
                contextMenu.items:Add(option4)
                contextMenu.items:Add(option6)
                
                contextMenu:ShowMenu()
        end
        
        SortBag.Resize=Turbine.UI.Control()
                SortBag.Resize:SetParent(SortBag)
                SortBag.Resize:SetZOrder(99)
                
                SortBag.ResizeBack=Turbine.UI.Control()
                SortBag.ResizeBack:SetParent(SortBag.Resize)
                SortBag.ResizeBack:SetBackColor(Turbine.UI.Color(0.7,0.3,0.3,1))
                SortBag.ResizeBack:SetVisible(false)
                SortBag.ResizeBack:SetMouseVisible(false)
                
                SortBag.Resize.MouseEnter=function() SortBag.ResizeBack:SetVisible(true) end
                SortBag.Resize.MouseLeave=function() SortBag.ResizeBack:SetVisible(false)  end
                
                SortBag.Resize.MouseDown=function ()
                        draggingr=true
                end
                SortBag.Resize.MouseUp=function ()
                        draggingr=false
                end
                SortBag.Resize.MouseMove=function(sender,args)
                        if draggingr then
                                local oldwidth=SB.width
                                SB.width,dummy=SortBag:GetMousePosition() 
                                
                                if SortBag:IsAltKeyDown() then
                                        SB.labelwidth=SB.width-oldwidth+SB.labelwidth
                                        if SB.labelwidth<SB.fontsize then SB.labelwidth=SB.fontsize end
                                else
                                        SB.icx=math.floor((SB.width-2*pad.side-SB.labelwidth)/36)
                                        SB.icy=math.floor((SB.maxheight-(pad.top+pad.bottom))/36)
                                        if SB.icx<3 then SB.icx=3 end
                                        if SB.icy<1 then SB.icy=1 end
                                end
                                        SB.width=36*SB.icx+2*pad.side+SB.labelwidth
                                        SortBag:SetSize(SB.width,SB.maxheight)
                        end
                end     
                
SortBag.SizeChanged=function()
        SortBagSetSize()
        SetGroupBoxSize()
        
        --Now, if the size of the bag would take the bottom of the bag off the screen, then re-position it.
        local x,y=SortBag:GetPosition()
        if y+SortBag:GetHeight()>SB.maxheight then y=SB.maxheight-SortBag:GetHeight() end
        SortBag:SetPosition(x,y)
end

SortBag:SetSize(SB.width,SB.maxheight)

SortBag.PositionChanged=function()
        local x,y=SortBag:GetPosition()
                if x<0 then x=0 end
                if y<0 then y=0 end
                SortBag:SetPosition(x,y)
                SB.x,SB.y=x,y   
end

populatebag()

SBOverride()

Go to most recent revision | Compare with Previous | Blame


All times are GMT -5. The time now is 06:06 PM.


Our Network
EQInterface | EQ2Interface | Minion | WoWInterface | ESOUI | LoTROInterface | MMOUI | Swtorui