Skip to content

Commit

Permalink
add support for Wx::AUI::AuiSerializer and Wx::AUI::AuiDeserializer f…
Browse files Browse the repository at this point in the history
…or wxw >= 3.3.0
  • Loading branch information
mcorino committed Oct 25, 2024
1 parent 8e45a52 commit e35931a
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 17 deletions.
75 changes: 61 additions & 14 deletions lib/wx/aui/auimanager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,66 @@
#
# This software is released under the MIT license.

class Wx::AUI::AuiManager
def get_all_panes
::Enumerator.new { |y| each_pane { |p| y << p } }
end
alias :all_panes :get_all_panes

unless Wx::EvtHandler.event_type_for_name(:evt_aui_find_manager)
# missing from XML API refs
Wx::EvtHandler.register_event_type Wx::EvtHandler::EventType[
'evt_aui_find_manager', 0,
Wx::AUI::EVT_AUI_FIND_MANAGER,
Wx::AUI::AuiManagerEvent
] if Wx::AUI.const_defined?(:EVT_AUI_FIND_MANAGER)
end
module Wx
module AUI

class AuiManager

wx_each_pane = instance_method(:each_pane)
define_method(:each_pane) do |&block|
if block
wx_each_pane.bind(self).call(&block)
else
::Enumerator.new { |y| wx_each_pane.bind(self).call { |p| y << p } }
end
end

def get_all_panes
each_pane.to_a
end
alias :all_panes :get_all_panes

unless Wx::EvtHandler.event_type_for_name(:evt_aui_find_manager)
# missing from XML API refs
Wx::EvtHandler.register_event_type Wx::EvtHandler::EventType[
'evt_aui_find_manager', 0,
Wx::AUI::EVT_AUI_FIND_MANAGER,
Wx::AUI::AuiManagerEvent
] if Wx::AUI.const_defined?(:EVT_AUI_FIND_MANAGER)
end
end

if WXWIDGETS_VERSION >= '3.3.0'

class AuiDockInfo

wx_each_pane = instance_method(:each_pane)
define_method(:each_pane) do |&block|
if block
wx_each_pane.bind(self).call(&block)
else
::Enumerator.new { |y| wx_each_pane.bind(self).call { |p| y << p } }
end
end

def get_panes
each_pane.to_a
end
alias :panes :get_panes

end

class AuiDeserializer

wx_initialize = instance_method(:initialize)
define_method(:initialize) do |manager|
wx_initialize.bind(self).call(manager)
@manager = manager # prevent GC for lifetime of deserializer
end

end

end

end
end
2 changes: 2 additions & 0 deletions lib/wx/doc/aui/auimanager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ module AUI
class AuiManager

# Yield each pane to the given block.
# If no block passed returns an Enumerator.
# @yieldparam [Wx::AUI::AuiPaneInfo] pane the Aui pane info yielded
# @return [::Object, ::Enumerator] result of last block execution or enumerator
def each_pane; end

# Returns an array of all panes managed by the frame manager.
Expand Down
121 changes: 118 additions & 3 deletions rakelib/lib/director/aui_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,98 @@ class AuiManager < EvtHandler

