sw, sh = guiGetScreenSize() pickerTable = {} colorPicker = {} colorPicker.__index = colorPicker function openPicker(id, start, title) if id and not pickerTable[id] then pickerTable[id] = colorPicker.create(id, start, title) pickerTable[id]:updateColor() return true end return false end function closePicker(id) if id and pickerTable[id] then pickerTable[id]:destroy() return true end return false end function colorPicker.create(id, start, title) local cp = {} setmetatable(cp, colorPicker) cp.id = id cp.color = {} cp.color.h, cp.color.s, cp.color.v, cp.color.r, cp.color.g, cp.color.b, cp.color.hex = 0, 1, 1, 255, 0, 0, "#FF0000" cp.color.white = tocolor(255,255,255,255) cp.color.black = tocolor(0,0,0,255) cp.color.current = tocolor(255,0,0,255) cp.color.huecurrent = tocolor(255,0,0,255) if start and getColorFromString(start) then cp.color.h, cp.color.s, cp.color.v = rgb2hsv(getColorFromString(start)) end cp.gui = {} cp.gui.width = 416 cp.gui.height = 304 cp.gui.snaptreshold = 0.02 cp.gui.window = guiCreateWindow((sw-cp.gui.width)/2, (sh-cp.gui.height)/2, cp.gui.width, cp.gui.height, tostring(title or "COLORPICKER"), false) cp.gui.svmap = guiCreateStaticImage(16, 32, 256, 256, "client/colorpicker/blank.png", false, cp.gui.window) cp.gui.hbar = guiCreateStaticImage(288, 32, 32, 256, "client/colorpicker/blank.png", false, cp.gui.window) cp.gui.blank = guiCreateStaticImage(336, 32, 64, 64, "client/colorpicker/blank.png", false, cp.gui.window) cp.gui.edith = guiCreateLabel(338, 106, 64, 20, "H: 0°", false, cp.gui.window) cp.gui.edits = guiCreateLabel(338, 126, 64, 20, "S: 100%", false, cp.gui.window) cp.gui.editv = guiCreateLabel(338, 146, 64, 20, "V: 100%", false, cp.gui.window) cp.gui.editr = guiCreateLabel(338, 171, 64, 20, "R: 255", false, cp.gui.window) cp.gui.editg = guiCreateLabel(338, 191, 64, 20, "G: 0", false, cp.gui.window) cp.gui.editb = guiCreateLabel(338, 211, 64, 20, "B: 0", false, cp.gui.window) cp.gui.okb = guiCreateButton(336, 235, 64, 24, "OK", false, cp.gui.window) cp.gui.closeb = guiCreateButton(336, 265, 64, 24, "Cancel", false, cp.gui.window) guiWindowSetSizable(cp.gui.window, false) cp.handlers = {} cp.handlers.mouseDown = function() cp:mouseDown() end cp.handlers.mouseSnap = function() cp:mouseSnap() end cp.handlers.mouseUp = function(b,s) cp:mouseUp(b,s) end cp.handlers.mouseMove = function(x,y) cp:mouseMove(x,y) end cp.handlers.render = function() cp:render() end cp.handlers.guiFocus = function() cp:guiFocus() end cp.handlers.guiBlur = function() cp:guiBlur() end cp.handlers.pickColor = function() cp:pickColor() end cp.handlers.destroy = function() cp:destroy() end addEventHandler("onClientGUIMouseDown", cp.gui.svmap, cp.handlers.mouseDown, false) addEventHandler("onClientMouseLeave", cp.gui.svmap, cp.handlers.mouseSnap, false) addEventHandler("onClientMouseMove", cp.gui.svmap, cp.handlers.mouseMove, false) addEventHandler("onClientGUIMouseDown", cp.gui.hbar, cp.handlers.mouseDown, false) addEventHandler("onClientMouseMove", cp.gui.hbar, cp.handlers.mouseMove, false) addEventHandler("onClientClick", root, cp.handlers.mouseUp) addEventHandler("onClientGUIMouseUp", root, cp.handlers.mouseUp) addEventHandler("onClientRender", root, cp.handlers.render) addEventHandler("onClientGUIFocus", cp.gui.window, cp.handlers.guiFocus, false) addEventHandler("onClientGUIBlur", cp.gui.window, cp.handlers.guiBlur, false) addEventHandler("onClientGUIClick", cp.gui.okb, cp.handlers.pickColor, false) addEventHandler("onClientGUIClick", cp.gui.closeb, cp.handlers.destroy, false) showCursor(true) return cp end function colorPicker:render() -- if not self.gui.focus then return end local x,y = guiGetPosition(self.gui.window, false) dxDrawRectangle(x+16, y+32, 256, 256, self.color.huecurrent, self.gui.focus) dxDrawImage(x+16, y+32, 256, 256, "client/colorpicker/sv.png", 0, 0, 0, self.color.white, self.gui.focus) dxDrawImage(x+288, y+32, 32, 256, "client/colorpicker/h.png", 0, 0, 0, self.color.white, self.gui.focus) dxDrawImageSection(x+8+math.floor(256*self.color.s), y+24+(256-math.floor(256*self.color.v)), 16, 16, 0, 0, 16, 16, "client/colorpicker/cursor.png", 0, 0, 0, self.color.white, self.gui.focus) dxDrawImageSection(x+280, y+24+(256-math.floor(256*self.color.h)), 48, 16, 16, 0, 48, 16, "client/colorpicker/cursor.png", 0, 0, 0, self.color.huecurrent, self.gui.focus) dxDrawRectangle(x+336, y+32, 64, 64, self.color.current, self.gui.focus) dxDrawText(self.color.hex, x+336, y+32, x+400, y+96, self.color.v < 0.5 and self.color.white or self.color.black, 1, "default", "center", "center", true, true, self.gui.focus) end function colorPicker:mouseDown() if source == self.gui.svmap or source == self.gui.hbar then self.gui.track = source local cx, cy = getCursorPosition() self:mouseMove(sw*cx, sh*cy) end end function colorPicker:mouseUp(button, state) if not state or state ~= "down" then if self.gui.track then triggerEvent("onColorPickerChange", root, self.id, self.color.hex, self.color.r, self.color.g, self.color.b) end self.gui.track = false end end function colorPicker:mouseMove(x,y) if self.gui.track and source == self.gui.track then local gx,gy = guiGetPosition(self.gui.window, false) if source == self.gui.svmap then local offsetx, offsety = x - (gx + 16), y - (gy + 32) self.color.s = offsetx/255 self.color.v = (255-offsety)/255 elseif source == self.gui.hbar then local offset = y - (gy + 32) self.color.h = (255-offset)/255 end self:updateColor() end end function colorPicker:mouseSnap() if self.gui.track and source == self.gui.track then if self.color.s < self.gui.snaptreshold or self.color.s > 1-self.gui.snaptreshold then self.color.s = math.round(self.color.s) end if self.color.v < self.gui.snaptreshold or self.color.v > 1-self.gui.snaptreshold then self.color.v = math.round(self.color.v) end self:updateColor() end end function colorPicker:updateColor() self.color.r, self.color.g, self.color.b = hsv2rgb(self.color.h, self.color.s, self.color.v) self.color.current = tocolor(self.color.r, self.color.g, self.color.b,255) self.color.huecurrent = tocolor(hsv2rgb(self.color.h, 1, 1)) self.color.hex = string.format("#%02X%02X%02X", self.color.r, self.color.g, self.color.b) guiSetText(self.gui.edith, "H: "..tostring(math.round(self.color.h*360)).."°") guiSetText(self.gui.edits, "S: "..tostring(math.round(self.color.s*100)).."%") guiSetText(self.gui.editv, "V: "..tostring(math.round(self.color.v*100)).."%") guiSetText(self.gui.editr, "R: "..tostring(self.color.r)) guiSetText(self.gui.editg, "G: "..tostring(self.color.g)) guiSetText(self.gui.editb, "B: "..tostring(self.color.b)) end function colorPicker:guiFocus() self.gui.focus = true guiSetAlpha(self.gui.window, 1) end function colorPicker:guiBlur() self.gui.focus = false guiSetAlpha(self.gui.window, 0.5) end function colorPicker:pickColor() triggerEvent("onColorPickerOK", root, self.id, self.color.hex, self.color.r, self.color.g, self.color.b) self:destroy() end function colorPicker:destroy() removeEventHandler("onClientGUIMouseDown", self.gui.svmap, self.handlers.mouseDown) removeEventHandler("onClientMouseLeave", self.gui.svmap, self.handlers.mouseSnap) removeEventHandler("onClientMouseMove", self.gui.svmap, self.handlers.mouseMove) removeEventHandler("onClientGUIMouseDown", self.gui.hbar, self.handlers.mouseDown) removeEventHandler("onClientMouseMove", self.gui.hbar, self.handlers.mouseMove) removeEventHandler("onClientClick", root, self.handlers.mouseUp) removeEventHandler("onClientGUIMouseUp", root, self.handlers.mouseUp) removeEventHandler("onClientRender", root, self.handlers.render) removeEventHandler("onClientGUIFocus", self.gui.window, self.handlers.guiFocus) removeEventHandler("onClientGUIBlur", self.gui.window, self.handlers.guiBlur) removeEventHandler("onClientGUIClick", self.gui.okb, self.handlers.pickColor) removeEventHandler("onClientGUIClick", self.gui.closeb, self.handlers.destroy) destroyElement(self.gui.window) pickerTable[self.id] = nil setmetatable(self, nil) --showCursor(areThereAnyPickers()) end function areThereAnyPickers() for _ in pairs(pickerTable) do return true end return false end function hsv2rgb(h, s, v) local r, g, b local i = math.floor(h * 6) local f = h * 6 - i local p = v * (1 - s) local q = v * (1 - f * s) local t = v * (1 - (1 - f) * s) local switch = i % 6 if switch == 0 then r = v g = t b = p elseif switch == 1 then r = q g = v b = p elseif switch == 2 then r = p g = v b = t elseif switch == 3 then r = p g = q b = v elseif switch == 4 then r = t g = p b = v elseif switch == 5 then r = v g = p b = q end return math.floor(r*255), math.floor(g*255), math.floor(b*255) end function rgb2hsv(r, g, b) r, g, b = r/255, g/255, b/255 local max, min = math.max(r, g, b), math.min(r, g, b) local h, s local v = max local d = max - min s = max == 0 and 0 or d/max if max == min then h = 0 elseif max == r then h = (g - b) / d + (g < b and 6 or 0) elseif max == g then h = (b - r) / d + 2 elseif max == b then h = (r - g) / d + 4 end h = h/6 return h, s, v end function math.round(v) return math.floor(v+0.5) end addEvent("onColorPickerOK", true) addEvent("onColorPickerChange", true)