*/}}
Browse Source

Dummy save

Yiming Wu 1 năm trước cách đây
mục cha
commit
6c96d62afd
7 tập tin đã thay đổi với 133 bổ sung23 xóa
  1. 74 3
      la_data.c
  2. 14 0
      la_data.h
  3. 8 0
      la_interface.h
  4. 2 2
      la_tns.h
  5. 15 16
      la_tns_kernel.c
  6. 4 1
      resources/la_operators.c
  7. 16 1
      resources/la_templates.c

+ 74 - 3
la_data.c

@@ -548,6 +548,26 @@ void* laget_InstanceActiveUDF(void* instance){
     if(level==2) return m->FromFile;
     return 0;
 }
+void* laget_DummyManagedUDFSingle(void* unused){
+    return MAIN.DummyManageUDFSingle;
+}
+void* laget_DummyManagedUDFSingleForce(void* unused){
+    return MAIN.DummyManageUDFSingleForce;
+}
+void laset_InstanceUDFFromSingle(void* instance, laUDF* udf){
+    if(!MAIN._CONTAINER_SETTING || !MAIN._CONTAINER_SETTING->UDFPropagate || !instance){ return; }
+    if(udf == MAIN.DummyManageUDF){
+        laInvoke(0, "LA_managed_save_new_file", 0,0,0,0);
+    }
+    MAIN._CONTAINER_SETTING->UDFPropagate(instance,udf,0);
+}
+void laset_InstanceUDFFromSingleForce(void* instance, laUDF* udf){
+    if(!MAIN._CONTAINER_SETTING || !MAIN._CONTAINER_SETTING->UDFPropagate || !instance){ return; }
+    if(udf == MAIN.DummyManageUDF){
+        laInvoke(0, "LA_managed_save_new_file", 0,0,0,0);
+    }
+    MAIN._CONTAINER_SETTING->UDFPropagate(instance,udf,0);
+}
 void laset_InstanceUDF(void* instance, void* set){
     int level; laMemNodeHyper* m=memGetHead(instance,&level);
     if(level==2) memAssignRef(instance, &m->FromFile, set);
@@ -570,6 +590,24 @@ void laset_InstanceUID(void* instance, char* buf){
     if(!buf[0]) memCreateNUID(m);
     sprintf(m->NUID.String,"%.30s",buf);
 }
+void* laget_SaverDummy(void* instance, laPropIterator* pi){
+    laSubProp* p=MAIN._PROP_SETTING; laListHandle* l = (((char*)instance)+p->ListHandleOffset);
+    if(!l->pFirst){
+        laSaverDummy* sd=memAcquireHyper(sizeof(laSaverDummy)); lstAppendItem(l,sd);
+    }
+    while(l->pFirst!=l->pLast){ memLeave(lstPopItem(l)); }
+    return l->pFirst;
+}
+laSaverDummy* laGetSaverDummy(void* instance, laSubProp* p){
+    laListHandle* l = (((char*)instance)+p->ListHandleOffset);
+    if(!l->pFirst){ laSaverDummy* sd=memAcquireHyper(sizeof(laSaverDummy)); lstAppendItem(l,sd); }
+    while(l->pFirst!=l->pLast){ memLeave(lstPopItem(l)); }
+    return l->pFirst;
+}
+void laPurgeSaverDummy(void* instance, laSubProp* p){
+    laListHandle* l = (((char*)instance)+p->ListHandleOffset);
+    while(l->pFirst){ memLeave(lstPopItem(l)); }
+}
 void la_FreeProperty(laProp* p){
     laIntProp *ip;laFloatProp *fp;laEnumProp *ep;laSubProp *sp;
     if(p->DetachedPP.Go){
@@ -634,7 +672,23 @@ void laPropContainerExtraFunctions(laPropContainer* pc, laContainerBeforeFreeF B
     pc->BeforeFree=BeforeFree; pc->Reset=Reset; pc->UndoTouched=Touched; pc->UDFPropagate=UDFPropagate; pc->MenuUiDefine=MenuUi;
     if(!pc->OtherAlloc && UDFPropagate){
         laAddOperatorProperty(pc,"__udf_propagate","Propagate","Propagate UDF to all child nodes", "LA_udf_propagate", 0,0);
+        laAddSubGroup(pc,"__single_udf_propagate","Save to","Assign file to all child nodes (From a ingle-instanced parent)","managed_udf",
+            0,LA_WIDGET_COLLECTION_SELECTOR,laui_ManagedUDFItem,-1,laget_InstanceUDF,laget_DummyManagedUDFSingle,laget_ListNext,laset_InstanceUDFFromSingle,0,0,0,LA_UDF_REFER|LA_UDF_IGNORE);
+        //laAddSubGroup(pc,"__single_udf_propagate_force","Force","Assign file to all child nodes (From a ingle-instanced parent)","managed_udf",
+        //    0,LA_WIDGET_COLLECTION_SELECTOR,laui_ManagedUDFItem,-1,laget_InstanceUDF,laget_DummyManagedUDFSingleForce,laget_ListNext,laset_InstanceUDFFromSingleForce,0,0,0,LA_UDF_REFER|LA_UDF_IGNORE);
+    
+    }
+}
+laProp* laPropContainerManageable(laPropContainer* pc, int offset_of_dummy_list){
+    if(!pc || pc->OtherAlloc || !offset_of_dummy_list) return;
+
+    if(!MAIN.SaverDummyContainer){
+        MAIN.SaverDummyContainer = laAddPropertyContainer("la_saver_dummy","Saver Dummy","Saver dummy",0,0,sizeof(laSaverDummy),0,0,2);
+        laAddSubGroup(MAIN.SaverDummyContainer, "__file", "File", "The file this block came from/saves to", "managed_udf",
+            0,LA_WIDGET_COLLECTION_SELECTOR,laui_ManagedUDFItem,-1,laget_InstanceUDF,laget_InstanceActiveUDF,laget_ListNext,laset_InstanceUDF,0,0,0,LA_UDF_REFER|LA_UDF_IGNORE);
     }
+    pc->SaverDummy=laAddSubGroup(pc,"__single_saver_dummy","Saver","Saver dummy","la_saver_dummy",0,0,0,-1,0,0,0,0,0,0,offset_of_dummy_list,0);
+    return pc->SaverDummy;
 }
 
 int la_GetPropertySize(int Type){
@@ -1836,6 +1890,8 @@ void *laGetActiveInstance(laProp *sub, void *FromInstance, laPropIterator *Iter)
 void laSetActiveInstance(laProp *sub, void *FromInstance, void *Instance){
     laSubProp *sp = sub;
     if (sub->PropertyType == LA_PROP_SUB){
+        MAIN._CONTAINER_SETTING=sub->Container;
+        MAIN._PROP_SETTING=sub;
         if (sp->Base.DetachedPP.LastPs){
             memAssignRef(sp, &sp->Detached, Instance);
             laNotifySubPropUsers(sp, FromInstance);
@@ -1949,6 +2005,10 @@ void laMarkPropChanged(laPropPack* pp){
     }
     laMarkPropChanged(pp->RawThis);
 }
+void laMarkMemChanged(void* memuser){
+    int level; laMemNodeHyper* m=memGetHead(memuser,&level); if(level!=2) return;
+    m->Modified=1;
+}
 
 laPropContainer *la_SetGeneralRoot(laPropContainer **GeneralRoot, const char *Identifier, const char *Name, const char *Description){
     laPropContainer* ret =memAcquire(sizeof(laPropContainer));
@@ -3050,6 +3110,8 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
 
                 Instance = laGetInstance(p, pp->LastPs->UseInstance, &PI);
 
+                la_ResetInstance(Instance, p->SubProp);
+
                 if (ItemType == LA_UDF_HYPER_ITEM){
                     if (p->SubProp->Hyper == 2){
                         if (!Parent && !IsExceptionNode) la_ReadHyperData(udf, Instance);
@@ -3108,7 +3170,7 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                     if (udf){
                         RealSize = RealSize ? RealSize : p->SubProp->NodeSize;
                         if (!Parent && !IsExceptionNode){
-                            if (p->UDFIsSingle && pp->EndInstance){ Instance = pp->EndInstance; }
+                            if (p->UDFIsSingle && pp->EndInstance){ Instance = pp->EndInstance; la_ResetInstance(Instance, pc); replaced=1; }
                             else{
                                 // if overwrite, find the instance here for hyper2, if not hyper 2 then notice can't overwrite.
                                 if (pc->Hyper == 2){
@@ -3172,7 +3234,9 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                             if (pp->LastPs->UseInstance){
                                 if (!p->UDFIsSingle){
                                     if (((laSubProp *)p)->ListHandleOffset){
-                                        lstAppendItem((BYTE *)pp->LastPs->UseInstance + ((laSubProp *)p)->ListHandleOffset, Instance);
+                                        laListHandle* inst_lst=(BYTE *)pp->LastPs->UseInstance + ((laSubProp *)p)->ListHandleOffset;
+                                        if(p->Container->SaverDummy && p==p->Container->SaverDummy){ laPurgeSaverDummy(pp->LastPs->UseInstance,p); }
+                                        lstAppendItem(inst_lst, Instance);
                                     }else{ lstAppendItem(&pc->FailedNodes, Instance); EStatus = 1; }
                                 }else{ if (!p->UDFNoCreate){ laSetActiveInstance(p, pp->LastPs->UseInstance, Instance); } }
                                 if (ReadInstance == ActiveInstance) laSetActiveInstance(p, pp->LastPs->UseInstance, Instance);
@@ -3370,6 +3434,10 @@ laManagedUDF* la_EnsureManagedUDF(char* FileName, int PutAtTop){
 }
 void la_MakeDummyManagedUDF(){
     MAIN.DummyManageUDF=la_EnsureManagedUDF("< Save as a new file >", 1);
+    if(!MAIN.DummyManageUDFSingle){
+        MAIN.DummyManageUDFSingle=memAcquire(sizeof(laManagedUDF)); strSafeSet(&MAIN.DummyManageUDFSingle->BaseName, "< Choose file >");
+        MAIN.DummyManageUDFSingleForce=memAcquire(sizeof(laManagedUDF)); strSafeSet(&MAIN.DummyManageUDFSingleForce->BaseName, "Force");
+    }
 }
 void laSaveProp(char* path){
     if(!path || !path[0]) return; laManagedSaveProp* msp=0;
@@ -4154,7 +4222,10 @@ void la_FreeInstance(void* inst, laPropContainer* pc, int no_free){
     }
     if(!no_free && !pc->OtherAlloc) memFree(inst);
 }
-void la_ResetInstance(void* inst, laPropContainer* pc){ if(pc->Reset) pc->Reset(inst); else memset(inst,0,pc->NodeSize); }
+void la_ResetInstance(void* inst, laPropContainer* pc){
+    if(pc->SaverDummy) 
+    if(pc->Reset) pc->Reset(inst); else memset(inst,0,pc->NodeSize);
+}
 
 laListHandle* la_GetOriginalListHandle(laDiffCommandSub* dcs){
     laProp*p =dcs->Base.p;

+ 14 - 0
la_data.h

@@ -106,6 +106,12 @@ typedef void (*laPanelDetachedPropFunc)(void *panel);
 NEED_STRUCTURE(laCanvasTemplate);
 NEED_STRUCTURE(laKeyMapper);
 
+
+STRUCTURE(laSaverDummy){
+    laListItem Item;
+    real pad;
+};
+
 STRUCTURE(laPropContainer){
     laListItem Item;
 
@@ -138,6 +144,8 @@ STRUCTURE(laPropContainer){
     laListHandle LocalUsers;
 
     int validated;
+    laProp* SaverDummy;
+
 };
 
 NEED_STRUCTURE(laUiType);
@@ -194,6 +202,7 @@ STRUCTURE(laProp){
     char UDFIgnore;
     char UDFOnly;
     char UDFIsSingle;
+    char UDFSingleManageable;
     char IsRadAngle;
 
     //int           SignalThrow;
@@ -733,6 +742,7 @@ void* laGetRaw(laPropPack *pp, int* r_size, int* return_is_a_copy);
 int laSetRaw(laPropPack *pp, void* data, int _size);
 
 void laMarkPropChanged(laPropPack* pp);
+void laMarkMemChanged(void* memuser);
 
 void *la_FindMatchingInstance(void *From, laProp *Sub, laProp *p, laPropStep *Value);
 
@@ -752,8 +762,12 @@ void laThrowToTrashBin(void* Data, char *ContainerString);
 void la_FreeProperty(laProp* p);
 void la_FreePropertyContainer(laPropContainer* pc);
 
+laSaverDummy* laGetSaverDummy(void* instance, laSubProp* p);
+void laPurgeSaverDummy(void* instance, laSubProp* p);
+
 laPropContainer *laAddPropertyContainer(const char *Identifier, const char *Name, const char *Description, uint32_t IconID, laUiDefineFunc DefaultUiDefine,
                                         int NodeSize, laContainerPostReadFunc PostRead, laContainerPostReadFunc PostReadIm, int IsHyper);
+laProp* laPropContainerManageable(laPropContainer* pc, int offset_of_dummy_list);
 void laPropContainerExtraFunctions(laPropContainer* pc, laContainerBeforeFreeF BeforeFree, laContainerResetF Reset, laContainerUndoTouchedF Touched, laContainerpUDFPropagateF UDFPropagate, laUiDefineFunc MenuUi);
 const char *la_GetPropertyTypeString(int Type);
 

+ 8 - 0
la_interface.h

@@ -307,6 +307,10 @@ STRUCTURE(LA){
     laPropContainer *ContainerOperator;
     laPropContainer *ContainerCollection;
 
+    laPropContainer *_CONTAINER_SETTING;
+    laProp          *_PROP_SETTING;
+    laPropContainer *_CONTAINER_SETTING_PROPAGATE_TO;
+    void            *_CONTAINER_SETTING_INSTANCE;
     laListHandle PropContainers;
     laRoot DataRoot;
     laPanel *PropMatcherContextP;
@@ -345,7 +349,11 @@ STRUCTURE(LA){
     laListHandle ManagedUDFs;
     laListHandle ManagedSaveProps;
     laManagedUDF* DummyManageUDF;
+    laManagedUDF* DummyManageUDFSingle;
+    laManagedUDF* DummyManageUDFSingleForce;
     int          ManagerDefaultView;
+    int          SetUDFPending;
+    laPropContainer* SaverDummyContainer;
 
     laListHandle DBInstPendingAcquireDBP;
     laListHandle DBInstPendingAcquireDiffCMD;

+ 2 - 2
la_tns.h

@@ -344,7 +344,7 @@ struct _tnsFontSingleCharacter
     int Generated;
     short width;
     short height;
-    short advx;
+    real  advx;
     short advy;
     short deltax;
     short deltay;
@@ -373,7 +373,7 @@ struct _tnsFont
     FT_Face ftfacemono;
     int NumFaces;/* excludes mono. */
     real MonoScale;
-    int MonoAdvance;
+    real MonoAdvance;
 
     real size;
     unsigned int height;

+ 15 - 16
la_tns_kernel.c

@@ -2757,9 +2757,10 @@ int tnsInvalidateFontCache(){
         FT_Set_Char_Size(f->ftfacemono, 0, (GenHeight << 6)*f->MonoScale, 96, 96); FT_Glyph glyph;
         if (FT_Load_Char(f->ftfacemono, 'a', FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)||
             FT_Get_Glyph(f->ftfacemono->glyph, &glyph)){ SEND_PANIC_ERROR("Monospace font doesn't contain character 'a'"); }
-        f->MonoAdvance=f->ftfacemono->glyph->advance.x/64.0;
+        f->MonoAdvance=(real)f->ftfacemono->glyph->advance.x/64.0;
         if(glyph) FT_Done_Glyph(glyph);
     }
+    glClearTexImage(f->TexBuffer.GLTexHandle, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
 }
 tnsFontSingleCharacter *tfntFetchCharTextureIDW(uint32_t ch, int UseMono);
 void tnsLoadSystemFontMono(char* mono){
@@ -2782,7 +2783,7 @@ void tnsLoadSystemFontMono(char* mono){
         logPrint("Monospace font scale: %.2f\n",f->MonoScale); FT_Glyph glyph;
         if (FT_Load_Char(f->ftfacemono, 'a', FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)||
             FT_Get_Glyph(f->ftfacemono->glyph, &glyph)){ SEND_PANIC_ERROR("Monospace font doesn't contain character 'a'"); }
-        f->MonoAdvance=f->ftfacemono->glyph->advance.x/64.0;
+        f->MonoAdvance=(real)f->ftfacemono->glyph->advance.x/64.0;
         if(glyph) FT_Done_Glyph(glyph);
     }
 };
@@ -2839,17 +2840,17 @@ int tnsLoadVectorGraphPackage(const char *name, unsigned int size){
 };
 
 int tfntBufferWidthEnough(int total_width, int current_width, int this_width){
-    return (current_width + this_width < total_width);
+    return (current_width + this_width +1 < total_width);
 }
 
 void tfntApplyCharacterBufferOffset(tnsFont *f, tnsFontSingleCharacter *fsc){
     if (!tfntBufferWidthEnough(TNS_FONT_BUFFER_W, f->CurrentX, fsc->width)){
-        f->CurrentY += f->height+1;
+        f->CurrentY += (f->height+1);
         f->CurrentX = 0;
     }
     fsc->bufferx = f->CurrentX;
     fsc->buffery = f->CurrentY;
-    f->CurrentX += fsc->width;
+    f->CurrentX += (fsc->width+1);
 }
 
 tnsFontSingleCharacter *tfntFetchVectorGraphTextureIDW(uint32_t ID){
@@ -2976,7 +2977,7 @@ tnsFontSingleCharacter *tfntFetchCharTextureIDW(uint32_t ch, int UseMono){
     h = bm.rows;
     fsc->width = w;
     fsc->height = h;
-    fsc->advx = face->glyph->advance.x / 64.0f;
+    fsc->advx = (real)face->glyph->advance.x / 64.0f;
     fsc->advy = face->size->metrics.y_ppem;
     fsc->deltax = bitmap_glyph->left;
     fsc->deltay = bitmap_glyph->top - h;
@@ -2995,8 +2996,6 @@ tnsFontSingleCharacter *tfntFetchCharTextureIDW(uint32_t ch, int UseMono){
         }
     }
 
-    //glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
-    //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     glTexSubImage2D(GL_TEXTURE_2D, 0, fsc->bufferx, fsc->buffery, w, h, GL_RED, GL_UNSIGNED_BYTE, buf);
 
@@ -3028,7 +3027,7 @@ int tnsUseFont(char *name){
 };
 
 int tnsStringGetDimension(char* content, uint32_t* contentU, int Count, int WLimit, int* Rows, int UseMono){
-    int sx = 0, sy = FM->UsingFont->height, MA=FM->UsingFont->MonoAdvance;
+    real sx = 0; int sy = FM->UsingFont->height; real MA=FM->UsingFont->MonoAdvance;
     int i, rows=1, advance=1;
     int C = 0;
     int len = contentU?strlenU(contentU):(content?strlen(content):0);
@@ -3048,7 +3047,7 @@ int tnsStringGetDimension(char* content, uint32_t* contentU, int Count, int WLim
             continue;
         }else{
             fsc = tfntFetchCharacterW(UC, UseMono);
-            int dx=fsc->advx; if(UseMono){ dx/=MA; if(dx<1) dx=1; if(dx>1)dx=2; dx*=MA; }
+            real dx=fsc->advx; if(UseMono){ dx/=MA; if(dx<1.01) dx=1; if(dx>1.01)dx=2; dx*=MA; }
             if(sx+dx > WLimit){ sx = 0; sy += LA_RH; rows++; }
             sx += dx;
             C += 1;
@@ -3058,7 +3057,7 @@ int tnsStringGetDimension(char* content, uint32_t* contentU, int Count, int WLim
     if(sx==0 && rows>1){rows--;}
     if(sx>MaxSX) MaxSX=sx;
     if(Rows) (*Rows)=rows;
-    return MaxSX;
+    return MaxSX+1;
 }
 int tnsStringGetWidth(char *content, int Count, int UseMono){
     return tnsStringGetDimension(content, 0, Count, 0, 0, UseMono);
@@ -3067,8 +3066,8 @@ int tnsStringGetWidthU(uint32_t *contentU, int Count, int UseMono){
     return tnsStringGetDimension(0, contentU, Count, 0, 0, UseMono);
 }
 void tnsDrawStringM(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags){
-    int sx = L, sy = (LA_RH!=LA_RH0)?(((((real)FM->UsingFont->height/LA_RH0-0.5)/MAIN.UiScale)+0.5)*LA_RH + T):(FM->UsingFont->height+T);
-    int MA=FM->UsingFont->MonoAdvance;
+    real sx = L; int sy = (LA_RH!=LA_RH0)?(((((real)FM->UsingFont->height/LA_RH0-0.5)/MAIN.UiScale)+0.5)*LA_RH + T):(FM->UsingFont->height+T);
+    real MA=FM->UsingFont->MonoAdvance;
     int i,advance=1;
     int len = contentU?strlenU(contentU):strlen(content);
     real xo, yo, xl, yl;
@@ -3085,14 +3084,14 @@ void tnsDrawStringM(char *content, uint32_t* contentU, real Color[4], int L, int
     for (i = 0; i < len && UC; i+=advance){
         UC = contentU?contentU[i]:laToUnicode(&content[i], &advance);
         tnsFontSingleCharacter *fsc;
-        int cx, cy;
+        real cx, cy;
 
         if (UC == L'\n'){ if(!OneLine){sx = L; sy += LA_RH; continue;}else{ UC=' '; } }
 
         fsc = tfntFetchCharacterW(UC, Flags&LA_TEXT_MONO);
 
-        int dx=fsc->advx; if(UseMono){ dx/=MA; if(dx<1) dx=1; if(dx>1)dx=2; dx*=MA; }
-        if (sx + dx > R){
+        real dx=fsc->advx; if(UseMono){ dx/=MA; if(dx<1.01) dx=1; if(dx>1.01)dx=2; dx*=MA; }
+        if (sx + dx > R+1){
             if(Flags&LA_TEXT_LINE_WRAP){
                 sx=L; sy+=LA_RH;
             }else{

+ 4 - 1
resources/la_operators.c

@@ -463,6 +463,8 @@ int OPMOD_ManagedSave(laOperator *a, laEvent *e){
 }
 
 int OPINV_ManagedSaveNewFile(laOperator *a, laEvent *e){
+    if(MAIN.SetUDFPending) return LA_FINISHED;
+    MAIN.SetUDFPending=1;
     a->CustomData = memAcquireSimple(sizeof(laUDFPreviewExtra));
     laInvoke(a, "LA_file_dialog", e, 0, 0, 0);
     return LA_RUNNING;
@@ -471,7 +473,7 @@ int OPMOD_ManagedSaveNewFile(laOperator *a, laEvent *e){
     laUDFPreviewExtra *upe = a->CustomData;
 
     if (a->ConfirmData){
-        if(a->ConfirmData->Mode==LA_CONFIRM_CANCEL){ return LA_FINISHED; }
+        if(a->ConfirmData->Mode==LA_CONFIRM_CANCEL){ MAIN.SetUDFPending=0; return LA_FINISHED; }
         if(a->ConfirmData->Mode==LA_CONFIRM_OK){
             if(a->ConfirmData->StrData){
                 char* path=a->ConfirmData->StrData;
@@ -485,6 +487,7 @@ int OPMOD_ManagedSaveNewFile(laOperator *a, laEvent *e){
                 la_MakeDummyManagedUDF();
                 laNotifyUsers("la.managed_udfs"); laNotifyUsers("la.managed_props");
             }
+            MAIN.SetUDFPending=0;
             return LA_FINISHED;
         }
         return LA_RUNNING;

+ 16 - 1
resources/la_templates.c

@@ -1032,6 +1032,13 @@ void laui_ManagedPropInstance(laUiList *uil, laPropPack *Base, laPropPack *Opera
     laSplitColumn(uil,cr,0.6); laColumn *crl=laLeftColumn(cr, 30); laColumn *crr=laRightColumn(cr,0);
 
     laPropContainer* pc=la_EnsureSubTarget(Base->LastPs->p, Base->EndInstance);
+
+
+    if(pc->UDFPropagate){
+        char buf[128]; sprintf(buf,"Assign all \"%s\" into:",pc->Name);
+        laShowLabel(uil,crl,buf,0,0)->Flags|=LA_TEXT_ALIGN_RIGHT;
+        laShowItem(uil,crr,Base,"__single_udf_propagate");
+    }
     
     if(pc->OtherAlloc || Base->LastPs->p->UDFIsSingle){
         //laShowLabel(uil,cr,"(Item not allocated by memAcquire)",0,0)->Expand=1;
@@ -1056,7 +1063,7 @@ void laui_ManagedPropInstance(laUiList *uil, laPropPack *Base, laPropPack *Opera
                 laShowItem(uil,crr,Base,"__file");
             }
         }else{
-            laShowItem(uil,crl,Base,"identifier")->Flags|=LA_UI_FLAGS_PLAIN;
+            //laShowItem(uil,crl,Base,"identifier")->Flags|=LA_UI_FLAGS_PLAIN;
         }
     }
     for(laProp*p=pc->Props.pFirst;p;p=p->Item.pNext){
@@ -1064,12 +1071,20 @@ void laui_ManagedPropInstance(laUiList *uil, laPropPack *Base, laPropPack *Opera
         la_EnsureSubTarget(p,0); 
         if(p->SubProp &&p->SubProp->Hyper!=2 &&(!p->UDFIsSingle)) continue;
         if(p->UDFNoCreate) continue;
+        if(p==pc->SaverDummy){
+            laShowItem(uil,cl,Base,"__single_saver_dummy.__modified");
+            laShowItem(uil,crl,Base,"identifier")->Flags|=LA_UI_FLAGS_PLAIN;
+            laShowItem(uil,crr,Base,"__single_saver_dummy.__file");
+            continue;
+        }
         char buf[128]; sprintf(buf,"🞄 %s",p->Identifier);
         laUiItem* b=laOnConditionToggle(uil,c,0,0,0,0,0);{ strSafePrint(&b->ExtraInstructions,"text=🞄 %s;",p->Identifier);
             b->Flags|=LA_UI_FLAGS_NO_DECAL|LA_TEXT_ALIGN_LEFT; b->State=LA_BT_ACTIVE;
             laShowItemFull(uil,cr,Base,p->Identifier,0, 0,laui_ManagedPropInstance,0)->Flags|=LA_UI_FLAGS_NO_DECAL|LA_UI_COLLECTION_NO_HIGHLIGHT;
         }laEndCondition(uil,b);
     }
+
+    laShowSeparator(uil,c);
 }
 void laui_ManagedProp(laUiList *uil, laPropPack *Base, laPropPack *OperatorInst, laColumn *ExtraColumns, int context){
     laColumn *c=laFirstColumn(uil);