ext/wxBookCtrl.cpp
/*
* wxBookCtrl.cpp
*
* Created on: 26.03.2012
* Author: hanmac
*/
#include "wxEvtHandler.hpp"
#include "wxNotifyEvent.hpp"
#include "wxSizer.hpp"
#include "wxBookCtrl.hpp"
#include "wxChoiceBook.hpp"
#include "wxNoteBook.hpp"
#include "wxListBook.hpp"
#include "wxToolBook.hpp"
#include "wxAuiBook.hpp"
#include "wxTreeBook.hpp"
#include "wxImageList.hpp"
VALUE rb_cWXBookCtrlBase,rb_cWXBookCtrlEvent;
#if wxUSE_BOOKCTRL
template <>
wxBookCtrlBase* unwrap<wxBookCtrlBase*>(const VALUE &arg)
{
return unwrapTypedPtr<wxBookCtrlBase>(arg,rb_cWXBookCtrlBase);
}
#define _self unwrap<wxBookCtrlBase*>(self)
namespace RubyWX {
namespace BookCtrl {
macro_attr(ImageList,wxImageList*)
macro_attr(InternalBorder,unsigned int)
macro_attr(ControlMargin,int)
macro_attr_selection(Selection,GetPageCount)
macro_attr(FitToCurrentPage,bool)
singlereturn(IsVertical)
singlereturn(GetControlSizer)
singlereturn(GetCurrentPage)
singlereturn(GetControllerSize)
/*
* call-seq:
* BookCtrl.new(parent, name, [options])
* BookCtrl.new(parent, [options])
*
* creates a new BookCtrl widget.
* ===Arguments
* * parent of this window or nil
* * name is a String describing a resource in a loaded xrc
*
* *options: Hash with possible options to set:
* * image_list [WX::Bitmap]
*
*/
DLL_LOCAL VALUE _initialize(int argc,VALUE *argv,VALUE self)
{
VALUE parent,name,hash;
rb_scan_args(argc, argv, "11:",&parent,&name,&hash);
rb_call_super(argc,argv);
if(rb_obj_is_kind_of(hash,rb_cHash))
{
set_obj_option(hash, "image_list", &wxBookCtrlBase::SetImageList, _self);
}
return self;
}
/*
* call-seq:
* page(pos) -> WX::Window
*
* returns the page with the given index.
* ===Arguments
* * pos is a Integer
*
* ===Return value
* WX::Window
* === Exceptions
* [IndexError]
* * pos is greater than the count of pages
*/
DLL_LOCAL VALUE _page(VALUE self,VALUE idx)
{
int cidx(RB_NUM2INT(idx));
if(check_index(cidx,_self->GetPageCount()))
return wrap(_self->GetPage(cidx));
return Qnil;
}
DLL_LOCAL VALUE _each_size(VALUE self)
{
return RB_UINT2NUM(_self->GetPageCount());
}
/*
* call-seq:
* each_page -> Enumerator
* each_page { |child| } -> self
*
* iterates the pages in this book control.
* ===Return value
* self
*
*/
DLL_LOCAL VALUE _each(VALUE self)
{
RETURN_SIZED_ENUMERATOR(self,0,NULL,RUBY_METHOD_FUNC(_each_size));
std::size_t count = _self->GetPageCount();
for(std::size_t i = 0; i < count; ++i)
rb_yield(wrap(_self->GetPage(i)));
return self;
}
macro_attr_item_simple(PageText, GetPageCount, wxString)
/*
* call-seq:
* get_page_image(pos) -> Integer
*
* returns the image idx of the given page.
* ===Arguments
* * pos is a Integer
*
* ===Return value
* Integer
* === Exceptions
* [IndexError]
* * pos is greater than the count of pages
*/
DLL_LOCAL VALUE _get_page_image(VALUE self,VALUE idx)
{
#if wxUSE_AUI
//TODO should be fixed in wx
if(rb_obj_is_kind_of(self,rb_cWXAuiNotebook))
rb_raise(
rb_eArgError,"get_page_image is not supported for %" PRIsVALUE,
RB_CLASSNAME(rb_cWXAuiNotebook)
);
#endif
int cidx(RB_NUM2INT(idx));
if(check_index(cidx,_self->GetPageCount()))
return RB_INT2NUM(_self->GetPageImage(cidx));
return Qnil;
}
/*
* call-seq:
* set_page_image(pos,iid) -> self
*
* sets the image idx of the given page.
* ===Arguments
* * pos is a Integer
* * iid Integer index of the image in the image_list
*
* ===Return value
* self
* === Exceptions
* [IndexError]
* * pos is greater than the count of pages
* * iid is greater than the count of images in the image_list
*/
DLL_LOCAL VALUE _set_page_image(VALUE self,VALUE idx,VALUE iid)
{
rb_check_frozen(self);
int cidx(RB_NUM2INT(idx));
if(check_index(cidx,_self->GetPageCount()))
{
int ciid(RB_NUM2INT(iid));
wxImageList *imglist = _self->GetImageList();
if(imglist && check_index(ciid,imglist->GetImageCount()))
{
_self->SetPageImage(cidx,ciid);
}
}
return self;
}
DLL_LOCAL bool check_imagelist(wxBookCtrlBase* self, VALUE imageid, int& iid)
{
if(NIL_P(imageid))
return true;
iid = RB_NUM2INT(imageid);
wxImageList *imglist = self->GetImageList();
if(imglist)
return check_index(iid,imglist->GetImageCount());
return true;
}
DLL_LOCAL bool check_window(VALUE self,VALUE hash, VALUE window, wxWindow*& w)
{
if(rb_obj_is_kind_of(window,rb_cClass) && RTEST(rb_class_inherited_p(window,rb_cWXWindow))) {
VALUE argv2[] = {self, hash };
w = unwrap<wxWindow*>(rb_class_new_instance(2,argv2,window));
return true;
#if wxUSE_TREEBOOK
}else if(nil_check(window,!rb_obj_is_kind_of(self,rb_cWXTreebook))) //TODO Tree Ctrl allows nil page, but i can't check that
#else
}else if(nil_check(window))
#endif
{
return window_parent_check(window,_self,w);
}
return false;
}
/*
* call-seq:
* add_page(window, text, [select], [bitmap]) -> true/false
* add_page(WindowClass, text, [select], [bitmap],**options) [{|window| }] -> true/false
*
* adds a new page to the BookCtrl widget.
*
* ===Arguments
* * window is a WX::Window instance
* * text is the Label of the page. String
* * select is true/false and says if the new page should be selected
* * bitmap is a Integer and says the position of the bitmap in the image_list
* ===Return value
* true/false
* === Exceptions
* [IndexError]
* * bitmap is greater than the list of bitmaps in the image_list
* [TypeError]
* * window is nil when the BookCtrl does not support it (currently only supported for TreeBookCtrl)
* [ArgumentError]
* * window does not have this BookCtrl as parent
*
*/
DLL_LOCAL VALUE _addPage(int argc,VALUE *argv,VALUE self)
{
VALUE window,text,select,imageid,hash;
wxWindow *w = NULL;
bool sel = false;
int iid = -1;
rb_scan_args(argc, argv, "22:",&window,&text,&select,&imageid,&hash);
rb_check_frozen(self);
if(!NIL_P(select))
sel = RTEST(select);
check_imagelist(_self,imageid,iid);
check_window(self,hash,window,w);
return wrap(_self->AddPage(w,unwrap<wxString>(text),sel,iid));
}
/*
* call-seq:
* insert_page(pos, window, text, [select], [bitmap]) -> true/false
* insert_page(pos, WindowClass, text, [select], [bitmap],**options) [{|window| }] -> true/false
*
* inserts a new page to the BookCtrl widget into the given position.
*
* ===Arguments
* * pos is a Integer
* * window is a WX::Window instance
* * text is the Label of the page. String
* * select is true/false and says if the new page should be selected
* * bitmap is a Integer and says the position of the bitmap in the image_list
* ===Return value
* true/false
* === Exceptions
* [IndexError]
* * pos is greater than the count of pages
* * bitmap is greater than the list of bitmaps in the image_list
* [TypeError]
* * window is nil when the BookCtrl does not support it (currently only supported for TreeBookCtrl)
* [ArgumentError]
* * window does not have this BookCtrl as parent
*
*/
DLL_LOCAL VALUE _insertPage(int argc,VALUE *argv,VALUE self)
{
VALUE idx,window,text,select,imageid,hash;
wxWindow *w = NULL;
bool sel = false;
int iid = -1;
rb_scan_args(argc, argv, "32:",&idx,&window,&text,&select,&imageid,&hash);
rb_check_frozen(self);
int cidx = RB_NUM2INT(idx);
if(check_index(cidx,_self->GetPageCount()+1))
{
if(!NIL_P(select))
sel = RTEST(select);
check_imagelist(_self,imageid,iid);
check_window(self,hash,window,w);
return wrap(_self->InsertPage(cidx,w,unwrap<wxString>(text),sel,iid));
}
return Qnil;
}
/*
* call-seq:
* prepend_page(window, text, [select], [bitmap]) -> true/false
* prepend_page(WindowClass, text, [select], [bitmap],**options) [{|window| }] -> true/false
*
* prepends a new page to the BookCtrl widget.
*
* ===Arguments
* * window is a WX::Window instance
* * text is the Label of the page. String
* * select is true/false and says if the new page should be selected
* * bitmap is a Integer and says the position of the bitmap in the image_list
* ===Return value
* true/false
* === Exceptions
* [IndexError]
* * bitmap is greater than the list of bitmaps in the image_list
* [TypeError]
* * window is nil when the BookCtrl does not support it (currently only supported for TreeBookCtrl)
* [ArgumentError]
* * window does not have this BookCtrl as parent
*
*/
DLL_LOCAL VALUE _prependPage(int argc,VALUE *argv,VALUE self)
{
VALUE window,text,select,imageid,hash;
wxWindow *w = NULL;
bool sel = false;
int iid = -1;
rb_scan_args(argc, argv, "22:",&window,&text,&select,&imageid,&hash);
rb_check_frozen(self);
if(!NIL_P(select))
sel = RTEST(select);
check_imagelist(_self,imageid,iid);
check_window(self,hash,window,w);
return wrap(_self->InsertPage(0,w,unwrap<wxString>(text),sel,iid));
}
/*
* call-seq:
* delete_page(pos) -> WX::Window
*
* deletes and returns the page with the given index from the BookCtrl.
* ===Arguments
* * pos is a Integer
*
* ===Return value
* WX::Window
* === Exceptions
* [IndexError]
* * pos is greater than the count of pages
*/
DLL_LOCAL VALUE _deletePage(VALUE self,VALUE idx)
{
rb_check_frozen(self);
int cidx = RB_NUM2INT(idx);
if(check_index(cidx,_self->GetPageCount()))
{
wxWindow *w = _self->GetPage(cidx);
if(_self->RemovePage(cidx))
return wrap(w);
}
return Qnil;
}
singlefunc(DeleteAllPages)
singlefunc(AdvanceSelection)
/*
* call-seq:
* prev_page -> self
*
* selects the previous page of the current selected.
* ===Return value
* self
*/
DLL_LOCAL VALUE _prev_page(VALUE self)
{
rb_check_frozen(self);
_self->AdvanceSelection(false);
return self;
}
/* Document-method: get_page_text
* call-seq:
* get_page_text(pos) -> String
*
* returns the text of the given page.
* ===Arguments
* * pos is a Integer
*
* ===Return value
* String
* === Exceptions
* [IndexError]
* * pos is greater than the count of pages
*/
/* Document-method: set_page_text
* call-seq:
* set_page_text(pos,text) -> self
*
* returns the text of the given page.
* ===Arguments
* * pos is a Integer
* * text is a String
*
* ===Return value
* self
* === Exceptions
* [IndexError]
* * pos is greater than the count of pages
*/
/* Document-method: delete_all_pages
* call-seq:
* delete_all_pages -> self
*
* deletes all pages from the BookCtrl. Returns self.
* ===Return value
* self
*/
/* Document-method: next_page
* call-seq:
* next_page -> self
*
* selects the next page of the current selected.
* ===Return value
* self
*/
/* Document-method: vertical?
* call-seq:
* vertical? -> true/false
*
* returns true is vertical orientation is used.
* ===Return value
* true/false
*/
/* Document-method: current_page
* call-seq:
* current_page -> WX::Window/nil
*
* returns the current selected page or nil if none is selected.
* ===Return value
* WX::Window/nil
*/
/* Document-method: control_sizer
* call-seq:
* current_page -> WX::Sizer/nil
*
* returns the sizer containing the control, if any
* ===Return value
* WX::Sizer/nil
*/
/* Document-method: controller_size
* call-seq:
* controller_size -> WX::Size
*
* return the size of the area needed to accommodate the controller
* ===Return value
* WX::Size
*/
/* Document-attr: image_list
* [WX::Bitmap] array of bitmap images,
* bitmap parameter for add, insert & prepend of pages must be smaller than size of array.
*/
/* Document-attr: selection
* Integer/nil returns the index of the current selected page, or nil if none is selected.
*/
/* Document-attr: internal_border
* Integer returns how many pixel the pages are depart of each other.
*/
/* Document-attr: control_margin
* Integer returns the margin of the pages.
*/
/* Document-const: TOP
* orient the book ctrl pages on top.
*/
/* Document-const: BOTTOM
* orient the book ctrl pages on bottom.
*/
/* Document-const: LEFT
* orient the book ctrl pages on left.
*/
/* Document-const: RIGHT
* orient the book ctrl pages on right.
*/
//for event
/* Document-attr: old_selection
* Integer/nil returns the index of the current selected page, or nil if none is selected.
*/
namespace Event {
#undef _self
#define _self unwrapTypedPtr<wxBookCtrlEvent>(self,rb_cWXBookCtrlEvent)
macro_attr(Selection,int)
macro_attr(OldSelection,int)
}
}
}
#endif
DLL_LOCAL void Init_WXBookCtrl(VALUE rb_mWX)
{
#if 0
rb_mWX = rb_define_module("WX");
rb_mWXEvtHandler = rb_define_module_under(rb_mWX,"EvtHandler");
rb_cWXWindow = rb_define_class_under(rb_mWX,"Window",rb_cObject);
rb_cWXControl = rb_define_class_under(rb_mWX,"Control",rb_cWXWindow);
rb_cWXEvent = rb_define_class_under(rb_mWX,"Event",rb_cObject);
rb_cWXCommandEvent = rb_define_class_under(rb_cWXEvent,"Command",rb_cWXEvent);
rb_cWXNotifyEvent = rb_define_class_under(rb_cWXEvent,"Notify",rb_cWXCommandEvent);
#endif
#if wxUSE_BOOKCTRL
using namespace RubyWX::BookCtrl;
rb_cWXBookCtrlBase = rb_define_class_under(rb_mWX,"BookCtrl",rb_cWXControl);
rb_undef_alloc_func(rb_cWXBookCtrlBase);
rb_cWXBookCtrlEvent = rb_define_class_under(rb_cWXEvent,"BookCtrl",rb_cWXNotifyEvent);
#if 0
rb_define_attr(rb_cWXBookCtrlBase,"selection",1,1);
rb_define_attr(rb_cWXBookCtrlBase,"image_list",1,1);
rb_define_attr(rb_cWXBookCtrlBase,"intenal_border",1,1);
rb_define_attr(rb_cWXBookCtrlBase,"control_margin",1,1);
rb_define_attr(rb_cWXBookCtrlEvent,"selection",1,1);
rb_define_attr(rb_cWXBookCtrlEvent,"old_selection",1,1);
#endif
rb_define_method(rb_cWXBookCtrlBase,"initialize",RUBY_METHOD_FUNC(_initialize),-1);
rb_define_attr_method(rb_cWXBookCtrlBase,"selection",_getSelection,_setSelection);
rb_define_attr_method(rb_cWXBookCtrlBase,"image_list",_getImageList,_setImageList);
rb_define_attr_method(rb_cWXBookCtrlBase,"intenal_border",_getInternalBorder,_setInternalBorder);
rb_define_attr_method(rb_cWXBookCtrlBase,"control_margin",_getControlMargin,_setControlMargin);
rb_define_method(rb_cWXBookCtrlBase,"add_page",RUBY_METHOD_FUNC(_addPage),-1);
rb_define_method(rb_cWXBookCtrlBase,"insert_page",RUBY_METHOD_FUNC(_insertPage),-1);
rb_define_method(rb_cWXBookCtrlBase,"prepend_page",RUBY_METHOD_FUNC(_prependPage),-1);
rb_define_method(rb_cWXBookCtrlBase,"each_page",RUBY_METHOD_FUNC(_each),0);
rb_define_method(rb_cWXBookCtrlBase,"page",RUBY_METHOD_FUNC(_page),1);
rb_define_method(rb_cWXBookCtrlBase,"get_page_text",RUBY_METHOD_FUNC(_getPageText),1);
rb_define_method(rb_cWXBookCtrlBase,"set_page_text",RUBY_METHOD_FUNC(_setPageText),2);
rb_define_method(rb_cWXBookCtrlBase,"get_page_image",RUBY_METHOD_FUNC(_get_page_image),1);
rb_define_method(rb_cWXBookCtrlBase,"set_page_image",RUBY_METHOD_FUNC(_set_page_image),2);
rb_define_method(rb_cWXBookCtrlBase,"vertical?",RUBY_METHOD_FUNC(_IsVertical),0);
rb_define_method(rb_cWXBookCtrlBase,"current_page",RUBY_METHOD_FUNC(_GetCurrentPage),0);
rb_define_method(rb_cWXBookCtrlBase,"controller_size",RUBY_METHOD_FUNC(_GetControllerSize),0);
rb_define_method(rb_cWXBookCtrlBase,"control_sizer",RUBY_METHOD_FUNC(_GetControlSizer),0);
rb_define_method(rb_cWXBookCtrlBase,"delete_page",RUBY_METHOD_FUNC(_deletePage),1);
rb_define_method(rb_cWXBookCtrlBase,"delete_all_pages",RUBY_METHOD_FUNC(_DeleteAllPages),0);
rb_define_method(rb_cWXBookCtrlBase,"next_page",RUBY_METHOD_FUNC(_AdvanceSelection),0);
rb_define_method(rb_cWXBookCtrlBase,"prev_page",RUBY_METHOD_FUNC(_prev_page),0);
rb_define_const(rb_cWXBookCtrlBase,"TOP",RB_INT2NUM(wxBK_TOP));
rb_define_const(rb_cWXBookCtrlBase,"BOTTOM",RB_INT2NUM(wxBK_BOTTOM));
rb_define_const(rb_cWXBookCtrlBase,"LEFT",RB_INT2NUM(wxBK_LEFT));
rb_define_const(rb_cWXBookCtrlBase,"RIGHT",RB_INT2NUM(wxBK_RIGHT));
rb_define_attr_method(rb_cWXBookCtrlEvent,"selection",Event::_getSelection,Event::_setSelection);
rb_define_attr_method(rb_cWXBookCtrlEvent,"old_selection",Event::_getOldSelection,Event::_setOldSelection);
registerInfo<wxBookCtrlBase>(rb_cWXBookCtrlBase);
registerInfo<wxBookCtrlEvent>(rb_cWXBookCtrlEvent);
#endif
}