Other Languages Moderators Lord Henry Posted May 31, 2018 Other Languages Moderators Share Posted May 31, 2018 (edited) Eae galera. Encontrei um bug na lista do meu painel de ranking. Onde os valores numéricos que são decimais não ficam na ordem correta do maior pro menor nem vice-versa. Eles ficam aleatórios. Os valores inteiros ficam organizados corretamente. Já configurei para a lista considerá-los como números usando guiGridSetItemText e setando o parâmetro number como true. Ele organiza os valores inteiros corretamente, mas os valores float não. Alguém sabe como resolver? Segue a print mostrando o problema: Spoiler Os valores estão sendo cortados para somente 3 casas decimais usando a função math.round, que está funcionando perfeitamente. Parte do script que preenche a lista: Spoiler function scoreInfo (names, kills, deaths, ratio, given, taken, copRatio) guiSetVisible (scoreWindow, true) guiSetVisible (closeGrid, true) showCursor (true) if names then for i, v in ipairs (names) do if type (ratio[i]) == "number" then ratio[i] = math.round (ratio[i], 3, "floor") -- Aplica o redutor decimal no ratio. end if type (copRatio[i]) == "number" then copRatio[i] = math.round (copRatio[i], 3, "floor") -- Aplica o redutor decimal no copRatio. end local row = guiGridListAddRow (scoreGrid) guiGridListSetItemText (scoreGrid, row, nameColumn, names[i], false, false) guiGridListSetItemText (scoreGrid, row, nilColumn, "|", false, false) guiGridListSetItemText (scoreGrid, row, killsColumn, kills[i], false, true) guiGridListSetItemText (scoreGrid, row, deathsColumn, deaths[i], false, true) guiGridListSetItemText (scoreGrid, row, ratioColumn, ratio[i], false, true) guiGridListSetItemText (scoreGrid, row, nullColumn, "|", false, false) guiGridListSetItemText (scoreGrid, row, givenColumn, given[i], false, true) guiGridListSetItemText (scoreGrid, row, takenColumn, taken[i], false, true) guiGridListSetItemText (scoreGrid, row, copColumn, copRatio[i], false, true) guiGridListSetItemColor (scoreGrid, row, nilColumn, 255, 0, 0) guiGridListSetItemColor (scoreGrid, row, nullColumn, 255, 0, 0) end end end addEvent ("showRank", true) addEventHandler ("showRank", getRootElement(), scoreInfo) Edited May 31, 2018 by Lord Henry Link to comment
[M]ister Posted June 1, 2018 Share Posted June 1, 2018 Provavelmente deve ser algum bug ele não funcionar com decimais... Fiz um teste rápido aqui e se você deixar o conteúdo como string no guiGridListSetItemText (não definir o último argumento como true) a ordenação funciona! Lua assim como outras linguagens convertem strings numéricas em números para fazer a comparação: -- https://www.lua.org/cgi-bin/demo if ("2.333" < "2.5555") then print("ok") else print("fail") end 1 Link to comment
Other Languages Moderators Lord Henry Posted June 1, 2018 Author Other Languages Moderators Share Posted June 1, 2018 Sim. Mas antes eu não defini como number e mesmo assim bugava a organização. Dai converti pra number pra ver se resolvia e não mudou em nada. function scoreInfo (names, kills, deaths, ratio, given, taken, copRatio) guiSetVisible (scoreWindow, true) guiSetVisible (closeGrid, true) showCursor (true) if names then for i, v in ipairs (names) do if type (ratio[i]) == "number" then ratio[i] = math.round (ratio[i], 3, "floor") -- Aplica o redutor decimal no ratio. end if type (copRatio[i]) == "number" then copRatio[i] = math.round (copRatio[i], 3, "floor") -- Aplica o redutor decimal no copRatio. end local row = guiGridListAddRow (scoreGrid, names[i], "|", kills[i], deaths[i], ratio[i], "|", given[i], taken[i], copRatio[i]) guiGridListSetItemColor (scoreGrid, row, nilColumn, 255, 0, 0) guiGridListSetItemColor (scoreGrid, row, nullColumn, 255, 0, 0) end end end addEvent ("showRank", true) addEventHandler ("showRank", getRootElement(), scoreInfo) Link to comment
[M]ister Posted June 1, 2018 Share Posted June 1, 2018 Sem usar guiGridListSetItemText local numeros = {1,2,2.5,2.75,2.333,3,4,5,6,7,8,9} local grid = guiCreateGridList ( 0.5, 0.5, 0.2, 0.3, true ) local column = guiGridListAddColumn( grid, "Números", 1 ) for _,n in ipairs(numeros) do local row = guiGridListAddRow ( grid, n ) end =========================================== Usando guiGridListSetItemText local numeros = {1,2,2.5,2.75,2.333,3,4,5,6,7,8,9} local grid = guiCreateGridList ( 0.5, 0.5, 0.2, 0.3, true ) local column = guiGridListAddColumn( grid, "Números", 1 ) for _,n in ipairs(numeros) do local row = guiGridListAddRow ( grid ) guiGridListSetItemText ( grid, row, column, n, false, false ) end Ou seja, quando tenta-se adicionar os itens direto pelo guiGridListAddRow a ordenação com números decimais não funciona (aparentemente no caso dos decimais ele mantém a ordem em que foram acionados), porém usando guiGridListSetItemText funciona... Se quiser manter como estava fazendo pode tentar usar table.sort antes de adicionar no gridList Link to comment
Other Languages Moderators Lord Henry Posted June 1, 2018 Author Other Languages Moderators Share Posted June 1, 2018 (edited) No caso, devo usar guiGridSetItemText, mas deixando como false no parâmetro de number? Edited June 1, 2018 by Lord Henry Link to comment
Other Languages Moderators Lord Henry Posted June 1, 2018 Author Other Languages Moderators Share Posted June 1, 2018 Teste usando números inteiros de 2 dígitos também, tipo 10, 12, 23. Link to comment
Other Languages Moderators Lord Henry Posted June 1, 2018 Author Other Languages Moderators Share Posted June 1, 2018 (edited) Continua não dando certo. Os números decimais estão funcionando, mas os inteiros que são com mais de um dígito não aparecem na ordem correta. Ele considera 14 menor que 2. Se eu deixar o parâmetro de number como true, os números inteiros funcionam bem, mas os decimais ficam aleatórios. (1.1 = 1.01 = 1.11) Se eu deixar o parâmetro de number como false, os números decimais funcionam bem, mas os inteiros de 2 ou mais dígitos ficam errados. (14 < 2) Edited June 1, 2018 by Lord Henry Link to comment
[M]ister Posted June 1, 2018 Share Posted June 1, 2018 É, realmente! Única solução que pensei aqui é essa: local numeros = {10,3,1,70,2,2.5,2.75,2.333,25,3,4,5,6,7,8,9} table.sort(numeros) local grid = guiCreateGridList ( 0.5, 0.5, 0.2, 0.3, true ) local column = guiGridListAddColumn( grid, "Números", 1 ) for _,n in ipairs(numeros) do local row = guiGridListAddRow ( grid ) guiGridListSetItemText ( grid, row, column, n, false, true ) end Link to comment
Other Languages Moderators Lord Henry Posted June 1, 2018 Author Other Languages Moderators Share Posted June 1, 2018 (edited) Teste nesta tabela: scoreGrid = guiCreateGridList (10, 20, 580, 330, false) nameColumn = guiGridListAddColumn (scoreGrid, "Player", 0.33) numberColumn = guiGridListAddColumn (scoreGrid, "K/D", 0.1) nomeTable = {"Nome5", "Nome3", "Nome7", "Nome9", "Nome1", "Nome2", "Nome4", "Nome8", "Nome10", "Nome6") numberTable = {8,4.1,4.2,4.01,4.11,10,2,4.001,5,1} Edited June 1, 2018 by Lord Henry Link to comment
[M]ister Posted June 1, 2018 Share Posted June 1, 2018 Se tentar usar o table.sort direto na tabela dos números irá perder a correspondência com a tabela dos nomes... algo do tipo deve resolver: nomeTable = {"Nome5", "Nome3", "Nome7", "Nome9", "Nome1", "Nome2", "Nome4", "Nome8", "Nome10", "Nome6"} numberTable = {8,4.1,4.2,4.01,4.11,10,2,4.001,5,1} sort = {} for i=1,#nomeTable do sort[i] = {nomeTable[i],numberTable[i]} end table.sort(sort, function(a, b) return a[2] < b[2] end) Link to comment
[M]ister Posted June 1, 2018 Share Posted June 1, 2018 Cara, fui testar aqui e vi que realmente nem funciona certo! Ele ordena como esperado, só que se você tentar ordenar a coluna do gridList de forma decrescente ele ainda buga nos decimais... Link to comment
Other Languages Moderators Lord Henry Posted June 2, 2018 Author Other Languages Moderators Share Posted June 2, 2018 O problema está no fato dele não reconhecer numero decimal. Pois se reconhecesse, ele organizaria direito quando colocamos true no parâmetro number. Link to comment
DNL291 Posted June 2, 2018 Share Posted June 2, 2018 Tentei aqui reproduzir o bug que você tiveram, mas não consegui, usando o table.sort do código do MaligNos. Qual número decimal vocês testaram? Link to comment
Other Languages Moderators Lord Henry Posted June 2, 2018 Author Other Languages Moderators Share Posted June 2, 2018 2 hours ago, DNL291 said: Tentei aqui reproduzir o bug que você tiveram, mas não consegui, usando o table.sort do código do MaligNos. Qual número decimal vocês testaram? Essa tabela de testes: 4 hours ago, Lord Henry said: Teste nesta tabela: scoreGrid = guiCreateGridList (10, 20, 580, 330, false) nameColumn = guiGridListAddColumn (scoreGrid, "Player", 0.33) numberColumn = guiGridListAddColumn (scoreGrid, "K/D", 0.1) nomeTable = {"Nome5", "Nome3", "Nome7", "Nome9", "Nome1", "Nome2", "Nome4", "Nome8", "Nome10", "Nome6") numberTable = {8,4.1,4.2,4.01,4.11,10,2,4.001,5,1} Link to comment
DNL291 Posted June 2, 2018 Share Posted June 2, 2018 Aqui funcionou com essa tabela: https://imgur.com/a/MWYrJAB Link to comment
Other Languages Moderators Lord Henry Posted June 2, 2018 Author Other Languages Moderators Share Posted June 2, 2018 10 hours ago, DNL291 said: Aqui funcionou com essa tabela: https://imgur.com/a/MWYrJAB Você apenas realocou os elementos pelo script. Vc não clicou na coluna para reorganizar. Preciso que os números fiquem na ordem correta quando eu clicar na coluna dos números. Tanto do maior pro menor, quanto do menor pro maior. Pois a tabela que estou usando possui várias colunas de números, o usuário pode escolher qual delas quer usar o filtro. Link to comment
DNL291 Posted June 10, 2018 Share Posted June 10, 2018 Bom, fiz um código aqui pra resolver isso, foi algo meio radical mas consegui resolver. Na verdade eu fiz um sistema de ordenação personalizado, que usa as propriedades "SortDirection" e "SortColumnID" para fazer tudo separadamente da coluna ratio. Quanto à coluna ratio, eu usei o table.sort que já foi mostrado aqui no tópico. Fiz tudo com detecção de clique nas áreas de cada coluna, sendo que a ordenação é feita pelo próprio script como já disse. Deixei o código comentado, testei ele e funcionou muito bem. Aqui está: local sortTable = { -- nick, kills, deaths, ratio { "Nome5", 10, 8, 8 }, { "Nome3", 2, 5, 4.1 }, { "Nome7", 3, 8, 4.2 }, { "Nome9", 4, 10, 4.01 }, { "Nome1", 5, 14, 4.11 }, { "Nome2", 12, 3, 10 }, { "Nome4", 2, 7, 5 }, { "Nome8", 20, 1, 2 }, { "Nome10", 5, 0, 1 }, { "Nome6", 7, 22, 4.001 } } local ratio_column = 4 --[[------------------------------------------------------------- - Você deve estruturar uma tabela para a lista - como acima. - - A coluna do ratio pode ser definida na variável 'ratio_column' ------------------------------------------------------------------]] local columns = {} local lastClickedColumn local selectedRowText addEventHandler( "onClientResourceStart", resourceRoot, function() createGridListInterface() showCursor (true) scoreInfo() -- mapeando as dimensões das colunas local gridX, gridY = guiGetPosition( scoreGrid, false ) local columnStartX = gridX + 8 local columnTop = gridY + 1 local columnBottom = columnTop + 22 columns[1] = { columnStartX, columnTop, columnStartX + guiGridListGetColumnWidth( scoreGrid, 1, false ), columnBottom } -- adicionando as posições das colunas na tabela for i=2, guiGridListGetColumnCount( scoreGrid ) do local left = columns[i-1][3] local columnW = guiGridListGetColumnWidth( scoreGrid, i, false ) columns[i] = { left, columnTop, (left + columnW), columnBottom } end -- teste -- Descomente esta linha se quiser testar as áreas do clique das colunas --addEventHandler("onClientRender", root, drawLines) end ) function createGridListInterface() scoreGrid = guiCreateGridList (10, 20, 580, 330, false) guiGridListSetSortingEnabled( scoreGrid, false ) nameColumn = guiGridListAddColumn (scoreGrid, "Player", 0.33) kills = guiGridListAddColumn (scoreGrid, "kills", 0.2) deaths = guiGridListAddColumn (scoreGrid, "daths", 0.2) numberColumn = guiGridListAddColumn (scoreGrid, "ratio", 0.1) -- criando uma label por cima das colunas para evitar o redimensionamento manual local gridX, gridY = guiGetPosition( scoreGrid, false ) guiSetProperty(guiCreateLabel(gridX, gridY, 580, 22, "", false), "AlwaysOnTop", "True") end function scoreInfo( direction ) if direction then --[[------------------------------------------------------------- - workaround para fazer a ordenação manual. - por algum motivo que eu não consegui descobrir, - as rows simplesmente não são atualizadas quando - clica na coluna do ratio (talvez pelo uso do guiSetProperty). - Nem mesmo removendo as colunas e recriando-as - eu pude resolver, pois me surgiu outro bug com - a posição das colunas -----------------------------------------------------------------]] destroyElement(scoreGrid) createGridListInterface() table.sort( sortTable, function(a, b) if direction == "Ascending" then return a[ratio_column] > b[ratio_column] else return a[ratio_column] < b[ratio_column] end end ) end for i,v in ipairs(sortTable) do local row = guiGridListAddRow (scoreGrid) guiGridListSetItemText ( scoreGrid, row, nameColumn, v[1], false, false ) guiGridListSetItemText ( scoreGrid, row, kills, v[2], false, true ) guiGridListSetItemText ( scoreGrid, row, deaths, v[3], false, true ) guiGridListSetItemText ( scoreGrid, row, numberColumn, v[ratio_column], false, true ) local itemText = guiGridListGetItemText( scoreGrid, row, 1 ) if selectedRowText and (itemText == selectedRowText) then guiGridListSetSelectedItem( scoreGrid, row, 1 ) end end end -- (teste) destacando as áreas de cada coluna function drawLines() if not scoreGrid then return end for i=1, guiGridListGetColumnCount( scoreGrid ) do local left = columns[i][1] local top = columns[i][2] local right = columns[i][3] local bottom = columns[i][4] dxDrawLine ( left, top, right, top, tocolor(255, 20, 20), 1, true ) -- Top dxDrawLine ( left, top, left, bottom, tocolor(255, 20, 20), 1, true ) -- Left dxDrawLine ( left, bottom, right, bottom, tocolor(255, 20, 20), 1, true ) -- Bottom dxDrawLine ( right, top, right, bottom, tocolor(255, 20, 20), 1, true ) -- Right end end addEventHandler ( "onClientGUIClick", guiRoot, function() if source == scoreGrid then selectedRowText = guiGridListGetSelectedText(scoreGrid) end end ) -- detecção do clique nas colunas addEventHandler( "onClientClick", root, function ( button, state ) if button == "left" and state == "up" and not (isMainMenuActive()) and scoreGrid then for i=1, guiGridListGetColumnCount( scoreGrid ) do local left = columns[i][1] local top = columns[i][2] local right = columns[i][3] local bottom = columns[i][4] if isMouseInPosition( left, top, right-left, bottom-top ) then onColumnClick( i ) break end end end end ) -- essa função é chamada quando uma coluna for clicada, -- o parâmetro 'id' é o índice da tabela correspondente à coluna local d = { "Ascending", "Descending" } function onColumnClick( id ) outputChatBox( "@onColumnClick: #" .. tostring(id) ) lastClickedColumn = id if lastClickedColumn ~= id then columns[lastClickedColumn].dir = nil columns[id].dir = d[1] guiSetProperty( scoreGrid, "SortDirection", d[1] ) else local direction = (columns[id].dir == d[1]) and d[2] or d[1] guiSetProperty( scoreGrid, "SortDirection", direction ) columns[id].dir = direction end if id == ratio_column then -- coluna ratio scoreInfo( columns[id].dir ) else guiSetProperty(scoreGrid, "SortColumnID", id ) end end -- funções úteis function isMouseInPosition ( x, y, width, height ) if ( not isCursorShowing( ) ) then return false end local sx, sy = guiGetScreenSize ( ) local cx, cy = getCursorPosition ( ) local cx, cy = ( cx * sx ), ( cy * sy ) if ( cx >= x and cx <= x + width ) and ( cy >= y and cy <= y + height ) then return true else return false end end function guiGridListGetSelectedText(gridList) local selectedItem = guiGridListGetSelectedItem(gridList) if (selectedItem) then local text = guiGridListGetItemText(gridList, selectedItem, 1) if (text) and not (text == "") then return text end end return false end Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now