def setup
super
spec.gc_as_object
spec.gc_as_object 'wxAuiManager'
if Config.instance.wx_version >= '3.3.0'
spec.items << 'wxAuiSerializer' << 'wxAuiDockInfo' << 'wxAuiDeserializer'
spec.gc_as_untracked 'wxAuiSerializer', 'wxAuiDockInfo'
spec.regard 'wxAuiDockInfo::rect',
'wxAuiDockInfo::dock_direction',
'wxAuiDockInfo::dock_layer',
'wxAuiDockInfo::dock_row',
'wxAuiDockInfo::size',
'wxAuiDockInfo::min_size',
'wxAuiDockInfo::resizable',
'wxAuiDockInfo::toolbar',
'wxAuiDockInfo::fixed',
'wxAuiDockInfo::reserved1'
spec.make_readonly 'wxAuiDockInfo::rect',
'wxAuiDockInfo::dock_direction',
'wxAuiDockInfo::dock_layer',
'wxAuiDockInfo::dock_row',
'wxAuiDockInfo::size',
'wxAuiDockInfo::min_size',
'wxAuiDockInfo::resizable',
'wxAuiDockInfo::toolbar',
'wxAuiDockInfo::fixed',
'wxAuiDockInfo::reserved1'
spec.add_extend_code 'wxAuiDockInfo', <<~__HEREDOC
VALUE each_pane()
{
wxAuiPaneInfoPtrArray panes = self->panes;
VALUE rc = Qnil;
for (wxAuiPaneInfo* pane : panes)
{
VALUE r_pane = SWIG_NewPointerObj(pane, SWIGTYPE_p_wxAuiPaneInfo, 0);
rc = rb_yield(r_pane);
}
return rc;
}
__HEREDOC
spec.map 'std::vector<wxAuiPaneInfo>' => 'Array<Wx::AuiPaneInfo>' do
map_out code: <<~__CODE
$result = rb_ary_new();
std::vector<wxAuiPaneInfo>& panes = (std::vector<wxAuiPaneInfo>&)$1;
for (const wxAuiPaneInfo& pane : panes)
{
VALUE r_pane = SWIG_NewPointerObj(new wxAuiPaneInfo(pane), SWIGTYPE_p_wxAuiPaneInfo, SWIG_POINTER_OWN);
rb_ary_push($result, r_pane);
}
__CODE
map_directorout code: <<~__CODE
if (TYPE($input) == T_ARRAY)
{
for (int i = 0; i < RARRAY_LEN($input); i++)
{
void *ptr;
VALUE r_pane = rb_ary_entry($input, i);
int res = SWIG_ConvertPtr(r_pane, &ptr, SWIGTYPE_p_wxAuiPaneInfo, 0);
if (!SWIG_IsOK(res) || !ptr) {
Swig::DirectorTypeMismatchException::raise(swig_get_self(), "load_panes", rb_eTypeError, "in return value. Expected Array of Wx::AuiPaneInfo");
}
wxAuiPaneInfo *pane = reinterpret_cast< wxAuiPaneInfo * >(ptr);
$result.push_back(*pane);
}
}
__CODE
end
spec.map 'std::vector<wxAuiDockInfo>' => 'Array<Wx::AuiDockInfo>' do
map_out code: <<~__CODE
$result = rb_ary_new();
std::vector<wxAuiDockInfo>& docks = (std::vector<wxAuiDockInfo>&)$1;
for (const wxAuiDockInfo& dock : docks)
{
VALUE r_dock = SWIG_NewPointerObj(new wxAuiDockInfo(dock), SWIGTYPE_p_wxAuiDockInfo, SWIG_POINTER_OWN);
rb_ary_push($result, r_dock);
}
__CODE
map_directorout code: <<~__CODE
if (TYPE($input) == T_ARRAY)
{
for (int i = 0; i < RARRAY_LEN($input); i++)
{
void *ptr;
VALUE r_dock = rb_ary_entry($input, i);
int res = SWIG_ConvertPtr(r_dock, &ptr, SWIGTYPE_p_wxAuiDockInfo, 0);
if (!SWIG_IsOK(res) || !ptr) {
Swig::DirectorTypeMismatchException::raise(swig_get_self(), "load_docks", rb_eTypeError, "in return value. Expected Array of Wx::AuiDockInfo");
}
wxAuiDockInfo *dock = reinterpret_cast< wxAuiDockInfo * >(ptr);
$result.push_back(*dock);
}
}
__CODE
end
end
# need a custom implementation to handle (event handler proc) cleanup
spec.add_header_code <<~__HEREDOC
#include "wx/aui/aui.h"
Expand Down Expand Up @@ -80,7 +171,7 @@ class WXRubyAuiManager : public wxAuiManager
rb_gc_mark( rb_art_prov );
}
}
__HEREDOC
__HEREDOC
spec.add_swig_code '%markfunc wxAuiManager "GC_mark_wxAuiManager";'
# provide pure Ruby implementation based on use custom alternative provided below
spec.ignore('wxAuiManager::GetAllPanes')
Expand Down Expand Up @@ -110,12 +201,36 @@ class WXRubyAuiManager : public wxAuiManager
WXRubyAuiManager* aui_mng = dynamic_cast<WXRubyAuiManager*> (self);
managedWnd->Bind(wxEVT_CLOSE_WINDOW, &WXRubyAuiManager::OnManagedWindowClose, aui_mng);
}
__HEREDOC
__HEREDOC
spec.suppress_warning(473, 'wxAuiManager::CreateFloatingFrame')
spec.do_not_generate(:variables, :defines, :enums, :functions) # with AuiPaneInfo
end

def doc_generator
AuiManagerDocGenerator.new(self)
end
end # class AuiManager

class AuiManagerDocGenerator < DocGenerator

def gen_class_doc_members(fdoc, clsdef, cls_members, alias_methods)
super
if Config.instance.wx_version >= '3.3.0' && clsdef.name == 'wxAuiDockInfo'
fdoc.doc.puts 'Yield each pane to the given block.'
fdoc.doc.puts 'If no block passed returns an Enumerator.'
fdoc.doc.puts '@yieldparam [Wx::AUI::AuiPaneInfo] pane the Aui pane info yielded'
fdoc.doc.puts '@return [::Object, ::Enumerator] result of last block execution or enumerator'
fdoc.puts 'def each_pane; end'
fdoc.puts
fdoc.doc.puts 'Returns an array of Wx::AuiPaneInfo for all panes managed by the frame manager.'
fdoc.doc.puts '@return [Array<Wx::AUI::AuiPaneInfo>] info for all managed panes'
fdoc.puts 'def get_panes; end'
fdoc.puts 'alias_method :panes, :get_panes'
end
end

end

end # class Director

end # module WXRuby3

0 comments on commit e35931a

Please sign in to comment.