Implement grid construction with given puzzle - crossword.koplugin - Unnamed repository; edit this file 'description' to name the repository. (DIR) Log (DIR) Files (DIR) Refs (DIR) Submodules (DIR) README (DIR) LICENSE --- (DIR) commit 1dc559aef64abdc2dd6effc6e857586f839c9e20 (DIR) parent caa49f4813c63862a41952e3500481f429cfc04c (HTM) Author: Scarlett <social@scarlettmcallister.com> Date: Fri, 10 Dec 2021 21:47:33 -0400 Implement grid construction with given puzzle - Includes letters and numbers (wow!) - Also have settings setup. Diffstat: A .gitmodules | 3 +++ M main.lua | 101 ++++++++++++++++++++++++++++--- A nyt_crosswords | 1 + D puzzle.lua | 83 ------------------------------- M puzzlerow.lua | 5 ++--- M puzzlesquare.lua | 76 +++++++++++++++++++++++++------ A puzzleview.lua | 120 +++++++++++++++++++++++++++++++ 7 files changed, 283 insertions(+), 106 deletions(-) --- (DIR) diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "nyt_crosswords"] + path = nyt_crosswords + url = https://github.com/doshea/nyt_crosswords (DIR) diff --git a/main.lua b/main.lua @@ -5,16 +5,24 @@ This is a debug plugin to test Plugin functionality. --]]-- -- This is a debug plugin, remove the following if block to enable it - +local DataStorage = require("datastorage") local Dispatcher = require("dispatcher") -- luacheck:ignore local InfoMessage = require("ui/widget/infomessage") +local LuaSettings = require("frontend/luasettings") local UIManager = require("ui/uimanager") local WidgetContainer = require("ui/widget/container/widgetcontainer") +local LuaSettings = require("frontend/luasettings") local logger = require("logger") +local json = require("json") local _ = require("gettext") local Crossword = WidgetContainer:new{ name = "crossword", + settings = nil, + settings_keys = { + puzzles_dir = "puzzles_dir" + }, + puzzles_dir = nil, } function Crossword:init() @@ -25,16 +33,95 @@ function Crossword:addToMainMenu(menu_items) menu_items.crossword = { text = _("Crossword"), -- a callback when tapping - sorting_hint = "tools", - callback = function() - self:gameView(); - end, + sub_item_table_func = function() + return self:getSubMenuItems() + end + } +end + +function Crossword:getSubMenuItems() + self:lazyInitialization() + return { + { + text = _("Play"), + callback = function() + self:gameView() + end + }, + { + text = _("Settings"), + sub_item_table = { + { + text = _("Set puzzles folder"), + keep_menu_open = true, + callback = function() + self:setPuzzlesDirectory() + end + } + } + } } end +function Crossword:lazyInitialization() + -- Load the settings + self.settings = LuaSettings:open(("%s/%s"):format(DataStorage:getSettingsDir(), "crossword_settings.lua")) + -- Load the puzzle directory value + self.puzzle_dir = self.settings_keys.puzzle_dir and + self.settings:readSetting(self.settings_keys.puzzle_dir) or + ("%s/plugins/crossword.koplugin/nyt_crosswords"):format( + DataStorage:getFullDataDir()) +end + +function Crossword:setPuzzlesDirectory() + local downloadmgr = require("ui/downloadmgr") + downloadmgr:new{ + onConfirm = function(path) + self.settings:saveSetting(self.settings_keys.puzzles_dir, ("%s/"):format(path)) + self.settings:flush() + end + }:chooseDir() + self:lazyInitialization() +end + function Crossword:gameView() - local Puzzle = require("puzzle"):new{} - UIManager:show(Puzzle) + local file_path = ("%s/%s"):format(self.puzzle_dir, "/1990/01/01.json") + local file, err = io.open(file_path, "rb") + + if not file then + return _("Could not load crossword") + end + + local file_content = file:read("*all") + file:close() + + local puzzle = json.decode(file_content) + logger.dbg(puzzle) + -- Create the grid, which contains the letters for + -- each row. + local grid = {} + local row = {} + for i, letter in ipairs(puzzle.grid) do + table.insert(row, { + letter = letter, + number = puzzle.gridnums[i], + }) + if i % 15 == 0 then + table.insert(grid, row) + row = {} + end + end + + local PuzzleView = require("puzzleview") + PuzzleView = PuzzleView:new{ + size = { + cols = puzzle.size.cols, + rows = puzzle.size.rows + }, + grid = grid + } + + UIManager:show(PuzzleView) end return Crossword (DIR) diff --git a/nyt_crosswords b/nyt_crosswords @@ -0,0 +1 @@ +Subproject commit 623e72e99b25a524c85b56bf832dd7cd8c2a34a9 (DIR) diff --git a/puzzle.lua b/puzzle.lua @@ -1,83 +0,0 @@ -local Blitbuffer = require("ffi/blitbuffer") -local Device = require("device") -local Screen = Device.screen -local Size = require("ui/size") -local Geom = require("ui/geometry") -local FrameContainer = require("ui/widget/container/framecontainer") -local InputContainer = require("ui/widget/container/inputcontainer") -local OverlapGroup = require("ui/widget/overlapgroup") -local VerticalGroup = require("ui/widget/verticalgroup") -local HorizontalGroup = require("ui/widget/horizontalgroup") -local logger = require("logger") - -local PuzzleRow = require("puzzlerow") -local PuzzleSquare = require("puzzlesquare") - - -local PuzzleView = InputContainer:new{ - width = nil, - height = nil, -} - -function PuzzleView:init() - self.dimen = Geom:new{ - w = self.width or Screen:getWidth(), - h = self.height or Screen:getHeight(), - } - self.outer_padding = Size.padding.large - self.inner_padding = Size.padding.small - self.inner_dimen = Geom:new{ - w = self.dimen.w - 2 * self.outer_padding, - h = self.dimen.h - self.outer_padding, -- no bottom padding - } - self.content_width = self.inner_dimen.w - -- The size of the game board - self.grid = { - cols = 10, - rows = 10, - } - self.main_content = VerticalGroup:new{} - - -- self.populate_items - -- Add the squares - - self.square_width = math.floor((self.dimen.w - (2 * self.outer_padding) - (2 * self.inner_padding)) / self.grid.cols) - - logger.dbg(self.square_width) - - local row = PuzzleRow:new{ - width = self.inner_dimen.w, - height = 20 - } - - for index = 0, self.grid.cols, 1 do - local square = PuzzleSquare:new{ - width = self.square_width, - height = 20, - } - row:addSquare(square) - end - - row:update() - - table.insert(self.main_content, row) - - - local content = VerticalGroup:new{ - align = "left", - self.main_content, - } - - self[1] = FrameContainer:new{ - width = self.dimen.w, - height = self.dimen.h, - padding = self.outer_padding, - padding_bottom = 0, - margin = 0, - bordersize = 0, - background = Blitbuffer.COLOR_GRAY, - content - } -end - -return PuzzleView (DIR) diff --git a/puzzlerow.lua b/puzzlerow.lua @@ -7,8 +7,6 @@ local Row = InputContainer:new{ width = nil, height = nil, padding = nil, - font_size = 10, - font_face = "xx_smallinfofont", } function Row:init() @@ -24,13 +22,14 @@ function Row:update() for num, square in ipairs(self.squares) do table.insert(hori, square) - table.insert(hori, HorizontalSpan:new{ width = self.padding, }) end self[1] = FrameContainer:new{ width = self.width, height = self.height, + bordersize = 0, padding = 0, + margin = 0, hori } end (DIR) diff --git a/puzzlesquare.lua b/puzzlesquare.lua @@ -4,39 +4,89 @@ local InputContainer = require("ui/widget/container/inputcontainer") local Font = require("ui/font") local Geom = require("ui/geometry") local FrameContainer = require("ui/widget/container/framecontainer") +local OverlapGroup = require("ui/widget/overlapgroup") local TextWidget = require("ui/widget/textwidget") +local TextBoxWidget = require("ui/widget/textboxwidget") local logger = require("logger") local PuzzleSquare = InputContainer:new{ - font_face = "xx_smallinfofont", - font_size = 10, + letter_font_face = "infofont", + letter_font_size = nil, + number_font_face = "infont", + number_font_size = nil, + margin = nil, + solve = nil, } function PuzzleSquare:init() + -- Lazy check to see if solve is set. + if not self.solve then + logger.dbg("PuzzleSquare: solve not set for square") + return + end + + -- Set up the right bg color, letter, etc. + local bg_color = self.solve.letter ~= "." and + Blitbuffer.COLOR_WHITE or + Blitbuffer.COLOR_BLACK + local letter = self.solve.letter and + self.solve.letter or + "" + local number = self.solve.number ~= 0 and + tostring(self.solve.number) or + "" + + self.letter_font_size = TextBoxWidget:getFontSizeToFitHeight(self.height, 1, 0.3) + self.number_font_size = self.letter_font_size / 2 + + -- This is the letter input by the player. self.letter = TextWidget:new{ - text = "A", - face = Font:getFace(self.font_face, self.font_size), + text = letter, + face = Font:getFace(self.letter_font_face, self.letter_font_size), fgcolor = Blitbuffer.COLOR_BLACK, padding = 0, bold = true, } - - logger.dbg(self.width) - + -- This is the number that corresponds to the question. + -- Note that the number is not always set! + self.number = TextWidget:new{ + text = number, + face = Font:getFace(self.number_font_face, self.number_font_size), + fgcolor = Blitbuffer.COLOR_BLACK, + padding = 0, + bold = true, + } + -- This is the container for the letter and number. self[1] = FrameContainer:new{ width = self.width, height = self.height, color = Blitbuffer.COLOR_WHITE, + background = bg_color, padding = 0, - CenterContainer:new{ - dimen = Geom:new{ - w = self.width, - h = self.height, + margin = self.margin or 0, + bordersize = 0, + OverlapGroup:new{ + dimen = { w = self.width }, + padding = 0, + -- Keep the letter centered + CenterContainer:new{ + dimen = Geom:new{ + w = self.width, + h = self.height, + }, + padding = 0, + -- Add the letter + self.letter, }, - self.letter, - } + -- Add the number + self.number, + }, } end +function PuzzleSquare:onTap() + logger.dbg("TA________________P") +end + return PuzzleSquare (DIR) diff --git a/puzzleview.lua b/puzzleview.lua @@ -0,0 +1,120 @@ +local Blitbuffer = require("ffi/blitbuffer") +local Device = require("device") +local Screen = Device.screen +local Size = require("ui/size") +local Geom = require("ui/geometry") +local FrameContainer = require("ui/widget/container/framecontainer") +local InputContainer = require("ui/widget/container/inputcontainer") +local OverlapGroup = require("ui/widget/overlapgroup") +local VerticalGroup = require("ui/widget/verticalgroup") +local HorizontalGroup = require("ui/widget/horizontalgroup") +local logger = require("logger") + +local PuzzleRow = require("puzzlerow") +local PuzzleSquare = require("puzzlesquare") + + +local PuzzleView = InputContainer:new{ + width = nil, + height = nil, + size = { + cols = nil, + rows = nil, + } +} + +function PuzzleView:init() + + -- Temp! This will be the puzzle object, eventually. + local letters = { + {"A","B",".","C","D","E"}, + {"B",".","C","D","E","C"}, + } + + local puzzle_cols = #letters[1] + local puzzle_rows = #letters + + self.dimen = Geom:new{ + w = self.width or Screen:getWidth(), + h = self.height or Screen:getHeight(), + } + self.outer_padding = Size.padding.large + self.inner_padding = Size.padding.small + self.inner_dimen = Geom:new{ + w = self.dimen.w - 2 * self.outer_padding, + h = self.dimen.h - self.outer_padding, -- no bottom padding + } + self.content_width = self.inner_dimen.w + -- The grid dimensions of the puzzle. + --self.grid = { + -- cols = puzzle_cols, + -- rows = puzzle_rows, + --} + -- The pixel dimensions of the squares. Calculate the initial width based on the size + -- of the device and the number of columns. Then make a minor adjustment to account for + -- the margins. To do this, divide margin in 4 and multiply by the number of columns. + self.square_margin = Size.border.window + self.square_width = math.floor( + (self.dimen.w - (2 * self.outer_padding) - (2 * self.inner_padding)) + / self.size.cols) - ((self.square_margin / 4) * (puzzle_cols)) + self.square_height = self.square_width + + ------------------ + -- Add the squares + self.rows_group = VerticalGroup:new{ border = 0 } + + for i, l in ipairs(self.grid) do + table.insert(self.rows_group, self:buildRow(l)) + end + + --------------- + -- Build the container + + self[1] = FrameContainer:new{ + width = self.dimen.w, + height = self.dimen.h, + padding = self.outer_padding, + padding_bottom = 0, + margin = 0, + bordersize = 0, + background = Blitbuffer.COLOR_BLACK, + VerticalGroup:new{ + align = "center", + background = Blitbuffer.COLOR_GRAY, + -- Add the rows vertical group. + self.rows_group, + } + } +end + +function PuzzleView:create() + +end + +-- Given a table containing letters, build a row containing +-- squares with said letters. +function PuzzleView:buildRow(squares) + local row = PuzzleRow:new{ + width = self.inner_dimen.w, + height = self.square_height, + } + for i, square in ipairs(squares) do + -- This needs a better name. It should be a combination of the user's input, + -- plus also like the square solve thing (hints, etc.) + local solve = { + letter = square.letter, + number = square.number, + } + local square = PuzzleSquare:new{ + width = self.square_width, + height = self.square_height, + margin = self.square_margin, + solve = solve, + } + row:addSquare(square) + end + row:update() + return row +end + +return PuzzleView