# Copyright (c) 2023 M.J.N. Corino, The Netherlands # # This software is released under the MIT license. # # Adapted for wxRuby from wxWidgets widgets sample # Copyright (c) 2001 Vadim Zeitlin module Widgets module ItemContainer class Page < Widgets::Page # Help track client data objects in wxItemContainer instances. class TrackedClientData def initialize(tracker, value) @tracker = tracker @value = value @tracker.__send__(:start_tracking_data) end def client_data_unlinked @tracker.__send__(:stop_tracking_data) end def get_value @value end end def initialize(book, images, icon) super(book, images, icon) @trackedDataObjects = 0 @items = %w[This is a List of strings] @container = nil end def on_button_test_item_container(event) @container = get_container ::Kernel.raise RuntimeError, 'Widget must have a test widget' unless @container Wx.log_message('wxItemContainer test for %s, %s:', get_widget.class.name, @container.is_sorted ? 'Sorted' : 'Unsorted') expected_result = @container.sorted? ? self.sorted_items : @items start_test('Append one item') item = @items.first @container.append(item) end_test([item]) start_test("Append some items") @container.append(@items) end_test(expected_result) start_test('Append some items with data') objects = [] @items.size.times { |i| objects << create_client_data(i) } @container.append(@items, objects) end_test(expected_result) objects = nil start_test('Append some items with data, one by one') @items.each_with_index { |item, i| @container.append(item, create_client_data(i)) } end_test(expected_result) unless @container.sorted? start_test('Insert in reverse order with data, one by one') @items.reverse.each_with_index do |item, i| @container.insert(item, 0, create_client_data(@items.size-(i+1))) end end_test(expected_result) end end def get_container ::Kernel.raise NotImplementedError end private def start_test(label) @container.clear Wx.log_message("Test - #{label}:") end def end_test(items) count = @container.count ok = (count == items.size) ::Kernel.raise RuntimeError, 'Item count does not match.' unless ok count.times do |i| str = @container.get_string(i) if str != items[i] Wx.log_error("Wrong string \"#{str}\" at position #{i} (expected \"#{items[i]}\")") ok = false break end if @container.has_client_data? data = @container.get_client_data(i) if data && !verify_client_data(data.get_value, str) ok = false break end end end Wx.log_message(dump_container_data(items)) unless ok @container.clear ok &= verify_all_client_data_destroyed Wx.log_message("...%s", ok ? "passed" : "failed") end # Track client data in wxItemContainer instances def create_client_data(value) TrackedClientData.new(self, value) end def start_tracking_data @trackedDataObjects += 1 end def stop_tracking_data @trackedDataObjects -= 1 end def verify_all_client_data_destroyed if @trackedDataObjects > 0 message = 'Bug in managing wxClientData: ' if @trackedDataObjects > 0 message << @trackedDataObjects.to_s << ' lost objects' else message << (-@trackedDataObjects).to_s << ' extra deletes' end ::Kernel.raise RuntimeError, message else true end end def verify_client_data(i, str) if i > @items.size || @items[i] != str Wx.log_error("Client data for '%s' does not match.", str) false else true end end def dump_container_data(expected) str = "Current content:\n" @container.each_string.each_with_index do |s, i| str << " - " << s << " [" if @container.has_client_data? data = @container.get_client_data(i) str << data.get_value.to_s if data end str << "]\n" end str << "Expected content:\n" expected.each do |item| str << " - " << item << "[" str << @items.find_index(item).to_s str << "]\n" end return str end def sorted_items @items.sort { |a,b| a.casecmp(b) } end end end end