Skip to content

Commit

Permalink
Rebased CWM::Tabs on CWM::Pager
Browse files Browse the repository at this point in the history
CWM::Tab is simply an alias for CWM::Page
  • Loading branch information
mvidner committed May 23, 2017
1 parent 50a18dd commit 887f687
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 157 deletions.
4 changes: 1 addition & 3 deletions library/cwm/src/lib/cwm/page.rb
Expand Up @@ -9,9 +9,7 @@ module CWM
#
# {TreePager} is a {Pager}.
#
# {Tabs} is a {Pager} and a {Tab} is its {Page}
# (FIXME: We haven't made Tabs a subclass of Pager yet.
# That will come after we have TreePager working.
# {Tabs} is a {Pager} and a {Tab} is its {Page}.
class Page < CustomWidget
# @return [Boolean] is this the initially selected tab
attr_accessor :initial
Expand Down
4 changes: 1 addition & 3 deletions library/cwm/src/lib/cwm/pager.rb
Expand Up @@ -7,9 +7,7 @@ module CWM
#
# {TreePager} is a {Pager}.
#
# {Tabs} is a {Pager} and a {Tab} is its {Page}
# (FIXME: We haven't made Tabs a subclass of Pager yet.
# That will come after we have TreePager working.
# {Tabs} is a {Pager} and a {Tab} is its {Page}.
#
# @see examples/object_api_tabs.rb
class Pager < CustomWidget
Expand Down
173 changes: 22 additions & 151 deletions library/cwm/src/lib/cwm/tabs.rb
@@ -1,180 +1,51 @@
module CWM
# Tab widget, usefull only with {CWM::Tabs}
# @see tabs example for usage
# FIXME: Make this a subclass of {Page} (if a distinct class is needed at all)
class Tab < CustomWidget
# @return [Boolean] is this the initially selected tab
attr_accessor :initial

# @return [WidgetTerm] contents of the tab, can contain {AbstractWidget}s
abstract_method :contents
# @return [String] label defines name of tab header
abstract_method :label

# @return [WidgetHash]
def cwm_definition
super.merge(
"widgets" => cwm_widgets,
"custom_widget" => Yast::CWM.PrepareDialog(cwm_contents, cwm_widgets)
)
end

# get cwm style of widget definitions
# @note internal api only used as gate to communicate with CWM
# @return [Array<WidgetHash>]
def cwm_widgets
return @cwm_widgets if @cwm_widgets

widgets = nested_widgets
names = widgets.map(&:widget_id)
definition = Hash[widgets.map { |w| [w.widget_id, w.cwm_definition] }]
@cwm_widgets = Yast::CWM.CreateWidgets(names, definition)
end
require "cwm/page"
require "cwm/pager"

# help that is result of used widget helps.
# If overwritting, do not forget to use `super`, otherwise widget helps will
# be missing
def help
Yast::CWM.MergeHelps(nested_widgets.map(&:cwm_definition))
end
end
module CWM
# Compatibility alias.
# (Tab and Tabs were here first, later Page and Pager
# were abstracted to allow for TreePager)
Tab = Page

# useful to have tabs as widget. It contained {CWM::Tab} with its content
# @see examples/object_api_tabs.rb
# FIXME: Make this a subclass of {Pager}
class Tabs < CustomWidget
# @param [Array<CWM::Tab>] tabs to be shown
def initialize(*tabs)
@tabs = tabs
@current_tab = nil
self.handle_all_events = true
end

# initializes tabs, show tab which is initial
def init
switch_tab(initial_tab_id)
end

def handle(event)
# pass it to content of tab at first, maybe something stop passing
res = Yast::CWM.handleWidgets(@current_tab.cwm_widgets, event)
return res if res

new_id = event["ID"]
tab = tab_for_id(new_id)

return nil unless tab

return nil if @current_tab.widget_id == new_id

unless validate
mark_tab(@current_tab)
return nil
end

store_tab(@current_tab.widget_id)

switch_tab(new_id)

nil
end

# store content of current tab
def store
store_tab(@current_tab.widget_id)
end

# validates current tab
def validate
Yast::CWM.validateWidgets(@current_tab.cwm_definition["widgets"], "ID" => @current_tab.widget_id)
end

def help
@current_tab ? @current_tab.help : ""
end

class Tabs < Pager
protected

# gets visual order of tabs
# This default implementation returns same order as passed to constructor
def tab_order
@tabs.map(&:widget_id)
end

# stores tab with given id
def store_tab(tab_id)
Yast::CWM.saveWidgets(tab_for_id(tab_id).cwm_definition["widgets"], "ID" => tab_id)
end

# switch to target tab
def switch_tab(tab_id)
tab = tab_for_id(tab_id)
return unless tab

mark_tab(tab)
Yast::UI.ReplaceWidget(Id(replace_point_id), tab.cwm_definition["custom_widget"])
Yast::CWM.initWidgets(tab.cwm_definition["widgets"])
@current_tab = tab

Yast::CWM.ReplaceWidgetHelp(widget_id, help)
end

# visually mark currently active tab
def mark_tab(tab)
# @param page [Page]
def mark_page(page)
if Yast::UI.HasSpecialWidget(:DumbTab)
Yast::UI.ChangeWidget(Id(widget_id), :CurrentItem, tab.widget_id)
Yast::UI.ChangeWidget(Id(widget_id), :CurrentItem, page.widget_id)
else
if @current_tab
if @current_page
Yast::UI.ChangeWidget(
Id(@current_tab.widget_id),
Id(@current_page.widget_id),
:Label,
@current_tab.label
@current_page.label
)
end
Yast::UI.ChangeWidget(
Id(tab.widget_id),
Id(page.widget_id),
:Label,
"#{Yast::UI.Glyph(:BulletArrowRight)} #{tab.label}"
"#{Yast::UI.Glyph(:BulletArrowRight)} #{page.label}"
)
end
end

# gets id of initial tab
# This default implementation returns first tab passed to constructor
def initial_tab_id
initial = @tabs.find(&:initial)

(initial || @tabs.first).widget_id
end

def contents
if Yast::UI.HasSpecialWidget(:DumbTab)
panes = tab_order.map do |tab_id|
tab = tab_for_id(tab_id)
Item(Id(tab.widget_id), tab.label, tab.widget_id == initial_tab_id)
panes = page_order.map do |page_id|
page = page_for_id(page_id)
Item(Id(page.widget_id), page.label, page.widget_id == initial_page_id)
end
DumbTab(Id(widget_id), panes, replace_point)
else
tabbar = tab_order.each_with_object(HBox()) do |tab, res|
tab = tab_for_id(tab)
res << PushButton(Id(tab.widget_id), tab.label)
tabbar = page_order.each_with_object(HBox()) do |page, res|
page = page_for_id(page)
res << PushButton(Id(page.widget_id), page.label)
end
VBox(Left(tabbar), Frame("", replace_point))
end
end

def tab_for_id(id)
@tabs.find { |t| t.widget_id == id }
end

private

def replace_point_id
:_cwm_tab_contents_rp
end

def replace_point
ReplacePoint(Id(replace_point_id), VBox(VStretch(), HStretch()))
end
end
end

0 comments on commit 887f687

Please sign in to comment.