Ejemplo n.º 1
0
			void printer::draw_text(
				const drawer out,
				const vec2i pos,
				const drafter& d,
				const ltrbi clipper
			) const {
				const auto& colors = d.cached_str;
				auto& lines = d.lines;
				auto& sectors = d.sectors;
				const bool clip = clipper.good();

				if (!lines.empty() && !sectors.empty()) {
					simple_pair<int, int> visible;

					if (clip) {
						visible = d.get_line_visibility(clipper - pos);
					}
					else {
						visible = { 0, static_cast<int>(lines.size()) - 1 };
					}

					if (visible.first == -1) {
						return;
					}

					/* for every visible line */
					for (unsigned l = visible.first; l <= static_cast<unsigned>(visible.second); ++l) {
						/* for every character in line */
						for (unsigned i = lines[l].begin; i < lines[l].end; ++i) {
							/* shortcut */
							auto& g = *d.cached[i];

							/* if it's not a whitespace */
							if (g.in_atlas.exists()) {
								rgba charcolor = style(colors[i]).color;

								out.aabb_clipped(
									g.in_atlas,
									xywhi({ sectors[i] + g.meta.bear_x, lines[l].top + lines[l].asc - g.meta.bear_y }, g.in_atlas.get_original_size()) + pos,
									clipper,
									charcolor
								);
							}
						}
					}
				}
			}
