• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[MOD] Windows (BP, EQ, Battle etc.) can be dragged only to 'panels' (right/left)

Gesior.pl

Mega Noob&LOL 2012
Senator
Joined
Sep 18, 2007
Messages
2,966
Solutions
99
Reaction score
3,383
Location
Poland
GitHub
gesior
I wrote some code that should be add to OTClient as feature (on/off in config?).
It's limit of dragging windows (as you could see in Tibianic.org client).
With normal OTClient you can drag window to any place on screen (for wars: BP of SD 5 pixels from target enemy, BP of potions 5 pixels from 'self').
With my modification, if you drop window outside 'panel' (right panel or [if is 'on' in client options] left panel), it will move that window to closest panel.

HOW TO INSTALL
In data/corelib/ui/uiminiwindow.lua under:
PHP:
function UIMiniWindow:onDragLeave(droppedWidget, mousePos)
paste:
PHP:
  local children = rootWidget:recursiveGetChildrenByMarginPos(mousePos)
  local dropInPanel = 0
  for i=1,#children do
    local child = children[i]
    if child:getId() == 'gameLeftPanel' or child:getId() == 'gameRightPanel' then
      dropInPanel = 1
    end
  end
  if dropInPanel == 0 then
    tmpp = self
    if(modules.game_interface.getLeftPanel():isVisible()) then
     if modules.game_interface.getRootPanel():getWidth() / 2 < mousePos.x then
       addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
     else
       addEvent(function() tmpp:setParent(modules.game_interface.getLeftPanel()) end)
     end
    else
      addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
    end
  end
 
I wrote some code that should be add to OTClient as feature (on/off in config?).
It's limit of dragging windows (as you could see in Tibianic.org client).
With normal OTClient you can drag window to any place on screen (for wars: BP of SD 5 pixels from target enemy, BP of potions 5 pixels from 'self').
With my modification, if you drop window outside 'panel' (right panel or [if is 'on' in client options] left panel), it will move that window to closest panel.

HOW TO INSTALL
In data/corelib/ui/uiminiwindow.lua under:
PHP:
function UIMiniWindow:onDragLeave(droppedWidget, mousePos)
paste:
PHP:
  local children = rootWidget:recursiveGetChildrenByMarginPos(mousePos)
  local dropInPanel = 0
  for i=1,#children do
    local child = children[i]
    if child:getId() == 'gameLeftPanel' or child:getId() == 'gameRightPanel' then
      dropInPanel = 1
    end
  end
  if dropInPanel == 0 then
    tmpp = self
    if(modules.game_interface.getLeftPanel():isVisible()) then
     if modules.game_interface.getRootPanel():getWidth() / 2 < mousePos.x then
       addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
     else
       addEvent(function() tmpp:setParent(modules.game_interface.getLeftPanel()) end)
     end
    else
      addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
    end
  end

Is it just me or does the "two spaces rule" really look crazy messy? Hate that they use that xD
Btw why go with an integer insted of a boolean value for dropInPanel?
Looks better and probbly would be faster to use a boolean value since you anyways only run 2 diffent outputs.
 
Is it just me or does the "two spaces rule" really look crazy messy? Hate that they use that xD
Btw why go with an integer insted of a boolean value for dropInPanel?
Looks better and probbly would be faster to use a boolean value since you anyways only run 2 diffent outputs.
Faster? Maybe, but about 0.0000001 sec :p
(I'm not sure, if 'boolean' is 1 byte in LUA or it's just normal 'integer' [4 bytes]).
Anyway using variables smaller then your CPU architecture won't make your code faster. In most languages INT is 32 bit or smaller, so it should not make any diffrence on common PCs.
// It can, if you read sequentialy table and CPU cache [L1,L2,L3] can read few values from RAM by 1 request

I used '1', because for tests I had to display many values with 'print' and LUA cannot display boolean values in string [ print(something .. ' ' .. dropInPanel) ].

I don't like 2 spaces too, but I modify client in many places. It looks even worse when I use TAB and rest of code uses 2 spaces.

