diff --git a/uppsrc/CtrlCore/CtrlClip.cpp b/uppsrc/CtrlCore/CtrlClip.cpp index d4416b0d8..39cdfefd4 100644 --- a/uppsrc/CtrlCore/CtrlClip.cpp +++ b/uppsrc/CtrlCore/CtrlClip.cpp @@ -308,4 +308,13 @@ Ctrl *Ctrl::GetDragAndDropTarget() return dndctrl; } +void InitRichImage(String (*fGetImageClip)(const Image& img, const String& fmt), + bool (*fAcceptImage)(PasteClip& clip), + Image (*fGetImage)(PasteClip& clip), + const char *(*fClipFmtsImage)()); + +INITBLOCK { + InitRichImage(GetImageClip, AcceptImage, GetImage, ClipFmtsImage); +} + END_UPP_NAMESPACE diff --git a/uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp b/uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp index 05296fe13..4435ec95a 100644 --- a/uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp +++ b/uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp @@ -1,4 +1,5 @@ -topic "ArrayCtrl";[2 $$0,0#00000000000000000000000000000000:Default] +topic "ArrayCtrl"; +[2 $$0,0#00000000000000000000000000000000:Default] [i448;a25;kKO9;*@(64)2 $$1,0#37138531426314131252341829483380:class] [l288;2 $$2,0#27521748481378242620020725143825:desc] [a83;*R6 $$3,0#31310162474203024125188417583966:caption] diff --git a/uppsrc/CtrlLib/src.tpp/HeaderCtrl$en-us.tpp b/uppsrc/CtrlLib/src.tpp/HeaderCtrl$en-us.tpp index ee1e25eb0..8993c9198 100644 --- a/uppsrc/CtrlLib/src.tpp/HeaderCtrl$en-us.tpp +++ b/uppsrc/CtrlLib/src.tpp/HeaderCtrl$en-us.tpp @@ -1,29 +1,424 @@ -TITLE("HeaderCtrl") -COMPRESSED -120,156,237,60,11,115,28,197,153,127,101,138,36,120,215,72,98,119,37,89,178,116,185,194,49,112,118,197,54,148,237,35,87,165,90,188,189,59,189,187,19,205,206,108,230,161,135,207,71,201,112,132,224,4,87,46,60,12,135,129,11,5,137,83,224,224,212,165,18,30,38,135,177,169,16,30,6,2,69,133,132,112,103,23,38,84,46,16,159,41,12,33,132,220,247,125,221,61,211,243,88,73,150,196,163,174,142,162,44,105,102,186,251,123,191,250,235,158,168,24,159,255,124,169,175,244,185,210,2,255,141,93,204,155,44,180,131,234,132,53,52,52,58,206,42,195,227,147,95,190,108,237,248,234,139,10,107,134,138,56,75,25,102,25,28,41,15,142,14,15,150,135,42,107,224,159,242,96,185,50,92,25,28,42,143,86,214,14,141,14,14,142,150,198,26,54,243,253,234,132,93,25,29,29,199,65,21,24,84,25,25,174,148,71,134,70,135,70,203,131,35,163,21,24,91,41,149,42,165,145,202,112,121,104,112,180,50,60,102,114,191,81,157,96,163,131,227,171,183,174,129,65,131,184,18,76, -94,42,175,169,12,141,12,85,74,131,165,202,16,44,85,30,29,29,42,143,12,143,14,174,93,179,102,172,193,186,129,229,58,114,45,171,92,174,148,199,235,229,145,113,128,249,170,171,174,26,40,15,149,4,4,67,48,89,185,52,4,160,150,225,89,105,168,50,82,30,94,91,90,59,60,90,30,45,13,194,228,195,35,165,225,177,46,243,88,167,55,234,195,11,162,62,82,26,179,2,14,83,172,190,160,92,30,129,33,107,250,214,124,174,60,52,2,136,142,14,14,13,143,142,148,96,241,74,165,50,56,88,41,15,86,214,174,173,12,175,25,30,25,107,115,102,114,175,58,241,143,59,254,233,11,151,108,233,255,251,109,198,132,63,56,110,76,124,161,84,234,47,149,140,13,244,122,125,224,217,213,243,171,19,126,105,220,16,63,86,27,19,171,13,162,244,142,106,252,13,190,171,136,79,224,199,69,23,89,29,214,226,99,229,193,225,210,249,229,225,210,213,215,252,106,238,214,185,185,185,107,222,252,43,252,59,247,254,3,251,223,186,237,200,13,143,31,122,230,91,79,220,118,235,163,183, -238,158,187,225,131,199,94,61,114,114,247,61,123,191,245,216,158,39,127,187,251,254,227,47,253,215,177,183,127,249,240,237,123,111,252,232,191,175,63,250,175,127,249,253,71,31,237,187,230,165,255,57,242,238,254,221,115,115,31,190,114,230,174,227,115,47,237,126,253,244,187,55,60,126,219,190,125,71,127,255,199,27,95,185,243,197,211,255,124,250,235,191,254,237,191,28,253,254,217,63,188,255,242,131,103,222,124,106,239,179,31,237,121,238,217,19,111,255,199,131,167,126,179,103,223,45,143,189,253,189,147,127,126,231,216,35,223,185,246,167,63,124,250,225,211,167,95,188,239,207,7,223,62,188,255,173,215,30,255,193,157,183,191,119,234,71,207,159,186,250,236,169,19,251,95,127,253,208,158,91,238,184,229,185,231,175,253,217,153,3,79,238,189,255,196,55,190,249,218,205,39,95,254,198,235,119,63,250,135,175,63,245,179,3,111,254,252,165,247,223,251,241,187,247,255,248,174,123,126,119,244,208,245,239,60,244,225,225,227,7,30,57,241,206,155,15,252,244,201,171,95,126,242,206,39,30, -121,253,224,145,127,127,252,166,131,247,29,123,234,221,191,30,61,114,211,205,111,239,249,211,59,207,223,123,221,153,159,220,125,221,247,238,251,221,161,135,239,185,227,55,191,60,114,248,153,61,199,62,248,225,27,199,79,253,228,204,129,147,143,222,184,251,201,239,158,124,232,254,235,63,252,224,190,183,190,253,204,47,254,120,219,137,61,183,220,124,247,53,239,239,63,126,246,195,59,159,126,245,240,137,155,30,61,118,240,219,103,239,57,241,111,167,110,61,240,235,239,62,125,251,119,238,125,246,251,7,223,120,233,244,13,199,239,248,197,95,14,62,247,252,243,199,94,188,249,181,187,95,125,228,204,131,143,237,61,253,212,45,15,237,251,222,189,135,95,125,239,133,195,255,121,246,228,207,223,184,246,87,223,124,232,195,87,31,152,187,245,186,35,167,78,159,189,109,238,208,61,71,31,220,247,194,129,167,31,159,219,251,194,157,123,30,58,246,167,39,14,252,224,186,187,14,237,127,101,238,65,141,143,165,241,139,10,165,129,210,64,101,120,184,104,76,92,120,81,201,184,152,123,214,20,55, -141,166,231,130,176,193,3,3,89,223,103,84,241,199,165,32,196,60,33,41,154,8,25,150,111,132,62,12,237,48,203,177,103,141,166,235,25,1,171,219,220,16,82,232,15,24,27,3,163,193,28,163,206,13,159,7,70,216,53,2,215,96,70,131,123,1,12,49,26,174,29,118,28,195,15,188,176,17,132,30,55,10,240,48,104,115,120,97,114,35,224,94,199,114,92,219,109,205,246,209,83,203,49,173,41,203,12,153,45,23,144,19,248,6,131,177,13,102,219,0,203,196,133,8,131,95,45,194,231,13,59,52,45,167,69,131,241,97,109,149,49,101,249,56,190,209,6,245,108,192,10,150,31,88,13,223,40,192,107,35,176,2,128,221,1,140,253,62,195,106,184,48,49,15,26,3,69,131,57,38,160,208,102,83,150,235,225,96,120,19,120,128,64,32,7,78,91,102,208,54,108,171,99,5,190,0,149,213,45,219,10,102,17,93,191,237,78,27,23,26,109,203,76,96,128,240,20,7,146,164,221,222,78,127,34,166,22,8,154,188,105,57,128,97,29,166,109,123,156,27,117,230,91,13,163,235, -185,93,160,167,197,253,49,90,26,8,0,36,179,26,250,4,85,192,7,128,133,87,64,81,171,19,118,170,132,19,254,205,102,240,111,163,107,205,112,91,126,60,64,128,200,47,233,67,245,85,140,44,2,4,224,192,34,98,228,20,179,67,238,11,24,145,228,58,141,80,46,186,237,89,159,96,42,208,168,162,226,189,192,111,192,184,76,48,222,133,127,60,163,13,107,10,58,102,48,17,164,104,129,196,58,64,42,248,163,110,193,50,222,172,17,58,68,252,233,182,213,16,208,117,192,245,88,93,219,18,20,139,133,206,135,249,16,194,38,240,31,0,155,110,115,135,79,193,162,184,92,36,86,78,224,185,36,223,54,179,76,195,13,3,228,100,211,10,232,171,41,139,79,27,190,181,147,19,161,60,14,248,129,216,184,94,7,36,16,121,195,45,15,4,192,7,4,3,0,131,181,0,178,208,68,226,184,78,109,85,0,79,2,16,188,62,227,171,161,31,200,175,61,6,142,199,207,145,134,20,64,168,75,200,109,22,160,160,0,97,67,207,48,173,102,19,128,112,2,37,219,29,80,30,160,232, -37,12,8,129,191,27,28,62,104,4,64,50,128,78,8,145,111,160,80,234,4,246,184,205,240,147,52,165,1,231,0,40,8,216,147,94,134,158,92,73,82,96,44,1,178,5,94,97,252,50,248,19,156,201,229,32,150,174,135,254,148,217,213,49,165,130,250,212,93,237,11,128,140,153,72,16,88,107,218,2,249,242,184,223,5,160,113,225,46,252,14,198,67,200,157,46,87,196,18,219,206,66,70,159,142,103,97,218,202,205,176,193,55,49,63,0,136,144,233,192,45,171,3,218,170,9,54,240,28,87,67,169,39,152,221,64,23,63,131,207,52,56,55,253,164,28,8,89,109,186,182,237,78,147,189,137,17,69,251,224,43,242,121,86,171,29,20,9,121,143,64,49,145,139,244,180,214,31,184,181,126,155,55,3,195,245,144,229,133,58,111,89,14,233,18,17,36,26,223,113,81,108,88,189,152,47,146,189,176,222,194,103,62,83,88,35,170,2,105,122,63,15,214,56,47,233,10,107,6,82,79,241,81,157,227,87,74,106,22,77,141,117,82,49,243,101,82,152,2,208,26,171,137,134,131,133, -129,11,234,138,26,98,207,38,45,146,212,76,41,149,210,199,161,5,128,135,96,86,90,30,103,2,90,38,44,27,88,27,84,78,205,118,124,69,183,60,231,64,113,101,19,228,154,13,48,12,118,172,162,82,132,4,213,73,125,224,59,52,254,96,29,44,244,205,82,231,136,190,210,221,66,172,170,116,39,101,131,46,133,160,64,124,226,185,45,136,5,58,220,171,173,242,97,14,80,64,195,109,210,16,1,149,22,22,4,108,18,44,76,195,237,116,109,30,240,200,120,185,10,87,19,156,174,103,213,67,2,3,38,33,97,81,162,7,1,133,7,242,1,180,3,3,141,12,225,166,64,78,112,26,191,233,8,7,213,70,69,208,45,35,12,205,179,226,133,96,182,43,56,104,152,161,135,66,3,126,111,19,155,5,171,94,69,74,193,95,151,163,65,169,146,12,185,117,242,18,109,215,179,118,194,4,145,131,235,186,190,133,0,251,4,113,214,81,215,129,225,147,2,13,9,71,135,168,47,135,209,139,46,46,35,3,28,242,126,38,11,88,138,226,27,155,198,102,119,10,161,148,82,232,169,48, -171,79,167,49,67,173,35,21,243,184,80,29,162,98,232,227,72,211,99,45,163,118,62,252,116,187,210,95,0,8,3,198,122,240,134,78,32,162,43,36,24,132,36,78,96,53,103,133,235,165,89,196,4,127,199,131,237,172,190,209,49,249,140,209,225,65,219,53,149,103,245,56,4,106,142,144,203,218,121,64,164,22,186,243,218,121,72,14,248,152,66,64,161,86,57,222,76,15,29,81,56,58,156,204,184,8,90,154,24,106,198,156,175,142,147,107,54,192,89,130,35,147,34,160,36,85,177,86,64,43,39,88,103,154,20,174,86,35,144,193,28,196,108,3,29,224,118,51,169,210,48,187,212,190,174,98,171,154,218,3,239,195,156,22,40,76,129,213,65,116,165,14,241,233,116,208,182,17,96,52,77,193,100,169,131,62,140,52,153,103,26,113,84,217,12,157,134,112,117,16,22,10,141,145,43,132,54,243,208,246,48,84,25,15,253,158,235,136,168,213,205,145,51,159,24,7,198,196,128,239,187,62,15,77,176,160,160,74,1,161,232,76,185,147,100,21,163,104,39,177,174,160,104,195,182,26, -147,220,148,17,130,84,22,132,180,13,83,50,164,36,90,166,117,52,172,74,97,117,157,53,38,37,59,208,75,16,39,28,8,102,250,157,208,150,161,95,95,158,230,1,29,60,225,167,129,131,141,73,146,142,142,139,234,65,48,8,109,225,51,188,1,246,88,200,129,90,45,25,150,165,232,2,160,130,74,68,104,32,180,34,15,129,133,136,4,104,228,186,97,23,194,65,80,242,132,105,0,228,132,108,111,5,226,43,65,193,113,38,23,233,6,215,141,181,237,54,152,50,82,49,73,53,138,33,252,64,217,150,48,163,168,110,166,59,237,68,248,167,35,25,229,112,98,217,82,43,232,50,53,60,254,101,149,175,95,89,27,171,141,33,168,87,26,4,176,74,227,119,168,223,32,93,211,240,81,175,11,209,235,56,215,67,3,151,29,62,104,88,209,211,98,85,230,137,91,53,29,175,187,161,160,122,221,157,73,146,1,17,41,80,18,7,150,3,140,0,178,48,142,34,221,180,83,16,170,3,102,192,242,149,235,34,158,65,108,46,201,229,107,234,44,105,92,176,45,96,230,58,207,99,179,56, -73,49,201,41,105,68,201,242,70,148,244,209,164,195,164,228,29,88,23,18,0,245,156,210,16,105,14,132,149,76,178,11,194,22,134,97,50,195,32,52,4,105,19,34,38,244,137,2,174,52,122,100,247,129,46,154,43,21,128,19,59,135,48,222,88,79,36,238,223,181,29,133,150,76,100,97,39,247,92,204,221,32,104,137,191,187,80,82,93,104,19,12,208,173,131,88,71,99,132,182,96,76,226,1,85,202,145,178,4,193,206,6,224,250,88,21,193,37,242,8,17,173,245,167,176,230,3,173,1,161,49,160,16,78,232,231,35,26,9,173,208,42,200,134,197,107,143,57,62,144,182,35,109,26,34,1,244,139,69,28,83,224,6,164,171,9,73,73,10,2,36,70,156,216,195,103,24,250,5,77,16,226,240,146,188,150,239,88,221,46,15,146,105,199,122,163,127,215,86,82,49,86,175,212,118,192,106,181,29,184,190,81,251,34,57,162,88,67,10,149,162,81,187,64,61,220,70,96,93,1,130,89,40,14,108,119,187,155,32,116,42,20,101,222,48,40,117,113,12,85,48,38,50,254,5,147, -213,64,242,131,90,145,178,145,49,80,194,9,77,211,232,97,117,130,74,125,168,106,164,196,235,73,86,175,20,15,197,31,234,147,218,249,59,170,48,165,252,171,80,157,72,107,109,52,19,201,82,113,7,45,144,163,171,88,244,244,172,46,49,14,153,175,1,45,215,175,106,181,22,82,102,145,72,199,22,77,241,5,87,96,24,18,114,207,71,3,168,107,44,197,28,16,192,241,169,76,16,20,215,34,6,140,75,129,159,160,55,16,72,185,97,171,29,3,39,99,190,54,193,152,1,171,15,60,12,88,29,14,76,159,79,137,50,26,183,88,181,98,70,65,33,135,98,78,153,115,35,146,243,60,136,36,228,117,173,144,52,112,14,34,66,210,209,91,4,148,157,22,130,16,243,250,92,4,34,37,10,128,34,57,231,121,240,92,65,73,73,10,134,74,34,23,22,16,163,16,49,154,84,159,65,168,2,193,196,34,197,164,184,2,22,86,198,48,145,172,47,78,26,84,132,43,232,145,21,134,164,239,78,74,133,148,128,20,243,201,0,196,254,28,194,216,121,29,185,52,47,25,87,174,125,209, -102,94,252,65,109,181,230,237,3,172,2,168,87,125,70,206,96,211,13,33,75,204,13,21,40,141,208,38,254,162,254,178,148,141,35,0,19,148,70,7,178,87,10,150,40,125,47,232,85,1,96,113,17,83,25,48,252,88,136,5,13,139,5,204,23,89,158,10,96,163,204,99,17,226,189,176,72,139,100,70,10,111,51,244,168,236,168,11,49,248,66,21,213,103,109,91,66,246,136,164,66,252,10,20,235,23,169,132,156,252,72,144,174,127,215,166,116,61,115,197,229,51,101,173,128,248,84,91,163,36,250,99,22,214,149,100,60,152,22,252,159,18,84,34,152,43,235,234,152,138,41,175,20,149,136,176,232,143,108,128,60,170,21,98,86,25,229,41,142,193,59,93,200,124,176,226,128,129,156,168,122,11,118,168,143,74,159,50,19,244,29,25,73,203,132,146,71,230,126,33,94,205,231,90,116,174,137,146,128,235,213,38,106,213,228,119,145,193,209,243,133,212,250,122,210,32,94,21,163,119,18,240,172,71,234,161,173,61,253,74,30,243,129,113,98,250,72,0,98,15,1,234,167,210,185,21, -113,13,189,25,158,1,120,97,110,206,67,75,202,223,214,67,108,159,250,162,176,16,77,245,162,183,19,118,234,88,118,108,38,181,136,242,123,44,121,130,146,226,110,24,214,24,40,207,6,226,18,166,152,39,97,232,77,90,129,133,98,80,8,210,10,172,150,144,102,128,214,82,9,2,12,33,147,153,254,124,116,219,18,1,66,16,244,48,54,26,133,166,92,203,204,241,53,37,9,75,214,180,208,115,95,15,252,168,198,226,82,121,70,193,9,156,131,92,167,224,241,14,88,11,159,236,140,190,221,182,36,128,182,181,221,105,20,178,229,229,216,185,46,183,238,186,118,238,56,220,58,76,248,91,48,48,60,34,5,66,68,217,46,110,45,250,185,5,138,172,42,4,185,170,144,248,140,86,237,223,213,180,89,139,194,55,204,159,177,30,223,230,228,37,85,62,8,159,133,182,73,37,232,54,230,147,5,144,32,132,175,90,148,48,129,250,210,195,38,179,125,120,186,28,226,111,0,12,151,79,252,136,114,27,122,19,44,223,250,0,22,146,255,5,171,79,32,84,172,158,11,113,231,199,187,135, -0,148,140,141,62,44,121,133,40,220,175,20,242,235,177,20,39,170,33,180,37,32,54,170,211,165,157,197,34,55,143,49,136,88,143,121,184,144,135,62,67,9,9,62,35,185,89,150,78,138,196,62,17,150,174,160,94,46,58,20,142,85,82,217,166,204,190,53,88,35,28,82,212,147,169,249,201,156,27,63,102,230,93,132,247,73,162,145,235,128,210,84,252,152,130,1,74,9,147,174,75,33,36,136,148,145,66,74,1,178,196,212,123,74,226,45,128,213,9,129,80,197,221,130,235,101,62,74,126,65,233,167,163,167,170,189,18,8,183,254,85,222,8,138,178,196,136,219,44,45,173,44,160,246,128,226,213,168,216,125,206,70,56,163,73,105,98,69,132,88,182,238,124,133,26,62,62,6,221,233,53,172,49,51,143,214,164,67,43,185,231,19,181,142,208,78,92,49,106,189,176,208,181,251,174,218,40,75,106,94,65,213,48,139,122,215,74,163,65,37,200,150,61,187,36,215,8,208,139,239,196,158,32,2,178,48,11,242,73,161,244,110,37,56,144,91,185,207,144,77,83,177,108,208,189,149, -119,56,197,110,65,155,5,70,33,116,108,238,251,233,26,62,186,69,39,82,35,218,120,174,82,139,73,49,185,162,182,169,142,154,218,104,51,167,197,227,108,77,219,110,150,188,92,103,183,92,15,94,119,132,95,178,93,167,85,235,199,50,191,209,97,142,213,13,109,166,237,21,211,24,95,223,214,245,185,7,97,159,181,147,190,42,170,200,132,217,211,108,22,107,153,33,238,85,59,61,250,137,150,175,157,25,66,199,198,217,216,226,6,92,144,148,162,238,168,152,97,249,212,10,20,101,52,125,96,206,26,172,199,6,118,232,83,180,98,179,157,144,68,42,74,81,81,159,205,138,222,164,204,152,62,138,233,229,118,183,218,88,147,145,140,46,119,24,231,119,96,22,95,244,3,169,237,80,220,103,196,157,119,28,81,87,249,171,106,133,74,187,156,156,242,231,182,105,214,221,142,13,119,84,3,237,19,133,208,115,178,78,114,130,37,41,70,211,242,252,5,170,92,189,134,250,28,8,104,230,152,40,128,199,23,116,145,239,86,71,11,137,244,41,126,42,231,72,109,233,229,80,105,51,100,39, -81,161,120,9,68,146,227,151,70,35,234,246,92,10,137,130,156,184,103,51,229,89,202,98,59,162,139,79,237,181,45,76,8,173,221,64,85,205,207,217,142,210,232,149,182,163,57,29,14,96,131,182,39,155,27,242,113,186,20,62,39,152,180,173,128,115,64,74,31,190,36,172,28,51,199,211,226,172,148,248,200,128,34,234,78,145,150,149,76,180,66,89,34,172,73,54,206,217,99,167,122,81,74,141,237,0,219,186,144,111,92,12,145,211,146,176,242,115,84,83,54,25,36,43,2,137,22,24,177,191,16,5,221,34,78,75,26,126,31,12,185,216,72,214,77,63,36,41,212,79,229,99,243,174,164,81,105,49,153,236,60,178,74,4,88,18,242,57,12,221,68,219,186,25,236,5,38,153,118,18,69,3,112,59,51,85,109,59,54,14,150,84,145,43,233,77,122,236,219,107,190,60,218,76,142,122,61,244,114,129,236,249,8,61,31,43,3,216,7,230,203,74,46,211,192,21,251,208,88,175,82,251,253,85,225,250,146,174,51,187,130,139,29,101,93,116,134,4,122,220,185,5,216,91,59,105, -239,152,150,78,109,26,97,44,151,105,243,90,60,81,18,59,242,243,229,193,27,149,221,208,80,149,97,148,71,129,81,109,162,52,48,160,202,128,133,98,77,84,80,106,253,101,209,114,131,72,114,140,189,28,87,155,66,206,48,101,53,176,234,53,171,199,117,212,157,183,2,101,73,25,225,37,115,194,94,233,157,222,90,41,218,142,93,199,158,29,139,182,109,4,121,221,102,19,147,182,168,77,92,79,5,133,221,81,53,221,66,23,66,39,7,203,121,24,224,201,38,199,162,234,175,160,221,101,170,204,139,87,56,151,222,254,220,151,18,26,25,11,42,96,74,196,129,212,120,26,24,247,80,42,157,39,39,47,246,49,196,36,212,240,227,199,225,108,226,107,45,182,93,92,161,148,232,226,163,58,137,61,169,28,65,67,205,19,52,210,72,161,4,64,147,96,211,194,174,7,234,244,219,174,135,227,25,117,39,89,65,140,184,217,74,201,185,14,191,210,119,152,163,129,33,184,208,122,63,172,7,120,118,66,176,47,42,37,99,64,65,69,88,21,98,247,210,36,36,23,245,48,75,44,17,134, -140,73,205,145,86,189,72,150,21,215,141,254,57,73,171,44,130,233,70,106,62,162,211,177,1,93,78,64,126,6,248,64,95,52,1,132,209,137,228,40,86,5,77,42,41,80,180,168,33,46,191,217,55,211,94,95,148,221,109,48,99,132,96,36,196,170,148,214,167,22,141,85,86,85,54,122,181,109,232,106,167,9,144,192,177,206,82,177,91,207,242,94,92,201,139,136,35,168,72,117,62,42,254,25,85,120,157,82,52,173,71,106,121,6,106,3,199,189,196,69,178,252,98,213,55,38,211,99,178,71,109,46,119,35,115,68,32,174,5,243,175,133,241,46,148,58,11,131,74,36,15,31,164,154,28,196,164,144,161,154,188,203,133,139,144,233,167,214,15,10,107,8,121,128,213,68,70,59,159,189,208,146,112,29,240,69,110,231,94,169,159,251,83,196,73,110,9,110,116,166,22,81,102,238,185,83,97,57,83,217,224,132,68,87,30,203,34,107,201,226,242,175,218,168,237,3,122,78,38,3,24,138,188,36,99,176,131,149,250,130,133,210,41,26,130,179,111,80,247,176,225,65,66,74,60,245, -3,60,10,50,237,122,147,70,61,153,18,203,198,95,143,227,49,53,95,86,162,211,13,36,0,127,82,164,233,188,86,60,75,44,209,81,233,26,38,150,147,172,70,19,155,224,24,124,220,191,171,90,91,141,6,114,197,120,180,29,204,238,228,210,248,83,219,17,36,6,103,55,147,176,6,167,155,67,189,215,92,154,45,189,110,131,58,66,221,219,241,54,80,109,21,115,172,14,186,137,218,42,85,122,240,184,222,113,153,91,39,21,193,161,30,175,199,70,79,129,173,206,167,136,2,134,102,245,36,139,147,16,162,159,23,173,246,22,254,250,181,144,211,185,34,237,232,75,28,148,138,29,66,173,80,146,3,72,188,178,16,128,204,210,217,64,216,104,241,64,65,1,75,99,40,164,29,95,73,36,39,24,166,64,48,228,183,177,151,121,35,193,60,109,249,92,53,162,104,46,54,99,78,196,17,139,25,25,254,209,204,44,96,114,63,174,182,170,206,29,206,130,54,112,67,239,147,11,209,31,9,159,6,222,65,235,173,69,76,228,196,124,6,91,150,169,91,193,67,76,218,204,51,167,241,124, -140,94,165,34,214,8,197,4,16,59,33,29,55,163,230,135,14,19,96,166,251,159,17,222,48,96,170,169,6,57,1,239,128,106,26,253,29,222,224,190,143,39,250,228,1,62,174,232,152,42,213,41,217,72,170,173,199,91,128,53,29,144,203,149,13,195,156,117,88,39,121,28,68,103,71,74,207,53,198,89,1,158,124,137,88,245,137,106,254,22,55,165,251,145,222,110,167,80,0,194,106,141,29,189,55,49,105,150,66,114,255,242,19,66,33,113,30,48,139,199,54,144,21,72,235,50,37,231,184,245,67,63,46,88,149,120,110,116,18,143,233,105,230,172,112,143,51,164,81,74,160,133,183,24,0,231,150,205,41,64,87,39,71,3,60,219,35,140,23,54,138,116,58,160,53,234,180,169,60,48,32,15,151,98,58,35,14,231,196,135,211,166,219,174,29,251,38,71,34,24,159,91,252,100,217,162,29,14,92,10,83,196,129,62,80,90,108,190,18,60,185,100,222,19,134,20,34,163,185,80,241,176,56,126,243,127,232,184,225,39,204,58,58,205,186,12,214,217,56,254,51,205,186,149,63,31, -251,137,177,40,74,3,151,194,32,22,229,144,5,145,59,21,99,171,23,51,66,201,231,255,31,98,77,29,98,61,71,38,231,239,207,128,120,213,10,24,85,107,213,251,115,23,3,49,209,210,34,247,122,239,152,125,157,60,173,36,37,65,20,11,213,17,193,58,234,16,243,168,194,104,166,187,21,58,3,134,188,156,71,148,45,232,220,19,79,100,147,57,242,79,125,117,86,67,254,200,235,60,159,175,236,29,152,201,116,61,209,212,23,111,91,71,103,39,83,245,24,153,16,22,180,146,40,201,186,43,111,234,80,6,41,26,79,25,182,186,161,4,131,221,68,23,96,126,154,157,46,73,148,18,60,95,47,15,39,170,62,91,249,103,143,18,5,169,134,60,102,172,130,53,81,68,151,71,28,177,176,32,206,62,154,243,222,66,209,194,212,44,186,135,162,144,248,148,146,225,232,136,43,96,126,161,235,69,91,239,180,237,158,45,173,45,27,41,89,100,90,62,82,145,218,23,18,230,46,170,30,127,108,176,95,17,53,190,45,132,133,31,99,97,69,16,99,133,140,117,187,160,94,212,127,105, -90,190,250,43,201,29,79,147,46,173,87,57,46,229,169,50,29,113,42,115,29,140,248,33,174,127,202,105,71,50,10,142,72,108,233,222,38,117,10,72,142,5,130,38,46,246,137,116,120,19,171,115,251,75,12,242,155,228,98,219,23,117,110,2,82,49,188,141,3,115,236,100,199,148,222,75,162,121,51,129,160,175,174,6,130,17,62,247,162,243,240,220,180,68,54,104,196,189,28,146,102,44,221,120,109,209,245,53,10,34,66,57,121,138,131,244,156,98,54,200,84,77,95,220,28,66,151,22,8,255,195,60,11,50,254,188,163,28,73,34,96,168,163,192,206,7,6,11,19,228,66,170,198,184,128,76,158,198,143,50,214,212,81,39,209,69,17,119,171,65,138,110,209,217,200,245,181,11,106,23,136,118,101,170,102,201,132,185,203,197,25,84,63,146,26,211,13,162,174,253,62,3,55,202,178,71,32,5,11,26,120,18,116,157,105,22,138,3,155,45,167,80,46,193,79,54,83,168,208,79,15,28,64,97,48,125,196,113,217,167,64,96,161,37,109,104,214,118,116,180,145,201,90,148,186,126, -40,217,109,37,118,54,76,233,187,132,98,89,190,234,83,199,111,85,68,209,246,66,103,50,186,31,200,194,52,222,17,5,241,72,93,129,109,129,219,18,37,47,22,104,157,135,29,23,185,17,59,10,185,3,190,62,2,185,127,215,102,13,60,25,37,59,114,47,103,5,67,204,197,115,128,45,173,247,1,208,97,189,58,242,244,75,159,22,228,0,224,186,113,203,246,218,142,205,235,254,161,74,237,99,120,25,150,222,31,156,164,33,195,205,215,205,153,91,165,62,93,26,90,206,82,201,184,196,86,154,94,178,95,119,129,22,189,238,223,138,89,161,110,175,240,177,64,142,89,155,44,252,224,61,14,209,115,113,249,19,222,22,1,164,35,147,208,17,22,193,209,58,216,53,230,116,22,37,220,137,33,206,103,143,151,151,194,202,243,31,163,236,217,24,181,76,158,168,43,64,144,246,242,102,12,253,254,173,14,155,212,43,225,218,165,86,204,9,32,3,87,59,77,146,89,200,168,102,159,209,204,231,85,19,8,79,152,126,86,200,30,181,86,207,71,249,37,182,213,207,215,216,219,171,79,188, -16,217,119,242,172,137,102,115,186,200,71,116,170,5,250,5,68,138,199,241,221,120,153,155,199,138,81,94,129,69,109,85,62,20,69,14,237,78,60,146,7,88,132,227,57,44,106,32,80,237,199,233,251,212,100,244,164,237,21,231,177,91,29,2,200,222,213,102,20,152,65,117,111,200,206,154,182,75,7,118,106,253,226,150,38,113,104,235,211,17,6,17,113,44,211,164,38,197,64,219,174,70,244,59,180,130,86,88,112,210,157,21,116,101,72,51,98,80,144,184,127,37,158,205,158,213,110,127,138,57,89,59,79,187,170,169,118,94,60,148,202,48,120,235,80,212,172,212,23,205,47,129,18,151,250,96,150,170,100,37,190,0,170,229,65,62,103,211,206,165,18,60,203,129,188,1,227,62,159,219,92,157,121,86,128,66,234,23,53,161,137,85,224,97,131,219,249,22,25,141,248,134,158,132,90,158,141,88,194,62,125,82,12,22,121,192,81,233,134,6,252,10,88,184,229,103,144,242,98,164,40,111,228,82,181,3,113,79,134,152,32,185,115,184,66,183,37,69,197,46,203,143,110,31,194,5, -101,135,220,18,238,78,90,176,139,85,40,56,254,134,248,124,137,121,99,61,8,88,78,81,176,156,36,225,223,192,208,218,249,127,155,164,36,60,83,100,188,220,115,167,196,161,188,14,228,57,114,55,135,246,152,103,2,186,148,134,168,161,39,153,42,101,171,254,47,9,219,7,117, - +topic "HeaderCtrl"; +[2 $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9;*@(64)2 $$1,0#37138531426314131252341829483380:class] +[l288;2 $$2,0#27521748481378242620020725143825:desc] +[a83;*R6 $$3,0#31310162474203024125188417583966:caption] +[l288;i1121;b17;O9;~~~.1408;2 $$4,0#10431211400427159095818037425705:param] +[i448;a25;kKO9;*@(64)2 $$5,0#37138531426314131252341829483370:item] +[*+117 $$6,6#14700283458701402223321329925657:header] +[{_}%EN-US +[s3;%- HeaderCtrl&] +[s0; &] +[s0; class_[* HeaderCtrl]&] +[s2; &] +[s2; +@@image:1350&150 +؀°̌ř⁤݁ҺÚ +΀ԁ™ٞݑçָʎۊĻ˺ӫ© +䰊ЅȎላޕֈ䢽ʾðΨ请ȂȞŻ +”Х򶢇簺̊⽓ȡ⹬ኖ +ᔽĭ嘨ڡ˛ͧΝӕޢܻʖѼ؋ܯ +øѨ€ўŨـ +&] +[s2; &] +[s0; [/ Derived from] Ctrl, [@(0.0.255) CtrlFrame]&] +[s0; &] +[s0; HeaderCtrl is used mainly for table headers. It can be set up +to a certain column structure (in the code terminology, the individual +header columns are called [/ tabs]) including the tabs`' visual +characteristics (tab title names, icons etc.) and behavioral +constraints (tab width limits, the ability to show / hide individual +tabs).&] +[s0; &] +[s0; The individual tab widths are defined by three basic properties: +the [/ logical tab width], its [/ minimum] and [/ maximum pixel width]. +The minimum and maximum tab width are final pixel values defining +constraints for physical (final) column widths. On the other +hand, the logical tab widths are given in arbitrary units, which +are multiplied by a certain scaling factor whenever the header +control is laid out to fit the view size. Therefore normally +their absolute magnitudes don`'t matter, just their ratios.&] +[s0; &] +[s0; The header control can operate in four different visual modes. +Each mode effectively defines how the logical relative tab widths +are fitted to the current view size:&] +[s0; &] +[s0;i150;O0; [* Proportional]: the tab widths are proportionally adjusted +with respect to preset width constraints to fill the current +view width;&] +[s0;i150;O0; [* ReduceLast]: every time a tab width is set and the total +tab width exceeds the view size, the following tab widths (tabs +to the right) are reduced in right`-to`-left order (beginning +with the rightmost tab) to fit the view size.&] +[s0;i150;O0; [* ReduceNext]: every time a tab width is set and the total +tab width exceeds the view size, the following tab widths (tabs +to the right) are reduced in left`-to`-right order (beginning +with the tab just after the tab being adjusted) to fit the view +size.&] +[s0;i150;O0; [* Absolute]: the tab widths are never modified automatically, +the logical header width can be smaller or greater than the actual +view size. Whenever the total tab width exceeds the view size, +the header can be scrolled to the left or right to pan its visible +portion within the parent view.&] +[s0; &] +[s0; From the programmer`'s point of view, the HeaderCtrl takes complete +control over the distribution of tabs and the user interface +needed to adjust them. The host control can use the header control +(typically during [/ Layout] or [/ Paint]) to obtain horizontal pixel +positions of the individual tab breaks and use them to position +and paint the column data.&] +[s0; &] +[s0; If Moving modifier is used, HeaderCtrl allows to reorder tabs +using drag `& drop operation. Client code can identify the order +using GetTabIndex method, which returns the `"original`" index +for the tab.&] +[s0; &] +[s0; The HeaderCtrl implements the [/ frame interface]; when attached +to a parent control using the [/ AddFrame] method, it positions +itself automatically at the top of the control rectangle (above +its view).&] +[s0; &] +[s0; In addition to the standard tab title functionality, the rectangular +areas corresponding to the individual tabs can act as pseudo`-buttons +invoking a certain functionality when clicked. Each header tab +has a [/ WhenAction] callback; when set to a non`-null value, the +header control starts to check for mouse clicks and executes +the callback whenever the corresponding tab is clicked. When +used to invoke popups, you can use the [/ GetTabRect] method to +determine the actual location of a certain header tab and align +the dropdown control with respect to the tab rectangle location.&] +[s0; &] +[s5;K%- [^`:`:Rect^ Rect]_[@0 GetTabRect]([@(0.0.255) int]_[@3 i])&] +[s2; Returns the bounding box of a certain tab (in coordinates relative +to the HeaderCtrl view). This can be used by controls using the +header (like ArrayCtrl) to determine column break locations or +by host applications for positioning dropdown controls (activated +upon clicking a tab) relative to the tab box within the header.&] +[s4; [*C@3 i]-|Tab index (zero based).&] +[s4; [*/ Return value]-|rectangular tab bounding box within the HeaderCtrl.&] +[s0;* &] +[s0; [* Hint:] to locate drop`-down controls (e.g. popup menus) relative +to the tab rectangle, you have to transform the returned rectangle +to screen coordinates. This can be done for example using the +following code snippet:&] +[s0; &] +[s0; [C -|Rect tab2`_scr`_rect `= tab.GetTabRect(2) `+ tab.GetScreenView().TopLeft();]&] +[s0;3 &] +[s5;:`:`:HeaderCtrl`:`:Tab`(int`)const: [@(0.0.255) const]_[^`:`:Column^ Column]`&_[@0 Tab]( +[@(0.0.255) int]_[@3 i][@0 )_const]&] +[s2; Returns the descriptive [* HeaderCtrl`::Column] structure of a +given header tab. This constant version can be used to retrieve +individual tab properties. For a thorough description of the +[* Column] structure, see below.&] +[s4; [*C@3 i]-|Tab index within the header (zero based).&] +[s4; [*/ Return value]-|a (constant) reference to the [* Column] structure +describing the tab.&] +[s0;3 &] +[s5;:`:`:HeaderCtrl`:`:Tab`(int`): [^`:`:Column^ Column][%- `&]_[@0 Tab]([@(0.0.255) int]_[@3 i +][@0 )]&] +[s2; Returns a (non`-constant) reference to the descriptive [* HeaderCtrl`::Column] +structure of a given header tab. This can be used to set and +retrieve individual tab properties (see below for a full description +of the [* Column] structure).&] +[s4; [*C@3 i]-|Tab index (zero based).&] +[s4; [*/ Return value]-|a non`-constant reference to the [* Column] structure +for the given tab.&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 Add]([@(0.0.255) const]_[@(0.0.255) char]_`* +[@3 text], [@(0.0.255) double]_[@3 ratio]_`=_[@3 0])&] +[s2; Adds a new tab after (to the right of) all existing header tabs. +The function returns a (non`-constant) reference to the [* HeaderCtrl`::Column] +structure which can be further used to set up additional tab +properties.&] +[s4; [*C@3 text]-|Tab (title) name.&] +[s4; [*C@3 ratio]-|Logical tab width.&] +[s4; [*/ Return value]-|a non`-constant reference to the [* Column] structure +describing the newly added tab.&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 Add]()&] +[s2; Adds a new tab after (to the right of) all existing header tabs. +This is identical to the above version with the [/ text] argument +set to an empty string and [/ ratio] set to 0.&] +[s4; [*/ Return value]-|a non`-constant reference to the [* Column] structure +describing the newly added tab.&] +[s0;3 &] +[s5;K%- [@(0.0.255) const]_[^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 operator`[`]]([@(0.0.255) i +nt]_[@3 i])_[@(0.0.255) const]&] +[s2; Returns a (constant) reference to a given header tab. This is +identical to the [/ const] version of the [* Tab] method.&] +[s4; [*C@3 i]-|Tab index (zero based).&] +[s4; [*/ Return value]-|a constant reference to the given header tab.&] +[s0;3 &] +[s5;K%- [@(0.0.255) int]_[@0 GetCount]()_[@(0.0.255) const]&] +[s2; Returns the current number of header tabs. Each [* Add] increases +this value by one and [* Reset] sets it to 0 (the initial value).&] +[s4; [*/ Return value]-|Number of tabs.&] +[s0;3 &] +[s5;K%- [@(0.0.255) void]_[@0 Reset]()&] +[s2; Resets the header tab to its initial state (removes all tabs).&] +[s0;3 &] +[s5;K%- [@(0.0.255) void]_[@0 ShowTab]([@(0.0.255) int]_[@3 i], [@(0.0.255) bool]_[@3 show]_`=_tr +ue)&] +[s2; Shows or hides a certain header tab.&] +[s4; [*C@3 i]-|tab index (zero based)&] +[s4; [*C@3 show]-|flag indicating whether the tab should be shown ([* true]) +or hidden ([* false]).&] +[s0;3 &] +[s5;K%- [@(0.0.255) void]_[@0 HideTab]([@(0.0.255) int]_[@3 i])&] +[s2; Hides a certain header tab. This is identical to [* ShowTab(i, +false)].&] +[s4; [*C@3 i]-|tab index (zero based)&] +[s0;3 &] +[s5;K%- [@(0.0.255) bool]_[@0 IsTabVisible]([@(0.0.255) int]_[@3 i])&] +[s2; Checks for visibility of a certain tab.&] +[s4; [*C@3 i]-|tab index (zero based).&] +[s4; [*/ Return value]-|[* false] `= hidden, [* true] `= shown.&] +[s0;3 &] +[s5;K%- [@(0.0.255) void]_[@0 SetTabRatio]([@(0.0.255) int]_[@3 i], [@(0.0.255) double]_[@3 ratio +])&] +[s2; Sets the logical tab width (ratio) of a given tab.&] +[s4; [*C@3 i]-|tab index&] +[s4; [*C@3 ratio]-|logical tab width.&] +[s0;3 &] +[s5;K%- [@(0.0.255) double]_[@0 GetTabRatio]([@(0.0.255) int]_[@3 i])_[@(0.0.255) const]&] +[s2; Retrieves the current logical width of a certain tab. The logical +tab width can be set using the [* SetTabRatio] method (or using +the [* SetRatio] method for an individual [* HeaderCtrl`::Column] +object) or by dragging the tab breaks using the mouse.&] +[s4; [*C@3 i]-|tab index (zero based)&] +[s4; [*/ Return value]-|current logical tab width&] +[s0;3 &] +[s5;K%- [@(0.0.255) void]_[@0 SetTabWidth]([@(0.0.255) int]_[@3 i], [@(0.0.255) int]_[@3 cx])&] +[s2; Sets the given header tab to a physical (pixel) size. This also +modifies the logical (relative) tab width accordingly.&] +[s4; [*C@3 i]-|tab index (zero based)&] +[s4; [*C@3 cx]-|tab pixel size&] +[s0;3 &] +[s5;K%- [@(0.0.255) int]_[@0 GetTabWidth]([@(0.0.255) int]_[@3 i])&] +[s2; Returns the physical (pixel) width of a given header tab. Remember +that (unless the HeaderCtrl is in the [* Scroll] mode) the physical +tab widths can change with the parent view size. Algorithms for +long`-term manipulation of tab sizes (typically serialization) +should always count on the logical tab widths.&] +[s4; [*C@3 i]-|tab index (zero based)&] +[s4; [*/ Return value]-|physical (pixel) tab width. Note that this function +isn`'t [/ const], because the header control uses a lazy algorithm +to lay out the header control, and during the call to [* GetTabWidth] +it may show that the tabs need to be newly laid out.&] +[s0;3 &] +[s5;K:`:`:HeaderCtrl`:`:SwapTabs`(int`,int`):%- [@(0.0.255) void]_[@0 SwapTabs]([@(0.0.255) i +nt]_[@3 first], [@(0.0.255) int]_[@3 second])&] +[s2; Swaps tabs [%-*@3 first] and [%-*@3 second].&] +[s0; &] +[s5;K:`:`:HeaderCtrl`:`:MoveTab`(int`,int`):%- [@(0.0.255) void]_[@0 MoveTab]([@(0.0.255) i +nt]_[@3 from], [@(0.0.255) int]_[@3 to])&] +[s2; Moves tab to another position.&] +[s0; &] +[s5;K:`:`:HeaderCtrl`:`:GetTabIndex`(int`):%- [@(0.0.255) int]_[@0 GetTabIndex]([@(0.0.255) i +nt]_[@3 i])&] +[s2; Returns `"original`" index of Tab.&] +[s0; &] +[s5;K:`:`:HeaderCtrl`:`:FindIndexTab`(int`):%- [@(0.0.255) int]_[@0 FindIndexTab]([@(0.0.255) i +nt]_[@3 ndx])&] +[s2; Finds a current position of tab with original index [%-*@3 ndx].&] +[s0; &] +[s5;K%- [@(0.0.255) void]_[@0 StartSplitDrag]([@(0.0.255) int]_[@3 s])&] +[s2; Starts the header tab drag `& drop for a given tab break.&] +[s4; [*C@3 s]-|break index (zero `= left side of tab 0).&] +[s0;3 &] +[s5;K%- [@(0.0.255) int]_[@0 GetSplit]([@(0.0.255) int]_[@3 x])&] +[s2; Locates the header tab break corresponding to a given [/ x] coordinate +(relative to the header control). This can be used by the parent +controls to check whether the mouse cursor hovers above a tab +break (e.g. [* ArrayCtrl] uses this function to check whether to +display the horizontal resizing cursor).&] +[s4; [*C@3 x]-|horizontal pixel coordinate (relative to the header control +bounding box).&] +[s4; [*/ Return value]-|Index of tab break (in the range `[0..GetCount()`]) +or `-1 when there is no tab break in the vicinity of a given +point.&] +[s0;3 &] +[s5;K%- [@(0.0.255) int]_[@0 GetScroll]()_[@(0.0.255) const]&] +[s2; [* Absolute] mode only: returns pixel offset defining the current +origin of the (potentially scrolled) header. For non`-scrolling +visual modes, this function always returns 0 (in non`-scrolling +modes the left side of first tab always aligns with the left +side of parent view).&] +[s4; [*/ Return value]-|Number of pixels by which the header control +is currently scrolled in the horizontal direction. The physical +[/ x] coordinate of a tab edge (relative to parent view) can be +calculated by subtracting this value from its logical coordinate +(relative to leftmost header edge).&] +[s0;3 &] +[s5;K%- [@(0.0.255) bool]_[@0 IsScroll]()_[@(0.0.255) const]&] +[s2; Checks whether the header control is currently in scrolling +mode (i.e., whether it is in the [* Absolute] visual mode and its +total tab width exceeds current view size). When [* IsScroll] returns +[* true], the [* GetScroll] method can be used to retrieve the current +horizontal scrollbar position.&] +[s4; [*/ Return value]-|[* true] `= scrolling header, [* false ]`= non`-scrolling +header.&] +[s0;3 &] +[s5;K%- [@(0.0.255) int]_[@0 GetHeight]()_[@(0.0.255) const]&] +[s2; Determines the pixel height of the header control. This is equal +to the maximum of all the individual tab heights (depending on +the tab title font and icon sizes).&] +[s4; [*/ Return value]-|HeaderCtrl pixel height.&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl^ HeaderCtrl]`&_[@0 Invisible]([@(0.0.255) bool]_[@3 inv])&] +[s2; When called with a [* true] argument, makes the header zero height +in frame mode (the tab placement routines still work but the +header itself remains hidden).&] +[s4; [*C@3 inv]-|[* true] `= hide the header, [* false] `= show it.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl^ HeaderCtrl]`&_[@0 Track]([@(0.0.255) bool]_[@3 `_track]_`=_true)&] +[s2; Sets whether the HeaderCtrl and its parent view contents should +be `'animated`' during repositioning the tab breaks using mouse +drag `& drop. When [* `_track] is set to [* true], the header and +its parents repaint is requested every time the mouse moves during +the drag `& drop. When set to [* false], the header and the parent +control get repainted only after the drag `& drop is finished. +It is wise to set this value depending on the complexity of the +data shown `'beneath`' the header (usually in an ArrayCtrl) and +on the expected target hardware because the track mode is much +more demanding with respect to computational time spent during +the necessary multiple repaints.&] +[s4; [*C@3 `_track]-|[* true] `= regenerate header and its parent dynamically +during drag `& drop, [* false] `= only after it`'s finished.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl^ HeaderCtrl]`&_[@0 NoTrack]()&] +[s2; Turns off track mode. This is identical to [* Track(false)].&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl^ HeaderCtrl]`&_[@0 Proportional]()&] +[s2; Switches the HeaderCtrl to the [/ proportional] mode. In proportional +mode, the individual logical tab widths are always recalculated +to physical (pixel) widths by scaling them using a common multiplication +factor in order to fit the whole header into the view width.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl^ HeaderCtrl]`&_[@0 ReduceNext]()&] +[s2; Switches the HeaderCtrl to the [/ reduce next] mode. Every time +a tab width is set in this mode and the total tab width exceeds +the view size, the following tab widths (tabs to the right) are +reduced in left`-to`-right order (beginning with the tab just +after the tab being adjusted) to fit the view size.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl^ HeaderCtrl]`&_[@0 ReduceLast]()&] +[s2; Switches the HeaderCtrl to the [/ reduce last] mode. Every time +a tab width is set in this mode and the total tab width exceeds +the view size, the following tab widths (tabs to the right) are +reduced in right`-to`-left order (beginning with the rightmost +tab) to fit the view size.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl^ HeaderCtrl]`&_[@0 Absolute]()&] +[s2; Switches the HeaderCtrl to the [/ absolute] (scroll) mode. In +this mode the tab widths are never modified automatically, the +logical header width can be smaller or greater than the actual +view size. Whenever the total tab width exceeds the view size, +the header can be scrolled to the left or right to pan its visible +portion within the parent view.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K:`:`:HeaderCtrl`:`:Moving`(bool`):%- [^`:`:HeaderCtrl^ HeaderCtrl]`&_[@0 Moving]([@(0.0.255) b +ool]_[@3 b]_`=_true)&] +[s2; Activates mode when tabs can be rearranged by dragging them. +Default is inactive.&] +[s0;3 &] +[s0;3 &] +[s5;K%- static static_[@(0.0.255) int]_[@0 GetStdHeight]()&] +[s2; Returns the standard header control height (when there are no +icons and the standard font is used in all tabs).&] +[s4; [*/ Return value]-|&] +[s0;3 &] +[s5;K%- [^`:`:Callback^ Callback]_[@0 WhenLayout]&] +[s2; This callback is executed whenever the header control gets laid +out (whenever the tab positions and/or widths change).&] +[s0;3 &] +[s5;K%- [^`:`:Callback^ Callback]_[@0 WhenScroll]&] +[s2; This callback is executed whenever the header control gets scrolled +([/ absolute] mode only).&] +[s0;3 &] +[s5;K%- [^`:`:Callback^ Callback]_[@0 WhenScrollVisibility]&] +[s2; This callback is executes whenever its scrollbar appears or +disappears (whenever the return value of the [* IsScroll] method +changes).&] +[s0; &] +[s0; &] +[s0; [*+117 HeaderCtrl`::Column (nested class)]&] +[s2; &] +[s0;%- [%%/ Derived from][%% ]LabelBase&] +[s0; &] +[s0; The [* HeaderCtrl`::Column] structure represents an individual +header tab. HeaderCtrl methods for tab insertion and editation +typically return a reference to this [/ Column] class which can +be used afterwards to program the various tab properties.&] +[s0; &] +[s0; The set methods return a reference to [* `*this] ; this allows +multiple tab properties to be set using a single C`+`+ statement +with repeated use of the dot operator, e.g.:&] +[s0; &] +[s0; [C -|headerctrl.Add().Min(10).Max(20).Margin(3);]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 Min]([@(0.0.255) int]_[@3 `_min])&] +[s2; Sets minimum tab pixel size. The default value is 0 (the tab +can be shrunk arbitrarily and can disappear altogether at a certain +moment).&] +[s4; [%-*C@3 `_min]-|Minimum tab width in pixels.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 Max]([@(0.0.255) int]_[@3 `_max])&] +[s2; Sets maximum tab pixel size. The default value is [/ INT`_MAX] +(unlimited).&] +[s4; [%-*C@3 `_max]-|Maximum tab width in pixels.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 MinMax]([@(0.0.255) int]_[@3 m], +[@(0.0.255) int]_[@3 n])&] +[s2; Sets both minimum and maximum tab pixel size at the same time. +This has the same effect as [* .Min(m).Max(n)].&] +[s4; [%-*C@3 m]-|Minimum tab width in pixels.&] +[s4; [%-*C@3 n]-|Maximum tab width in pixels.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 Fixed]([@(0.0.255) int]_[@3 f])&] +[s2; Sets both minimum and maximum tab pixel size to the same value, +effectively making the tab width constant. Equal to [* .MinMax(f, +f)].&] +[s4; [%-*C@3 f]-|Fixed tab width in pixels.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 SetRatio]([@(0.0.255) double]_[@3 ratio])&] +[s2; Sets logical (relative) tab width. The logical tab width (together +with logical widths of other tabs and the minimum / maximum width +constraints) is used to calculate the final pixel size of each +tab according to the current header visual mode.&] +[s4; [%-*C@3 ratio]-|relative tab width (a generic floating`-point value)&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:HeaderCtrl`:`:Column^ Column]`&_[@0 SetMargin]([@(0.0.255) int]_[@3 m])&] +[s2; Sets horizontal tab margin size, the number of pixels to deflate +the tab rectangle horizontally to obtain the final `"column data`" +rectangle. In [/ ArrayCtrl], the tab margin areas are used to paint +the grid lines and the inverted selection rectangle outside of +the table cells.&] +[s4; [%-*C@3 m]-|Horizontal tab margin size in pixels.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [@(0.0.255) int]_[@0 GetMargin]()_[@(0.0.255) const]&] +[s2; Returns current tab margin width in pixels.&] +[s4; [*/ Return value]-|[* `*this]&] +[s0;3 &] +[s5;K%- [^`:`:Callback^ Callback]_[@0 WhenAction]&] +[s2; The tab action callback. When set to a non`-null value, the +header control starts to check for mouse clicks within this tab +and calls this callback whenever the corresponding tab is clicked.&] +[s0; &] +[s5;K:`:`:HeaderCtrl`:`:Column`:`:WhenBar:%- [^`:`:Callback1^ Callback1]_[@0 WhenB +ar]&] +[s2; Provides am optional context menu for header tab. &] +[s0; ] \ No newline at end of file diff --git a/uppsrc/Draw/Image.cpp b/uppsrc/Draw/Image.cpp index 6885a0dd2..93e711bf6 100644 --- a/uppsrc/Draw/Image.cpp +++ b/uppsrc/Draw/Image.cpp @@ -1,730 +1,730 @@ -#include "Draw.h" - -NAMESPACE_UPP - -#define LTIMING(x) // RTIMING(x) - -int ImageBuffer::ScanKind() const -{ - bool a255 = false; - bool a0 = false; - const RGBA *s = pixels; - const RGBA *e = s + GetLength(); - while(s < e) { - if(s->a == 0) - a0 = true; - else - if(s->a == 255) - a255 = true; - else - return IMAGE_ALPHA; - s++; - } - return a255 ? a0 ? IMAGE_MASK : IMAGE_OPAQUE : IMAGE_EMPTY; -} - -void ImageBuffer::Create(int cx, int cy) -{ - ASSERT(cx >= 0 && cy >= 0); - size.cx = cx; - size.cy = cy; - pixels.Alloc(GetLength()); -#ifdef _DEBUG - RGBA *s = pixels; - RGBA *e = pixels + GetLength(); - byte a = 0; - while(s < e) { - s->a = a; - a = ~a; - s->r = 255; - s->g = s->b = 0; - s++; - } -#endif - kind = IMAGE_UNKNOWN; - spot2 = hotspot = Point(0, 0); - dots = Size(0, 0); -} - -void ImageBuffer::DeepCopy(const ImageBuffer& img) -{ - Create(img.GetSize()); - SetHotSpot(img.GetHotSpot()); - Set2ndSpot(img.Get2ndSpot()); - SetDots(img.GetDots()); - memcpy(pixels, img.pixels, GetLength() * sizeof(RGBA)); -} - -void ImageBuffer::Set(Image& img) -{ - if(img.data) - if(img.data->refcount == 1) { - size = img.GetSize(); - kind = IMAGE_UNKNOWN; - hotspot = img.GetHotSpot(); - spot2 = img.Get2ndSpot(); - dots = img.GetDots(); - pixels = img.data->buffer.pixels; - img.Clear(); - } - else { - DeepCopy(img.data->buffer); - kind = IMAGE_UNKNOWN; - img.Clear(); - } - else - Create(0, 0); -} - - -void ImageBuffer::operator=(Image& img) -{ - Clear(); - Set(img); -} - -void ImageBuffer::operator=(ImageBuffer& img) -{ - Clear(); - Image m = img; - Set(m); -} - -ImageBuffer::ImageBuffer(Image& img) -{ - Set(img); -} - -ImageBuffer::ImageBuffer(ImageBuffer& b) -{ - kind = b.kind; - size = b.size; - dots = b.dots; - pixels = b.pixels; - hotspot = b.hotspot; - spot2 = b.spot2; -} - -void (Image::Data::*Image::Data::sSysInit)(); -void (Image::Data::*Image::Data::sSysRelease)(); -int (Image::Data::*Image::Data::sGetResCount)() const; -void (Image::Data::*Image::Data::sPaint)(SystemDraw& w, int x, int y, const Rect& src, Color c); - -void Image::Data::InitSystemImage( - void (Image::Data::*fSysInit)(), - void (Image::Data::*fSysRelease)(), - int (Image::Data::*fGetResCount)() const, - void (Image::Data::*fPaint)(SystemDraw& w, int x, int y, const Rect& src, Color c) -) -{ - Image::Data::sSysInit = fSysInit; - Image::Data::sSysRelease = fSysRelease; - Image::Data::sGetResCount = fGetResCount; - Image::Data::sPaint = fPaint; -} - -void Image::Data::SysInit() -{ - if(sSysInit) - (this->*sSysInit)(); -} - -void Image::Data::SysRelease() -{ - if(sSysRelease) - (this->*sSysRelease)(); -} - -int Image::Data::GetResCount() const -{ - if(sGetResCount) - return (this->*sGetResCount)(); - return 0; -} - -void Image::Data::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) -{ - if(sPaint) - (this->*sPaint)(w, x, y, src, c); -} - -void Image::Set(ImageBuffer& b) -{ - if(b.GetWidth() == 0 || b.GetHeight() == 0) - data = NULL; - else - data = new Data(b); -} - -void Image::Clear() -{ - if(data) - data->Release(); - data = NULL; -} - -Image& Image::operator=(ImageBuffer& img) -{ - if(data) - data->Release(); - Set(img); - return *this; -} - -Image& Image::operator=(const Image& img) -{ - Data *d = data; - data = img.data; - if(data) - data->Retain(); - if(d) - d->Release(); - return *this; -} - -const RGBA* Image::operator~() const -{ - return data ? ~data->buffer : NULL; -} - -Image::operator const RGBA*() const -{ - return data ? ~data->buffer : NULL; -} - -const RGBA* Image::operator[](int i) const -{ - ASSERT(data); - return data->buffer[i]; -} - -Size Image::GetSize() const -{ - return data ? data->buffer.GetSize() : Size(0, 0); -} - -int Image::GetLength() const -{ - return data ? data->buffer.GetLength() : 0; -} - -Point Image::GetHotSpot() const -{ - return data ? data->buffer.GetHotSpot() : Point(0, 0); -} - -Point Image::Get2ndSpot() const -{ - return data ? data->buffer.Get2ndSpot() : Point(0, 0); -} - -Size Image::GetDots() const -{ - return data ? data->buffer.GetDots() : Size(0, 0); -} - -int Image::GetKindNoScan() const -{ - return data ? data->buffer.GetKind() : IMAGE_EMPTY; -} - -int Image::Data::GetKind() -{ - int k = buffer.GetKind(); - if(k != IMAGE_UNKNOWN) - return k; - k = buffer.ScanKind(); - buffer.SetKind(k); - return k; -} - -int Image::GetKind() const -{ - return data ? data->GetKind() : IMAGE_EMPTY; -} - -void Image::PaintImage(SystemDraw& w, int x, int y, const Rect& src, Color c) const -{ - if(data) - data->Paint(w, x, y, src, c); -} - -void Image::Serialize(Stream& s) -{ - int version = 0; - s / version; - Size sz = GetSize(); - Point p = GetHotSpot(); - Size dots = GetDots(); - s % sz % p % dots; - int len = sz.cx * sz.cy; - if(s.IsLoading()) - if(len) { - ImageBuffer b(sz); - if(!s.GetAll(~b, len * sizeof(RGBA))) - s.SetError(); - b.SetDots(dots); - b.SetHotSpot(p); - *this = b; - } - else - Clear(); - else - s.Put(~*this, len * sizeof(RGBA)); -} - -INITBLOCK { - RichValue::Register(); -} - -bool Image::operator==(const Image& img) const -{ - if(GetLength() != img.GetLength()) - return false; - return memcmp(~*this, ~img, GetLength() * sizeof(RGBA)) == 0; -} - -bool Image::operator!=(const Image& img) const -{ - return !operator==(img); -} - -dword Image::GetHashValue() const -{ - return memhash(~*this, GetLength() * sizeof(RGBA)); -} - -Image::Image(const Image& img) -{ - data = img.data; - if(data) - data->Retain(); -} - -Image::Image(Image (*fn)()) -{ - data = NULL; - *this = (*fn)(); -} - -Image::Image(const Value& src) -{ - data = NULL; - if(!IsNull(src)) - *this = RawValue::Extract(src); -} - -Image::Image(ImageBuffer& b) -{ - Set(b); -} - -Image::~Image() -{ - if(data) - data->Release(); -} - -Image::Image(const Init& init) -{ - ASSERT(init.info[0] >= 1); - Size sz; - sz.cx = Peek32le(init.info + 1); - sz.cy = Peek32le(init.info + 5); - ImageBuffer b(sz); - int i = 0; - while(i < init.scan_count) { - UnpackRLE(b[i], (const byte *)init.scans[i], sz.cx); - i++; - } - while(i < sz.cy) - memset(b[i++], 0, sizeof(RGBA) * sz.cx); - b.SetHotSpot(Point(Peek32le(init.info + 9), Peek32le(init.info + 13))); - Set(b); -} - -String Image::ToString() const -{ - return String("Image ").Cat() << GetSize(); -} - -Link Image::Data::ResData[1]; -int Image::Data::ResCount; - -Image::Data::Data(ImageBuffer& b) -: buffer(b) -{ - paintcount = 0; - paintonly = false; - refcount = 1; - INTERLOCKED { - static int64 gserial; - serial = ++gserial; - } - SysInit(); -} - -Image::Data::~Data() -{ - DrawLock __; - SysRelease(); - Unlink(); -} - -void Image::Data::PaintOnlyShrink() -{ - if(paintonly) { - LTIMING("PaintOnlyShrink"); - DrawLock __; - DropPixels___(buffer); - ResCount -= GetResCount(); - Unlink(); - } -} - -static void sMultiply(ImageBuffer& b, int (*op)(RGBA *t, const RGBA *s, int len)) -{ - if(b.GetKind() != IMAGE_OPAQUE && b.GetKind() != IMAGE_EMPTY) - (*op)(~b, ~b, b.GetLength()); -} - -void Premultiply(ImageBuffer& b) -{ - sMultiply(b, Premultiply); -} - -void Unmultiply(ImageBuffer& b) -{ - sMultiply(b, Unmultiply); -} - -static Image sMultiply(const Image& img, int (*op)(RGBA *t, const RGBA *s, int len)) -{ - int k = img.GetKind(); - if(k == IMAGE_OPAQUE || k == IMAGE_EMPTY) - return img; - ImageBuffer ib(img.GetSize()); - ib.SetHotSpot(img.GetHotSpot()); - ib.Set2ndSpot(img.Get2ndSpot()); - ib.SetKind(Premultiply(~ib, ~img, ib.GetLength())); - return ib; -} - -Image Premultiply(const Image& img) -{ - return sMultiply(img, Premultiply); -} - -Image Unmultiply(const Image& img) -{ - return sMultiply(img, Unmultiply); -} - -void SetPaintOnly___(Image& m) -{ - if(m.data && m.data->refcount == 1) - m.data->paintonly = true; -} - -void Iml::Init(int n) -{ - for(int i = 0; i < n; i++) - map.Add(name[i]); -} - -void Iml::Reset() -{ - int n = map.GetCount(); - map.Clear(); - Init(n); -} - -void Iml::Set(int i, const Image& img) -{ - map[i].image = img; - map[i].loaded = true; -} - -static StaticCriticalSection sImgImlLock; - -Image Iml::Get(int i) -{ - IImage& m = map[i]; - if(!m.loaded) { - INTERLOCKED_(sImgImlLock) { - if(data.GetCount()) { - int ii = 0; - for(;;) { - const Data& d = data[ii]; - if(i < d.count) { - static const char *cached_data; - static Vector cached; - if(cached_data != d.data) { - cached_data = d.data; - cached = UnpackImlData(String(d.data, d.len)); - if(premultiply) - for(int i = 0; i < cached.GetCount(); i++) - cached[i] = Premultiply(cached[i]); - } - m.image = cached[i]; - break; - } - i -= d.count; - ii++; - } - } - else - m.image = Premultiply(Image(img_init[i])); - } - m.loaded = true; - } - return m.image; -} - -#ifdef _DEBUG -int Iml::GetBinSize() const -{ - int size = 0; - for(int i = 0; i < map.GetCount(); i++) { - const Image::Init& init = img_init[i]; - size += (int)strlen(name[i]) + 1 + 24; - for(int q = 0; q < init.scan_count; q++) - size += (int)strlen(init.scans[q]); - } - return size; -} -#endif - -Iml::Iml(const Image::Init *img_init, const char **name, int n) -: img_init(img_init), - name(name) -{ -#ifdef flagCHECKINIT - RLOG("Constructing iml " << *name); -#endif - premultiply = true; - Init(n); -} - -void Iml::AddData(const byte *_data, int len, int count) -{ - Data& d = data.Add(); - d.data = (const char *)_data; - d.len = len; - d.count = count; - data.Shrink(); -} - -static StaticCriticalSection sImgMapLock; - -static VectorMap& sImgMap() -{ - static VectorMap x; - return x; -} - -void Register(const char *imageclass, Iml& list) -{ -#ifdef flagCHECKINIT - RLOG("Registering iml " << imageclass); -#endif - INTERLOCKED_(sImgMapLock) - sImgMap().GetAdd(imageclass) = &list; -} - -int GetImlCount() -{ - int q; - INTERLOCKED_(sImgMapLock) - q = sImgMap().GetCount(); - return q; -} - -Iml& GetIml(int i) -{ - return *sImgMap()[i]; -} - -void Iml::Enter() -{ - sImgMapLock.Enter(); -} - -void Iml::Leave() -{ - sImgMapLock.Leave(); -} - -String GetImlName(int i) -{ - String x; - INTERLOCKED_(sImgMapLock) - x = sImgMap().GetKey(i); - return x; -} - -int FindIml(const char *name) -{ - int q; - INTERLOCKED_(sImgMapLock) - q = sImgMap().Find(name); - return q; -} - -Image GetImlImage(const char *name) -{ - Image m; - const char *w = strchr(name, ':'); - if(w) { - int q = FindIml(String(name, w)); - if(q >= 0) { - INTERLOCKED_(sImgMapLock) { - Iml& iml = *sImgMap()[q]; - while(*w == ':') - w++; - q = iml.Find(w); - if(q >= 0) - m = iml.Get(q); - } - } - } - return m; -} - -void SetImlImage(const char *name, const Image& m) -{ - const char *w = strchr(name, ':'); - if(w) { - int q = FindIml(String(name, w)); - if(q >= 0) { - INTERLOCKED_(sImgMapLock) { - Iml& iml = *sImgMap()[q]; - while(*w == ':') - w++; - q = iml.Find(w); - if(q >= 0) - iml.Set(q, m); - } - } - } -} - -String StoreImageAsString(const Image& img) -{ - if(img.GetKind() == IMAGE_EMPTY) - return Null; - int type = img.GetKind() == IMAGE_OPAQUE ? 3 : 4; - StringStream ss; - ss.Put(type); - Size sz = img.GetSize(); - ss.Put16le(sz.cx); - ss.Put16le(sz.cy); - Point p = img.GetHotSpot(); - ss.Put16le(p.x); - ss.Put16le(p.y); - Size dots = img.GetDots(); - ss.Put16le(dots.cx); - ss.Put16le(dots.cy); - const RGBA *s = img; - const RGBA *e = s + img.GetLength(); - Buffer b(type * img.GetLength()); - byte *t = b; - if(type == 3) - while(s < e) { - *t++ = s->r; - *t++ = s->g; - *t++ = s->b; - s++; - } - else - while(s < e) { - *t++ = s->r; - *t++ = s->g; - *t++ = s->b; - *t++ = s->a; - s++; - } - MemReadStream m(b, type * img.GetLength()); - ZCompress(ss, m); - return ss; -} - -Image LoadImageFromString(const String& src) -{ - if(src.GetLength() < 13) - return Null; - StringStream ss(src); - int type = ss.Get(); - Size sz; - sz.cx = ss.Get16le(); - sz.cy = ss.Get16le(); - if(sz.cx < 0 || sz.cy < 0) - return Null; - Point p; - p.x = ss.Get16le(); - p.y = ss.Get16le(); - if(p.x < 0 || p.y < 0) - return Null; - Size dots; - dots.cx = ss.Get16le(); - dots.cy = ss.Get16le(); - if(dots.cx < 0 || dots.cy < 0) - return Null; - StringStream out; - ZDecompress(out, ss); - String data = out; - if(data.GetLength() != type * sz.cx * sz.cy) - return Image(); - ImageBuffer ib(sz); - ib.SetHotSpot(p); - ib.SetDots(dots); - RGBA *t = ib; - const RGBA *e = t + ib.GetLength(); - const byte *s = data; - if(type == 3) - while(t < e) { - t->r = *s++; - t->g = *s++; - t->b = *s++; - t->a = 255; - t++; - } - else - if(type == 4) - while(t < e) { - t->r = *s++; - t->g = *s++; - t->b = *s++; - t->a = *s++; - t++; - } - else - return Image(); - return ib; -} - -Size GetImageStringSize(const String& src) -{ - if(src.GetLength() < 13) - return Size(0, 0); - StringStream ss(src); - ss.Get(); - Size sz; - sz.cx = ss.Get16le(); - sz.cy = ss.Get16le(); - return sz; -} - -Size GetImageStringDots(const String& src) -{ - if(src.GetLength() < 13) - return Size(0, 0); - StringStream ss(src); - ss.SeekCur(9); - Size sz; - sz.cx = ss.Get16le(); - sz.cy = ss.Get16le(); - return sz; -} - -END_UPP_NAMESPACE +#include "Draw.h" + +NAMESPACE_UPP + +#define LTIMING(x) // RTIMING(x) + +int ImageBuffer::ScanKind() const +{ + bool a255 = false; + bool a0 = false; + const RGBA *s = pixels; + const RGBA *e = s + GetLength(); + while(s < e) { + if(s->a == 0) + a0 = true; + else + if(s->a == 255) + a255 = true; + else + return IMAGE_ALPHA; + s++; + } + return a255 ? a0 ? IMAGE_MASK : IMAGE_OPAQUE : IMAGE_EMPTY; +} + +void ImageBuffer::Create(int cx, int cy) +{ + ASSERT(cx >= 0 && cy >= 0); + size.cx = cx; + size.cy = cy; + pixels.Alloc(GetLength()); +#ifdef _DEBUG + RGBA *s = pixels; + RGBA *e = pixels + GetLength(); + byte a = 0; + while(s < e) { + s->a = a; + a = ~a; + s->r = 255; + s->g = s->b = 0; + s++; + } +#endif + kind = IMAGE_UNKNOWN; + spot2 = hotspot = Point(0, 0); + dots = Size(0, 0); +} + +void ImageBuffer::DeepCopy(const ImageBuffer& img) +{ + Create(img.GetSize()); + SetHotSpot(img.GetHotSpot()); + Set2ndSpot(img.Get2ndSpot()); + SetDots(img.GetDots()); + memcpy(pixels, img.pixels, GetLength() * sizeof(RGBA)); +} + +void ImageBuffer::Set(Image& img) +{ + if(img.data) + if(img.data->refcount == 1) { + size = img.GetSize(); + kind = IMAGE_UNKNOWN; + hotspot = img.GetHotSpot(); + spot2 = img.Get2ndSpot(); + dots = img.GetDots(); + pixels = img.data->buffer.pixels; + img.Clear(); + } + else { + DeepCopy(img.data->buffer); + kind = IMAGE_UNKNOWN; + img.Clear(); + } + else + Create(0, 0); +} + + +void ImageBuffer::operator=(Image& img) +{ + Clear(); + Set(img); +} + +void ImageBuffer::operator=(ImageBuffer& img) +{ + Clear(); + Image m = img; + Set(m); +} + +ImageBuffer::ImageBuffer(Image& img) +{ + Set(img); +} + +ImageBuffer::ImageBuffer(ImageBuffer& b) +{ + kind = b.kind; + size = b.size; + dots = b.dots; + pixels = b.pixels; + hotspot = b.hotspot; + spot2 = b.spot2; +} + +void (Image::Data::*Image::Data::sSysInit)(); +void (Image::Data::*Image::Data::sSysRelease)(); +int (Image::Data::*Image::Data::sGetResCount)() const; +void (Image::Data::*Image::Data::sPaint)(SystemDraw& w, int x, int y, const Rect& src, Color c); + +void Image::Data::InitSystemImage( + void (Image::Data::*fSysInit)(), + void (Image::Data::*fSysRelease)(), + int (Image::Data::*fGetResCount)() const, + void (Image::Data::*fPaint)(SystemDraw& w, int x, int y, const Rect& src, Color c) +) +{ + Image::Data::sSysInit = fSysInit; + Image::Data::sSysRelease = fSysRelease; + Image::Data::sGetResCount = fGetResCount; + Image::Data::sPaint = fPaint; +} + +void Image::Data::SysInit() +{ + if(sSysInit) + (this->*sSysInit)(); +} + +void Image::Data::SysRelease() +{ + if(sSysRelease) + (this->*sSysRelease)(); +} + +int Image::Data::GetResCount() const +{ + if(sGetResCount) + return (this->*sGetResCount)(); + return 0; +} + +void Image::Data::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) +{ + if(sPaint) + (this->*sPaint)(w, x, y, src, c); +} + +void Image::Set(ImageBuffer& b) +{ + if(b.GetWidth() == 0 || b.GetHeight() == 0) + data = NULL; + else + data = new Data(b); +} + +void Image::Clear() +{ + if(data) + data->Release(); + data = NULL; +} + +Image& Image::operator=(ImageBuffer& img) +{ + if(data) + data->Release(); + Set(img); + return *this; +} + +Image& Image::operator=(const Image& img) +{ + Data *d = data; + data = img.data; + if(data) + data->Retain(); + if(d) + d->Release(); + return *this; +} + +const RGBA* Image::operator~() const +{ + return data ? ~data->buffer : NULL; +} + +Image::operator const RGBA*() const +{ + return data ? ~data->buffer : NULL; +} + +const RGBA* Image::operator[](int i) const +{ + ASSERT(data); + return data->buffer[i]; +} + +Size Image::GetSize() const +{ + return data ? data->buffer.GetSize() : Size(0, 0); +} + +int Image::GetLength() const +{ + return data ? data->buffer.GetLength() : 0; +} + +Point Image::GetHotSpot() const +{ + return data ? data->buffer.GetHotSpot() : Point(0, 0); +} + +Point Image::Get2ndSpot() const +{ + return data ? data->buffer.Get2ndSpot() : Point(0, 0); +} + +Size Image::GetDots() const +{ + return data ? data->buffer.GetDots() : Size(0, 0); +} + +int Image::GetKindNoScan() const +{ + return data ? data->buffer.GetKind() : IMAGE_EMPTY; +} + +int Image::Data::GetKind() +{ + int k = buffer.GetKind(); + if(k != IMAGE_UNKNOWN) + return k; + k = buffer.ScanKind(); + buffer.SetKind(k); + return k; +} + +int Image::GetKind() const +{ + return data ? data->GetKind() : IMAGE_EMPTY; +} + +void Image::PaintImage(SystemDraw& w, int x, int y, const Rect& src, Color c) const +{ + if(data) + data->Paint(w, x, y, src, c); +} + +void Image::Serialize(Stream& s) +{ + int version = 0; + s / version; + Size sz = GetSize(); + Point p = GetHotSpot(); + Size dots = GetDots(); + s % sz % p % dots; + int len = sz.cx * sz.cy; + if(s.IsLoading()) + if(len) { + ImageBuffer b(sz); + if(!s.GetAll(~b, len * sizeof(RGBA))) + s.SetError(); + b.SetDots(dots); + b.SetHotSpot(p); + *this = b; + } + else + Clear(); + else + s.Put(~*this, len * sizeof(RGBA)); +} + +INITBLOCK { + RichValue::Register(); +} + +bool Image::operator==(const Image& img) const +{ + if(GetLength() != img.GetLength()) + return false; + return memcmp(~*this, ~img, GetLength() * sizeof(RGBA)) == 0; +} + +bool Image::operator!=(const Image& img) const +{ + return !operator==(img); +} + +dword Image::GetHashValue() const +{ + return memhash(~*this, GetLength() * sizeof(RGBA)); +} + +Image::Image(const Image& img) +{ + data = img.data; + if(data) + data->Retain(); +} + +Image::Image(Image (*fn)()) +{ + data = NULL; + *this = (*fn)(); +} + +Image::Image(const Value& src) +{ + data = NULL; + if(!IsNull(src)) + *this = RawValue::Extract(src); +} + +Image::Image(ImageBuffer& b) +{ + Set(b); +} + +Image::~Image() +{ + if(data) + data->Release(); +} + +Image::Image(const Init& init) +{ + ASSERT(init.info[0] >= 1); + Size sz; + sz.cx = Peek32le(init.info + 1); + sz.cy = Peek32le(init.info + 5); + ImageBuffer b(sz); + int i = 0; + while(i < init.scan_count) { + UnpackRLE(b[i], (const byte *)init.scans[i], sz.cx); + i++; + } + while(i < sz.cy) + memset(b[i++], 0, sizeof(RGBA) * sz.cx); + b.SetHotSpot(Point(Peek32le(init.info + 9), Peek32le(init.info + 13))); + Set(b); +} + +String Image::ToString() const +{ + return String("Image ").Cat() << GetSize(); +} + +Link Image::Data::ResData[1]; +int Image::Data::ResCount; + +Image::Data::Data(ImageBuffer& b) +: buffer(b) +{ + paintcount = 0; + paintonly = false; + refcount = 1; + INTERLOCKED { + static int64 gserial; + serial = ++gserial; + } + SysInit(); +} + +Image::Data::~Data() +{ + DrawLock __; + SysRelease(); + Unlink(); +} + +void Image::Data::PaintOnlyShrink() +{ + if(paintonly) { + LTIMING("PaintOnlyShrink"); + DrawLock __; + DropPixels___(buffer); + ResCount -= GetResCount(); + Unlink(); + } +} + +static void sMultiply(ImageBuffer& b, int (*op)(RGBA *t, const RGBA *s, int len)) +{ + if(b.GetKind() != IMAGE_OPAQUE && b.GetKind() != IMAGE_EMPTY) + (*op)(~b, ~b, b.GetLength()); +} + +void Premultiply(ImageBuffer& b) +{ + sMultiply(b, Premultiply); +} + +void Unmultiply(ImageBuffer& b) +{ + sMultiply(b, Unmultiply); +} + +static Image sMultiply(const Image& img, int (*op)(RGBA *t, const RGBA *s, int len)) +{ + int k = img.GetKind(); + if(k == IMAGE_OPAQUE || k == IMAGE_EMPTY) + return img; + ImageBuffer ib(img.GetSize()); + ib.SetHotSpot(img.GetHotSpot()); + ib.Set2ndSpot(img.Get2ndSpot()); + ib.SetKind(Premultiply(~ib, ~img, ib.GetLength())); + return ib; +} + +Image Premultiply(const Image& img) +{ + return sMultiply(img, Premultiply); +} + +Image Unmultiply(const Image& img) +{ + return sMultiply(img, Unmultiply); +} + +void SetPaintOnly___(Image& m) +{ + if(m.data && m.data->refcount == 1) + m.data->paintonly = true; +} + +void Iml::Init(int n) +{ + for(int i = 0; i < n; i++) + map.Add(name[i]); +} + +void Iml::Reset() +{ + int n = map.GetCount(); + map.Clear(); + Init(n); +} + +void Iml::Set(int i, const Image& img) +{ + map[i].image = img; + map[i].loaded = true; +} + +static StaticCriticalSection sImgImlLock; + +Image Iml::Get(int i) +{ + IImage& m = map[i]; + if(!m.loaded) { + INTERLOCKED_(sImgImlLock) { + if(data.GetCount()) { + int ii = 0; + for(;;) { + const Data& d = data[ii]; + if(i < d.count) { + static const char *cached_data; + static Vector cached; + if(cached_data != d.data) { + cached_data = d.data; + cached = UnpackImlData(String(d.data, d.len)); + if(premultiply) + for(int i = 0; i < cached.GetCount(); i++) + cached[i] = Premultiply(cached[i]); + } + m.image = cached[i]; + break; + } + i -= d.count; + ii++; + } + } + else + m.image = Premultiply(Image(img_init[i])); + } + m.loaded = true; + } + return m.image; +} + +#ifdef _DEBUG +int Iml::GetBinSize() const +{ + int size = 0; + for(int i = 0; i < map.GetCount(); i++) { + const Image::Init& init = img_init[i]; + size += (int)strlen(name[i]) + 1 + 24; + for(int q = 0; q < init.scan_count; q++) + size += (int)strlen(init.scans[q]); + } + return size; +} +#endif + +Iml::Iml(const Image::Init *img_init, const char **name, int n) +: img_init(img_init), + name(name) +{ +#ifdef flagCHECKINIT + RLOG("Constructing iml " << *name); +#endif + premultiply = true; + Init(n); +} + +void Iml::AddData(const byte *_data, int len, int count) +{ + Data& d = data.Add(); + d.data = (const char *)_data; + d.len = len; + d.count = count; + data.Shrink(); +} + +static StaticCriticalSection sImgMapLock; + +static VectorMap& sImgMap() +{ + static VectorMap x; + return x; +} + +void Register(const char *imageclass, Iml& list) +{ +#ifdef flagCHECKINIT + RLOG("Registering iml " << imageclass); +#endif + INTERLOCKED_(sImgMapLock) + sImgMap().GetAdd(imageclass) = &list; +} + +int GetImlCount() +{ + int q; + INTERLOCKED_(sImgMapLock) + q = sImgMap().GetCount(); + return q; +} + +Iml& GetIml(int i) +{ + return *sImgMap()[i]; +} + +void Iml::Enter() +{ + sImgMapLock.Enter(); +} + +void Iml::Leave() +{ + sImgMapLock.Leave(); +} + +String GetImlName(int i) +{ + String x; + INTERLOCKED_(sImgMapLock) + x = sImgMap().GetKey(i); + return x; +} + +int FindIml(const char *name) +{ + int q; + INTERLOCKED_(sImgMapLock) + q = sImgMap().Find(name); + return q; +} + +Image GetImlImage(const char *name) +{ + Image m; + const char *w = strchr(name, ':'); + if(w) { + int q = FindIml(String(name, w)); + if(q >= 0) { + INTERLOCKED_(sImgMapLock) { + Iml& iml = *sImgMap()[q]; + while(*w == ':') + w++; + q = iml.Find(w); + if(q >= 0) + m = iml.Get(q); + } + } + } + return m; +} + +void SetImlImage(const char *name, const Image& m) +{ + const char *w = strchr(name, ':'); + if(w) { + int q = FindIml(String(name, w)); + if(q >= 0) { + INTERLOCKED_(sImgMapLock) { + Iml& iml = *sImgMap()[q]; + while(*w == ':') + w++; + q = iml.Find(w); + if(q >= 0) + iml.Set(q, m); + } + } + } +} + +String StoreImageAsString(const Image& img) +{ + if(img.GetKind() == IMAGE_EMPTY) + return Null; + int type = img.GetKind() == IMAGE_OPAQUE ? 3 : 4; + StringStream ss; + ss.Put(type); + Size sz = img.GetSize(); + ss.Put16le(sz.cx); + ss.Put16le(sz.cy); + Point p = img.GetHotSpot(); + ss.Put16le(p.x); + ss.Put16le(p.y); + Size dots = img.GetDots(); + ss.Put16le(dots.cx); + ss.Put16le(dots.cy); + const RGBA *s = img; + const RGBA *e = s + img.GetLength(); + Buffer b(type * img.GetLength()); + byte *t = b; + if(type == 3) + while(s < e) { + *t++ = s->r; + *t++ = s->g; + *t++ = s->b; + s++; + } + else + while(s < e) { + *t++ = s->r; + *t++ = s->g; + *t++ = s->b; + *t++ = s->a; + s++; + } + MemReadStream m(b, type * img.GetLength()); + ZCompress(ss, m); + return ss; +} + +Image LoadImageFromString(const String& src) +{ + if(src.GetLength() < 13) + return Null; + StringStream ss(src); + int type = ss.Get(); + Size sz; + sz.cx = ss.Get16le(); + sz.cy = ss.Get16le(); + if(sz.cx < 0 || sz.cy < 0) + return Null; + Point p; + p.x = ss.Get16le(); + p.y = ss.Get16le(); + if(p.x < 0 || p.y < 0) + return Null; + Size dots; + dots.cx = ss.Get16le(); + dots.cy = ss.Get16le(); + if(dots.cx < 0 || dots.cy < 0) + return Null; + StringStream out; + ZDecompress(out, ss); + String data = out; + if(data.GetLength() != type * sz.cx * sz.cy) + return Image(); + ImageBuffer ib(sz); + ib.SetHotSpot(p); + ib.SetDots(dots); + RGBA *t = ib; + const RGBA *e = t + ib.GetLength(); + const byte *s = data; + if(type == 3) + while(t < e) { + t->r = *s++; + t->g = *s++; + t->b = *s++; + t->a = 255; + t++; + } + else + if(type == 4) + while(t < e) { + t->r = *s++; + t->g = *s++; + t->b = *s++; + t->a = *s++; + t++; + } + else + return Image(); + return ib; +} + +Size GetImageStringSize(const String& src) +{ + if(src.GetLength() < 13) + return Size(0, 0); + StringStream ss(src); + ss.Get(); + Size sz; + sz.cx = ss.Get16le(); + sz.cy = ss.Get16le(); + return sz; +} + +Size GetImageStringDots(const String& src) +{ + if(src.GetLength() < 13) + return Size(0, 0); + StringStream ss(src); + ss.SeekCur(9); + Size sz; + sz.cx = ss.Get16le(); + sz.cy = ss.Get16le(); + return sz; +} + +END_UPP_NAMESPACE diff --git a/uppsrc/RichText/Object.cpp b/uppsrc/RichText/Object.cpp index 1b235e2f0..ef07c2d8d 100644 --- a/uppsrc/RichText/Object.cpp +++ b/uppsrc/RichText/Object.cpp @@ -1,5 +1,7 @@ #include "RichText.h" +#define LLOG(x) DLOG(x) + NAMESPACE_UPP RichObjectType::RichObjectType() {} diff --git a/uppsrc/RichText/ParaData.cpp b/uppsrc/RichText/ParaData.cpp index 7215eb00c..b64076f61 100644 --- a/uppsrc/RichText/ParaData.cpp +++ b/uppsrc/RichText/ParaData.cpp @@ -500,8 +500,13 @@ void RichPara::UnpackParts(Stream& in, const RichPara::CharFormat& chrstyle, part.Top().format = format; in.Get(); } - else - part.Top().text.Cat(in.GetUtf8()); + else { + WStringBuffer wb(part.Top().text); + wb.Reserve(512); + while(in.Term() >= 32 || in.Term() == 9) + wb.Cat(in.GetUtf8()); + part.Top().text = wb; + } if(part.Top().text.GetLength() == 0 && part.Top().IsText()) part.Drop(); } diff --git a/uppsrc/RichText/RichImage.icpp b/uppsrc/RichText/RichImage.icpp index 9b4738bcc..6a12383a7 100644 --- a/uppsrc/RichText/RichImage.icpp +++ b/uppsrc/RichText/RichImage.icpp @@ -42,7 +42,7 @@ void InitRichImage(String (*fGetImageClip)(const Image& img, const String& bool RichImage::Accept(PasteClip& clip) { - return sAcceptImage? sAcceptImage(clip) : false; + return sAcceptImage ? sAcceptImage(clip) : false; } Value RichImage::Read(PasteClip& clip) diff --git a/uppsrc/RichText/RichText.h b/uppsrc/RichText/RichText.h index 8c0f1ae26..6e68d2051 100644 --- a/uppsrc/RichText/RichText.h +++ b/uppsrc/RichText/RichText.h @@ -107,7 +107,7 @@ struct PageDraw { class RichObject; class Bar; -struct RichObjectType : Moveable { +struct RichObjectType { virtual String GetTypeName(const Value& v) const = 0; virtual String GetCreateName() const; virtual Value Read(const String& s) const; diff --git a/uppsrc/ide/Browser/CodeBrowser.cpp b/uppsrc/ide/Browser/CodeBrowser.cpp index f47c21748..0f8042d1e 100644 --- a/uppsrc/ide/Browser/CodeBrowser.cpp +++ b/uppsrc/ide/Browser/CodeBrowser.cpp @@ -148,8 +148,10 @@ int ItemCompareLexical(const Value& v1, const Value& v2) return SgnCompare(a.qitem, b.qitem); } -void GatherMethods(const String& type, VectorMap& inherited, bool g) +void GatherMethods(const String& type, VectorMap& inherited, bool g, Index& done) { + if(done.Find(type) >= 0) return; + done.Add(type); int q = CodeBase().Find(type); if(q < 0) return; const Array& n = CodeBase()[q]; @@ -158,7 +160,7 @@ void GatherMethods(const String& type, VectorMap& inherited, bool if(m.IsType()) { Vector base = Split(m.qptype, ';'); for(int i = 0; i < base.GetCount(); i++) - GatherMethods(base[i], inherited, true); + GatherMethods(base[i], inherited, true, done); } if(m.IsCode() && g) { bool& virt = inherited.GetAdd(m.qitem); @@ -167,6 +169,12 @@ void GatherMethods(const String& type, VectorMap& inherited, bool } } +void GatherMethods(const String& type, VectorMap& inherited, bool g) +{ + Index done; + GatherMethods(type, inherited, g, done); +} + void CodeBrowser::LoadScope() { String find = ToUpper((String)~search);