コード例 #1
0
ファイル: action.cpp プロジェクト: kevinmcdonnell/openage
void BuildAction::update_in_range(unsigned int time, Unit *target_unit) {
	if (target_unit->has_attribute(attr_type::building)) {
		auto &build = target_unit->get_attribute<attr_type::building>();

		// upgrade floating outlines
		auto target_location = target_unit->location.get();
		if (target_location->is_floating()) {

			// try to place the object
			if (target_location->place(object_state::placed)) {

				// modify ground terrain
				if (build.foundation_terrain > 0) {
					target_location->set_ground(build.foundation_terrain, 0);
				}
			}
			else {

				// failed to start construction
				this->complete = 1.0f;
				return;
			}
		}

		// increment building completion
		build.completed += build_rate * time;
		this->complete = build.completed;

		if (this->complete >= 1.0f) {
			target_location->place(build.completion_state);
		}
	}
	else {
		this->complete = 1.0f;
	}

	// inc frame
	this->frame += time * this->frame_rate / 2.5f;
}
コード例 #2
0
ファイル: pointer.c プロジェクト: casucci/bspwm
void grab_pointer(pointer_action_t pac)
{
    PRINTF("grab pointer %u\n", pac);

    xcb_window_t win = XCB_NONE;
    xcb_point_t pos;

    query_pointer(&win, &pos);

    coordinates_t loc;
    if (locate_window(win, &loc)) {
        client_t *c = NULL;
        frozen_pointer->position = pos;
        frozen_pointer->action = pac;
        c = loc.node->client;
        frozen_pointer->monitor = loc.monitor;
        frozen_pointer->desktop = loc.desktop;
        frozen_pointer->node = loc.node;
        frozen_pointer->client = c;
        frozen_pointer->window = c->window;
        frozen_pointer->horizontal_fence = NULL;
        frozen_pointer->vertical_fence = NULL;

        switch (pac)  {
            case ACTION_FOCUS:
                if (loc.node != mon->desk->focus) {
                    bool backup = pointer_follows_monitor;
                    pointer_follows_monitor = false;
                    focus_node(loc.monitor, loc.desktop, loc.node);
                    pointer_follows_monitor = backup;
                } else if (focus_follows_pointer) {
                    stack(loc.node, STACK_ABOVE);
                }
                frozen_pointer->action = ACTION_NONE;
                break;
            case ACTION_MOVE:
            case ACTION_RESIZE_SIDE:
            case ACTION_RESIZE_CORNER:
                if (is_tiled(c)) {
                    frozen_pointer->rectangle = c->tiled_rectangle;
                    frozen_pointer->is_tiled = true;
                } else if (is_floating(c)) {
                    frozen_pointer->rectangle = c->floating_rectangle;
                    frozen_pointer->is_tiled = false;
                } else {
                    frozen_pointer->action = ACTION_NONE;
                    return;
                }
                if (pac == ACTION_RESIZE_SIDE) {
                    float W = frozen_pointer->rectangle.width;
                    float H = frozen_pointer->rectangle.height;
                    float ratio = W / H;
                    float x = pos.x - frozen_pointer->rectangle.x;
                    float y = pos.y - frozen_pointer->rectangle.y;
                    float diag_a = ratio * y;
                    float diag_b = W - diag_a;
                    if (x < diag_a) {
                        if (x < diag_b)
                            frozen_pointer->side = SIDE_LEFT;
                        else
                            frozen_pointer->side = SIDE_BOTTOM;
                    } else {
                        if (x < diag_b)
                            frozen_pointer->side = SIDE_TOP;
                        else
                            frozen_pointer->side = SIDE_RIGHT;
                    }
                } else if (pac == ACTION_RESIZE_CORNER) {
                    int16_t mid_x = frozen_pointer->rectangle.x + (frozen_pointer->rectangle.width / 2);
                    int16_t mid_y = frozen_pointer->rectangle.y + (frozen_pointer->rectangle.height / 2);
                    if (pos.x > mid_x) {
                        if (pos.y > mid_y)
                            frozen_pointer->corner = CORNER_BOTTOM_RIGHT;
                        else
                            frozen_pointer->corner = CORNER_TOP_RIGHT;
                    } else {
                        if (pos.y > mid_y)
                            frozen_pointer->corner = CORNER_BOTTOM_LEFT;
                        else
                            frozen_pointer->corner = CORNER_TOP_LEFT;
                    }
                }
                if (frozen_pointer->is_tiled) {
                    if (pac == ACTION_RESIZE_SIDE) {
                        switch (frozen_pointer->side) {
                            case SIDE_TOP:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
                                break;
                            case SIDE_RIGHT:
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
                                break;
                            case SIDE_BOTTOM:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
                                break;
                            case SIDE_LEFT:
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
                                break;
                        }
                    } else if (pac == ACTION_RESIZE_CORNER) {
                        switch (frozen_pointer->corner) {
                            case CORNER_TOP_LEFT:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
                                break;
                            case CORNER_TOP_RIGHT:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
                                break;
                            case CORNER_BOTTOM_RIGHT:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
                                break;
                            case CORNER_BOTTOM_LEFT:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
                                break;
                        }
                    }
                    if (frozen_pointer->horizontal_fence != NULL)
                        frozen_pointer->horizontal_ratio = frozen_pointer->horizontal_fence->split_ratio;
                    if (frozen_pointer->vertical_fence != NULL)
                        frozen_pointer->vertical_ratio = frozen_pointer->vertical_fence->split_ratio;
                }
                break;
            case ACTION_NONE:
                break;
        }
    } else {
        if (pac == ACTION_FOCUS) {
            monitor_t *m = monitor_from_point(pos);
            if (m != NULL && m != mon)
                focus_node(m, m->desk, m->desk->focus);
        }
        frozen_pointer->action = ACTION_NONE;
    }
}
コード例 #3
0
ファイル: events.c プロジェクト: sg3des/bspwm
void configure_request(xcb_generic_event_t *evt)
{
	xcb_configure_request_event_t *e = (xcb_configure_request_event_t *) evt;

	PRINTF("configure request %X\n", e->window);

	coordinates_t loc;
	bool is_managed = locate_window(e->window, &loc);
	client_t *c = (is_managed ? loc.node->client : NULL);
	int w = 0, h = 0;

	if (is_managed && !is_floating(c)) {
		if (e->value_mask & XCB_CONFIG_WINDOW_X)
			c->floating_rectangle.x = e->x;
		if (e->value_mask & XCB_CONFIG_WINDOW_Y)
			c->floating_rectangle.y = e->y;
		if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH)
			w = e->width;
		if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT)
			h = e->height;

		if (w != 0) {
			restrain_floating_width(c, &w);
			c->floating_rectangle.width = w;
		}

		if (h != 0) {
			restrain_floating_height(c, &h);
			c->floating_rectangle.height = h;
		}

		xcb_configure_notify_event_t evt;
		xcb_rectangle_t rect;
		xcb_window_t win = c->window;
		unsigned int bw = c->border_width;

		if (c->fullscreen)
			rect = loc.monitor->rectangle;
		else
			rect = c->tiled_rectangle;

		evt.response_type = XCB_CONFIGURE_NOTIFY;
		evt.event = win;
		evt.window = win;
		evt.above_sibling = XCB_NONE;
		evt.x = rect.x;
		evt.y = rect.y;
		evt.width = rect.width;
		evt.height = rect.height;
		evt.border_width = bw;
		evt.override_redirect = false;

		xcb_send_event(dpy, false, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *) &evt);

		if (c->pseudo_tiled)
			arrange(loc.monitor, loc.desktop);
	} else {
		uint16_t mask = 0;
		uint32_t values[7];
		unsigned short i = 0;

		if (e->value_mask & XCB_CONFIG_WINDOW_X) {
			mask |= XCB_CONFIG_WINDOW_X;
			values[i++] = e->x;
			if (is_managed)
				c->floating_rectangle.x = e->x;
		}

		if (e->value_mask & XCB_CONFIG_WINDOW_Y) {
			mask |= XCB_CONFIG_WINDOW_Y;
			values[i++] = e->y;
			if (is_managed)
				c->floating_rectangle.y = e->y;
		}

		if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
			mask |= XCB_CONFIG_WINDOW_WIDTH;
			w = e->width;
			if (is_managed) {
				restrain_floating_width(c, &w);
				c->floating_rectangle.width = w;
			}
			values[i++] = w;
		}

		if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
			mask |= XCB_CONFIG_WINDOW_HEIGHT;
			h = e->height;
			if (is_managed) {
				restrain_floating_height(c, &h);
				c->floating_rectangle.height = h;
			}
			values[i++] = h;
		}

		if (!is_managed && e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
			mask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
			values[i++] = e->border_width;
		}

		if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) {
			mask |= XCB_CONFIG_WINDOW_SIBLING;
			values[i++] = e->sibling;
		}

		if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
			mask |= XCB_CONFIG_WINDOW_STACK_MODE;
			values[i++] = e->stack_mode;
		}

		xcb_configure_window(dpy, e->window, mask, values);
	}

	if (is_managed)
		translate_client(monitor_from_client(c), loc.monitor, c);
}
コード例 #4
0
void CL_CSSUsedValues::set_width(const CL_CSSBoxProperties &properties)
{
	margin.left = get_margin_width(properties.margin_width_left);
	margin.right = get_margin_width(properties.margin_width_right);
	border.left = properties.border_width_left.length.value;
	border.right = properties.border_width_right.length.value;
	padding.left = get_padding_width(properties.padding_width_left);
	padding.right = get_padding_width(properties.padding_width_right);

	width = 0;
	undetermined_width = false;

	if (replaced)
	{
		if (properties.width.type == CL_CSSBoxWidth::type_auto && properties.height.type == CL_CSSBoxHeight::type_auto && intrinsic.has_width)
		{
			width = intrinsic.width;
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_auto && properties.height.type == CL_CSSBoxHeight::type_auto && intrinsic.has_height && intrinsic.has_ratio)
		{
			width = intrinsic.height / intrinsic.ratio;
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_auto && properties.height.type == CL_CSSBoxHeight::type_auto && intrinsic.has_ratio)
		{
			if (containing.undetermined_width)
			{
				width = 0;
				undetermined_width = true;
			}
			else
			{
				width = containing.width - margin.left - margin.right - border.left - border.right - padding.left - padding.right;
			}
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_auto && intrinsic.has_width)
		{
			width = intrinsic.width;
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_auto)
		{
			width = 300; // bug: Should be 300px (css physical length)
			/*if (width > device.width)
			{
				width = largest_2_1_ratio_rect();
			}*/
		}
	}
	else if (is_inline(properties))
	{
		// width property does not apply.
		width = 0;
		undetermined_width = true;
	}
	else if (is_absolute(properties))
	{
		if (properties.width.type == CL_CSSBoxWidth::type_length)
		{
			width = properties.width.length.value;
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_percentage)
		{
			if (containing.undetermined_width)
			{
				width = 0;
				undetermined_width = true;
			}
			else
			{
				width = properties.width.percentage * containing.width / 100.0f;
			}
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_auto && properties.left.type != CL_CSSBoxLeft::type_auto && properties.right.type != CL_CSSBoxRight::type_auto)
		{
			if (containing.undetermined_width)
			{
				width = 0;
				undetermined_width = true;
			}
			else
			{
				// To do: Handle the cases where the length property is a percentage. Also determine what the containing box is (the viewport/page-area?)
				width = containing.width - properties.left.length.value - properties.right.length.value - margin.left - margin.right - border.left - border.right - padding.left - padding.right;
			}
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_auto)
		{
			width = 0.0f;
			undetermined_width = true; // shrink-to-fit
		}
	}
	else if (is_floating(properties) || is_inline_block(properties))
	{
		if (properties.width.type == CL_CSSBoxWidth::type_length)
		{
			width = properties.width.length.value;
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_percentage)
		{
			if (containing.undetermined_width)
			{
				width = 0;
				undetermined_width = true;
			}
			else
			{
				width = properties.width.percentage * containing.width / 100.0f;
			}
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_auto)
		{
			width = 0.0f;
			undetermined_width = true; // shrink-to-fit
		}
	}
	else if (is_block(properties))
	{
		if (properties.width.type == CL_CSSBoxWidth::type_length)
		{
			width = properties.width.length.value;
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_percentage)
		{
			if (containing.undetermined_width)
			{
				width = 0;
				undetermined_width = true;
			}
			else
			{
				width = properties.width.percentage * containing.width / 100.0f;
			}
		}
		else if (properties.width.type == CL_CSSBoxWidth::type_auto)
		{
			if (containing.undetermined_width)
			{
				width = 0;
				undetermined_width = true;
			}
			else
			{
				width = cl_max(0.0f, containing.width - margin.left - margin.right - border.left - border.right - padding.left - padding.right);
			}
		}
	}

	if (!undetermined_width)
	{
		if (properties.max_width.type == CL_CSSBoxMaxWidth::type_length)
		{
			width = cl_min(width, properties.max_width.length.value);
		}
		else if (properties.max_width.type == CL_CSSBoxMaxWidth::type_percentage && !containing.undetermined_width)
		{
			width = cl_min(width, properties.max_width.percentage * containing.width / 100.0f);
		}

		if (properties.min_width.type == CL_CSSBoxMinWidth::type_length)
		{
			width = cl_max(width, properties.min_width.length.value);
		}
		else if (properties.min_width.type == CL_CSSBoxMinWidth::type_percentage && !containing.undetermined_width)
		{
			width = cl_max(width, properties.min_width.percentage * containing.width / 100.0f);
		}
	}

	calc_noncontent_width(properties);
}
コード例 #5
0
void CL_CSSUsedValues::calc_noncontent_width(const CL_CSSBoxProperties &properties)
{
	margin.left = get_margin_width(properties.margin_width_left);
	margin.right = get_margin_width(properties.margin_width_right);
	border.left = properties.border_width_left.length.value;
	border.right = properties.border_width_right.length.value;
	padding.left = get_padding_width(properties.padding_width_left);
	padding.right = get_padding_width(properties.padding_width_right);

	if (is_inline(properties) || is_inline_block(properties) || is_floating(properties))
	{
		// Do nothing. Correct values already set by get_margin_width.
	}
	else if (is_block(properties))
	{
		if (properties.margin_width_left.type == CL_CSSBoxMarginWidth::type_auto && properties.margin_width_right.type == CL_CSSBoxMarginWidth::type_auto)
		{
			margin.left = cl_max(0.0f, (containing.width-border.left-border.right-padding.left-padding.right-width)/2.0f);
			margin.right = cl_max(0.0f, containing.width-border.left-border.right-padding.left-padding.right-width-margin.left);
		}
		else if (properties.margin_width_left.type == CL_CSSBoxMarginWidth::type_auto)
		{
			margin.left = cl_max(0.0f, containing.width-margin.right-border.left-border.right-padding.left-padding.right-width);
		}
		else if (properties.margin_width_right.type == CL_CSSBoxMarginWidth::type_auto)
		{
			margin.right = cl_max(0.0f, containing.width-margin.left-border.left-border.right-padding.left-padding.right-width);
		}

		if (margin.left + border.left + width + border.right + padding.right + margin.right > containing.width)
		{
			if (properties.direction.type == CL_CSSBoxDirection::type_ltr)
				margin.right = cl_max(0.0f, containing.width-margin.left-border.left-border.right-padding.left-padding.right-width);
			else
				margin.left = cl_max(0.0f, containing.width-margin.right-border.left-border.right-padding.left-padding.right-width);
		}
	}
	else if (is_absolute(properties) && !replaced)
	{
		// Lots of annoying calculations here using 'left', 'right', 'width', 'direction' and the margin+border+padding+width=containing.width constraint
	}
	else if (is_absolute(properties) && replaced)
	{
		if (properties.margin_width_left.type == CL_CSSBoxMarginWidth::type_auto)
		{
			if (properties.left.type == CL_CSSBoxLeft::type_auto || properties.right.type == CL_CSSBoxRight::type_auto)
			{
				margin.left = 0;
			}
			else
			{
				// solve using margin+border+padding+width=containing.width constraint
			}
		}

		if (properties.margin_width_right.type == CL_CSSBoxMarginWidth::type_auto)
		{
			if (properties.left.type == CL_CSSBoxLeft::type_auto || properties.right.type == CL_CSSBoxRight::type_auto)
			{
				margin.right = 0;
			}
			else
			{
				// solve using margin+border+padding+width=containing.width constraint
			}
		}
	}
}
コード例 #6
0
ファイル: tree.c プロジェクト: ThomasAdam/bspwm
void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, xcb_rectangle_t root_rect)
{
    if (n == NULL)
        return;

    n->rectangle = rect;

    if (is_leaf(n)) {
        if (n->client->fullscreen)
            return;

        if (is_floating(n->client) && n->client->border_width != border_width) {
            int ds = 2 * (border_width - n->client->border_width);
            n->client->floating_rectangle.width += ds;
            n->client->floating_rectangle.height += ds;
        }

        if (borderless_monocle && is_tiled(n->client) && d->layout == LAYOUT_MONOCLE)
            n->client->border_width = 0;
        else
            n->client->border_width = border_width;

        xcb_rectangle_t r;
        if (is_tiled(n->client)) {
            if (d->layout == LAYOUT_TILED)
                r = rect;
            else if (d->layout == LAYOUT_MONOCLE)
                r = root_rect;
            int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : window_gap);
            int bleed = wg + 2 * n->client->border_width;
            r.width = (bleed < r.width ? r.width - bleed : 1);
            r.height = (bleed < r.height ? r.height - bleed : 1);
            n->client->tiled_rectangle = r;
        } else {
            r = n->client->floating_rectangle;
        }

        window_move_resize(n->client->window, r.x, r.y, r.width, r.height);
        window_border_width(n->client->window, n->client->border_width);
        window_draw_border(n, n == d->focus, m == mon);

    } else {
        xcb_rectangle_t first_rect;
        xcb_rectangle_t second_rect;

        if (n->first_child->vacant || n->second_child->vacant) {
            first_rect = second_rect = rect;
        } else {
            unsigned int fence;
            if (n->split_type == TYPE_VERTICAL) {
                fence = rect.width * n->split_ratio;
                first_rect = (xcb_rectangle_t) {rect.x, rect.y, fence, rect.height};
                second_rect = (xcb_rectangle_t) {rect.x + fence, rect.y, rect.width - fence, rect.height};

            } else if (n->split_type == TYPE_HORIZONTAL) {
                fence = rect.height * n->split_ratio;
                first_rect = (xcb_rectangle_t) {rect.x, rect.y, rect.width, fence};
                second_rect = (xcb_rectangle_t) {rect.x, rect.y + fence, rect.width, rect.height - fence};
            }
        }

        apply_layout(m, d, n->first_child, first_rect, root_rect);
        apply_layout(m, d, n->second_child, second_rect, root_rect);
    }
}