Edit:
I did test [timeMillis() is my function that call boost timer, not like g_clock.millis() ]
Boolean: 9337
Number: 13905

So we can save 1 ms (0.001 sec) on every 218914 loops! :)
But we can also say that boolean algorithm is 48% faster then number algorithm.

PHP:
local start = timeMillis()
local x = true
for i = 1, 1000000000 do
    if x then
        x = false
    else
        x = true
    end
end
print(timeMillis() - start)

local start = timeMillis()
local x = 1
for i = 1, 1000000000 do
    if x == 1 then
        x = 0
    else
        x = 1
    end
end
print(timeMillis() - start)
So my script execution time would be 0,000.000.004 seconds faster, not 0,000.000.1 :)

ALGORITHMS AND DATA STRUCTURES - all my studies, time to learn LUA effective programming!

Edit 2:
After change from 'if x then' to 'if x == true then' boolean algorithm is only 8% faster then number (14139 ms vs. 13091 ms).
 
Last edited:
Faster? Maybe, but about 0.0000001 sec :p
(I'm not sure, if 'boolean' is 1 byte in LUA or it's just normal 'integer' [4 bytes]).
Anyway using variables smaller then your CPU architecture won't make your code faster. In most languages INT is 32 bit or smaller, so it should not make any diffrence on common PCs.
// It can, if you read sequentialy table and CPU cache [L1,L2,L3] can read few values from RAM by 1 request

I used '1', because for tests I had to display many values with 'print' and LUA cannot display boolean values in string [ print(something .. ' ' .. dropInPanel) ].

I don't like 2 spaces too, but I modify client in many places. It looks even worse when I use TAB and rest of code uses 2 spaces.

Edit:
I did test [timeMillis() is my function that call boost timer, not like g_clock.millis() ]
Boolean: 9337
Number: 13905

So we can save 1 ms (0.001 sec) on every 218914 loops! :)
But we can also say that boolean algorithm is 48% faster then number algorithm.

PHP:
local start = timeMillis()
local x = true
for i = 1, 1000000000 do
    if x then
        x = false
    else
        x = true
    end
end
print(timeMillis() - start)

local start = timeMillis()
local x = 1
for i = 1, 1000000000 do
    if x == 1 then
        x = 0
    else
        x = 1
    end
end
print(timeMillis() - start)
So my script execution time would be 0,000.000.004 seconds faster, not 0,000.000.1 :)

ALGORITHMS AND DATA STRUCTURES - all my studies, time to learn LUA effective programming!

Edit 2:
After change from 'if x then' to 'if x == true then' boolean algorithm is only 8% faster then number (14139 ms vs. 13091 ms).

Good information!
One note is that you actually don't have to call "== true" aswell as what ever the results would be it will always look cleaner with either enums / constants or boolean values insted of integers.
Just imagine a code with nested if statments of let's say 30 inquiries, in this case I would use constant values (ex. THIS_IS_MY_FIRST_VALUE) insted of 1.

Code:
local x = true
if(x) then
     true

if(not x) then
     false

And about the "two spaces rule" - ive been thinking and actually started to try replace all the spaces with tabs, but after sitting about 2 hours trying to find good REGEX codes to serach for I gave up.
Most of the code looked good, except some places where ret*rds have been using spaces as paddings in arrays, meaning 1 space = ½ of a tab = 10-20 tabs between some columns.
As ive said before, OTC could get alot more help (me included) if they actually moved from that stupid 2 spaces rule and actually close if statments even if it's just a one line code (aka TFS code style).
 
TO MAKE IT ON/OFF OPTION ON CONFIGS:

modules/client_options/game.otui:

under
Code:
  OptionCheckBox
    id: showLeftPanel
    !text: tr('Show left panel')
add
Code:
  OptionCheckBox
    id: moveWindowsToPanel
    !text: tr('Move windows to panel')


modules/client_options/options.lua:
under
Code:
  showLeftPanel = false,
add
Code:
  moveWindowsToPanel = false,

under
Code:
  elseif key == 'showLeftPanel' then
    modules.game_interface.getLeftPanel():setOn(value)
