--- /dev/null
+{
+ "Version" : 0.2,
+ "ModuleName" : "SlideTest",
+ "Options" : {
+ "Warnings" : "All",
+ "PreprocessorDefinitions" : [
+ "IMPORT_STATIC=\"\""
+ ],
+ "TargetType" : "Executable",
+ "TargetFileName" : "SlideTest",
+ "Libraries" : [
+ "ecere"
+ ]
+ },
+ "Configurations" : [
+ {
+ "Name" : "Debug",
+ "Options" : {
+ "Debug" : true,
+ "Optimization" : "None",
+ "PreprocessorDefinitions" : [
+ "_DEBUG"
+ ],
+ "Console" : true,
+ "FastMath" : false
+ }
+ },
+ {
+ "Name" : "Release",
+ "Options" : {
+ "Debug" : false,
+ "Optimization" : "Speed",
+ "FastMath" : true
+ }
+ }
+ ],
+ "Files" : [
+ {
+ "Folder" : "autoLayout",
+ "Files" : [
+ "autoLayout.ec",
+ "wrapText.ec"
+ ]
+ },
+ {
+ "Folder" : "graphics",
+ "Files" : [
+ "bg1.png"
+ ]
+ },
+ {
+ "Folder" : "slides",
+ "Files" : [
+ "slide1.ec",
+ "./base.ec",
+ "titleSlide.ec",
+ "languageSlide.ec",
+ "classesSlide.ec",
+ "instancesSlide.ec",
+ "formSlide.ec",
+ "buttonSlide.ec",
+ "gnosisSlide.ec"
+ ]
+ },
+ "slides.ec"
+ ],
+ "ResourcesPath" : "",
+ "Resources" : [
+
+ ]
+}
--- /dev/null
+import "ecere"
+import "wrapText"
+
+// Add 'unset' ?
+enum UnitType { percent, pixels, points };
+
+struct Dimension
+{
+ UnitType type;
+ union { double d; int i; };
+ property double { set { d = value; type = percent; } get { return 0; } /* TODO: Compute this? Avoid use? */ }
+ property int { set { i = value; type = pixels; } get { return 0; } /* TODO: Compute this? Avoid use? */ }
+ int getPixels(int p) { return (type == pixels) ? i : (int)(d * p + 0.5); }
+};
+
+struct DimensionBox { Dimension left, top, right, bottom; };
+
+struct Dimensions { Dimension w, h; };
+
+enum Direction { horizontal, vertical };
+
+enum HVAlignment : Alignment { bottom = right, top = left };
+enum SelfAlignment : HVAlignment { inherit };
+
+FontResource defaultFont { "Tahoma", 8.25f };
+
+class Element
+{
+private:
+ List<Element> nodes;
+ DimensionBox margin;
+ DimensionBox border;
+ DimensionBox padding;
+ Size contentSize; // Computed from the content (Max of Text/Primitives extent and Children minimum extent)
+ Element parent;
+
+ Dimensions minSize, maxSize; // Size specification
+ Size clientSize;
+ BorderStyle borderStyle;
+ Point scroll;
+ bool hScroll, vScroll;
+ const String caption;
+ ColorAlpha bgColor;
+ ColorAlpha fgColor;
+ ColorAlpha borderColor;
+ Direction direction;
+ bool autoLayoutFlag;
+ Point position; // Position relative to parent's client area, including margin offset
+ Point tlPosition;
+ HVAlignment hAlignment, vAlignment; // Alignment of content (children or graphics) ?
+ SelfAlignment selfHAlignment, selfVAlignment;
+
+ selfHAlignment = inherit;
+ selfVAlignment = inherit;
+
+ autoLayoutFlag = true;
+ fgColor = black;
+ bgColor = 0;
+
+ FontResource font;
+ Font fontObject;
+ BitmapResource bitmap;
+ Bitmap bmpObject;
+ ColorAlpha bitmapTint;
+ bitmapTint = white;
+ /*
+ List<Primitive> primitives; // Displays above nodes
+ List<Primitive> bgPrimitives; // Displays behind nodes, need to figure out how to scale to width (e.g. Rectangle with a gradient)
+ List<Effects> effects;
+ */
+
+ void loadGraphics(DisplaySystem displaySystem)
+ {
+ if(!fontObject)
+ {
+ Element e = this;
+ FontResource font;
+ while(e && !e.font) e = e.parent;
+ font = e ? e.font : defaultFont;
+ displaySystem.LoadResource(font);
+ fontObject = font.font;
+ }
+
+ if(!bmpObject && bitmap)
+ {
+ displaySystem.LoadResource(bitmap);
+ bmpObject = bitmap.bitmap;
+ }
+
+ for(n : nodes)
+ n.loadGraphics(displaySystem);
+ }
+
+ void computeContentSize(DisplaySystem displaySystem)
+ {
+ int cw = clientSize.w, ch = clientSize.h;
+ int minimum = 0, thickness = 0;
+ Size graphicsSize { };
+ int rcw = cw, rch = ch;
+ for(n : nodes)
+ {
+ Element e = n;
+ if(e.autoLayoutFlag)
+ {
+ int xw = e.maxSize.w.getPixels(cw);
+ int xh = e.maxSize.h.getPixels(ch);
+ int nw = e.minSize.w.getPixels(cw);
+ int nh = e.minSize.h.getPixels(ch);
+ int w = 0, h = 0;
+ Box m
+ {
+ left = e.margin.left.getPixels(cw);
+ right = e.margin.right.getPixels(cw);
+ top = e.margin.top.getPixels(ch);
+ bottom = e.margin.bottom.getPixels(ch);
+ };
+
+ xw += m.left = m.right;
+ xh += m.top = m.bottom;
+ nw += m.left = m.right;
+ nh += m.top = m.bottom;
+
+ if(xw > w)
+ w = Min(xw, rcw);
+ //if(xh > h)
+ h = Min(xh, rch);
+
+ if(xw && xw < w) w = xw;
+ if(xh && xh < h) h = xh;
+ if(nw && nw > w) w = nw;
+ if(nh && nh > h) h = nh;
+
+ if(!w) w = cw;
+ if(!h) h = ch;
+
+ w -= m.left + m.right;
+ h -= m.top + m.bottom;
+
+ e.clientSize = { w, h };
+
+ e.computeContentSize(displaySystem);
+ if(!e.hScroll && e.contentSize.w > nw) nw = e.contentSize.w;
+ if(!e.vScroll && e.contentSize.h > nh) nh = e.contentSize.h;
+
+ if(direction == horizontal)
+ rcw -= nw;
+
+ if(direction == horizontal)
+ {
+ minimum += nw;
+ if(nh > thickness) thickness = nh;
+ }
+ else
+ {
+ minimum += nh;
+ if(nw > thickness) thickness = nw;
+ }
+ }
+ }
+ if(caption)
+ {
+ /*if(!cw) cw = MAXINT;
+ if(!ch) ch = MAXINT;*/
+
+ //displaySystem.FontExtent(fontObject, caption, strlen(caption), (int *)&graphicsSize.w, (int *)&graphicsSize.h);
+ wrapTextExtent(displaySystem, fontObject, caption, cw, ch, (int *)&graphicsSize.w, (int *)&graphicsSize.h);
+ if(graphicsSize.w)
+ graphicsSize.w += 1;
+ }
+
+ // Set the content size to the max of (minimum extent of children, graphics extent)
+ if(direction == horizontal)
+ contentSize = { Max(graphicsSize.w, minimum), Max(graphicsSize.h, thickness) };
+ else
+ contentSize = { Max(graphicsSize.w, thickness), Max(graphicsSize.h, minimum) };
+ }
+
+ void updateTLPosition()
+ {
+ for(n : nodes)
+ {
+ Element e = n;
+ e.tlPosition = { e.position.x + tlPosition.x, e.position.y + tlPosition.y };
+ n.updateTLPosition();
+ }
+ }
+
+ void autoLayout()
+ {
+ int cw = clientSize.w, ch = clientSize.h;
+ int totalMax = 0;
+ int totalUsed[Alignment] = { 0 };
+ int thickness = direction == vertical ? clientSize.w : clientSize.h;
+ int start = 0;
+ SelfAlignment lastAlignment = (direction == horizontal) ? nodes[0].selfHAlignment : nodes[0].selfVAlignment;
+ int totalMin = 0;
+ if(lastAlignment == inherit) lastAlignment = (direction == horizontal) ? hAlignment : vAlignment;
+
+ // Allocate extra space
+ for(n : nodes)
+ {
+ Element e = n;
+ e.clientSize = { };
+ if(e.autoLayoutFlag)
+ {
+ Box m
+ {
+ left = e.margin.left.getPixels(cw);
+ right = e.margin.right.getPixels(cw);
+ top = e.margin.top.getPixels(ch);
+ bottom = e.margin.bottom.getPixels(ch);
+ };
+
+ if(direction == horizontal)
+ {
+ int xw = e.maxSize.w.getPixels(cw);
+ int nw = e.minSize.w.getPixels(cw);
+ int w = Max(nw, e.contentSize.w);
+ int mm = m.left + m.right;
+ if(xw && xw < w) w = xw;
+
+ totalMin += w + mm;
+
+ if(xw && w > xw) xw = w;
+
+ totalMax += Max(w, xw) + mm;
+ totalUsed[e.selfHAlignment == inherit ? hAlignment : e.selfHAlignment] += Max(xw, w) + mm;
+ }
+ else
+ {
+ int xh = e.maxSize.h.getPixels(ch);
+ int nh = e.minSize.h.getPixels(ch);
+ int h = Max(nh, e.contentSize.h);
+ int mm = m.top + m.bottom;
+ if(xh && xh < h) h = xh;
+
+ totalMin += h + mm;
+
+ if(xh && h > xh) xh = h;
+
+ totalMax += Max(h, xh) + mm;
+ totalUsed[e.selfVAlignment == inherit ? vAlignment : e.selfVAlignment] += Max(xh, h) + mm;
+ }
+ }
+ }
+
+ if(direction == horizontal)
+ {
+ if(totalUsed[lastAlignment] < cw)
+ {
+ if(lastAlignment == right)
+ start = (cw - totalUsed[lastAlignment]);
+ else if(lastAlignment == center)
+ start = (cw - totalUsed[lastAlignment]) / 2;
+ }
+ }
+ else
+ {
+ if(totalUsed[lastAlignment] < ch)
+ {
+ if(lastAlignment == right)
+ start = (ch - totalUsed[lastAlignment]);
+ else if(lastAlignment == center)
+ start = (ch - totalUsed[lastAlignment]) / 2;
+ }
+ }
+
+ for(n : nodes)
+ {
+ Element e = n;
+ int w = e.hScroll ? 0 : e.contentSize.w;
+ int h = e.vScroll ? 0 : e.contentSize.h;
+ int nw = e.minSize.w.getPixels(cw);
+ int nh = e.minSize.h.getPixels(ch);
+ int xw = e.maxSize.w.getPixels(cw);
+ int xh = e.maxSize.h.getPixels(ch);
+ Box m
+ {
+ left = e.margin.left.getPixels(cw);
+ right = e.margin.right.getPixels(cw);
+ top = e.margin.top.getPixels(ch);
+ bottom = e.margin.bottom.getPixels(ch);
+ };
+ bool positionUpdated = false;
+
+ if(nw > w) w = nw;
+ if(nh > h) h = nh;
+
+ w += m.left + m.right;
+ h += m.top + m.bottom;
+ xw += m.left + m.right;
+ xh += m.top + m.bottom;
+
+ if(xw && w > xw) w = xw;
+ if(xh && h > xh) h = xh;
+
+ if(direction == horizontal)
+ {
+ SelfAlignment alignment = e.selfHAlignment == inherit ? hAlignment : e.selfHAlignment;
+ int y = 0;
+ xw = (w < xw && totalMax > totalMin && cw > totalMin) ? (int)(w + (xw - w) * Min(1.0f, (float)(cw - totalMin) / (totalMax - totalMin))) : 0;
+
+ if(xw > w) w = xw;
+ if(xh > h) h = xh;
+ if(h > thickness) h = thickness;
+
+ w = Min(w, Max(0, cw - start));
+
+ if(alignment != lastAlignment && totalUsed[alignment] < cw && lastAlignment != right && (lastAlignment != center || alignment == right))
+ {
+ int newStart = (cw - totalUsed[alignment]);
+ if(alignment == center)
+ newStart /= 2;
+ if(newStart > start)
+ start = newStart;
+ lastAlignment = alignment;
+ }
+
+ switch(e.selfVAlignment == inherit ? vAlignment : e.selfVAlignment)
+ {
+ case right: y = thickness - h; break;
+ case center: y = (thickness - h) / 2; break;
+ }
+ e.position = { start, y + m.top };
+ start += w;
+ }
+ else
+ {
+ SelfAlignment alignment = e.selfVAlignment == inherit ? vAlignment : e.selfVAlignment;
+ int x = 0;
+ xh = (h < xh && totalMax > totalMin && ch > totalMin) ? (int)(h + (xh - h) * Min(1.0f, (float)(ch - totalMin) / (totalMax - totalMin))) : 0;
+
+ if(xh > h) h = xh;
+ if(xw > w) w = xw;
+ if(w > thickness) w = thickness;
+
+ h = Min(h, Max(0, ch - start));
+
+ if(alignment != lastAlignment && totalUsed[alignment] < ch && lastAlignment != right && (lastAlignment != center || alignment == right))
+ {
+ int newStart = (ch - totalUsed[alignment]);
+ if(alignment == center)
+ newStart /= 2;
+ if(newStart > start)
+ start = newStart;
+ lastAlignment = alignment;
+ }
+
+ switch(e.selfHAlignment == inherit ? hAlignment : e.selfHAlignment)
+ {
+ case right: x = thickness - w; break;
+ case center: x = (thickness - w) / 2; break;
+ }
+
+ e.position = { x + m.left, start };
+ start += h;
+ }
+ w -= m.left + m.right;
+ h -= m.top + m.bottom;
+
+ if(w != e.clientSize.w || h != e.clientSize.h)
+ {
+ e.tlPosition = { e.position.x + tlPosition.x, e.position.y + tlPosition.y };
+ e.clientSize = { w, h };
+ if(e.autoLayoutFlag && e.nodes)
+ e.autoLayout();
+ }
+ else
+ {
+ if(e.tlPosition.x != e.position.x + tlPosition.x || e.tlPosition.y != e.position.y + tlPosition.y )
+ positionUpdated = true;
+ e.tlPosition = { e.position.x + tlPosition.x, e.position.y + tlPosition.y };
+ if(positionUpdated && e.nodes)
+ e.updateTLPosition();
+ }
+ }
+ }
+
+ void render(Surface surface)
+ {
+ surface.background = bgColor;
+ surface.Area(tlPosition.x, tlPosition.y, tlPosition.x + clientSize.w - 1, tlPosition.y + clientSize.h - 1);
+ if(bmpObject)
+ {
+ int sw = bmpObject.width, sh = bmpObject.height;
+ int x = (clientSize.w - sw) / 2;
+ int y = (clientSize.h - sh) / 2;
+ surface.blitTint = bitmapTint;
+ surface.Blit(bmpObject, x,y,0,0, sw,sh);
+ }
+ if(caption)
+ {
+ int sw = contentSize.w, sh = contentSize.h;
+ int x = tlPosition.x, y = tlPosition.y;
+ if(hAlignment == center)
+ x += (clientSize.w - sw) / 2;
+ if(vAlignment == center)
+ y += (clientSize.h - sh) / 2;
+
+ surface.foreground = fgColor;
+ surface.font = fontObject;
+ // surface.WriteText(x, y, caption, strlen(caption));
+ wrapText(surface, caption, x, y, tlPosition.x + clientSize.w, tlPosition.y + clientSize.h);
+ }
+ if(nodes)
+ {
+ for(n : nodes)
+ n.render(surface);
+ }
+ }
+
+public:
+ property Element parent
+ {
+ set
+ {
+ if(!value.nodes) value.nodes = { };
+ value.nodes.Add(this);
+
+ parent = value;
+ }
+ }
+}
+
+/*
+class Elemental : Col
+{
+ Bar r1
+ {
+ Element b0 { caption = "<<" };
+ Bar s1 { };
+ Element b1 { caption = "The" };
+ Element b2 { caption = "Quick" };
+ Element b3 { caption = "Brown" };
+ Bar s2 { };
+ };
+ Bar r2
+ {
+ Element b4 { caption = "Fox." };
+ Element b5 { };
+ Element b6 { };
+ };
+ Bar r3
+ {
+ Element b7 { caption = "Left" };
+ Element b8 { caption = "Address Bar" };
+ Element b9 { caption = "Right" };
+ };
+}
+
+{ [
+ { "class == Elemental", bgColor = ivory },
+ { "id == Elemental::r1", bgColor = gray, maxSize = { 100%, 100 } },
+ { "id == Elemental::b0", fgColor = white, bgColor = navy },
+ { "id == Elemental::b1", bgColor = red },
+ { "id == Elemental::b2", bgColor = blue, fgColor = white },
+
+ { "id == Elemental::r2", bgColor = lightGray, maxSize = { 100%, 150 } },
+ { "id == Elemental::b4", bgColor = yellow },
+ { "id == Elemental::b5", bgColor = aquamarine, maxSize = { 25%, 50 } },
+ { "id == Elemental::b6", bgColor = tomato, maxSize = { 50%, 50 } },
+
+ { "id == Elemental::r3", bgColor = lightGray, maxSize = { 100%, 0 } },
+ { "id == Elemental::b7", bgColor = skyBlue },
+ { "id == Elemental::b8", bgColor = teal, maxSize.w = 100% },
+ { "id == Elemental::b9", bgColor = maroon }
+] };
+*/
+
+class Bar : Element
+{
+ direction = horizontal;
+ maxSize = { 1.0, 1.0 };
+}
+
+class Col : Element
+{
+ direction = vertical;
+ maxSize = { 1.0, 1.0 };
+}
+
+/*
+class Elemental : Col
+{
+ bgColor = ivory;
+
+ Bar header { this, bgColor = blue };
+ Bar middle { this, bgColor = white };
+ Col col1 { middle, bgColor = lime };
+ Element e1 { col1, caption = "Foo", bgColor = gray, selfHAlignment = center, selfVAlignment = center };
+ Col col2 { middle, bgColor = skyBlue };
+ Element e2 { col2, caption = "Bar", bgColor = lightGray, selfHAlignment = center, selfVAlignment = center };
+ Col col3 { middle, bgColor = tomato };
+ Element e3 { col3, caption = "Third", bgColor = lightGray, selfHAlignment = center, selfVAlignment = center };
+ Bar footer { this, bgColor = red };
+}
+
+class Elemental2 : Col
+{
+ bgColor = skyBlue;
+
+ Bar r1 { this };
+ Col c1 { r1, maxSize.w = 0.25, bgColor = blue };
+ Col c2 { r1, maxSize.w = 0.5, bgColor = red };
+ Col c3 { r1, maxSize.w = 0.25, bgColor = blue };
+
+ Bar r { this, bgColor = beige, maxSize.h = 10 };
+
+ Bar r2 { this };
+ Col d1 { r2, maxSize.w = 0.25, bgColor = blue };
+ Col d11 { r2, maxSize.w = 0.5, caption = "Hello", bgColor = green };
+ Col d2 { r2, maxSize.w = 0.5, bgColor = red };
+ Col d3 { r2, maxSize.w = 0.25, bgColor = blue };
+ Col d4 { r2, maxSize.w = 0.25, bgColor = green };
+
+ Bar rr { this, bgColor = beige, maxSize.h = 10 };
+
+ Bar r3 { this };
+ Col { r3, minSize.w = 30, maxSize.w = 0, bgColor = blue };
+ Col { r3, maxSize.w = 1.0, caption = "Hello", bgColor = green };
+ Col { r3, minSize.w = 30, maxSize.w = 0, bgColor = red };
+}
+*/
+
+class AutoLayoutForm : Window
+{
+ displayDriver = "OpenGL";
+ caption = "";
+ background = formColor;
+ borderStyle = sizable;
+ hasMaximize = true;
+ hasMinimize = true;
+ hasClose = true;
+ clientSize = { 640, 480 };
+
+ Element contents;
+
+ bool OnLoadGraphics()
+ {
+ contents.loadGraphics(displaySystem);
+ return true;
+ }
+
+ void OnResize(int width, int height)
+ {
+ int nw = contents.minSize.w.getPixels(width);
+ int nh = contents.minSize.h.getPixels(height);
+ contents.clientSize = { Max(nw, width), Max(nh, height) };
+ if(contents.nodes)
+ {
+ contents.computeContentSize(displaySystem);
+ contents.autoLayout();
+ }
+ Update(null);
+ }
+
+ void OnRedraw(Surface surface)
+ {
+ contents.render(surface);
+ }
+}
--- /dev/null
+import IMPORT_STATIC "ecere"
+
+int wrapText(Surface surface, const String text, int sx, int sy, int ex, int ey)
+{
+ const String start = text;
+ const String drawUntil = null;
+ int w = 0;
+ int y = sy;
+ int tw, th;
+ int lh;
+
+ surface.TextExtent("W", 1, &tw, &th);
+ lh = th;
+ surface.Clip({ sx, sy, ex, ey });
+
+ while(true)
+ {
+ bool canAddMore = false;
+ if(ey - y >= 2*th)
+ {
+ const String s = drawUntil ? drawUntil + 1 : start;
+ const String nextSpace = strchr(s, ' ');
+ const String newLine = strchr(s, '\n');
+ if(newLine && (!nextSpace || (newLine < nextSpace)))
+ nextSpace = newLine;
+ if(!nextSpace)
+ nextSpace = strchr(s, 0);
+ if(nextSpace)
+ {
+ surface.TextExtent(drawUntil ? drawUntil : start, (int)(nextSpace - (drawUntil ? drawUntil : start)), &tw, &th);
+ if(!th) th = lh;
+ if(w + tw < ex - sx || !drawUntil)
+ {
+ drawUntil = nextSpace;
+ w += tw;
+ if(*nextSpace != 0 && *nextSpace != '\n')
+ canAddMore = true;
+ }
+ }
+ }
+ if(!canAddMore)
+ {
+ if(drawUntil)
+ {
+ surface.WriteText(sx, y, start, (int)(drawUntil - start));
+ w = 0;
+ y += th;
+ if(!*drawUntil)
+ break;
+ start = drawUntil + 1;
+ drawUntil = null;
+ }
+ else
+ {
+ surface.WriteText(sx, y, start, strlen(start));
+ y += th;
+ break;
+ }
+ }
+ }
+
+ surface.Clip(null);
+ return y;
+}
+
+int wrapTextExtent(DisplaySystem displaySystem, Font font, const String text, int ex, int ey, int * wtw, int * wth)
+{
+ const String start = text;
+ const String drawUntil = null;
+ int w = 0;
+ int y = 0;
+ int tw, th;
+ int lh;
+
+ displaySystem.FontExtent(font, "W", 1, &tw, &th);
+ lh = th;
+
+ *wtw = 0;
+ *wth = th;
+
+ while(true)
+ {
+ bool canAddMore = false;
+ if(ey - y >= 2*th)
+ {
+ const String s = drawUntil ? drawUntil + 1 : start;
+ const String nextSpace = strchr(s, ' ');
+ const String newLine = strchr(s, '\n');
+ if(newLine && (!nextSpace || (newLine < nextSpace)))
+ nextSpace = newLine;
+ if(!nextSpace)
+ nextSpace = strchr(s, 0);
+ if(nextSpace)
+ {
+ displaySystem.FontExtent(font, drawUntil ? drawUntil : start, (int)(nextSpace - (drawUntil ? drawUntil : start)), &tw, &th);
+ if(!th) th = lh;
+ if(w + tw < ex || !drawUntil)
+ {
+ drawUntil = nextSpace;
+ w += tw;
+ if(*nextSpace != 0 && *nextSpace != '\n')
+ canAddMore = true;
+ }
+ }
+ }
+ if(!canAddMore)
+ {
+ if(!drawUntil && !y && !w)
+ {
+ drawUntil = strchr(start, '\0');
+ if(drawUntil)
+ displaySystem.FontExtent(font, start, (int)(drawUntil - start), &w, &th);
+ }
+ if(drawUntil)
+ {
+ *wtw = Max(*wtw, w);
+ *wth = Max(*wth, y + th);
+ w = 0;
+ y += th;
+ if(!*drawUntil)
+ break;
+ start = drawUntil + 1;
+ drawUntil = null;
+ }
+ else
+ {
+ *wtw = Max(*wtw, w);
+ *wth = Max(*wth, y + th);
+ y += th;
+ break;
+ }
+ }
+ }
+ return y;
+}
--- /dev/null
+import "autoLayout"
+
+class Title : Element { maxSize = { 1430, 0 }, font = { "Verdana", 60, bold = true }, fgColor = textColor; };
+class CCol : Col { hAlignment = center, vAlignment = center; };
+class BMBar : Bar { maxSize.h = 60; };
+class MBar : Bar { maxSize.h = 30; };
+define textColor = 0xFF2F3A3E;
+class Header : Element { font = { "Verdana", 50, bold = true }; fgColor = textColor; }
+class SmallHeader : Element { font = { "Verdana", 30, bold = true }; fgColor = textColor; }
+class Bullet : Element
+{
+ fgColor = textColor;
+ property const String caption
+ {
+ set { text.caption = value; }
+ get { return text.caption; }
+ }
+ Element bullet { this, caption = "▪ ", fgColor = 0xFF104A4A; };
+ Col text { this, fgColor = textColor; };
+}
+
+class BaseSlide : CCol
+{
+ bitmap = { "graphics/bg1.png" };
+ bitmapTint = { 41, white };
+ bgColor = 0x59C6D2E3;
+ font = { "Verdana", 32 };
+}
+
+class CodeBlock : CCol
+{
+ selfHAlignment = center, selfVAlignment = center;
+ vAlignment = center;
+ maxSize = { };
+ //bgColor = { 180, 0x094B55 };
+ bgColor = { 220, black };
+ font = { "Consolas", 30 };
+
+ // Since we don't have padding yet
+ CCol text { this, fgColor = lime /*white*/; maxSize = { 1.0, 1.0 }; /*margin = { 20, 20, 20, 20 }*/ };
+ property const String caption
+ {
+ set { text.caption = value; }
+ get { return text.caption; }
+ }
+}
--- /dev/null
+import "autoLayout"
+
+import "titleSlide"
+import "languageSlide"
+import "classesSlide"
+import "instancesSlide"
+import "formSlide"
+import "buttonSlide"
+import "gnosisSlide"
+
+Array<Class> slides
+{ [
+ class(TitleSlide),
+ class(LanguageSlide),
+ class(ClassesSlide),
+ class(InstancesSlide),
+ class(FormSlide),
+ class(ButtonSlide),
+ class(GNOSISSlide)
+] };
+
+class SlideForm : AutoLayoutForm
+{
+ int slideNum;
+ caption = "Butterbur Slides";
+
+ SlideForm()
+ {
+ subclass(Element) c = slides.count ? (subclass(Element))slides[slideNum] : null;
+ if(c)
+ contents = eInstance_New(c);
+ }
+
+ bool OnKeyHit(Key key, unichar ch)
+ {
+ int num = slideNum;
+ switch(key)
+ {
+ case home: num = 0; break;
+ case end: if(slides.count) num = slides.count-1; break;
+ case pageUp: if(num > 0) num--; break;
+ case pageDown: if(num < slides.count-1) num++; break;
+ case p: printSlides(caption); break;
+ }
+ if(slideNum != num)
+ {
+ delete contents;
+ slideNum = num;
+ contents = eInstance_New(slides[num]);
+ OnLoadGraphics();
+ OnResize(clientSize.w, clientSize.h);
+ }
+ return true;
+ }
+}
+
+SlideForm slideForm { clientSize = { 1600, 1200 } };
+
+class SlidePrinter : Window
+{
+ fullRender = true;
+ size = { 1600, 1200 };
+ displayDriver = "Win32Printer";
+}
+
+Bitmap outputSlide(Class sc)
+{
+ Element c = eInstance_New(sc);
+ Bitmap bmp { };
+ AutoLayoutForm form1 { contents = c, clientSize = { 1600, 1200 } };
+ bmp.Allocate(null, 1600, 1200, 0, pixelFormat888, false);
+ form1.Create();
+ form1.display.Lock(true);
+ form1.Grab(bmp, null, false);
+ form1.display.Unlock();
+ form1.Destroy(0);
+ delete c;
+ bmp.Save("test.png", null, null);
+ return bmp;
+}
+
+void printSlides(const String title)
+{
+ int i = 0;
+ SlidePrinter printer { size = { 1600, 1200 } };
+ SetPrintingDocumentName(title);
+
+ printer.Create();
+ for(s : slides)
+ {
+ Bitmap bmp = outputSlide(s);
+ Picture pic { printer, anchor = { 0, 0, 0, 0 }, bitmapImage = bmp };
+ if(i++) printer.display.NextPage();
+ pic.Create();
+ pic.UpdateDisplay();
+ pic.Destroy(0);
+ delete bmp;
+ }
+ printer.Destroy(0);
+}
--- /dev/null
+import "base"
+
+class ButtonSlide : BaseSlide
+{
+ BMBar { this };
+ Title title { this, caption = "A Button instance" };
+
+ MBar { this };
+ Col t { this, maxSize = { 1550, 1250 }, margin = { 60, 15, 60, 15 } };
+ //Header { t, caption = "Features" };
+ MBar { t };
+ Bullet { t, caption = "Form controls defined as member instances" };
+ Bullet { t, caption = "Events defined by overriding methods" };
+ BMBar { t };
+ SmallHeader { t, caption = " Syntax:" };
+ MBar { t };
+ CodeBlock { t, minSize = { 1200, 600 }, caption =
+ "Button button1\n"
+ "{\n"
+ " this, caption = $\"button1\",\n"
+ " position = { 272, 248 };\n"
+ "\n"
+ " bool NotifyClicked(Button button,\n"
+ " int x, int y, Modifiers mods)\n"
+ " {\n"
+ "\n"
+ " return true;\n"
+ " }\n"
+ "};\n"
+ };
+}
--- /dev/null
+import "base"
+
+class ClassesSlide : BaseSlide
+{
+ BMBar { this };
+ Title title { this, caption = "Classes" };
+
+ MBar { this };
+ //Col t { this, maxSize = { 1450, 1150 }, margin = { 115, 15, 115, 15 } };
+ Col t { this, maxSize = { 1550, 1250 }, margin = { 60, 15, 60, 15 } };
+ //Header { t, caption = "Features" };
+ BMBar { t };
+ Bullet { t, caption = "Define a 'class' of objects for reusability" };
+ Bullet { t, caption = "Inheritance to define specialized classes" };
+ Bullet { t, caption = "Can contain methods, properties and data members" };
+ BMBar { t };
+ SmallHeader { t, caption = " Syntax:" };
+ MBar { t };
+ CodeBlock { t, minSize = { 900, 550 }, caption =
+ "class MyClass : MyBaseClass\n"
+ "{\n"
+ " SomeType member1;\n"
+ "\n"
+ " member1 = someDefaultValue;\n"
+ "\n"
+ " void someMethod()\n"
+ " {\n"
+ " }\n"
+ "}";
+ };
+}
--- /dev/null
+import "base"
+
+class FormSlide : BaseSlide
+{
+ BMBar { this };
+ Title title { this, caption = "A Form class" };
+
+ MBar { this };
+ Col t { this, maxSize = { 1550, 1250 }, margin = { 60, 15, 60, 15 } };
+ //Header { t, caption = "Features" };
+ MBar { t };
+ Bullet { t, caption = "The Ecere library provides a cross-platform GUI toolkit." };
+ Bullet { t, caption = "All controls and form derive from the Window class." };
+ Bullet { t, caption = "Let's define a Form class inheriting from Window:" };
+ BMBar { t };
+ SmallHeader { t, caption = " Syntax:" };
+ MBar { t };
+ CodeBlock { t, minSize = { 900, 600 }, caption =
+ "import \"ecere\"\n"
+ "class Form : Window\n"
+ "{\n"
+ " caption = $\"My Form\";\n"
+ " background = formColor;\n"
+ " borderStyle = sizable;\n"
+ " hasMaximize = true;\n"
+ " hasMinimize = true;\n"
+ " hasClose = true;\n"
+ " clientSize = { 640, 480 };\n"
+ "}\n"
+ "Form form { };\n"
+ };
+}
--- /dev/null
+import "base"
+
+class GNOSISSlide : BaseSlide
+{
+ BMBar { this };
+ Title title { this, caption = "GNOSIS Sample" };
+
+ MBar { this };
+ Col t { this, maxSize = { 1550, 1250 }, margin = { 60, 15, 60, 15 } };
+ //Header { t, caption = "Features" };
+ MBar { t };
+ Bullet { t, caption = "The GNOSIS SDK presents a simple object-oriented API" };
+ Bullet { t, caption = "Key Classes: View3D, MapSource, MapLayer" };
+ MBar { t };
+ CodeBlock { t, minSize = { 1550, 930 }, font = { "Consolas", 20 }, caption =
+ "import \"ecere\"\n"
+ "import \"gnosis2\"\n"
+ "import \"cameraController\"\n"
+ "class MainWindow : Window\n"
+ "{\n"
+ " displayDriver = \"OpenGL\";\n"
+ " caption = \"GNOSIS SDK Sample App\";\n"
+ " background = black;\n"
+ " borderStyle = sizable;\n"
+ " hasMaximize = true, hasMinimize = true, hasClose = true;\n"
+ " clientSize = { 640, 480 };\n"
+ "\n"
+ " MapSource bmNGSrc;\n"
+ " bmNGSrc = \"maps/BlueMarbleNextGen - August 2004\";\n"
+ "\n"
+ " View3D view { void update() { window.Update(null); } };\n"
+ " MapLayer bmNG { view, source = bmNGSrc };\n"
+ "\n"
+ " controller = CameraController\n"
+ " {\n"
+ " controlled = view,\n"
+ " position = { 0, 0, Kilometers { 20000 } };\n"
+ " orientation = { yaw = 0, pitch = 90, roll = 0 };\n"
+ " };\n"
+ "}\n"
+ "MainWindow window { };\n"
+ };
+}
--- /dev/null
+import "base"
+
+class InstancesSlide : BaseSlide
+{
+ BMBar { this };
+ Title title { this, caption = "Instances" };
+
+ MBar { this };
+ //Col t { this, maxSize = { 1450, 1150 }, margin = { 115, 15, 115, 15 } };
+ Col t { this, maxSize = { 1550, 1250 }, margin = { 60, 15, 60, 15 } };
+ //Header { t, caption = "Features" };
+ BMBar { t };
+ Bullet { t, caption = "Multiple objects can be instantiated from same class" };
+ Bullet { t, caption = "Value of members can be modified from defaults" };
+ Bullet { t, caption = "Virtual methods can be overridden" };
+ BMBar { t };
+ SmallHeader { t, caption = " Syntax:" };
+ MBar { t };
+ CodeBlock { t, minSize = { 920, 320 }, caption =
+ "// Named Instance (declaration)\n"
+ "MyClass object { member = value };\n"
+ "\n"
+ "// Anonymous Instance (expression)\n"
+ "MyClass { member = value };"
+ };
+}
--- /dev/null
+import "base"
+
+class LanguageSlide : BaseSlide
+{
+ BMBar { this };
+ Title title { this, caption = "The eC Language" };
+
+ MBar { this };
+ //Col t { this, maxSize = { 1450, 1150 }, margin = { 115, 15, 115, 15 } };
+ Col t { this, maxSize = { 1550, 1250 }, margin = { 60, 15, 60, 15 } };
+ //Header { t, caption = "Features" };
+ BMBar { t };
+ Bullet { t, caption = "C Superset" };
+ Bullet { t, caption = "C Compatible" };
+ Bullet { t, caption = "Native" };
+ Bullet { t, caption = "Object-Oriented" };
+ Bullet { t, caption = "Properties" };
+ Bullet { t, caption = "Modules" };
+ Bullet { t, caption = "Reflection" };
+ Bullet { t, caption = "Dynamic Imports" };
+}
--- /dev/null
+import "base"
+
+class Slide1 : BaseSlide
+{
+ BMBar { this };
+ Element title { this, maxSize = { 1430, 0 }, font = { "Verdana", 50, bold = true }, caption = "eC - A crash course", fgColor = textColor };
+
+ MBar { this };
+ Col t { this, maxSize = { 1400, 1100 }, margin = { 15, 15, 15, 15 } };
+ Header { t, caption = "eC Language" };
+ Bullet { t, caption = "Classes" };
+ Bullet { t, caption = "Instances" };
+ Bullet { t, caption = "Methods" };
+ Bullet { t, caption = "Flow Control" };
+ Bullet { t, caption = "Variables" };
+ Bullet { t, caption = "Style Guidelines" };
+ Bullet { t, caption = "Member Instance" };
+ Bullet { t, caption = "Instance method" };
+ Bullet { t, caption = "Setting properties" };
+ Bullet { t, caption = "Default properties" };
+ MBar { t };
+ Header { t, caption = "Ecere GUI" };
+ Bullet { t, caption = "Creating a Form" };
+ Bullet { t, caption = "Positions and Anchors" };
+ Bullet { t, caption = "Button: Responding to a click" };
+ Bullet { t, caption = "MessageBox and Modal Loops" };
+ Bullet { t, caption = "This is very long text that would ideally have automatic line-wrapping onto the next line. Now we have to implement this into autoLayout.ec." };
+}
--- /dev/null
+import "base"
+
+class TitleSlide : BaseSlide
+{
+ vAlignment = center;
+ Element title { this, font = { "Verdana", 100, bold = true }, caption = "eC", fgColor = textColor };
+ Element subTitle { this, font = { "Verdana", 80, italic = true }, caption = "An introduction", fgColor = textColor };
+ MBar { this, maxSize.h = 600 };
+}