Code Monkey home page Code Monkey logo

pop.box's Introduction

Pop.Box

Do not mix with Cola.

GitHub release GitHub downloads GitHub issues GitHub license

Pop.Box is a GUI library for use in the LÖVE engine, designed to be easy to use and require as little code as possible to set up. It is primarily designed to make it easy to experiment with GUIs during development.

Supports LÖVE versions 0.9.1 and higher.

Documentation

Building the documentation relies on a specific version of LDoc. Run sudo luarocks install ldoc 1.4.4-1 to install the necessary version.

Note: Currently rewriting and redesigning Pop.Box. The following info is out of date until I finish:

Features

  • Quickly set up and align GUI elements.
  • Fully customizable alignment / styling.
  • Moving/resizing elements takes alignment into account.
  • Mouse and key input handling. (Note: Work in progress.)
  • Extensible: Make your own elements, skins, extensions, and everything is automatically loaded.

Usage

The basics:

local pop = require "pop"
-- define LÖVE callbacks here (update, draw, textinput, mouse/key events)
local window = pop.window():align("center"):setTitle("Welcome!")
window:addChild(pop.text("Welcome to Pop.Box()!"))

Note: Due to this being so early in development...the above example doesn't actually work as expected. window is a very new element.

For more examples, see the code in demo. For documentation, see docs (and links to documentation below).

Documentation

Note: Docs are a work in progress, sometimes lagging behind the actual code.

  • Pop Module (The main module/interface.)
  • Elements (Basic features of elements/types of elements.)
  • Skins (A basic system for quickly applying settings to many elements.)
  • Extensions (A way to load custom code in.)
  • Drawables (Reference for what can be used as a background/color.)

pop.box's People

Contributors

tangentfoxy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pop.box's Issues

Data-driven design capability

As an alternate to the crazy function-calling I have going on right now:

Data-driven UI design. I want to be able to describe an entire UI without calling any
functions or requiring any libraries.

So, build a table of what you want, and then call pop.something(table) and it will build it.

Related:

An API that dovetails with the data-driven format, such that changing data fields
after the UI has been constructed triggers any appropriate behavior. In other words,
an API primarily based on function-bound properties.

So, when a UI is created that way, it should pay attention to what was passed to it and change appropriately.

Note: I may want to try this as a separate project or a fork of this project, as it is a completely different concept. I may want to have everything be using closures everywhere so it can relate back to the original data and automatically update or something, idk exactly how it would work.

excludeDraw -> visibility

Make visibility a standard member of elements. Add getter/setter in the form isVisibility() and setVisibility() Replace excludeDraw with this.

In the streamlined_get_set, add show and hide methods, as well as a visible double-function method...you know what I mean, me.

excludeMovement -> static

Replace the concept of excludeMovement with a stationary member. Have getter/setter isStatic and setStatic, and streamlined static fn.

excludeUpdate -> live?

Make a live member with the same concept. Setter/getter: isUpdating() toggleUpdating()?

Not sure at all about this one.

Write documents

  • Start with elemental_handling branch.
  • Write out docs purely from a use standpoint. Do not go over internals, only interface.
  • Write docs for development, separately, that cover internals.

Make a MoonScript branch

Basically, since I've been working with MoonScript lately, I figure I should try redoing this in MoonScript and see if I like that better or find it easier. If I get it working nicer / better this way, I'll switch it to this.

