# encoding: UTF-8 # Zori Eruta Edition: # # Zori is a GUI library for mruby and the Eruta engine. # beoran@gmail.com, 2009, 2010 # # Zori (japanese footwear) follows the Shoes philosophy in that it sees # width as largely static, and height as dynamic and scrollable because # of the mouse wheel and pageup/pagedown keys. # # Zori is oriented towards relatively simple UIs. # Therefore, there is only one top-level widget, the Root widget. # This widget, in turn contains several Pages, of which only # one can be active at the same time. # The default page is used for the in game HUD, NPC or PC dialog and # status display. Other pages are used for the various menus. # Every page can contain can contain any amount of child widgets. # Widgets in turn may or may not contain sub-widgets. # # The box model used in Zori is as follows: # ...................................... # .margin . # . +-------------border-----------+ . # . | padding | . # . | .......................... | . # . | . . | . # . | . contents . | . # . | . . | . # . | .......................... | . # . | padding | . # . +------------------------------+ . # .margin . # ...................................... # # The padding determines the minimal distance between the border or the # parent widget and it's contents and/or child widgets. # # The border's thickness is only relevant for visual effects. It does not change # the layout. The border is effectively "inside" the padding of the widget. # # The margin of a widget determines how closely that widget may be packed # to it's sibling widgets. # # The work in Zori is divided between Root, Page, and Widget. The Root class, # of which the root widget is the only instance, handles everything that # depends on and/or may influence several widgets at once, such as event # dispatching but also setting the focus, determining which widget is # being hovered, or dragged, etc. The latter functions # change the state of several widgets, so they are handled on the level of # the Hanao class. # The Widget module and the widget classes that include it the individual # state and actions of the various widgets individually. # # Widget state: # A widget can be considered a state machine with the following states: # * hidden : Invisible (implies inactive) # * inactive: Will ignore input # * active : Ready to receive input # * marked : Currently "hovered" by keyboard cursor. Only one widget can be # marked. # * selected: Previously "pressed" on and still relevantly "selected". # * hovered: Currently "hovered" by mouse cursor. Only one widget can be hovered # at most. # * focused : This widget and it's children receive keyjoy input excusively # some simpler widgets such as buttons cannot be focused since they # perform their action immediately when "clicked". Only # one widget can be focused a the same time. # * triggered:Widgets that can't be focused become triggered in stead while # they perform their action. # * dragged : The widget is being dragged. # # The all states and mutually exclusive except for the "marked" and "hovered" # state which are different since one widget may be e.g. focused and marked # and hovered at the same time. Yet different is the selected flag, # which keeps track of previously marked items such as the marked parent menu, # or for exammple, when swapping two items in an item list, etc. # Therefore marked and hovered are separate flag from the rest of the states. # # Allowed transitions: # * hide : Set to hidden state. # * show : Set to active state from hidden state. # * disable : Set to inactive state from active state or higher. # * enable : Set to active state from inactive state. # * mark : Set to marked state. # * focus : Set to focused state. # * trigger : Set to triggered state. # # The state is orthogonal with the value of the widget. A pushbutton or # checkbox will have a boolean value, a slider a numerical one, # and a text boxt a string value. # module Zori DEBUG = true # We define structs for stuff that's too simple to need classes yet. # Structure for mouse button info MouseButtonInfo = Struct.new(:button, :pressed, :released) # Structure for Click Info ClickInfo = Struct.new(:button, :widget, :when) # Structure for Drag Info DragInfo = Struct.new(:button, :widget, :when) # Class that models the state of a single key KeyInfo = Struct.new(:pressed, :sym, :mod, :text, :repeated) # script 'zori/rect.rb' # script 'zori/handler.rb' # script 'zori/element.rb' script 'zori/style.rb' script 'zori/state.rb' script 'zori/capability.rb' script 'zori/graphic.rb' script 'zori/widget.rb' script 'zori/draggable.rb' script 'zori/button.rb' script 'zori/longtext.rb' script 'zori/menu.rb' script 'zori/page.rb' script 'zori/root.rb' # script 'zori/mouse.rb' # script 'zori/joystick.rb' # script 'zori/keyboard.rb' # script 'zori/control.rb' # script 'zori/hanao.rb' # script 'zori/sizemixin.rb' # script 'zori/layoutmixin.rb' # script 'zori/flowlayout.rb' # script 'zori/stacklayout.rb' # script 'zori/fixedlayout.rb' # script 'zori/widget.rb' # # script 'zori/button.rb' # script 'zori/checkbox.rb' # script 'zori/flow.rb' # script 'zori/frame.rb' # script 'zori/input.rb' # script 'zori/label.rb' # script 'zori/mainwidget.rb' # script 'zori/menu.rb' # script 'zori/menu.rb' # script 'zori/menuitem.rb' # script 'zori/progress.rb' # script 'zori/radiobutton.rb' # script 'zori/ring.rb' # # script 'zori/slider.rb' # script 'zori/stack.rb' # # script 'zori/style.rb' # script 'zori/menu.rb' # script 'zori/text.rb' # script 'zori/shortcut.rb' # # script 'zori/mapeditor.rb' # script 'zori/mouse.rb' # script 'zori/keyboard.rb' # script 'zori/joystick.rb' # # script 'zori/dialog.rb' # script 'zori/console.rb' # Non-mouse cursor graph def self.cursor_graph self.root.cursor_graph end # Non-mouse cursor image def self.cursor_image self.root.cursor_image end # Mouse cursor graph def self.mouse_graph self.root.mouse_graph end # Mouse cursor image def self.mouse_image self.root.mouse_image end # Default font for the UI. def self.font self.root.font end # Closes the UI subsystem. def self.close @root = nil end # Initializes the UI subsystem def self.open() @root = Zori::Root.new() return @root end # Returns the root, that is the active top-level controller of the UI def self.root unless @root self.open end return @root end # Makes a new UI page def self.make_page(name) page = Zori::Page.new(:name => name) yield page if block_given? @root.register(page) return page end # Activate a given UI page. def self.go(name) self.root.go(name) end # Looks up a registered page by page name def self.[](page_name) return self.root[page_name] end # Send an event to the UI subsystem. This may NOT be named on_poll # or we get infinite recursion due to inheritance from Object. def self.on_event(*args) return self.root.on_event(*args) end end