mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 13:42:59 +00:00 
			
		
		
		
	Standardise on term colour parsing
- colors.toBlit now performs bounds checks on the passed value, preventing weird behaviour like color.toBlit(2 ^ 16) returning "10". - The window API now uses colors.toBlit (or rather a copy of it) for parsing colours, allowing doing silly things like term.setTextColour(colours.blue + 5). - Add some top-level documentation to the term API to explain some of the basics. Closes #1736
This commit is contained in:
		| @@ -13,8 +13,54 @@ import dan200.computercraft.core.util.Colour; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Interact with a computer's terminal or monitors, writing text and drawing | ||||
|  * ASCII graphics. | ||||
|  * Interact with a computer's terminal or monitors, writing text and drawing ASCII graphics. | ||||
|  * | ||||
|  * <h2>Writing to the terminal</h2> | ||||
|  * The simplest operation one can perform on a terminal is displaying (or writing) some text. This can be performed with | ||||
|  * the [`term.write`] method. | ||||
|  * | ||||
|  * <pre>{@code | ||||
|  * term.write("Hello, world!") | ||||
|  * }</pre> | ||||
|  * <p> | ||||
|  * When you write text, this advances the cursor, so the next call to [`term.write`] will write text immediately after | ||||
|  * the previous one. | ||||
|  * | ||||
|  * <pre>{@code | ||||
|  * term.write("Hello, world!") | ||||
|  * term.write("Some more text") | ||||
|  * }</pre> | ||||
|  * <p> | ||||
|  * [`term.getCursorPos`] and [`term.setCursorPos`] can be used to manually change the cursor's position. | ||||
|  * <p> | ||||
|  * <pre>{@code | ||||
|  * term.clear() | ||||
|  * | ||||
|  * term.setCursorPos(1, 1) -- The first column of line 1 | ||||
|  * term.write("First line") | ||||
|  * | ||||
|  * term.setCursorPos(20, 2) -- The 20th column of line 2 | ||||
|  * term.write("Second line") | ||||
|  * }</pre> | ||||
|  * <p> | ||||
|  * [`term.write`] is a relatively basic and low-level function, and does not handle more advanced features such as line | ||||
|  * breaks or word wrapping. If you just want to display text to the screen, you probably want to use [`print`] or | ||||
|  * [`write`] instead. | ||||
|  * | ||||
|  * <h2>Colours</h2> | ||||
|  * So far we've been writing text in black and white. However, advanced computers are also capable of displaying text | ||||
|  * in a variety of colours, with the [`term.setTextColour`] and [`term.setBackgroundColour`] functions. | ||||
|  * | ||||
|  * <pre>{@code | ||||
|  * print("This text is white") | ||||
|  * term.setTextColour(colours.green) | ||||
|  * print("This text is green") | ||||
|  * }</pre> | ||||
|  * <p> | ||||
|  * These functions accept any of the constants from the [`colors`] API. [Combinations of colours][`colors.combine`] may | ||||
|  * be accepted, but will only display a single colour (typically following the behaviour of [`colors.toBlit`]). | ||||
|  * <p> | ||||
|  * The [`paintutils`] API provides several helpful functions for displaying graphics using [`term.setBackgroundColour`]. | ||||
|  * | ||||
|  * @cc.module term | ||||
|  */ | ||||
|   | ||||
| @@ -353,7 +353,8 @@ end | ||||
|  | ||||
| --[[- Converts the given color to a paint/blit hex character (0-9a-f). | ||||
|  | ||||
| This is equivalent to converting floor(log_2(color)) to hexadecimal. | ||||
| This is equivalent to converting `floor(log_2(color))` to hexadecimal. Values | ||||
| outside the range of a valid colour will error. | ||||
|  | ||||
| @tparam number color The color to convert. | ||||
| @treturn string The blit hex code of the color. | ||||
| @@ -367,7 +368,11 @@ colors.toBlit(colors.red) | ||||
| ]] | ||||
| function toBlit(color) | ||||
|     expect(1, color, "number") | ||||
|     return color_hex_lookup[color] or string.format("%x", math.floor(math.log(color, 2))) | ||||
|     local hex = color_hex_lookup[color] | ||||
|     if hex then return hex end | ||||
|  | ||||
|     if color < 0 or color > 0xffff then error("Colour out of range", 2) end | ||||
|     return string.format("%x", math.floor(math.log(color, 2))) | ||||
| end | ||||
|  | ||||
| --[[- Converts the given paint/blit hex character (0-9a-f) to a color. | ||||
|   | ||||
| @@ -58,6 +58,17 @@ local type = type | ||||
| local string_rep = string.rep | ||||
| local string_sub = string.sub | ||||
|  | ||||
| --- A custom version of [`colors.toBlit`], specialised for the window API. | ||||
| local function parse_color(color) | ||||
|     if type(color) ~= "number" then | ||||
|         -- By tail-calling expect, we ensure expect has the right error level. | ||||
|         return expect(1, color, "number") | ||||
|     end | ||||
|  | ||||
|     if color < 0 or color > 0xffff then error("Colour out of range", 3) end | ||||
|     return 2 ^ math.floor(math.log(color, 2)) | ||||
| end | ||||
|  | ||||
| --[[- Returns a terminal object that is a space within the specified parent | ||||
| terminal object. This can then be used (or even redirected to) in the same | ||||
| manner as eg a wrapped monitor. Refer to [the term API][`term`] for a list of | ||||
| @@ -341,10 +352,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible) | ||||
|     end | ||||
|  | ||||
|     local function setTextColor(color) | ||||
|         if type(color) ~= "number" then expect(1, color, "number") end | ||||
|         if tHex[color] == nil then | ||||
|             error("Invalid color (got " .. color .. ")" , 2) | ||||
|         end | ||||
|         if tHex[color] == nil then color = parse_color(color) end | ||||
|  | ||||
|         nTextColor = color | ||||
|         if bVisible then | ||||
| @@ -356,11 +364,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible) | ||||
|     window.setTextColour = setTextColor | ||||
|  | ||||
|     function window.setPaletteColour(colour, r, g, b) | ||||
|         if type(colour) ~= "number" then expect(1, colour, "number") end | ||||
|  | ||||
|         if tHex[colour] == nil then | ||||
|             error("Invalid color (got " .. colour .. ")" , 2) | ||||
|         end | ||||
|         if tHex[colour] == nil then colour = parse_color(colour) end | ||||
|  | ||||
|         local tCol | ||||
|         if type(r) == "number" and g == nil and b == nil then | ||||
| @@ -385,10 +389,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible) | ||||
|     window.setPaletteColor = window.setPaletteColour | ||||
|  | ||||
|     function window.getPaletteColour(colour) | ||||
|         if type(colour) ~= "number" then expect(1, colour, "number") end | ||||
|         if tHex[colour] == nil then | ||||
|             error("Invalid color (got " .. colour .. ")" , 2) | ||||
|         end | ||||
|         if tHex[colour] == nil then colour = parse_color(colour) end | ||||
|         local tCol = tPalette[colour] | ||||
|         return tCol[1], tCol[2], tCol[3] | ||||
|     end | ||||
| @@ -396,10 +397,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible) | ||||
|     window.getPaletteColor = window.getPaletteColour | ||||
|  | ||||
|     local function setBackgroundColor(color) | ||||
|         if type(color) ~= "number" then expect(1, color, "number") end | ||||
|         if tHex[color] == nil then | ||||
|             error("Invalid color (got " .. color .. ")", 2) | ||||
|         end | ||||
|         if tHex[color] == nil then color = parse_color(color) end | ||||
|         nBackgroundColor = color | ||||
|     end | ||||
|  | ||||
|   | ||||
| @@ -92,6 +92,11 @@ describe("The colors library", function() | ||||
|         it("floors colors", function() | ||||
|             expect(colors.toBlit(16385)):eq("e") | ||||
|         end) | ||||
|  | ||||
|         it("errors on out-of-range colours", function() | ||||
|             expect.error(colors.toBlit, -120):eq("Colour out of range") | ||||
|             expect.error(colors.toBlit, 0x10000):eq("Colour out of range") | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
|     describe("colors.fromBlit", function() | ||||
|   | ||||
| @@ -58,7 +58,14 @@ describe("The window library", function() | ||||
|             w.setTextColour(colors.white) | ||||
|  | ||||
|             expect.error(w.setTextColour, nil):eq("bad argument #1 (number expected, got nil)") | ||||
|             expect.error(w.setTextColour, -5):eq("Invalid color (got -5)") | ||||
|             expect.error(w.setTextColour, -5):eq("Colour out of range") | ||||
|         end) | ||||
|  | ||||
|         it("supports invalid combined colours", function() | ||||
|             local w = mk() | ||||
|             w.setTextColour(colours.combine(colours.red, colours.green)) | ||||
|  | ||||
|             expect(w.getTextColour()):eq(colours.red) | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
| @@ -69,7 +76,7 @@ describe("The window library", function() | ||||
|             w.setPaletteColour(colors.white, 0x000000) | ||||
|  | ||||
|             expect.error(w.setPaletteColour, nil):eq("bad argument #1 (number expected, got nil)") | ||||
|             expect.error(w.setPaletteColour, -5):eq("Invalid color (got -5)") | ||||
|             expect.error(w.setPaletteColour, -5):eq("Colour out of range") | ||||
|             expect.error(w.setPaletteColour, colors.white):eq("bad argument #2 (number expected, got nil)") | ||||
|             expect.error(w.setPaletteColour, colors.white, 1, false):eq("bad argument #3 (number expected, got boolean)") | ||||
|             expect.error(w.setPaletteColour, colors.white, 1, nil, 1):eq("bad argument #3 (number expected, got nil)") | ||||
| @@ -82,7 +89,7 @@ describe("The window library", function() | ||||
|             local w = mk() | ||||
|             w.getPaletteColour(colors.white) | ||||
|             expect.error(w.getPaletteColour, nil):eq("bad argument #1 (number expected, got nil)") | ||||
|             expect.error(w.getPaletteColour, -5):eq("Invalid color (got -5)") | ||||
|             expect.error(w.getPaletteColour, -5):eq("Colour out of range") | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
| @@ -92,7 +99,7 @@ describe("The window library", function() | ||||
|             w.setBackgroundColour(colors.white) | ||||
|  | ||||
|             expect.error(w.setBackgroundColour, nil):eq("bad argument #1 (number expected, got nil)") | ||||
|             expect.error(w.setBackgroundColour, -5):eq("Invalid color (got -5)") | ||||
|             expect.error(w.setBackgroundColour, -5):eq("Colour out of range") | ||||
|         end) | ||||
|     end) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jonathan Coates
					Jonathan Coates