Make it possible to tell Pop exactly what to load when making a new instance

  • defaults to loading everything
  • if a table of values is passed, it only loads those elements, skins, extensions
    ex: tbl = { elements = { "window", "element" }, skins = { "clearcut" } } would not load extensions and load specified elements and the one skin (make sure it errors if you tell it to load something that doesn't exist)

data x and y values are not being accepted

Currently experiencing this issue while attempting to use x/y values from the icon element I made in SCP-Clicker. Solved temporarily by just moving the object after creation, but it is odd how x/y are not respected while every other piece of data is.

Relative sizing/positioning

I already knew I wanted this, but another quote from kikito that might help me think of what to do:

I mean that instead of saying "this button is 30px width and 50 px high", I want a gui
where I can say "in this group of buttons, each one is as wide as the container, and
25% its height". The only place I should have to specify pixel dimensions would be the
root "window"; this way, the Gui would work in any resolution.

Sibling relative positioning

I would like to be able to have some mechanism for elements to position and align themselves relative to siblings.

Make it possible to navigate elements with keys

Based on this from kikito:

Don't assume that "esc", or the joypad "b", are for "going back". Give me a hook for
setting up the "go back" action. Same with "enter/a/activate", "up/up/previous",
"down/down/next", etc. Don't assume that the mouse is in love.mouse.getposition.
Give me a hook function in case I want to apply transformations to the gui in a way
which changes the mouse, or I want to move the cursor with the pad.

Make sure it is possible to easily change what keys do what, and there needs to be visual feedback of some kind for what element is selected.

Sizing relative to parent

There is already a fill() method, but I would like something that perhaps allows you to set your size based on a percentage, or based on percentage and siblings, or auto-sizing a group of siblings.

Make Pop instancable

Instead of:

local pop = require "pop"
pop.box() --or whatever

do

local Pop = require "pop"
local pop = Pop()
pop.box() --or whatever

So that someone can fuck with as many instances of Pop.Box as they want. Why I would do this, I'm not exactly sure.

Start testing using busted

Just make shims around anything that would call a LOVE function to make it work. Make sure these shims check arguments passed to them for type correctness and number of args correctness at the least. Consider making that its own project to help others with the same kind of thing (it would have its own spec suite to run through and make sure everything is working).

textbox element

  • has placeholder text of different color from normal text
    • this will be autosquashed the same way we do with window element (when that is done...)
  • has text
  • has ability to fire a changed event if you define that function, will be passed oldtext and newtext
  • box background, which is the text area
  • no outline, or extra outside styling, very minimal

window element improvements

  • minimize button?
  • close button?
  • turn moving the window on/off
  • getters/setters for sub-elements (ex: getTitleColor())

Organize methods documentation

Methods are currently documented mostly in the order they appear in the code.

Instead, document them in this order:

  • setters at the top (still in pretty much the same order, but all on top)
  • anything that's not a setter/getter (so, modification methods)
  • getters at the bottom (again, in pretty much same order, only at the bottom)

modifying size of an element should move children?

setSize, setWidth, setHeight DON'T MOVE CHILDREN. Is this intended?

  • Imagine a box centered, growing, its children should probably be re-aligned.
  • Imagine a box aligned right, growing. Again, its children should probably be
    re-aligned.

USE ALIGN() for this, however, as this is moving children, checks should be
against excludeMovement

Circle element

  • See if I can extend it from box or if that makes no sense.
  • The primary difference between it and box is drawing...actually, that's pretty much it.
  • Click handling will need to be a little special... (have a handler, that then checks if it should be trying to handle it and notifies a user-set handler? or maybe no)

More advanced elements

  • textbox (text input area)
  • scrollbox (internal box area with scrollbars if external area is too small)
  • dropdown (openable selectable dropdown list)
  • slider (essentially a scrollbar you can tie to whatever you want)
  • radio (internally has group, that way you can position however you want)
  • checkbox
  • collapsiblebox (box changes size when header clicked)

Support for 9-slices

Essentially the able to take ImageData and a description of where to slice it, and set things up to use that for nice GUIs. :D

I think what I'd have to do might be complicated...but we'll see.

Redo skinning entirely

The current system was half-baked and is only used on the two most basic elements. After designing more of the library, come back and find a more unified way to approach skinning.

Also, as a sidenote: Things need to be accessing variables through getters/setters more, and less of this direct access!

Table-based element creation

Use:

pop.box({
  x = 60,
  y = 20,
  w = 120,
  h = 20
})

Function:

@data = {} -- the table passed by the user

And all access to object values needs to be changed to access data.value. This will probably be a little slower. In the future, if it becomes a problem, it can be removed even easier than it is to add.

This also makes writing the streamlined_get_set stuff easier, since values will be separate from the class access.

If a user passes an incomplete table, it will be completed by the defaults. (Note to self: Does MoonScript have table merging? If so, use that, else, check and see if lume has it.)

Wishlist

This is a list of things that I want to add to Pop.Box. It is called wishlist because I will determine what should actually be added and what is a bad idea at a later date.

element Methods

  • addChild(e) Removes specified element from any parent it may have, appends it to this element's children.
  • removeChild(e_or_index) Removes specified element from this element's children based on an index or a reference to the element itself.
  • delete() Recursively deletes all children, then deletes itself.

element Properties

  • margin Used by alignment features to specify a minimum distance between two elements or between the inside edge of an element and a child element. Not 100% sure how this will be done.
  • static Stops any automatic movement on an element when things are moved around it.

Elements

  • window (progress has already begun). This needs to be super flexible for a variety of roles..or I need to come up with different window types. This remains to be decided upon. See #27 #7
  • textbox An input textbox. See #1
  • See #2 and #12 and #13

streamlined_get_set

This is an extension that will be included by default allowing quicker easier code-writing with getters/setters.

  • show/hide for updating @data.draw
  • width for updating/accessing @data.w
  • height for updating/accessing @data.h
  • size for updating/accessing @data.w and @data.h
  • ToDo: Populate this list with more stuff based on what else is added.

Reference WPF elements

Basically, take a look at what exists, why it exists, and decide what minimal subset I need.

Alternately, implement most WPF stuff as a separate project, an addon for this.

Features: Window snapping and offset

Window snapping for window elements? Optional feature. Also resizing and toggleable close button and toggleable moving or resizing.

data.offset table with data about how to offset an element from default positioning? Percentage and/or absolute value.

Set up tests

  • I need to come up with some system to run tests.
  • It needs to be able to handle multiple files of tests because I plan on writing all sorts of dumb tests so when I make dumb mistakes, I catch them...

Ideas reference based on WPF stuffs a bit

Just copied from a file in a deleted branch:

Element - a box with no visual component, base of every element
Slider - is vertical or horizontal, has a size and position, just stores a value for where the slider is (between 0 and 1)
Box - box, has size and color
Text - boxed text, does no wordwrapping or anything, just raw text
ScrollBox - a box area, with a Slider (or two) as needed (handled entirely internally), takes over drawing of its children
            note: only one child allowed, needs to know the size of the contained element
Grid - box area with rows and columns, place objects in it based on these grid values, this is for placement only,
       (custom sizing of grid boxes like WPF?), drawing is still handled by the internals (things can go outside of their grid)
       does not limit elements within it
RadioGroup - manages a series of Radio buttons, non-visual element for grouping purposes
             (contains reference specifically for the selected radio)
Radio - Small clickable circle, must be inside a RadioGroup element (true selected value)
CheckBox - Small clickable box, true/false checked value
DropMenu - click to open a dropdown menu, click to select an item
TextBox - primarily for input, multiline or single-line, scrolls as needed, allows text input (can also output of course..)
          (option for disable/enable editing, and option for hiding input text with placeholder (for password input for example))
ProgressBar - You know what this is. Value between 0 and 1.

Border - not needed, just use a box behind other things or above them ?
Button - anything can be a button using the click event
Image - not needed, just use an image background on something else
Label - Text element does this
List - Use a ScrollBox with internal elements
Tab - Implement yourself / I need to do this later, or as an extra
Canvas - ? I might want to make my own wrapper for a canvas
Menu - Implement yourself, a button that makes other elements appear

Write an article about mouse handling?

Essentially "How to handle mouse input" with disclaimer that I don't know it fully. What I've learned as I went, the solution I came up with, what might still be wrong or needed, how I might do it.

REDESIGN (Based on eOS mockups)

Anything with image background should also be able to use a 9-slice

ToggleButton - has pressed/unpressed state, which can be used to trigger something else

  • can be a solid color, image, or container

Box

  • color/image/container
  • for an image or spacing or whatever, most basic element (well..besides Element)

Button - self-explanatory

  • solid color, image, or container
  • optional bgToggle (image/color/container to show while button is held)

RoundButton

  • just like a button, but has extra code to check for click correctly, and you specify different function
  • Alternately, make some fancy metatable shit so that when a programmer specifies the function, it correctly handles this! (Actually, do both, and warn that the fancy metable shit will break if you change it more than once!)

RadioButton

  • use an ID (doesn't matter what it is! I suggest strings (will default to auto-assigning numbers ??))
  • you know how this works, me
  • make two kinds of radio buttons ? circular default, and square (think of square horiz menus..those are radio buttons!)

DropdownButton - A ToggleButton that automatically arranges a dropdown menu when toggled depending on available space

  • solid color, image, or container

Grid - For easier alignment/sorting of many objects

  • solid color or image used for background, IS a container

Menu (actually, call it a list)

  • a single dimension grid that automatically aligns vertically (or horizontally)

TextBox - For text entry

  • solid color or image background, can use as container for extra stuff (overlaid search icon for example)
  • support copy/paste/cut (anything else??)

Scrollbar

  • vert/horiz, scales slider size based on internal width/height, controls rendering (via canvases) of internals
  • like a slider, but different..optional top/bottom arrow buttons

TextEdit

  • more advanced text entry
  • support same stuff as textbox, but multiline, optional line numbering, scrollbars automatically when text is too big for size

Checkbox - Just a ToggleButton, in fact, this should be the togglebutton, and default

  • default has state=true/false, uses diff image (or color!) depending on state (btnTrue, btnFalse)

Text

  • color for text, optional color/image background, can contain things (anything can contain things!)
  • Alignment is important, word wrap? font selection, all sorts of stuff can be tricky!

Slider

  • holds a percentage value, can either use 2 bar colors and a slider color, or images for those things
  • slider thingie is optional, output is pure 0 to 1 percentage

VideoPlayer

  • play/pause/stop, loop on/off, volume controls, timing info, fullscreen toggle
  • all of the features need to be optional and programmable
  • they also need to default to overlaying on the video, but can be made to extend area below video for controls

Window

  • optional minimize/maximize/close buttons, customizable top bar size/style, optional drag-to-resize and drag-to-move

Multibar

  • any number of different colored/imaged pieces of different percentages of the full size
  • (think of things like how phones show what files are using storage space)

(EXTENSION)
DatePicker, TimePicker, ColorPicker, Popup (darkens everything under it and blocks input not to it)
Shadow effects! Controller support (including pop-up keyboards for text entry)

Come up with better property names than btnTrue/btnFalse and bgToggle!

GIFs in the documentation

To demonstrate concepts like how alignment works.

  • Make myself a simple console (using the library!) to execute code.
  • Use this console to demonstrate usage of the library.
  • Record it, export it as a GIF, put in the docs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.