add
Code:
  elseif key == 'moveWindowsToPanel' then
    g_settings.set('moveWindowsToPanel', true)


modules/corelib/ui/uiminiwindow.lua: replace your function onDragLeave(droppedWidget, mousePos) for
Code:
function UIMiniWindow:onDragLeave(droppedWidget, mousePos)

    if g_settings.getBoolean('moveWindowsToPanel') then
        local children = rootWidget:recursiveGetChildrenByMarginPos(mousePos)
        local dropInPanel = 0
     
        for i=1,#children do
            local child = children[i]
            if child:getId() == 'gameLeftPanel' or child:getId() == 'gameRightPanel' then
                dropInPanel = 1
            end
        end

        if dropInPanel == 0 then
            tmpp = self
                if(modules.game_interface.getLeftPanel():isVisible()) then
                    if modules.game_interface.getRootPanel():getWidth() / 2 < mousePos.x then
                        addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
                    else
                        addEvent(function() tmpp:setParent(modules.game_interface.getLeftPanel()) end)
                    end
                else
                    addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
            end
        end
     
    else
        if self.movedWidget then
          self.setMovedChildMargin(self.movedOldMargin or 0)
          self.movedWidget = nil
          self.setMovedChildMargin = nil
          self.movedOldMargin = nil
          self.movedIndex = nil
        end
     
        self:saveParent(self:getParent())
    end
end
 
I wrote some code that should be add to OTClient as feature (on/off in config?).
It's limit of dragging windows (as you could see in Tibianic.org client).
With normal OTClient you can drag window to any place on screen (for wars: BP of SD 5 pixels from target enemy, BP of potions 5 pixels from 'self').
With my modification, if you drop window outside 'panel' (right panel or [if is 'on' in client options] left panel), it will move that window to closest panel.

HOW TO INSTALL
In data/corelib/ui/uiminiwindow.lua under:
PHP:
function UIMiniWindow:onDragLeave(droppedWidget, mousePos)
paste:
PHP:
  local children = rootWidget:recursiveGetChildrenByMarginPos(mousePos)
  local dropInPanel = 0
  for i=1,#children do
    local child = children[i]
    if child:getId() == 'gameLeftPanel' or child:getId() == 'gameRightPanel' then
      dropInPanel = 1
    end
  end
  if dropInPanel == 0 then
    tmpp = self
    if(modules.game_interface.getLeftPanel():isVisible()) then
     if modules.game_interface.getRootPanel():getWidth() / 2 < mousePos.x then
       addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
     else
       addEvent(function() tmpp:setParent(modules.game_interface.getLeftPanel()) end)
     end
    else
      addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
    end
  end

My OTC doesnt start after this implementation.

Lua:
function UIMiniWindow:onDragLeave(droppedWidget, mousePos)

  local children = rootWidget:recursiveGetChildrenByMarginPos(mousePos)
  local dropInPanel = 0
  for i=1,#children do
    local child = children[i]
    if child:getId() == 'gameLeftPanel' or child:getId() == 'gameRightPanel' then
      dropInPanel = 1
    end
  end
  if dropInPanel == 0 then
    tmpp = self
    if(modules.game_interface.getLeftPanel():isVisible()) then
     if modules.game_interface.getRootPanel():getWidth() / 2 < mousePos.x then
       addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
     else
       addEvent(function() tmpp:setParent(modules.game_interface.getLeftPanel()) end)
     end
    else
      addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
    end
  end
    
    else
        if self.movedWidget then
          self.setMovedChildMargin(self.movedOldMargin or 0)
          self.movedWidget = nil
          self.setMovedChildMargin = nil
          self.movedOldMargin = nil
          self.movedIndex = nil
        end
    
        self:saveParent(self:getParent())
    end
end
 
humm, because i don't want the option to enable or disable this, how can i remove the options?
 
humm, because i don't want the option to enable or disable this, how can i remove the options?
Dont do changes on client_options folder and on uiminiwindow.lua change:
Code:
if g_settings.getBoolean('moveWindowsToPanel') then
to
Code:
if 0 == 0 then
if you want to make windows fixed on panels

