bool tscrollbar_container::content_resize_height(const int height_modification)
{
	if(height_modification == 0) {
		return true;
	}

	const int new_height =
			content_grid_->get_height() + height_modification;

	DBG_GUI_L << LOG_HEADER
			<< " current height " << content_grid_->get_height()
			<< " wanted height " << new_height;

	assert(new_height > 0);

	if(static_cast<unsigned>(new_height) <= content_->get_height()) {
		DBG_GUI_L << " height in container, resize allowed.\n";
		set_scrollbar_mode(vertical_scrollbar_grid_
				, vertical_scrollbar_
				, vertical_scrollbar_mode_
				, new_height
				, content_->get_height());
		return true;
	}

	assert(vertical_scrollbar_ && vertical_scrollbar_grid_);
	if(vertical_scrollbar_mode_ == always_invisible
			|| (vertical_scrollbar_mode_ == auto_visible_first_run
				&& vertical_scrollbar_grid_->get_visible()
					== twidget::tvisible::invisible)) {

		DBG_GUI_L << " can't use vertical scrollbar, ask window.\n";
		twindow* window = get_window();
		assert(window);
		window->invalidate_layout();
		return false;
	}

	DBG_GUI_L << " use the vertical scrollbar, resize allowed.\n";
	set_scrollbar_mode(vertical_scrollbar_grid_
			, vertical_scrollbar_
			, vertical_scrollbar_mode_
			, new_height
			, content_->get_height());

	return true;
}
bool tscrollbar_container::content_resize_width(const int width_modification)
{
	if(width_modification == 0) {
		return true;
	}

	const int new_width = content_grid_->get_width() + width_modification;
	DBG_GUI_L << LOG_HEADER
			<< " current width " << content_grid_->get_width()
			<< " wanted width " << new_width;

	assert(new_width > 0);

	if(static_cast<unsigned>(new_width) <= content_->get_width()) {
		DBG_GUI_L << " width fits in container, test height.\n";
		set_scrollbar_mode(horizontal_scrollbar_grid_
				, horizontal_scrollbar_
				, horizontal_scrollbar_mode_
				, new_width
				, content_->get_width());
		return true;
	}

	assert(horizontal_scrollbar_ && horizontal_scrollbar_grid_);
	if(horizontal_scrollbar_mode_ == always_invisible
			|| (horizontal_scrollbar_mode_ == auto_visible_first_run
				&& horizontal_scrollbar_grid_->get_visible()
					== twidget::tvisible::invisible)) {

		DBG_GUI_L << " can't use horizontal scrollbar, ask window.\n";
		twindow* window = get_window();
		assert(window);
		window->invalidate_layout();
		return false;
	}

	DBG_GUI_L << " use the horizontal scrollbar, test height.\n";
	set_scrollbar_mode(horizontal_scrollbar_grid_
			, horizontal_scrollbar_
			, horizontal_scrollbar_mode_
			, new_width
			, content_->get_width());

	return true;
}
void tscrollbar_container::place(const tpoint& origin, const tpoint& size)
{
	// Inherited.
	tcontainer_::place(origin, size);

	// Set content size
	assert(content_ && content_grid_);

	const tpoint content_origin = content_->get_origin();

	const tpoint best_size = content_grid_->get_best_size();
	const tpoint content_size(content_->get_width(), content_->get_height());

	const tpoint content_grid_size(std::max(best_size.x, content_size.x),
								   std::max(best_size.y, content_size.y));

	set_content_size(content_origin, content_grid_size);

	// Set vertical scrollbar
	set_scrollbar_mode(vertical_scrollbar_grid_,
					   vertical_scrollbar_,
					   vertical_scrollbar_mode_,
					   content_grid_->get_height(),
					   content_->get_height());

	// Set horizontal scrollbar
	set_scrollbar_mode(horizontal_scrollbar_grid_,
					   horizontal_scrollbar_,
					   horizontal_scrollbar_mode_,
					   content_grid_->get_width(),
					   content_->get_width());

	// Update the buttons.
	set_scrollbar_button_status();

	// Now set the visible part of the content.
	content_visible_area_ = content_->get_rectangle();
	content_grid_->set_visible_rectangle(content_visible_area_);
}
static void
adjust_scrollbar_mode(tgrid* scrollbar_grid,
				   tscrollbar_* scrollbar,
				   tscrollbar_container::tscrollbar_mode& scrollbar_mode,
				   const unsigned items_before,
				   const unsigned items_after,
				   const int insertion_pos,
				   const unsigned visible_items)
{
	assert(scrollbar_grid && scrollbar);
	if(items_before != scrollbar->get_item_count()) {
		return set_scrollbar_mode(scrollbar_grid, scrollbar, scrollbar_mode, items_after, visible_items);
	}
	//TODO: does this also work well in case the items were removed?
	const unsigned previous_item_position = scrollbar->get_item_position();
	//Casts insertion_pos to an unsigned so negative values are interpreted as 'at end'
	const bool inserted_before_visible_area = is_inserted_before(static_cast<unsigned>(insertion_pos), items_before, previous_item_position, visible_items);

	if(scrollbar_mode == tscrollbar_container::always_invisible) {
		scrollbar_grid->set_visible(twidget::tvisible::invisible);
		return;
	}

	scrollbar->set_item_count(items_after);
	scrollbar->set_item_position(inserted_before_visible_area ? previous_item_position + items_after - items_before : previous_item_position);
	//scrollbar->set_item_position(0);
	scrollbar->set_visible_items(visible_items);

	if(scrollbar_mode == tscrollbar_container::auto_visible) {

		const bool scrollbar_needed = items_after > visible_items;

		scrollbar_grid->set_visible(scrollbar_needed
											? twidget::tvisible::visible
											: twidget::tvisible::hidden);
	}
}