예제 #1
0
파일: tiling.c 프로젝트: gwash/ion-3plus
bool tiling_do_attach_initial(WTiling *ws, WRegion *reg)
{
    assert(ws->split_tree==NULL);
    
    ws->split_tree=(WSplit*)create_splitregion(&REGION_GEOM(reg), reg);
    if(ws->split_tree==NULL)
        return FALSE;
    
    ws->split_tree->ws_if_root=ws;
    
    if(!tiling_managed_add(ws, reg)){
        destroy_obj((Obj*)ws->split_tree);
        ws->split_tree=NULL;
        return FALSE;
    }
    
    return TRUE;
}
예제 #2
0
파일: splitfloat.c 프로젝트: dkogan/notion
WSplitRegion *splittree_split_floating(WSplit *node, int dir, int primn,
                                       int nmins, WRegionSimpleCreateFn *fn,
                                       WTiling *ws)
{
    WSplitFloat *sf;
    int omins, mins;
    int sn, so, s, rs;
    int bn, bo;
    WRectangle gn, go, gnc, goc;
    WFitParams fp;
    WRegion *nreg;
    WSplitRegion *nnode;
    WSplitInner *psplit;

    if(primn!=PRIMN_TL && primn!=PRIMN_BR)
        primn=PRIMN_BR;

    split_update_bounds(split_find_root(node), TRUE);

    sf=create_splitfloat(&node->geom, ws, dir);

    if(sf==NULL)
        return NULL;

    omins=(dir==SPLIT_VERTICAL ? node->min_h : node->min_w);
    s=split_size(node, dir);

    if(primn==PRIMN_BR){
        bn=BR_BORDER(sf);
        bo=TL_BORDER(sf);
    }else{
        bn=TL_BORDER(sf);
        bo=BR_BORDER(sf);
    }

    mins=MAXOF(omins+bo, nmins+bn);

    /* Potentially resize old node. */

    splittree_begin_resize();

    if(mins>s){
        WRectangle ng=node->geom, rg;
        if(dir==SPLIT_VERTICAL)
            ng.h=mins;
        else
            ng.w=mins;

        split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, TRUE);
        rs=(dir==SPLIT_VERTICAL ? rg.h : rg.w);
        if(rs<mins){
            warn(TR("Unable to split: not enough free space."));
            destroy_obj((Obj*)sf);
            return NULL;
        }
        split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, FALSE);
        s=split_size(node, dir);
    }else{
        splittree_scan_stdisp_rootward(node);
    }

    /* Calculate geometries. */

    sn=MAXOF(nmins+bn, s/2);
    so=MAXOF(omins+bo, s-s/2);

    ((WSplit*)sf)->geom=node->geom;

    if(primn==PRIMN_TL){
        calc_tlg_brg(&(node->geom), sn, so, dir, &gn, &go);
        splitfloat_update_handles(sf, &gn, &go);
        gnc=gn; splitfloat_tl_pwin_to_cnt(sf, &gnc);
        goc=go; splitfloat_br_pwin_to_cnt(sf, &goc);
    }else{
        calc_tlg_brg(&(node->geom), so, sn, dir, &go, &gn);
        splitfloat_update_handles(sf, &go, &gn);
        goc=go; splitfloat_tl_pwin_to_cnt(sf, &goc);
        gnc=gn; splitfloat_br_pwin_to_cnt(sf, &gnc);
    }

    /* Create the region. */

    fp.mode=REGION_FIT_EXACT;
    fp.g=gnc;

    nreg=fn(REGION_PARENT(ws), &fp);

    if(nreg==NULL){
        destroy_obj((Obj*)sf);
        return NULL;
    }

    nnode=create_splitregion(&(fp.g), nreg);
    if(nnode==NULL){
        destroy_obj((Obj*)nreg);
        destroy_obj((Obj*)sf);
        return NULL;
    }

    /* Now that everything's ok, resize and move original node. */

    split_do_resize(node, &goc,
                    (dir==SPLIT_HORIZONTAL ? primn : PRIMN_ANY),
                    (dir==SPLIT_VERTICAL ? primn : PRIMN_ANY),
                    FALSE);

    /* Set up split structure. */

    psplit=node->parent;

    if(psplit!=NULL)
        splitinner_replace(psplit, node, (WSplit*)sf);
    else
        splittree_changeroot(node, (WSplit*)sf);

    node->parent=(WSplitInner*)sf;
    ((WSplit*)nnode)->parent=(WSplitInner*)sf;

    if(primn==PRIMN_BR){
        sf->ssplit.tl=node;
        sf->ssplit.br=(WSplit*)nnode;
    }else{
        sf->ssplit.tl=(WSplit*)nnode;
        sf->ssplit.br=node;
    }

    /*splittree_end_resize();*/

    return nnode;
}