Object* RoomContainer::_ObjectAtPoint(const IE::point& point, int32& cursorIndex) const { Object* object = NULL; cursorIndex = -1; ::TileCell* cell = fBackMap->TileAtPoint(point); if (cell == NULL) return object; if (Door* door = cell->Door()) { if (rect_contains(door->Frame(), point)) return door; } else { std::vector<Object*> objects; if (cell->GetObjects(objects) > 0) { std::vector<Object*>::iterator i; for (i = objects.begin(); i != objects.end(); i++) { if (rect_contains((*i)->Frame(), point)) { object = *i; } } } } if (Region* region = _RegionAtPoint(point)) { object = region; cursorIndex = region->CursorIndex(); } return object; }
/* virtual */ void Scrollbar::MouseDown(IE::point point) { if (rect_contains(fUpArrow->Frame(), point)) { fUpArrowPressed = true; } else if (rect_contains(fDownArrow->Frame(), point)) { fDownArrowPressed = true; } }
void RoomContainer::MouseOver(uint16 x, uint16 y) { const uint16 kScrollingStep = 64; uint16 horizBorderSize = 35; uint32 vertBorderSize = 40; // TODO: Less hardcoding of the window number Window* window = GUI::Get()->GetWindow(1); if (window != NULL) { horizBorderSize += window->Width(); } sint16 scrollByX = 0; sint16 scrollByY = 0; if (x <= horizBorderSize) scrollByX = -kScrollingStep; else if (x >= fViewPort.w - horizBorderSize) scrollByX = kScrollingStep; if (y <= vertBorderSize) scrollByY = -kScrollingStep; else if (y >= fViewPort.h - vertBorderSize) scrollByY = kScrollingStep; IE::point point = { int16(x), int16(y) }; ConvertToArea(point); _UpdateCursor(x, y, scrollByX, scrollByY); // TODO: This screams for improvements if (fWed != NULL) { int32 cursor = -1; fMouseOverObject = _ObjectAtPoint(point, cursor); if (cursor != -1) GUI::Get()->SetCursor(cursor); } else if (fWorldMap != NULL) { for (uint32 i = 0; i < fWorldMap->CountAreaEntries(); i++) { AreaEntry& area = fWorldMap->AreaEntryAt(i); GFX::rect areaRect = area.Rect(); if (rect_contains(areaRect, point)) { ConvertFromArea(areaRect); ConvertToScreen(areaRect); //char* toolTip = area.TooltipName(); //RenderString(toolTip, GraphicsEngine::Get()->ScreenSurface()); //free(toolTip); GraphicsEngine::Get()->ScreenBitmap()->StrokeRect(areaRect, 600); break; } } } IE::point newAreaOffset = fAreaOffset; newAreaOffset.x += scrollByX; newAreaOffset.y += scrollByY; SetAreaOffset(newAreaOffset); }
bool Object::IsInsideVisibleArea() const { IE::rect rect = gfx_rect_to_rect(RoomContainer::Get()->VisibleArea()); if (rect_contains(rect, Position())) return true; return false; }
bool sprite_contains(struct sprite* self, float x, float y) { struct rect world = { self->glyph.bl.position[0], self->glyph.bl.position[1], self->width, self->height, }; return rect_contains(&world, x, y); }
Region* RoomContainer::_RegionAtPoint(const IE::point& point) const { std::vector<Reference<Region> >::const_iterator i; for (i = fRegions.begin(); i != fRegions.end(); i++) { IE::rect rect = i->Target()->Frame(); if (rect_contains(rect_to_gfx_rect(rect), point)) return i->Target(); } return NULL; }
Window* GUI::_GetWindow(IE::point pt) { std::vector<Window*>::reverse_iterator i; for (i = fActiveWindows.rbegin(); i < fActiveWindows.rend(); i++) { Window* window = (*i); if (rect_contains(window->Frame(), pt)) return window; } return NULL; }
int layout_frame_number_by_coord(struct layout *l, struct coord probe) { /* FIXME use a more efficient implementation. */ for (int f = 0; f < l->frame_count; f++) { struct rect ff = layout_frame_rect_by_number(l, f); if (rect_contains(ff, probe)) { return f; } } return -1; }
void dirty_addrect(struct rect *rt) { if (rt == NULL) { _dirty_rects[0].left = 0; _dirty_rects[0].top = 0; _dirty_rects[0].right = SCREEN_WIDTH; _dirty_rects[0].bottom = SCREEN_HEIGHT; _rect_count = 1; return; } if (_rect_count==0) { _dirty_rects[_rect_count] = *rt; ++_rect_count; } else { int i; struct rect comb; int area1, area2, areac, areaBest; int bestidx = -1; if (_rect_count>=MAX_DIRTY-1) { dirty_addrect(NULL); return; } for (i=0; i<_rect_count; ++i) { if (rect_contains(&_dirty_rects[i], rt)) return; } for (i=0; i<_rect_count; ++i) { comb = rect_combine(&_dirty_rects[i], rt); area1 = rect_calc_area(&_dirty_rects[i]); area2 = rect_calc_area(rt); areac = rect_calc_area(&comb); if (areac < area1 + area2) { if (bestidx < 0 || area1 + area2 - areac > areaBest) { areaBest = area1 + area2 - areac; bestidx = i; } } } if (bestidx >= 0) _dirty_rects[bestidx] = rect_combine(&_dirty_rects[bestidx], rt); else _dirty_rects[_rect_count++] = *rt; } }
static int scrollrect(VTermRect rect, int downward, int rightward, void *user) { VTermScreen *screen = user; if(screen->damage_merge != VTERM_DAMAGE_SCROLL) { vterm_scroll_rect(rect, downward, rightward, moverect_internal, erase_internal, screen); vterm_screen_flush_damage(screen); vterm_scroll_rect(rect, downward, rightward, moverect_user, erase_user, screen); return 1; } if(screen->damaged.start_row != -1 && !rect_intersects(&rect, &screen->damaged)) { vterm_screen_flush_damage(screen); } if(screen->pending_scrollrect.start_row == -1) { screen->pending_scrollrect = rect; screen->pending_scroll_downward = downward; screen->pending_scroll_rightward = rightward; } else if(rect_equal(&screen->pending_scrollrect, &rect) && ((screen->pending_scroll_downward == 0 && downward == 0) || (screen->pending_scroll_rightward == 0 && rightward == 0))) { screen->pending_scroll_downward += downward; screen->pending_scroll_rightward += rightward; } else { vterm_screen_flush_damage(screen); screen->pending_scrollrect = rect; screen->pending_scroll_downward = downward; screen->pending_scroll_rightward = rightward; } vterm_scroll_rect(rect, downward, rightward, moverect_internal, erase_internal, screen); if(screen->damaged.start_row == -1) return 1; if(rect_contains(&rect, &screen->damaged)) { /* Scroll region entirely contains the damage; just move it */ vterm_rect_move(&screen->damaged, -downward, -rightward); rect_clip(&screen->damaged, &rect); } /* There are a number of possible cases here, but lets restrict this to only * the common case where we might actually gain some performance by * optimising it. Namely, a vertical scroll that neatly cuts the damage * region in half. */ else if(rect.start_col <= screen->damaged.start_col && rect.end_col >= screen->damaged.end_col && rightward == 0) { if(screen->damaged.start_row >= rect.start_row && screen->damaged.start_row < rect.end_row) { screen->damaged.start_row -= downward; if(screen->damaged.start_row < rect.start_row) screen->damaged.start_row = rect.start_row; if(screen->damaged.start_row > rect.end_row) screen->damaged.start_row = rect.end_row; } if(screen->damaged.end_row >= rect.start_row && screen->damaged.end_row < rect.end_row) { screen->damaged.end_row -= downward; if(screen->damaged.end_row < rect.start_row) screen->damaged.end_row = rect.start_row; if(screen->damaged.end_row > rect.end_row) screen->damaged.end_row = rect.end_row; } } else { DEBUG_LOG2("TODO: Just flush and redo damaged=" STRFrect " rect=" STRFrect "\n", ARGSrect(screen->damaged), ARGSrect(rect)); } return 1; }
void RoomContainer::Clicked(uint16 x, uint16 y) { IE::point point = {int16(x), int16(y)}; ConvertToArea(point); if (fWorldMap != NULL) { for (uint32 i = 0; i < fWorldMap->CountAreaEntries(); i++) { AreaEntry& area = fWorldMap->AreaEntryAt(i); if (rect_contains(area.Rect(), point)) { LoadArea(area); break; } } return; } if (fSelectedActor != NULL) fSelectedActor.Target()->ClearActionList(); // TODO: Temporary, for testing if (Door* door = dynamic_cast<Door*>(fMouseOverObject.Target())) { if (fSelectedActor != NULL) fSelectedActor.Target()->ClickedOn(door); return; } if (Actor* actor = dynamic_cast<Actor*>(fMouseOverObject.Target())) { if (fSelectedActor != actor) { /*if (fSelectedActor != NULL) fSelectedActor->Select(false); fSelectedActor = actor; if (fSelectedActor != NULL) fSelectedActor->Select(true); */ if (fSelectedActor != NULL) fSelectedActor.Target()->ClickedOn(actor); } return; } if (Region* region = _RegionAtPoint(point)) { // TODO: if (fSelectedActor != NULL) fSelectedActor.Target()->ClickedOn(region); if (region->Type() == IE::REGION_TYPE_TRAVEL) { LoadArea(region->DestinationArea(), "foo", region->DestinationEntrance()); return; } else if (region->Type() == IE::REGION_TYPE_INFO) { int32 strRef = region->InfoTextRef(); if (strRef >= 0) Core::Get()->DisplayMessage(strRef); return; } } else if (Container* container = _ContainerAtPoint(point)) { // TODO: if (fSelectedActor != NULL) fSelectedActor.Target()->ClickedOn(container); } if (fSelectedActor != NULL) { WalkTo* walkTo = new WalkTo(fSelectedActor.Target(), point); fSelectedActor.Target()->AddAction(walkTo); } }
static int update(gesture_t *gest, const inputs_t *inputs, int mask) { const touch_t *ts = inputs->touches; int nb_ts = 0; int i, j; for (i = 0; i < ARRAY_SIZE(inputs->touches); i++) { for (j = 0; j < ARRAY_SIZE(inputs->touches[i].down); j++) { if (ts[i].down[j]) { nb_ts++; break; } } } if (gest->type == GESTURE_DRAG) { switch (gest->state) { case GESTURE_POSSIBLE: if (nb_ts == 1 && ts[0].down[gest->button]) { vec2_copy(ts[0].pos, gest->start_pos[0]); vec2_copy(gest->start_pos[0], gest->pos); if (!rect_contains(gest->viewport, gest->pos)) { gest->state = GESTURE_FAILED; break; } gest->state = (mask & (GESTURE_CLICK | GESTURE_PINCH)) ? GESTURE_RECOGNISED : GESTURE_BEGIN; } break; case GESTURE_RECOGNISED: if (vec2_dist(gest->start_pos[0], ts[0].pos) >= g_start_dist) gest->state = GESTURE_BEGIN; if (nb_ts == 0) { gest->state = (!(mask & GESTURE_CLICK)) ? GESTURE_BEGIN : GESTURE_FAILED; } if (nb_ts > 1) gest->state = GESTURE_FAILED; break; case GESTURE_BEGIN: case GESTURE_UPDATE: vec2_copy(ts[0].pos, gest->pos); gest->state = GESTURE_UPDATE; if (!ts[0].down[gest->button]) gest->state = GESTURE_END; break; } } if (gest->type == GESTURE_CLICK) { vec2_copy(ts[0].pos, gest->pos); switch (gest->state) { case GESTURE_POSSIBLE: if (ts[0].down[gest->button]) { vec2_copy(ts[0].pos, gest->start_pos[0]); gest->state = GESTURE_RECOGNISED; } break; case GESTURE_RECOGNISED: if (!ts[0].down[gest->button]) gest->state = GESTURE_TRIGGERED; break; } } if (gest->type == GESTURE_PINCH) { switch (gest->state) { case GESTURE_POSSIBLE: if (ts[0].down[0] && ts[1].down[0]) { gest->state = GESTURE_BEGIN; vec2_copy(ts[0].pos, gest->start_pos[0]); vec2_copy(ts[1].pos, gest->start_pos[1]); gest->pinch = 1; gest->rotation = 0; vec2_mix(ts[0].pos, ts[1].pos, 0.5, gest->pos); } break; case GESTURE_BEGIN: case GESTURE_UPDATE: gest->state = GESTURE_UPDATE; gest->pinch = vec2_dist(ts[0].pos, ts[1].pos) / vec2_dist(gest->start_pos[0], gest->start_pos[1]); gest->rotation = get_angle(gest->start_pos[0], gest->start_pos[1], ts[0].pos, ts[1].pos); vec2_mix(ts[0].pos, ts[1].pos, 0.5, gest->pos); if (!ts[0].down[0] || !ts[1].down[0]) gest->state = GESTURE_END; break; } } if (gest->type == GESTURE_HOVER) { switch (gest->state) { case GESTURE_POSSIBLE: if (DEFINED(GOXEL_MOBILE)) break; //Workaround. if (nb_ts == 0) { vec2_copy(ts[0].pos, gest->pos); if (rect_contains(gest->viewport, gest->pos)) { gest->state = GESTURE_BEGIN; } } break; case GESTURE_BEGIN: case GESTURE_UPDATE: vec2_copy(ts[0].pos, gest->pos); gest->state = rect_contains(gest->viewport, gest->pos) ? GESTURE_UPDATE : GESTURE_END; break; } } return 0; }