Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* === shoes_place_decide() ===
- place : actual element being calculated - child
- c : parent canvas
- attr : actual element attributes - child attributes
- dw : parent->place.iw, imw (real image width), canvas->width, PATTERN width, defaul control width
- dh : same but for height
- rel : a flag to sort elements (bakground,border : 4, image : 10 (8+2), slots : 2, widgets : 2
- slot with :attach => Shoes::Window : 1)
- padded : a boolean, controls are padded (SETUP_CONTROL), images if REL_CANVAS [means all ?] (SETUP)
- - 2 rounds (gathering info + real computation ?) for each element being evaluated
- - for slots, images, image blocks, backgrounds, borders, widgets
- shapes are using 'shoes_place_exact', textblock 'shoes_textblock_draw' (pango)
- - image 4 rounds (when alone ?)
- - app alone : nothing to place !
- in app (top level canvas) coordinates :
- x, y => coords
- ix, iy => margin + left, top, right, bottom
- dx, dy => displacement
- iw, ih => real dimension
- w, h => dimension + margin
- ox, oy => original placement
- cx, cy => coords of next possible placement
- endx, endy => coords of next possible placement (for parent canvas)
- */
- void
- shoes_place_decide(shoes_place *place, VALUE c, VALUE attr, int dw, int dh,
- unsigned char rel, int padded)
- {
- shoes_canvas *canvas = NULL;
- if (!NIL_P(c)) Data_Get_Struct(c, shoes_canvas, canvas);
- VALUE ck = rb_obj_class(c);
- VALUE stuck = ATTR(attr, attach);
- // for image : we want to scale the image, given only one attribute :width or :height
- // get dw and dh, set width or height
- if (REL_FLAGS(rel) & REL_SCALE) { // 8
- VALUE rw = ATTR(attr, width), rh = ATTR(attr, height);
- if (NIL_P(rw) && !NIL_P(rh)) { // we have height
- // fetch height in pixels whatever the input (string, float, positive/negative int)
- int spx = shoes_px(rh, dh, CPH(canvas), 1);
- // compute width with image aspect ratio [(dh == dw) means a square ]
- dw = (dh == dw) ? spx : ROUND(((dh * 1.) / dw) * spx);
- dh = spx; // now re-init 'dh' for next calculations
- ATTRSET(attr, width, INT2NUM(dw)); // set calculated width
- }
- else if (NIL_P(rh) && !NIL_P(rw)) {
- int spx = shoes_px(rw, dw, CPW(canvas), 1);
- dh = (dh == dw) ? spx : ROUND(((dh * 1.) / dw) * spx);
- dw = spx;
- ATTRSET(attr, height, INT2NUM(dh));
- }
- }
- // get margins
- ATTR_MARGINS(attr, 0, canvas);
- if (padded || dh == 0) dh += tmargin + bmargin;
- if (padded || dw == 0) dw += lmargin + rmargin;
- int testw = dw;
- if (testw == 0) testw = lmargin + 1 + rmargin;
- // for displacements
- place->dx = place->dy = 0;
- // Do we have sticky elements ?
- if (!NIL_P(stuck)) {
- if (stuck == cShoesWindow)
- rel = REL_FLAGS(rel) | REL_WINDOW; // 1
- else if (stuck == cMouse)
- rel = REL_FLAGS(rel) | REL_CURSOR; // 3
- else
- rel = REL_FLAGS(rel) | REL_STICKY; // 5
- }
- place->flags = rel;
- // MAIN WORK
- if (canvas == NULL) { // no parent ?
- place->ix = place->x = 0;
- place->iy = place->y = 0;
- place->iw = place->w = dw;
- place->ih = place->h = dh;
- }
- else {
- // ox, oy original x, y -- cx, cy computed ?
- int cx, cy, ox, oy, tw = dw, th = dh;
- // compute cx, cy, ox, oy depending on kind of element being evaluated
- // also testw, dh if REF_TILE (background, border, ?)
- switch (REL_COORDS(rel)) { // rel & 0x07
- case REL_WINDOW: // 1
- cx = 0; cy = 0;
- ox = 0; oy = canvas->slot->scrolly;
- break;
- case REL_CANVAS: // 2
- cx = canvas->cx - CPX(canvas);
- cy = canvas->cy - CPY(canvas);
- ox = CPX(canvas);
- oy = CPY(canvas);
- break;
- case REL_CURSOR: // 3
- cx = 0; cy = 0;
- ox = canvas->app->mousex; oy = canvas->app->mousey;
- break;
- case REL_TILE: // 4
- cx = 0; cy = 0;
- ox = CPX(canvas);
- oy = CPY(canvas);
- testw = dw = CPW(canvas);
- //dh = max(canvas->height, CPH(canvas));
- dh = max(canvas->height, (canvas->fully - CPB(canvas)) - CPY(canvas));
- break;
- default:
- cx = 0; cy = 0;
- ox = canvas->cx; oy = canvas->cy;
- if ((REL_COORDS(rel) & REL_STICKY) && shoes_is_element(stuck))
- {
- shoes_element *element;
- Data_Get_Struct(stuck, shoes_element, element);
- ox = element->place.x;
- oy = element->place.y;
- }
- break;
- }
- /****** compute width and height of child*/
- // testw is now a default value for width
- place->w = PX(attr, width, testw, CPW(canvas)); // calculate width of child
- // endx, endy where is next avalaible room in the canvas
- // where is next possible placement
- if (dw == 0 && place->w + (int)canvas->cx > canvas->place.iw) {
- canvas->cx = canvas->endx = CPX(canvas);
- canvas->cy = canvas->endy;
- place->w = canvas->place.iw;
- }
- place->h = PX(attr, height, dh, CPH(canvas)); // calculate height of child
- if (REL_COORDS(rel) != REL_TILE) { // not a background or a border
- tw = place->w; // tw = dw otherwise
- th = place->h; // th = dh otherwise
- }
- /****** compute x and y of child*/
- // calculate placement of child in regards of eventual left, right, top, bottom attributes
- place->x = PX2(attr, left, right, cx, tw, canvas->place.iw) + ox;
- place->y = PX2(attr, top, bottom, cy, th,
- ORIGIN(canvas->place) ? canvas->height : canvas->fully) + oy;
- if (!ORIGIN(canvas->place)) { // ??
- place->dx = canvas->place.dx;
- place->dy = canvas->place.dy;
- }
- // calculate displacement of child
- place->dx += PXN(attr, displace_left, 0, CPW(canvas));
- place->dy += PXN(attr, displace_top, 0, CPH(canvas));
- /* set absolute placement flags */
- place->flags |= NIL_P(ATTR(attr, left)) && NIL_P(ATTR(attr, right)) ? 0 : FLAG_ABSX;
- place->flags |= NIL_P(ATTR(attr, top)) && NIL_P(ATTR(attr, bottom)) ? 0 : FLAG_ABSY;
- // if we are in a flow with not enough width for next element
- // or in a Stack
- // not a background or border, not absolute positioned
- if (REL_COORDS(rel) != REL_TILE && ABSY(*place) == 0 && (ck == cStack || place->x + place->w > CPX(canvas) + canvas->place.iw))
- {
- rb_warn("ck: %s\n", RSTRING_PTR(rb_inspect(ck)));
- canvas->cx = place->x = CPX(canvas);
- canvas->cy = place->y = canvas->endy;
- }
- } // MAIN
- /* take care of margins */
- place->ix = place->x + lmargin;
- place->iy = place->y + tmargin;
- place->iw = place->w - (lmargin + rmargin);
- if (place->iw < 0) place->iw = 0;
- place->ih = place->h - (tmargin + bmargin);
- if (place->ih < 0) place->ih = 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement