]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/sizepolicy.c
Imported Upstream version 20090110
[ion3.git] / ioncore / sizepolicy.c
index 7101da8b2632024ba6b340951e0d625458798f33..8c42327669236d6e5b56f08f1dd733e4b130bf14 100644 (file)
@@ -1,12 +1,9 @@
 /*
  * ion/ioncore/sizepolicy.c
  *
- * Copyright (c) Tuomo Valkonen 1999-2007
+ * Copyright (c) Tuomo Valkonen 1999-2009
  *
- * 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
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
+ * See the included file LICENSE for details.
  */
 
 #include <libtu/minmax.h>
@@ -201,6 +198,18 @@ static void sizepolicy_free_snap(WSizePolicy *szplcy, WRegion *reg,
 }
 
 
+static WSizePolicy org(WSizePolicy base, WSizePolicy g)
+{
+    if((base&SIZEPOLICY_VERT_MASK)==0)
+        base|=g&SIZEPOLICY_VERT_MASK;
+        
+    if((base&SIZEPOLICY_HORIZ_MASK)==0)
+        base|=g&SIZEPOLICY_HORIZ_MASK;
+    
+    return base;
+}
+
+
 void sizepolicy(WSizePolicy *szplcy, WRegion *reg,
                 const WRectangle *rq_geom, int rq_flags,
                 WFitParams *fp)
@@ -234,34 +243,49 @@ void sizepolicy(WSizePolicy *szplcy, WRegion *reg,
         break;
         
     case SIZEPOLICY_STRETCH_LEFT:
-        gravity_stretch_policy(SIZEPOLICY_HORIZ_LEFT|SIZEPOLICY_VERT_CENTER
+        gravity_stretch_policy(org(*szplcy, SIZEPOLICY_HORIZ_LEFT|SIZEPOLICY_VERT_CENTER)
                                reg, &tmp, fp, FALSE, TRUE);
         break;
         
     case SIZEPOLICY_STRETCH_RIGHT:
-        gravity_stretch_policy(SIZEPOLICY_HORIZ_RIGHT|SIZEPOLICY_VERT_CENTER
+        gravity_stretch_policy(org(*szplcy, SIZEPOLICY_HORIZ_RIGHT|SIZEPOLICY_VERT_CENTER)
                                reg, &tmp, fp, FALSE, TRUE);
         break;
         
     case SIZEPOLICY_STRETCH_TOP:
-        gravity_stretch_policy(SIZEPOLICY_VERT_TOP|SIZEPOLICY_HORIZ_CENTER
+        gravity_stretch_policy(org(*szplcy, SIZEPOLICY_VERT_TOP|SIZEPOLICY_HORIZ_CENTER)
                                reg, &tmp, fp, TRUE, FALSE);
         break;
         
     case SIZEPOLICY_STRETCH_BOTTOM:
-        gravity_stretch_policy(SIZEPOLICY_VERT_BOTTOM|SIZEPOLICY_HORIZ_CENTER
+        gravity_stretch_policy(org(*szplcy, SIZEPOLICY_VERT_BOTTOM|SIZEPOLICY_HORIZ_CENTER)
                                reg, &tmp, fp, TRUE, FALSE);
         break;
         
     case SIZEPOLICY_FULL_EXACT:
-        gravity_stretch_policy(SIZEPOLICY_VERT_CENTER|SIZEPOLICY_HORIZ_CENTER
+        gravity_stretch_policy(org(*szplcy, SIZEPOLICY_VERT_CENTER|SIZEPOLICY_HORIZ_CENTER)
                                reg, &tmp, fp, TRUE, TRUE);
         break;
         
     case SIZEPOLICY_FREE:
+        if(reg!=NULL)
+            region_size_hints_correct(reg, &tmp.w, &tmp.h, FALSE);
         rectangle_constrain(&tmp, &(fp->g));
+        fp->g=tmp;
+        break;
+        
+    case SIZEPOLICY_VISIBILITY_CONSTRAINED:
         if(reg!=NULL)
             region_size_hints_correct(reg, &tmp.w, &tmp.h, FALSE);
+        { 
+            /* Constraint such that at least min(size, CF_VISIBILITY_CONSTRAINT) 
+             * much is visible at each border.
+             */
+            int dx=maxof(0, tmp.w-CF_VISIBILITY_CONSTRAINT);
+            int dy=maxof(0, tmp.h-CF_VISIBILITY_CONSTRAINT);
+            tmp.x=maxof(fp->g.x-dx, minof(tmp.x, fp->g.x+fp->g.w+dx-tmp.w));
+            tmp.y=maxof(fp->g.y-dy, minof(tmp.y, fp->g.y+fp->g.h+dy-tmp.h));
+        }
         fp->g=tmp;
         break;
         
@@ -283,14 +307,8 @@ void sizepolicy(WSizePolicy *szplcy, WRegion *reg,
 }
 
 
-struct szplcy_spec {
-    const char *spec;
-    int szplcy;
-};
-
-
 /* translation table for sizepolicy specifications */
-static struct szplcy_spec szplcy_specs[] = {
+static StringIntMap szplcy_specs[] = {
     {"default",         SIZEPOLICY_DEFAULT},
     {"full",            SIZEPOLICY_FULL_EXACT},
     {"full_bounds",     SIZEPOLICY_FULL_BOUNDS},
@@ -318,23 +336,29 @@ static struct szplcy_spec szplcy_specs[] = {
     {"free_glue_southwest",  SIZEPOLICY_FREE_GLUE__SOUTHWEST},
     {"free_glue_south",      SIZEPOLICY_FREE_GLUE__SOUTH},
     {"free_glue_southeast",  SIZEPOLICY_FREE_GLUE__SOUTHEAST},
+    {"visibility_constrained",   SIZEPOLICY_VISIBILITY_CONSTRAINED},
+    {"unconstrained",   SIZEPOLICY_UNCONSTRAINED},
     { NULL,             SIZEPOLICY_DEFAULT}   /* end marker */
 };
 
 
 bool string2sizepolicy(const char *szplcy, WSizePolicy *value)
 {
-    const struct szplcy_spec *sp;
+    int tmp;
     
-    *value=SIZEPOLICY_DEFAULT;
-
-    for(sp=szplcy_specs; sp->spec; ++sp){
-       if(strcasecmp(szplcy,sp->spec)==0){
-           *value=sp->szplcy;
-           return TRUE;
-        }
-    }
+    tmp=stringintmap_value(szplcy_specs, szplcy, -1);
     
-    return FALSE;
+    if(tmp==-1){
+        *value=SIZEPOLICY_DEFAULT;
+        return FALSE;
+    }else{
+        *value=tmp;
+        return TRUE;
+    }
 }
 
+
+const char *sizepolicy2string(WSizePolicy szplcy)
+{
+    return stringintmap_key(szplcy_specs, szplcy, NULL);
+}