Пример #1
0
void listbox::set_row_shown(const unsigned row, const bool shown)
{
	assert(generator_);

	window* window = get_window();
	assert(window);

	const int selected_row = get_selected_row();

	bool resize_needed = false;

	// Local scope for invalidate_layout_blocker
	{
		window::invalidate_layout_blocker invalidate_layout_blocker(*window);

		generator_->set_item_shown(row, shown);

		point best_size = generator_->calculate_best_size();
		generator_->place(generator_->get_origin(), {std::max(best_size.x, content_visible_area().w), best_size.y});

		resize_needed = !content_resize_request();
	}

	if(resize_needed) {
		window->invalidate_layout();
	} else {
		content_grid_->set_visible_rectangle(content_visible_area());
		set_is_dirty(true);
	}

	if(selected_row != get_selected_row()) {
		fire(event::NOTIFY_MODIFIED, *this, nullptr);
	}
}
Пример #2
0
void tlistbox::set_row_shown(const unsigned row, const bool shown)
{
	assert(generator_);

	twindow* window = get_window();
	assert(window);

	const int selected_row = get_selected_row();

	bool resize_needed;
	{
		twindow::tinvalidate_layout_blocker invalidate_layout_blocker(*window);

		generator_->set_item_shown(row, shown);
		tpoint best_size = generator_->calculate_best_size();
		generator_->place(generator_->get_origin(), { std::max(best_size.x, content_visible_area().w), best_size.y });
		resize_needed = !content_resize_request();
	}

	if(resize_needed) {
		window->invalidate_layout();
	} else {
		content_grid_->set_visible_rectangle(content_visible_area());
		set_is_dirty(true);
	}

	if(selected_row != get_selected_row() && callback_value_changed_) {
		callback_value_changed_(*this);
	}
}
Пример #3
0
void tlistbox::handle_key_right_arrow(SDLMod modifier, bool& handled)
{
	assert(generator_);

	generator_->handle_key_right_arrow(modifier, handled);

	// Inherited.
	if(handled) {
		// When scrolling make sure the new items is visible but leave the
		// vertical scrollbar position.
		const SDL_Rect& visible = content_visible_area();
		SDL_Rect rect = generator_->item(
				generator_->get_selected_item()).get_rect();

		rect.y = visible.y;
		rect.h = visible.h;

		show_content_rect(rect);

		if(callback_value_changed_) {
			callback_value_changed_(this);
		}
	} else {
		tscrollbar_container::handle_key_left_arrow(modifier, handled);
	}
}
Пример #4
0
void tlistbox::set_row_shown(const std::vector<bool>& shown)
{
	assert(generator_);
	assert(shown.size() == get_item_count());

	twindow *window = get_window();
	assert(window);

	const int selected_row = get_selected_row();

	bool resize_needed;
	{
		twindow::tinvalidate_layout_blocker invalidate_layout_blocker(*window);

		for(size_t i = 0; i < shown.size(); ++i) {
			generator_->set_item_shown(i, shown[i]);
		}
		generator_->place(generator_->get_origin()
				, generator_->calculate_best_size());
		resize_needed = !content_resize_request();
	}

	if(resize_needed) {
		window->invalidate_layout();
	} else {
		content_grid_->set_visible_area(content_visible_area());
		set_dirty();
	}

	if(selected_row != get_selected_row() && callback_value_changed_) {
		callback_value_changed_(this);
	}
}
Пример #5
0
void tlistbox::handle_key_down_arrow(SDLMod modifier, bool& handled)
{
	assert(generator_);

	generator_->handle_key_down_arrow(modifier, handled);

	if(handled) {
		// When scrolling make sure the new items is visible but leave the
		// horizontal scrollbar position.
		const SDL_Rect& visible = content_visible_area();
		SDL_Rect rect = generator_->item(generator_->get_selected_item())
								.get_rectangle();

		rect.x = visible.x;
		rect.w = visible.w;

		show_content_rect(rect);

		if(callback_value_changed_) {
			callback_value_changed_(*this);
		}
	} else {
		// Inherited.
		tscrollbar_container::handle_key_up_arrow(modifier, handled);
	}
}
Пример #6
0
void listbox::place(const point& origin, const point& size)
{
	boost::optional<unsigned> vertical_scrollbar_position, horizontal_scrollbar_position;

	// Check if this is the first time placing the list box
	if(get_origin() != point {-1, -1}) {
		vertical_scrollbar_position = get_vertical_scrollbar_item_position();
		horizontal_scrollbar_position = get_horizontal_scrollbar_item_position();
	}

	// Inherited.
	scrollbar_container::place(origin, size);

	const int selected_item = generator_->get_selected_item();
	if(vertical_scrollbar_position && horizontal_scrollbar_position) {
		LOG_GUI_L << LOG_HEADER << " restoring scroll position" << std::endl;

		set_vertical_scrollbar_item_position(*vertical_scrollbar_position);
		set_horizontal_scrollbar_item_position(*horizontal_scrollbar_position);
	} else if(selected_item != -1) {
		LOG_GUI_L << LOG_HEADER << " making the initially selected item visible" << std::endl;

		const SDL_Rect& visible = content_visible_area();
		SDL_Rect rect = generator_->item(selected_item).get_rectangle();

		rect.x = visible.x;
		rect.w = visible.w;

		show_content_rect(rect);
	}
}
Пример #7
0
void listbox::set_row_shown(const boost::dynamic_bitset<>& shown)
{
	assert(generator_);
	assert(shown.size() == get_item_count());

	if(generator_->get_items_shown() == shown) {
		LOG_GUI_G << LOG_HEADER << " returning early" << std::endl;
		return;
	}

	window* window = get_window();
	assert(window);

	const int selected_row = get_selected_row();

	bool resize_needed = false;

	// Local scope for invalidate_layout_blocker
	{
		window::invalidate_layout_blocker invalidate_layout_blocker(*window);

		for(size_t i = 0; i < shown.size(); ++i) {
			generator_->set_item_shown(i, shown[i]);
		}

		point best_size = generator_->calculate_best_size();
		generator_->place(generator_->get_origin(), {std::max(best_size.x, content_visible_area().w), best_size.y});

		resize_needed = !content_resize_request();
	}

	if(resize_needed) {
		window->invalidate_layout();
	} else {
		content_grid_->set_visible_rectangle(content_visible_area());
		set_is_dirty(true);
	}

	if(selected_row != get_selected_row()) {
		fire(event::NOTIFY_MODIFIED, *this, nullptr);
	}
}
Пример #8
0
void tlistbox::set_row_shown(const boost::dynamic_bitset<>& shown)
{
	assert(generator_);
	assert(shown.size() == get_item_count());

	if (generator_->get_items_shown() == shown)
	{
		LOG_GUI_G << LOG_HEADER << " returning early" << std::endl;
		return;
	}

	twindow* window = get_window();
	assert(window);

	const int selected_row = get_selected_row();

	bool resize_needed;
	{
		twindow::tinvalidate_layout_blocker invalidate_layout_blocker(*window);

		for(size_t i = 0; i < shown.size(); ++i) {
			generator_->set_item_shown(i, shown[i]);
		}
		tpoint best_size = generator_->calculate_best_size();
		generator_->place(generator_->get_origin(), { std::max(best_size.x, content_visible_area().w), best_size.y });
		resize_needed = !content_resize_request();
	}

	if(resize_needed) {
		window->invalidate_layout();
	} else {
		content_grid_->set_visible_rectangle(content_visible_area());
		set_is_dirty(true);
	}

	if(selected_row != get_selected_row() && callback_value_changed_) {
		callback_value_changed_(*this);
	}
}
Пример #9
0
bool ttree_view::handle_up_down_arrow()
{
	if(ttree_view_node* next = get_next_node<func>())
	{
		next->select_node();
		SDL_Rect visible = content_visible_area();
		SDL_Rect rect = next->get_grid().get_rectangle();
		visible.y = rect.y;// - content_grid()->get_y();
		visible.h = rect.h;
		show_content_rect(visible);
		return true;
	}
	return false;
}
Пример #10
0
void listbox::list_item_clicked(widget& caller)
{
	assert(generator_);

	/** @todo Hack to capture the keyboard focus. */
	get_window()->keyboard_capture(this);

	for(size_t i = 0; i < generator_->get_item_count(); ++i) {
		if(generator_->item(i).has_widget(caller)) {
			toggle_button* checkbox = dynamic_cast<toggle_button*>(&caller);

			if(checkbox != nullptr) {
				generator_->select_item(i, checkbox->get_value_bool());
			} else {
				generator_->toggle_item(i);
			}

			// TODO: enable this code once toggle_panel::set_value dispatches
			// NOTIFY_MODIFED events. See comment in said function for more details.
#if 0
			selectable_item& selectable = dynamic_cast<selectable_item&>(caller);

			generator_->select_item(i, selectable.get_value_bool());
#endif

			fire(event::NOTIFY_MODIFIED, *this, nullptr);
			break;
		}
	}

	const int selected_item = generator_->get_selected_item();
	if(selected_item == -1) {
		return;
	}

	const SDL_Rect& visible = content_visible_area();
	SDL_Rect rect = generator_->item(selected_item).get_rectangle();

	if(sdl::rects_overlap(visible, rect)) {
		rect.x = visible.x;
		rect.w = visible.w;

		show_content_rect(rect);
	}
}
Пример #11
0
bool tlistbox::update_content_size()
{
	if(get_visible() == twidget::INVISIBLE) {
		return true;
	}

	if(get_size() == tpoint(0, 0)) {
		return false;
	}

	if(content_resize_request(true)) {
		content_grid_->set_visible_area(content_visible_area());
		set_dirty();
		return true;
	}

	return false;
}
Пример #12
0
bool tlistbox::update_content_size()
{
	if(get_visible() == twidget::tvisible::invisible) {
		return true;
	}

	if(get_size() == tpoint(0, 0)) {
		return false;
	}

	if(content_resize_request(true)) {
		content_grid_->set_visible_rectangle(content_visible_area());
		set_is_dirty(true);
		return true;
	}

	return false;
}
Пример #13
0
void listbox::update_visible_area_on_key_event(const KEY_SCROLL_DIRECTION direction)
{
	const SDL_Rect& visible = content_visible_area();
	SDL_Rect rect = generator_->item(generator_->get_selected_item()).get_rectangle();

	// When scrolling make sure the new items are visible...
	if(direction == KEY_VERTICAL) {
		// ...but leave the horizontal scrollbar position.
		rect.x = visible.x;
		rect.w = visible.w;
	} else {
		// ...but leave the vertical scrollbar position.
		rect.y = visible.y;
		rect.h = visible.h;
	}

	show_content_rect(rect);

	fire(event::NOTIFY_MODIFIED, *this, nullptr);
}
Пример #14
0
void tlistbox::place(const tpoint& origin, const tpoint& size)
{
	// Inherited.
	tscrollbar_container::place(origin, size);

	/**
	 * @todo Work-around to set the selected item visible again.
	 *
	 * At the moment the listboxes and dialogs in general are resized a lot as
	 * work-around for sizing. So this function makes the selected item in view
	 * again. It doesn't work great in all cases but the proper fix is to avoid
	 * resizing dialogs a lot. Need more work later on.
	 */
	const int selected_item = generator_->get_selected_item();
	if(selected_item != -1) {
		const SDL_Rect& visible = content_visible_area();
		SDL_Rect rect = generator_->item(selected_item).get_rect();

		rect.x = visible.x;
		rect.w = visible.w;

		show_content_rect(rect);
	}
}