Ejemplo n.º 2
0
void gui_system::advance_gui_elements(const logic_step step) {
	auto& cosmos = step.cosm;

	for (const auto root : cosmos.get(processing_subjects::WITH_GUI_ELEMENT)) {
		auto& element = root.get<components::gui_element>();
		auto& rect_world = element.rect_world;
		const auto screen_size = element.get_screen_size();

		if (root.has<components::item_slot_transfers>()) {
			game_gui_rect_tree tree;
			augs::gui::gui_entropy<game_gui_element_location> entropy;
			
			root_of_inventory_gui root_of_gui(screen_size);

			logic_gui_context context(step, root, tree, root_of_gui);

			root_of_inventory_gui_in_context root_location;

			rect_world.build_tree_data_into_context(context, root_location);

			const auto& entropies = step.entropy.entropy_per_entity;
			const auto& inputs_for_this_element = entropies.find(root);

			if (inputs_for_this_element != entropies.end()) {
				for (const auto& e : (*inputs_for_this_element).second) {
					//if (!element.is_gui_look_enabled) {
					//	ensure(!e.has_event_for_gui);
					//}

					if (e.has_event_for_gui) {
						bool fetched = false;
						const auto& change = e.event_for_gui;
						const auto held_rect = context._dynamic_cast<item_button_in_item>(rect_world.rect_held_by_lmb);
			
						if (held_rect != nullptr) {
							const auto& item_entity = cosmos[held_rect.get_location().item_id];
							auto& dragged_charges = element.dragged_charges;
			
							if (change.msg == augs::window::event::message::rdown
								|| change.msg == augs::window::event::message::rdoubleclick
								) {
								if (rect_world.held_rect_is_dragged) {
									step.transient.messages.post(item_slot_transfer_request_data{ item_entity, cosmos[inventory_slot_id()], dragged_charges });
									fetched = true;
								}
							}
			
							if (change.msg == augs::window::event::message::wheel) {
								const auto& item = item_entity.get<components::item>();
			
								const auto delta = change.scroll.amount;
			
								dragged_charges += delta;
			
								if (dragged_charges <= 0) {
									dragged_charges = item.charges + dragged_charges;
								}
								if (dragged_charges > item.charges) {
									dragged_charges = dragged_charges - item.charges;
								}
							}
						}
			
						if (!fetched) {
							rect_world.consume_raw_input_and_generate_gui_events(context, root_location, e.event_for_gui, entropy);
						}
					}
				}
			}
			
			// rect_world.call_idle_mousemotion_updater(context, root_location, entropy);
			rect_world.advance_elements(context, root_location, entropy, cosmos.get_fixed_delta());

			auto& transfers = step.transient.messages.get_queue<item_slot_transfer_request_data>();

			for (const auto& t : transfers) {
				perform_transfer(cosmos[t], step);
			}

			rect_world.rebuild_layouts(context, root_location);

			int max_height = 0;
			int total_width = 0;

			for (size_t i = 0; i < element.hotbar_buttons.size(); ++i) {
				const auto& hb = element.hotbar_buttons[i];

				const auto bbox = hb.get_bbox(root);
				max_height = std::max(max_height, bbox.y);

				total_width += bbox.x;
			}

			const int left_rc_spacing = 2;
			const int right_rc_spacing = 1;

			int current_x = screen_size.x / 2 - total_width / 2 - left_rc_spacing;

			auto set_rc = [&](auto& hb) {
				const auto bbox = hb.get_bbox(root);

				hb.rc = xywh(xywhi(current_x, screen_size.y - max_height - 50, bbox.x + left_rc_spacing + right_rc_spacing, max_height));

				current_x += bbox.x + left_rc_spacing + right_rc_spacing;
			};

			for (size_t i = 1; i < element.hotbar_buttons.size(); ++i) {
				set_rc(element.hotbar_buttons[i]);
			}

			set_rc(element.hotbar_buttons[0]);

			transfers.clear();
		}
	}
}
Ejemplo n.º 3
0
			void printer::draw_text(
				const drawer_with_default out,
				const vec2i pos,
				const drafter& d,
				const caret_info& caret,
				const ltrbi clipper
			) const {
				const auto& colors = d.cached_str;

				auto& lines = d.lines;
				auto& sectors = d.sectors;
				const bool clip = clipper.good();

				auto getf = [&](auto& f) -> decltype(auto) {
					return *f;
				};

				/* here we highlight the line caret is currently on */
				if (active && highlight_current_line) {
					drafter::line highlighted = lines.size() ? lines[d.get_line(caret.pos)] : drafter::line();
					out.aabb_clipped(
						xywhi(
							0, 
							highlighted.top, 
							clip ? d.get_bbox().x + clipper.w() : d.get_bbox().x,
							/* snap to default style's height */
							highlighted.empty() ? 
								getf(caret.default_style.font).metrics.get_height()
								: highlighted.height()
						) + pos, 
						clipper,
						highlight_col
					);
				}
				
				auto caret_rect = xywhi(0, 0, 0, 0);

				if (!lines.empty() && !sectors.empty()) {
					/* only these lines we want to process */
					simple_pair<int, int> visible;

					if (clip)
						visible = d.get_line_visibility(clipper - pos);
					else visible = { 0, static_cast<int>(lines.size() - 1) };

					/* if this happens:
					- check if there is always an empty line
					- check if we return when clipper is not valid
					- check if scroll is always aligned */
					if (visible.first == -1) {
						return;
					}

					/* we'll need these variables later so we declare them here */
					unsigned select_left = 0;
					unsigned select_right = 0;
					unsigned caret_line = 0;

					caret_line = d.get_line(caret.pos);

					/* let's calculate some values only once */
					select_left = caret.get_left_selection();
					select_right = caret.get_right_selection();

					if (caret.selection_offset) {
						const unsigned select_left_line = d.get_line(select_left);
						const unsigned select_right_line = d.get_line(select_right);
						const unsigned first_visible_selection = std::max(select_left_line, static_cast<unsigned>(visible.first));
						const unsigned last_visible_selection = std::min(select_right_line, static_cast<unsigned>(visible.second));

						/* manage selections */
						for (unsigned i = first_visible_selection; i <= last_visible_selection; ++i) {
							/* init selection rect on line rectangle;
							its values won't change if selecting between first and the last line
							*/
							ltrbi sel_rect = d.lines[i].get_rect();

							/* if it's the first line to process and we can see it, we have to trim its x coordinate */
							if (i == first_visible_selection && select_left_line >= first_visible_selection) {
								sel_rect.l = d.sectors[select_left];
							}

							/* similiarly with the last one
							note that with only one line selecting, it is still correct to apply these two conditions
							*/
							if (i == last_visible_selection && select_right_line <= last_visible_selection) {
								sel_rect.r = d.sectors[select_right];
							}

							out.aabb_clipped(sel_rect + pos, clipper, active ? selection_bg_col : selection_inactive_bg_col);
						}
					}

					/* for every visible line */
					for (unsigned l = visible.first; l <= static_cast<unsigned>(visible.second); ++l) {
						/* for every character in line */
						for (unsigned i = lines[l].begin; i < lines[l].end; ++i) {
							/* shortcut */
							auto& g = *d.cached[i];

							/* if it's not a whitespace */
							if (g.in_atlas.exists()) {
								rgba charcolor = style(colors[i]).color;

								/* if a character is between selection bounds, we change its color to the one specified in selected_text_color
								if there's no caret, this is never true
								*/
								if (i > select_left && i < select_right) {
									charcolor = selected_text_color;
								}

								/* add the resulting character taking bearings into account */
								out.aabb_clipped(
									g.in_atlas,
									ltrb(xywhi({ sectors[i] + g.meta.bear_x, lines[l].top + lines[l].asc - g.meta.bear_y }, g.in_atlas.get_original_size()) + pos),
									ltrb(clipper),
									charcolor
								);
							}
						}
					}

					if (active) {
						/* if we can retrieve some sane values */
						if (!lines[caret_line].empty()) {
							if (align_caret_height)
								caret_rect = xywhi(sectors[caret.pos], lines[caret_line].top, caret_width, lines[caret_line].height());
							else {
								const auto pos = std::max(1u, caret.pos);
								auto& glyph_font = getf(colors[pos - 1].format.font);
								
								caret_rect = xywhi(
									sectors[caret.pos], 
									lines[caret_line].top + lines[caret_line].asc - glyph_font.metrics.ascender,
									caret_width, 
									glyph_font.metrics.get_height()
								);
							}
						}
						/* otherwise set caret's height to default style's height to avoid strange situations */
						else {
							caret_rect = xywhi(0, d.lines[caret_line].top, caret_width, getf(caret.default_style.font).metrics.get_height());
						}
					}
				}
				/* there is nothing to draw, but we are still active so we want to draw caret anyway */
				else if (active) {
					caret_rect = xywhi(0, 0, caret_width, getf(caret.default_style.font).metrics.get_height());
				}

				if (blink.caret_visible) {
					out.aabb_clipped(caret_rect + pos, clipper, caret_col);
				}
			}