unit uListView;

interface

uses
{$IFDEF VCL}
  ComCtrls,
{$ELSE}
  QComCtrls,
{$ENDIF}
  Rubies;

var
  cIconOptions, cListView: Tvalue;

function ap_cIconOptions: Tvalue;
function ap_cListView: Tvalue;
function ap_iListView(real: TListView; owner: Tvalue): Tvalue;
procedure Init_ListView;

implementation

uses
  SysUtils, Classes,
  uDefUtils, uIntern, uHandle, uAlloc, uProp, uPhi, uIO, uConv,
  uSizeConstraints, uCanvas, uFont, uListItem, uListColumn,
  uPoint, uRect,
  uPersistent, uComponent, uControl;

function ap_cIconOptions: Tvalue;
begin
  result := cIconOptions;
end;

function ap_cListView: Tvalue;
begin
  result := cListView;
end;

function IconOptions_alloc(This: Tvalue; real: TIconOptions): Tvalue;
begin
  result := TmpAlloc(This, real);
end;

function ap_iIconOptions(real: TIconOptions; owner: Tvalue): Tvalue;
begin
  result := IconOptions_alloc(cIconOptions, real);
  ap_owner(result, owner);
end;

procedure ListView_setup(obj: Tvalue; real: TListView);
begin
{$IFDEF VCL}
  rb_iv_set(obj, '@icon_options', ap_iIconOptions(real.IconOptions, obj));
  rb_iv_set(obj, '@canvas', ap_iCanvas(real.Canvas, obj));
{$ENDIF}
  rb_iv_set(obj, '@font', ap_iFont(real.Font, obj));
  rb_iv_set(obj, '@items', ap_iListItems(real.Items, obj));
  rb_iv_set(obj, '@columns', ap_iListColumns(real.Columns, obj));
//    AssignPropMethod(real, [Handle]);
end;

function ListView_event_handle(This, name: Tvalue): Tvalue; cdecl;
begin
  EventHandle(This, name, [Handle]);
  result := Qnil;
end;

function ListView_alloc(This: Tvalue; real: TListView): Tvalue;
begin
  result := ChildAlloc(This, real);
  ListView_setup(result, real);
end;

function ap_iListView(real: TListView; owner: Tvalue): Tvalue;
begin
  result := ListView_alloc(cListView, real);
  ap_owner(result, owner);
end;

function ap_iListView_v(var AControl; owner: Tvalue): Tvalue;
begin
  result := ap_iListView(TListView(AControl), owner);
end;

