/*
* ion/ioncore/mplexpholder.c
*
- * Copyright (c) Tuomo Valkonen 2005-2006.
+ * Copyright (c) Tuomo Valkonen 2005-2007.
*
* Ion is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
#include "mplex.h"
#include "mplexpholder.h"
#include "llist.h"
+#include "framedpholder.h"
static void mplex_watch_handler(Watch *watch, Obj *mplex);
void mplexpholder_do_unlink(WMPlexPHolder *ph, WMPlex *mplex)
{
+ if(ph->recreate_pholder!=NULL){
+ if(ph->prev!=NULL)
+ ph->prev->recreate_pholder=ph->recreate_pholder;
+ else
+ destroy_obj((Obj*)ph->recreate_pholder);
+ ph->recreate_pholder=NULL;
+ }
+
if(ph->after!=NULL){
UNLINK_ITEM(ph->after->phs, ph, next, prev);
}else if(mplex!=NULL && on_ph_list(mplex->mx_phs, ph)){
UNLINK_ITEM(mplex->mx_phs, ph, next, prev);
}else{
- assert(ph->next==NULL && ph->prev==NULL);
+ WMPlexPHolder *next=ph->next;
+
+ assert((ph->next==NULL && ph->prev==NULL)
+ || ph->mplex_watch.obj==NULL);
+
+ if(ph->next!=NULL)
+ ph->next->prev=ph->prev;
+ if(ph->prev!=NULL)
+ ph->prev->next=next;
}
ph->after=NULL;
ph->next=NULL;
ph->prev=NULL;
ph->param.flags=0;
+ ph->recreate_pholder=NULL;
if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler)){
pholder_deinit(&(ph->ph));
/*{{{ Move, attach, layer */
+typedef struct{
+ WMPlexPHolder *ph, *ph_head;
+ WRegionAttachData *data;
+ WFramedParam *param;
+} RP;
+
+
+WRegion *recreate_handler(WWindow *par,
+ const WFitParams *fp,
+ void *rp_)
+{
+ RP *rp=(RP*)rp_;
+ WMPlexPHolder *ph=rp->ph, *ph_head=rp->ph_head, *phtmp;
+ WFramedParam *param=rp->param;
+ WFrame *frame;
+ WRegion *reg;
+
+ frame=create_frame(par, fp, param->mode);
+
+ if(frame==NULL)
+ return NULL;
+
+ /* Move pholders to frame */
+ frame->mplex.mx_phs=ph_head;
+
+ for(phtmp=frame->mplex.mx_phs; phtmp!=NULL; phtmp=phtmp->next)
+ watch_setup(&(phtmp->mplex_watch), (Obj*)frame, mplex_watch_handler);
+
+ /* Attach */
+ if(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER))
+ ph->param.flags|=MPLEX_ATTACH_WHATEVER;
+
+ reg=mplex_do_attach_pholder(&frame->mplex, ph, rp->data);
+
+ ph->param.flags&=~MPLEX_ATTACH_WHATEVER;
+
+ if(reg==NULL){
+ /* Try to recover */
+ for(phtmp=frame->mplex.mx_phs; phtmp!=NULL; phtmp=phtmp->next)
+ watch_reset(&(phtmp->mplex_watch));
+ frame->mplex.mx_phs=NULL;
+
+ destroy_obj((Obj*)frame);
+
+ return NULL;
+ }else{
+ frame_adjust_to_initial(frame, fp, param, reg);
+
+ return (WRegion*)frame;
+ }
+}
+
+
+static WMPlexPHolder *get_head(WMPlexPHolder *ph)
+{
+ while(1){
+ if(ph->prev->next==NULL)
+ break;
+ ph=ph->prev;
+ }
+
+ return ph;
+}
+
+
+static WFramedPHolder *get_recreate_ph(WMPlexPHolder *ph)
+{
+ return get_head(ph)->recreate_pholder;
+}
+
+
+static WRegion *mplexpholder_attach_recreate(WMPlexPHolder *ph, int flags,
+ WRegionAttachData *data)
+{
+ WRegionAttachData data2;
+ WFramedPHolder *fph;
+ WPHolder *root;
+ WRegion *reg;
+ RP rp;
+
+ rp.ph_head=get_head(ph);
+
+ assert(rp.ph_head!=NULL);
+
+ fph=rp.ph_head->recreate_pholder;
+
+ if(fph==NULL)
+ return NULL;
+
+ rp.ph=ph;
+ rp.data=data;
+ rp.param=&fph->param;
+
+ data2.type=REGION_ATTACH_NEW;
+ data2.u.n.fn=recreate_handler;
+ data2.u.n.param=&rp;
+
+ reg=pholder_do_attach(fph->cont, flags, &data2); /* == frame */
+
+ if(reg!=NULL){
+ destroy_obj((Obj*)fph);
+ rp.ph_head->recreate_pholder=NULL;
+ }
+
+ return reg;
+}
+
+
WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags,
WRegionAttachData *data)
{
WMPlex *mplex=(WMPlex*)ph->mplex_watch.obj;
- WRegion *reg=NULL;
if(mplex==NULL)
- return FALSE;
+ return mplexpholder_attach_recreate(ph, flags, data);
if(flags&PHOLDER_ATTACH_SWITCHTO)
ph->param.flags|=MPLEX_ATTACH_SWITCHTO;
bool mplexpholder_do_goto(WMPlexPHolder *ph)
{
- WMPlex *mplex=(WMPlex*)ph->mplex_watch.obj;
-
- if(mplex!=NULL)
- return region_goto((WRegion*)mplex);
+ WRegion *reg=(WRegion*)ph->mplex_watch.obj;
- return FALSE;
+ if(reg!=NULL){
+ return region_goto(reg);
+ }else{
+ WFramedPHolder *fph=get_recreate_ph(ph);
+
+ return (fph!=NULL
+ ? pholder_do_goto((WPHolder*)fph)
+ : FALSE);
+ }
}
WRegion *mplexpholder_do_target(WMPlexPHolder *ph)
{
- return (WRegion*)ph->mplex_watch.obj;
+ WRegion *reg=(WRegion*)ph->mplex_watch.obj;
+
+ if(reg!=NULL){
+ return reg;
+ }else{
+ WFramedPHolder *fph=get_recreate_ph(ph);
+
+ return (fph!=NULL
+ ? pholder_do_target((WPHolder*)fph)
+ : NULL);
+ }
+}
+
+
+WPHolder *mplexpholder_do_root(WMPlexPHolder *ph)
+{
+ WRegion *reg=(WRegion*)ph->mplex_watch.obj;
+
+ if(reg!=NULL){
+ return &ph->ph;
+ }else{
+ WFramedPHolder *fph=get_recreate_ph(ph);
+ WPHolder *root;
+
+ if(fph==NULL)
+ return NULL;
+
+ root=pholder_root((WPHolder*)fph);
+
+ return (root!=(WPHolder*)fph
+ ? root
+ : &ph->ph);
+ }
}
{(DynFun*)pholder_do_target,
(DynFun*)mplexpholder_do_target},
+
+ {(DynFun*)pholder_do_root,
+ (DynFun*)mplexpholder_do_root},
END_DYNFUNTAB
};