Hi,
I cannot figure out how to add a tab to a tabbook dynamically, while the program
is running.
Does anyone know how to force the tab to appear? I tried calling recalc,
repaint, layout or forceRefresh, but no success... Below is a small example.
Thanks!
Philippe
P.S. Windows XP SP2, Ruby 1.8.4, FXRuby-1.6.2-ruby184.exe
-----------------------------
#!/usr/bin/ruby
require ''fox16''
include Fox
class MyWindow < FXMainWindow
def initialize(app)
super(app, "Window", nil, nil, DECOR_ALL, 0, 0, 600, 350)
# Menu bar stretched along the top of the main window
menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
# File menu
filemenu = FXMenuPane.new(self)
FXMenuTitle.new(menubar, "&File", nil, filemenu)
FXMenuCommand.new(filemenu, "&Quit\tCtl-Q\tQuit the
application",
nil, app, FXApp::ID_QUIT)
# Tab menu
tabmenu = FXMenuPane.new(self)
FXMenuTitle.new(menubar, "Tab", nil, tabmenu)
FXMenuCommand.new(tabmenu, "Add a tab").connect(SEL_COMMAND,
method(:onAddTab))
# Tabbook
@tabbook = FXTabBook.new(self, nil, 0,
LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
# First tab
FXTabItem.new(@tabbook, "Tab 1", nil)
FXVerticalFrame.new(@tabbook,
LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED)
end
def onAddTab(sender, sel, data)
puts "A tab is added..."
FXTabItem.new(@tabbook, "Another tab", nil)
FXVerticalFrame.new(@tabbook,
LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED)
self.recalc
self.repaint
self.layout
self.forceRefresh
@tabbook.recalc
@tabbook.repaint
@tabbook.layout
@tabbook.forceRefresh
end
def create
super
show(PLACEMENT_SCREEN)
end
end
if __FILE__ == $0
application = FXApp.new("Attik System", "FXRuby Test")
MyWindow.new(application)
application.create
application.run
end
---------------
Philippe Lang
Attik System
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3125 bytes
Desc: not available
Url :
http://rubyforge.org/pipermail/fxruby-users/attachments/20061003/3312b620/attachment.bin
On Oct 3, 2006, at 5:52 AM, Philippe Lang wrote:> I cannot figure out how to add a tab to a tabbook dynamically, > while the program is running. > > Does anyone know how to force the tab to appear? I tried calling > recalc, repaint, layout or forceRefresh, but no success... Below is > a small example.<snip>> def onAddTab(sender, sel, data) > puts "A tab is added..." > FXTabItem.new(@tabbook, "Another tab", nil) > FXVerticalFrame.new(@tabbook, > LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED) > > self.recalc > self.repaint > self.layout > self.forceRefresh > > @tabbook.recalc > @tabbook.repaint > @tabbook.layout > @tabbook.forceRefresh > endYou need to call create() on the new tab item and vertical frame. Another way would be to call create() on their parent (@tabbook). You don''t need any of that other stuff (i.e. the calls to recalc, repaint, layout and forceRefresh).
Jeroen van der Zijp
2006-Oct-03 13:40 UTC
[fxruby-users] Add a tab to a tabbok dynamically?
On Tuesday 03 October 2006 05:52, Philippe Lang wrote:> Hi, > > I cannot figure out how to add a tab to a tabbook dynamically, while the program is running. > > Does anyone know how to force the tab to appear? I tried calling recalc, repaint, layout or forceRefresh, but no success... Below is a small example. > > Thanks! > > Philippe > > P.S. Windows XP SP2, Ruby 1.8.4, FXRuby-1.6.2-ruby184.exe > > ----------------------------- > > #!/usr/bin/ruby > > require ''fox16'' > > include Fox > > class MyWindow < FXMainWindow > > def initialize(app) > > super(app, "Window", nil, nil, DECOR_ALL, 0, 0, 600, 350) > > # Menu bar stretched along the top of the main window > menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X) > > # File menu > filemenu = FXMenuPane.new(self) > FXMenuTitle.new(menubar, "&File", nil, filemenu) > FXMenuCommand.new(filemenu, "&Quit\tCtl-Q\tQuit the application", > nil, app, FXApp::ID_QUIT) > > # Tab menu > tabmenu = FXMenuPane.new(self) > FXMenuTitle.new(menubar, "Tab", nil, tabmenu) > FXMenuCommand.new(tabmenu, "Add a tab").connect(SEL_COMMAND, method(:onAddTab)) > > # Tabbook > @tabbook = FXTabBook.new(self, nil, 0, > LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT) > > # First tab > FXTabItem.new(@tabbook, "Tab 1", nil) > FXVerticalFrame.new(@tabbook, > LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED) > > end > > def onAddTab(sender, sel, data) > puts "A tab is added..." > FXTabItem.new(@tabbook, "Another tab", nil) > FXVerticalFrame.new(@tabbook, > LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED) > > self.recalc > self.repaint > self.layout > self.forceRefresh > > @tabbook.recalc > @tabbook.repaint > @tabbook.layout > @tabbook.forceRefresh > end > > def create > super > show(PLACEMENT_SCREEN) > end > > end > > if __FILE__ == $0 > application = FXApp.new("Attik System", "FXRuby Test") > MyWindow.new(application) > application.create > application.run > endIf you add new widgets on the fly, don''t forget to .create them. The ones that exist at the time you call application.create will be recursively created, new ones weren''t part of the widget tree yet at that time. You were right about recalc, although you should call it on the widget you added the new children to [in this case, tabbook. The call to recalc flags the tabbook''s layout as "dirty", and when control returns to the event loop it will perform a layout on the dialog. In FOX, layouts are delayed, which means you can make many changes to your widget tree, but incur the cost of the [expensive] layout only a single time. Its therefore very rare that you want to call layout directly; most of the time recalc suffices. Recalc is cheap because all it does is set dirty flags on a couple of widgets. - Jeroen
Jeroen van der Zijp wrote:> If you add new widgets on the fly, don''t forget to .create > them. The ones that exist at the time you call > application.create will be recursively created, new ones > weren''t part of the widget tree yet at that time. > > You were right about recalc, although you should call it on > the widget you added the new children to [in this case, > tabbook. The call to recalc flags the tabbook''s layout as > "dirty", and when control returns to the event loop it will > perform a layout on the dialog. > > In FOX, layouts are delayed, which means you can make many > changes to your widget tree, but incur the cost of the > [expensive] layout only a single time. > > Its therefore very rare that you want to call layout > directly; most of the time recalc suffices. Recalc is cheap > because all it does is set dirty flags on a couple of widgets.It works great, thanks a lot for your help. Cheers, --------------- Philippe Lang Attik System -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3125 bytes Desc: not available Url : http://rubyforge.org/pipermail/fxruby-users/attachments/20061003/b468b846/attachment.bin