function ListView_new(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := TListView.Create(nil);
  result := CompoAlloc(This, real);
  CompoSetup(argc, argv, real);
  ListView_setup(result, real);
  ap_obj_call_init(result, argc, argv);
end;

function ListView_get_selected(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
  item: TListItem;
begin
  real := ap_data_get_struct(This);
  item := real.Selected;
  if item = nil then
    result := Qnil
  else
    result := ap_ListItem(item);
end;

function ListView_set_selected(This, v: Tvalue): Tvalue; cdecl;
var
  real: TListView;
  item: TListItem;
begin
  real := ap_data_get_struct(This);
  item := dl_ListItem(v);
  real.Selected := item;
  result := v;
end;

{$IFDEF VCL}
function ListView_hit_test_info_at(This, x, y: Tvalue): Tvalue; cdecl;
var
  real: TListView;
  tests: THitTests;
begin
  real := ap_data_get_struct(This);
  tests := real.GetHitTestInfoAt(dl_Integer(x), dl_Integer(y));
  result := ap_Set(tests);
end;

function ListView_get_item_index(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_Fixnum(real.ItemIndex);
end;

function ListView_set_item_index(This, v: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  real.ItemIndex := dl_Integer(v);
  result := v;
end;
{$ENDIF}

function ListView_scroll(This, x, y: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  real.Scroll(dl_Integer(x), dl_Integer(y));
  result := This;
end;

function ListView_alpha_sort(This : Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_Bool(real.AlphaSort);
end;
{$IFDEF VCL}
function ListView_clear(This : Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  real.Clear;  //ListItems_clear を考慮しないとだめ
  result := This;
end;

function ListView_clear_selection(This : Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  real.ClearSelection;
  result := This;
end;

function ListView_delete_selected(This : Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  real.DeleteSelected;
  result := This;
end;
{$ENDIF}
function ListView_find_caption(This, StartIndex, Value, Partial,
Inclusive, Wrap : Tvalue): Tvalue; cdecl;
var
  real: TListView;
  dl_StartIndex : Integer;
  dl_Value : string;
  dl_Partial : Boolean;
  dl_Inclusive : Boolean;
  dl_Wrap : Boolean;
  item: TListItem;
begin
  real := ap_data_get_struct(This);
  dl_StartIndex := dl_Integer(StartIndex);
  dl_Value := dl_String(Value);
  dl_Partial := dl_Boolean(Partial);
  dl_Inclusive := dl_Boolean(Inclusive);
  dl_Wrap := dl_Boolean(Wrap);
  item := real.FindCaption( dl_StartIndex, dl_Value, dl_Partial, dl_Inclusive, dl_Wrap );
  if item = nil then
    result := Qnil
  else
    result := Tvalue(item.Data);
  //result := ap_iListItem(item, This);
end;

function ListView_get_item_at(This, x, y: Tvalue): Tvalue; cdecl;
var
  real: TListView;
  item: TListItem;
begin
  real := ap_data_get_struct(This);
  item := real.GetItemAt(dl_Integer(x), dl_Integer(y));
  if item = nil then
    result := Qnil
  else
    result := ap_ListItem(item);
end;

function ListView_item_at(This, x, y: Tvalue): Tvalue; cdecl;
var
  real: TListView;
  item: TListItem;
begin
  real := ap_data_get_struct(This);
  item := real.GetItemAt(dl_Integer(x), dl_Integer(y));
  if item = nil then
    result := Qnil
  else
    result := ap_ListItem(item);
end;
{$IFDEF VCL}
function ListView_get_search_string(This : Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_String(real.GetSearchString);
end;
{$ENDIF}
function ListView_is_editing(This : Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_Bool(real.IsEditing);
end;
{$IFDEF VCL}
function ListView_select_all(This : Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  real.SelectAll;
  result := This;
end;
{$ENDIF}
function ListView_get_drop_target(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_iListItem(real.DropTarget,This);  // uses uListItem
end;
{$IFDEF VCL}
function ListView_set_drop_target(This, v: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  real.DropTarget := dl_ListItem(v);
  result := v;
end;
{$ENDIF}
function ListView_get_item_focused(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_iListItem(real.ItemFocused,This);  // uses uListItem
end;

function ListView_set_item_focused(This, v: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  real.ItemFocused := dl_ListItem(v);
  result := v;
end;

function ListView_get_sel_count(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_Integer(Ord(real.SelCount));
end;
{$IFDEF VCL}
function ListView_string_width(This, S : Tvalue): Tvalue; cdecl;
var
  real: TListView;
  dl_S : string;
begin
  real := ap_data_get_struct(This);
  dl_S := dl_String(S);
  result := ap_Integer(real.StringWidth( dl_S ));
end;
{$ENDIF}
function ListView_update_items(This, FirstIndex, LastIndex : Tvalue):
Tvalue; cdecl;
var
  real: TListView;
  dl_FirstIndex : Integer;
  dl_LastIndex : Integer;
begin
  real := ap_data_get_struct(This);
  dl_FirstIndex := dl_Integer(FirstIndex);
  dl_LastIndex := dl_Integer(LastIndex);
  real.UpdateItems( dl_FirstIndex, dl_LastIndex );
  result := This;
end;

function ListView_get_top_item(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_iListItem(real.TopItem,This);  // uses uListItem
end;
{$IFDEF VCL}
function ListView_get_view_origin(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_iPoint(real.ViewOrigin, This);
end;

function ListView_get_visible_row_count(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_Integer(Ord(real.VisibleRowCount));
end;

function ListView_get_bounding_rect(This: Tvalue): Tvalue; cdecl;
var
  real: TListView;
begin
  real := ap_data_get_struct(This);
  result := ap_iRect(real.BoundingRect, This);
end;

function ListView_get_hit_test_info_at(This, x, y: Tvalue): Tvalue; cdecl;
var
  real: TListView;
  ht: THitTests;
begin
  real := ap_data_get_struct(This);
  ht := real.GetHitTestInfoAt(FIX2INT(x), FIX2INT(y));
  result := ap_Set(ht);
end;
{$ENDIF}
procedure Init_ListView;
begin
  OutputConstSetType(mPhi, TypeInfo(TIconArrangement));
  OutputConstSetType(mPhi, TypeInfo(TItemChange));

  cIconOptions := rb_define_class_under(mPhi, 'IconOptions', ap_cObject);
  OutputProp(cIconOptions, TIconOptions);

  OutputConstSetType(mPhi, TypeInfo(TViewStyle));

  cListView := OutputPersistentClass(mPhi, TListView, cWinControl, ap_iListView_v);
  DefineAttrGet(cListView, 'selected', ListView_get_selected);
  DefineAttrSet(cListView, 'selected', ListView_set_selected);
  rb_define_attr(cListView, 'items', 1, 0);

  rb_define_method(cListView, 'event_handle', @ListView_event_handle, 1);
  DefineSingletonMethod(cListView, 'new', ListView_new);
  rb_define_attr(cListView, 'canvas', 1, 0);

{$IFDEF VCL}
  rb_define_method(cListView, 'hit_test_info_at', @ListView_hit_test_info_at, 2);
  DefineAttrGet(cListView, 'item_index', ListView_get_item_index);
  DefineAttrSet(cListView, 'item_index', ListView_set_item_index);
{$ENDIF}
  rb_define_method(cListView, 'scroll', @ListView_scroll, 2);

  rb_define_method(cListView, 'alpha_sort', @ListView_alpha_sort, 0);
{$IFDEF VCL}
  rb_define_method(cListView, 'clear', @ListView_clear, 0);
  rb_define_method(cListView, 'clear_selection', @ListView_clear_selection, 0);
  rb_define_method(cListView, 'delete_selected', @ListView_delete_selected, 0);
{$ENDIF}
  rb_define_method(cListView, 'find_caption', @ListView_find_caption, 5);
  rb_define_method(cListView, 'get_item_at', @ListView_get_item_at, 2);
  rb_define_method(cListView, 'item_at', @ListView_item_at, 2);  //alias にすべき
{$IFDEF VCL}
  rb_define_method(cListView, 'get_search_string', @ListView_get_search_string, 0);
{$ENDIF}
  rb_define_method(cListView, 'is_editing', @ListView_is_editing, 0);
{$IFDEF VCL}
  rb_define_method(cListView, 'select_all', @ListView_select_all, 0);
{$ENDIF}
  DefineAttrGet(cListView, 'drop_target', ListView_get_drop_target);
{$IFDEF VCL}
  DefineAttrSet(cListView, 'drop_target', ListView_set_drop_target);
{$ENDIF}
  DefineAttrGet(cListView, 'item_focused', ListView_get_item_focused);
  DefineAttrSet(cListView, 'item_focused', ListView_set_item_focused);
  DefineAttrGet(cListView, 'sel_count', ListView_get_sel_count);
{$IFDEF VCL}
  rb_define_method(cListView, 'string_width', @ListView_string_width, 1);
{$ENDIF}
  rb_define_method(cListView, 'update_items', @ListView_update_items, 2);
  DefineAttrGet(cListView, 'top_item', ListView_get_top_item);
{$IFDEF VCL}
  DefineAttrGet(cListView, 'view_origin', ListView_get_view_origin);
  DefineAttrGet(cListView, 'visible_row_count', ListView_get_visible_row_count);
  DefineAttrGet(cListView, 'bounding_rect', ListView_get_bounding_rect);
  rb_define_method(cListView, 'get_hit_test_info_at', @ListView_get_hit_test_info_at, 2);
{$ENDIF}
end;

end.