or change to:
Code:
if 0 ~= 0 then
if you want to make it completely movable

I think that will work
 
I followed every step just as said. But now appeared a problem: whenever I drag a window and move it inside the panel (left or right) it creates empty spaces (image)... how do I solve it?

1617226161289.png
 
bug with extra panels it will always throw bp into most left or most right panel. (and does not allow bps to use extra panels)
Fixed for otcv8 make
local child = children
Lua:
    if child:getId() == 'gameLeftPanels' or child:getId() == 'gameRightPanels' then
however when dragging will always go to most right panel and first left panel
 
Last edited:
Probably someone used this code to add commit to otland/otclient: d291c7c
I wrote about problems who mentioned by @tiothiago in this issue: #33
And I prepare fix for it: Fix problem with positioning when "Move windows to panels" #60

In @Gesior.pl script, @Gesior.pl only missing mentioned about paste this script under UIMiniWindow cleaning lines:

Lua:
if self.movedWidget then
    self.setMovedChildMargin(self.movedOldMargin or 0)
    self.movedWidget = nil
    self.setMovedChildMargin = nil
    self.movedOldMargin = nil
    self.movedIndex = nil
end

And above line:

Lua:
self:saveParent(self:getParent())

@hotdog1337 Do you mean second and third panel right/left from otland/otclient with Panels improvements #34 feature?
I want to fix this too, but now I wait for accept changes for Fix problem with positioning when "Move windows to panels" #60

If someone test that, additionally may add review in pull request to faster contributing new fixes/changes.
 
Probably someone used this code to add commit to otland/otclient: d291c7c
I wrote about problems who mentioned by @tiothiago in this issue: #33
And I prepare fix for it: Fix problem with positioning when "Move windows to panels" #60

In @Gesior.pl script, @Gesior.pl only missing mentioned about paste this script under UIMiniWindow cleaning lines:

Lua:
if self.movedWidget then
    self.setMovedChildMargin(self.movedOldMargin or 0)
    self.movedWidget = nil
    self.setMovedChildMargin = nil
    self.movedOldMargin = nil
    self.movedIndex = nil
end

And above line:

Lua:
self:saveParent(self:getParent())

@hotdog1337 Do you mean second and third panel right/left from otland/otclient with Panels improvements #34 feature?
I want to fix this too, but now I wait for accept changes for Fix problem with positioning when "Move windows to panels" #60

If someone test that, additionally may add review in pull request to faster contributing new fixes/changes.
the fix i put is just adding s in extrapanel var basically when this was in play for otcv8 it didnt allow players to use extra panels but now it does and now when u drag to left position of player window it goes to first left panel and if u drag to right side player window it jumps to max right panel so only if you quick dragging it goes to them but whatever
 
how to make it work using otcv8?

fixed:

you have to replace the whole
Code:
function UIMiniWindow:onDragLeave(droppedWidget, mousePos)
with this one:

Code:
function UIMiniWindow:onDragLeave(droppedWidget, mousePos)

  if self.movedWidget then
    self.setMovedChildMargin(self.movedOldMargin or 0)
    self.movedWidget = nil
    self.setMovedChildMargin = nil
    self.movedOldMargin = nil
    self.movedIndex = nil
  end


      local children = rootWidget:recursiveGetChildrenByMarginPos(mousePos)
      local dropInPanel = 0
      for i=1,#children do
        local child = children[i]
        if child:getId() == 'gameLeftPanel' or child:getId() == 'gameRightPanel' then
          dropInPanel = 1
        end
      end
      if dropInPanel == 0 then
        tmpp = self
        if(modules.game_interface.getLeftPanel():isVisible()) then
         if modules.game_interface.getRootPanel():getWidth() / 2 < mousePos.x then
           addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
         else
           addEvent(function() tmpp:setParent(modules.game_interface.getLeftPanel()) end)
         end
        else
          addEvent(function() tmpp:setParent(modules.game_interface.getRightPanel()) end)
        end
      end

end
 
Last edited:
Back
Top