Jump to content

[HELP] edit box


iwalidza

Recommended Posts

Hello iwalidza,

if you want to have selection support inside edit boxes you need to play around with the text-width. First you have to establish text of a certain font with a certain scale. This gives you the ability to call dxGetTextWidth to obtain metrics about your text. Knowing that you need to search for the text offset into your editbox content at click event. I suggest to set the middle of each character as tipping point.

-- THIS IS JUST SAMPLE CODE! It has not been tested using Unicode/UTF-8 so be warned!
local strsub = string.sub;
local dxGetTextWidth = dxGetTextWidth;

function getTextLogicalOffset(text, offset, charScale, charFont)
    local n = 1;
    local len = #text;
    local curOffset = 0;
    local charWidth;

    while (n <= len) do
        charWidth = dxGetTextWidth(strsub(text, n, n), charScale, charFont);
        curOffset = curOffset + charWidth;
        
        n = n + 1;
        
        if (curOffset > offset) then
            break;
        end
    end
    
    if not (n == 1) and (curOffset - offset > charWidth * 0.5) then
        return n-1, curOffset - charWidth;
    end
    
    return n, curOffset;
end

(taken from resedit resource at https://github.com/quiret/resedit/blob/master/utilities_client.Lua#L822)

It is very important to establish drag&drop inside of your editbox. This is done by remembering when the player triggered "mouse1" to start the selection and disabling it when he released "mouse1". While the player is pressing down "mouse1" you should update the selection every time the mouse cursor is moved.

local select_start = 1
local select_end = 0
local text = "test"
local font = "sans"
local fontScale = 1.2
local text_pixels_off_x = 2
local is_selecting = false

local function has_selection()
  return ( select_start <= select_end )
end

local function mouse_click(x_abs, y_abs)
  if not (is_selecting) then
    select_start = getTextLogicalOffset(text, x_abs - text_pixels_off_x, fontScale, font)
  
    is_selecting = true
  end
end

local function mouse_move(x_abs, y_abs)
  select_end = getTextLogicalOffset(text, x_abs - text_pixels_off_y, fontScale, font) - 1
end

local function mouse_release()
  if (is_selecting) then
    is_selecting = false
  end
end

(this code has not been tested yet)

At render-time you should highlight the text that is selected using a custom rectangle backdrop. This is done by simply remembering start-offset and end-offset of the selection and, if the selection is not empty, using dxDrawRectangle before or after rendering the text at text render offset start-offset to end-offset. I leave it to you as an exercise.

Edited by The_GTA
  • Like 2
Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...