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