lite-xl-plugins icon indicating copy to clipboard operation
lite-xl-plugins copied to clipboard

[Request] Color picker

Open xdanielc opened this issue 1 year ago • 1 comments

There's already a color highlight so I think it would be nice to have to complement that functionality in such a lightweight editor.

xdanielc avatar Sep 01 '22 12:09 xdanielc

I started working on a color picker widget for the widgets support library some weeks ago but totally got caught in other things and forgot about it:

initial-color-picker-widget

This was the initial source code in case some one wants to play with it and make something complete that can later be adapted as a floating widget:

-- mod-version:3
local core = require "core"
local style = require "core.style"
local command = require "core.command"
local common = require "core.common"
local config = require "core.config"
local View = require "core.view"

---@class plugins.colorpicker : core.view
local ColorPicker = View:extend()


function ColorPicker:new()
  ColorPicker.super.new(self)

  self.base_color = 0
  self.selector = {
    x = 0,
    y = 0,
    w = 0,
    h = 0
  }
end


function ColorPicker:get_name()
  return "Color Picker"
end


function ColorPicker:draw_colorgram(x, y, w, h)
  local sx = x
  local step = 1
  local cwidth = 1
  local cheight = h or 10

  if w < 255*6 then
    step = 255 / (w / 6)
  else
    cwidth = (w / 6) / 255
  end

  -- red -> yellow
  for g=0, 255, step do
    renderer.draw_rect(x, y, cwidth, cheight, {255, g, 0, 255})
    x = x + cwidth
  end

  -- yellow -> green
  for r=255, 0, -step do
    renderer.draw_rect(x, y, cwidth, cheight, {r, 255, 0, 255})
    x = x + cwidth
  end

  -- green -> cyan
  for b=0, 255, step do
    renderer.draw_rect(x, y, cwidth, cheight, {0, 255, b, 255})
    x = x + cwidth
  end

  -- cyan -> blue
  for g=255, 0, -step do
    renderer.draw_rect(x, y, cwidth, cheight, {0, g, 255, 255})
    x = x + cwidth
  end

  -- blue -> purple
  for r=0, 255, step do
    renderer.draw_rect(x, y, cwidth, cheight, {r, 0, 255, 255})
    x = x + cwidth
  end

  -- purple -> red
  for b=255, 0, -step do
    renderer.draw_rect(x, y, cwidth, cheight, {255, 0, b, 255})
    x = x + cwidth
  end

  sx = sx + self.base_color

  renderer.draw_rect(sx-2, y-2, 2, cheight+4, {255, 255, 255, 255})
  renderer.draw_rect(sx+10, y-2, 2, cheight+4, {255, 255, 255, 255})
  renderer.draw_rect(sx-2, y-2, 10+4, 2, {255, 255, 255, 255})
  renderer.draw_rect(sx-2, y+cheight, 10+4, 2, {255, 255, 255, 255})

  renderer.draw_rect(sx, y, 10, cheight, {255, 0, 0, 255})
end

function ColorPicker:on_mouse_pressed(button, x, y, clicks)
  if
    x >= self.selector.x and x <= self.selector.x + self.selector.w
    and
    y >= self.selector.y and y <= self.selector.y + self.selector.h
  then
    self.base_color = (x - self.position.x) - 7 - style.padding.x
  end
end

function ColorPicker:on_mouse_moved(x, y, dx, dy)
  self:on_mouse_pressed("left", x, y, 1)
end


function ColorPicker:draw()
  self:draw_background(style.background)
  local x, y = self.position.x, self.position.y
  local w, h = self.size.x, self.size.y

  self.selector.x = style.padding.x + x
  self.selector.y = style.padding.y + y
  self.selector.w = w - style.padding.x * 2
  self.selector.h = 10 * SCALE

  self:draw_colorgram(
    self.selector.x,
    self.selector.y,
    self.selector.w,
    self.selector.h
  )
end


command.add(nil, {
  ["color-picker:open"] = function()
    local node = core.root_view:get_active_node()
    node:add_view(ColorPicker())
  end,
})


return ColorPicker

One of the missing parts is rendering a square with the tones of the selected color like this one for the picker:

colorgram

jgmdev avatar Sep 07 '22 23:09 jgmdev

Closing this as implemented on https://github.com/lite-xl/lite-xl-plugins/commit/aebce8ccf05f2c27d21b475149278193b9d70d43

https://user-images.githubusercontent.com/1702572/212220044-0a7e5b66-c025-41d8-876c-381647f20352.mp4

jgmdev avatar Jan 13 '23 02:01 jgmdev