std::shared_ptr<Composite>& AlloyContext::getGlassPane() {
	if (glassPane.get() == nullptr) {
		glassPane = std::shared_ptr<Composite>(
				new Composite("Glass Pane", CoordPX(0, 0),
						CoordPercent(1.0f, 1.0f)));
		glassPane->backgroundColor = MakeColor(
				theme.DARKEST.toSemiTransparent(0.5f));
	}
	return glassPane;
}
	ExpandTree::ExpandTree(const std::string& name, const AUnit2D& pos,
		const AUnit2D& dims) :
		Composite(name, pos, dims), selectedItem(nullptr), dirty(true) {
		setScrollEnabled(true);
		setAlwaysShowVerticalScrollBar(true);
		drawRegion = DrawPtr(
			new Draw("Tree Region", CoordPX(0.0f, 0.0f),
				CoordPercent(1.0f, 1.0f)));
		drawRegion->onDraw = [this](AlloyContext* context, const box2px& bounds) {
			root.draw(this, context, bounds.position);
		};
		drawRegion->onMouseOver =
			[this](AlloyContext* context, const InputEvent& e) {
			box2px box = drawRegion->getBounds();
			overArrow = false;
			selectedItem = root.locate(context, e.cursor - box.position,overArrow);
			return false;
		};
		drawRegion->onMouseDown =
			[this](AlloyContext* context, const InputEvent& e) {
			if (e.button == GLFW_MOUSE_BUTTON_LEFT) {
				if (selectedItem != nullptr) {
					if ((isOverArrow()|| !selectedItem->onSelect)&&(selectedItem->onExpand || selectedItem->hasChildren())) {
						selectedItem->setExpanded(!selectedItem->isExpanded());
					}
					else {
						if (selectedItem->onSelect) {
							selectedItem->onSelect(selectedItem, e);
						}
					}
					setDirty(true);
					update(context);
					return true;
				}
			}
			return false;
		};
		Composite::add(drawRegion);
	}
void Application::run(int swapInterval) {
    const double POLL_INTERVAL_SEC = 0.5f;

    context->makeCurrent();
    if (!init(rootRegion)) {
        throw std::runtime_error("Error occurred in application init()");
    }
    rootRegion.add(getContext()->getGlassPane());
    if (showDebugIcon) {
        GlyphRegionPtr debug = MakeGlyphRegion(
                                   createAwesomeGlyph(0xf188, FontStyle::Outline, 20),
                                   CoordPercent(1.0f, 1.0f), CoordPX(20, 20), RGBA(0, 0, 0, 0),
                                   RGBA(64, 64, 64, 128), RGBA(192, 192, 192, 128), UnitPX(0));

        debug->setOrigin(Origin::BottomRight);
        debug->onMouseDown =
        [this,debug](AlloyContext* context,const InputEvent& e) {
            if(e.button==GLFW_MOUSE_BUTTON_LEFT) {
                context->toggleDebug();
                debug->foregroundColor=context->isDebugEnabled()?MakeColor(255,64,64,255):MakeColor(64,64,64,128);
                context->setMouseFocusObject(nullptr);
                return true;
            }
            return false;
        };
        rootRegion.add(debug);
    }

    //First pack triggers computation of aspect ratios  for components.
    rootRegion.pack(context.get());
    context->getGlassPane()->setVisible(false);
    context->requestPack();
    glfwSwapInterval(swapInterval);
    glfwSetTime(0);
    uint64_t frameCounter = 0;
    std::chrono::steady_clock::time_point endTime;
    std::chrono::steady_clock::time_point lastFpsTime =
        std::chrono::steady_clock::now();
    if (!forceClose) {
        glfwShowWindow(context->window);
    } else {
        context->executeDeferredTasks();
        context->dirtyUI = true;
        context->dirtyLayout = true;
        draw();
        context->dirtyUI = true;
        context->dirtyLayout = true;
        context->update(rootRegion);
    }
    do {
        //Events could have modified layout! Pack before draw to make sure things are correctly positioned.
        if (context->dirtyLayout) {
            context->dirtyLayout = false;
            context->dirtyCursorLocator = true;
            rootRegion.pack();
        }
        draw();
        context->update(rootRegion);
        double elapsed =
            std::chrono::duration<double>(endTime - lastFpsTime).count();
        frameCounter++;
        if (elapsed > POLL_INTERVAL_SEC) {
            frameRate = (float) (frameCounter / elapsed);
            lastFpsTime = endTime;
            frameCounter = 0;
        }
        glfwSwapBuffers(context->window);
        glfwPollEvents();
        for (std::exception_ptr e : caughtExceptions) {
            std::rethrow_exception(e);
        }
        if (glfwWindowShouldClose(context->offscreenWindow)) {
            context->setOffScreenVisible(false);
        }
    } while (!glfwWindowShouldClose(context->window) && !forceClose);
}
void Application::initInternal() {
    rootRegion.setBounds(CoordPercent(0.0f, 0.0f), CoordPercent(1.0f, 1.0f));
    context->addAssetDirectory("assets/");
    context->addAssetDirectory("../assets/");
    context->addAssetDirectory("../../assets/");
    context->loadFont(FontType::Normal, "sans", "fonts/Roboto-Regular.ttf");
    context->loadFont(FontType::Bold, "sans-bold", "fonts/Roboto-Bold.ttf");
    context->loadFont(FontType::Italic, "sans-italic",
                      "fonts/Roboto-Italic.ttf");
    context->loadFont(FontType::Code, "sans", "fonts/Hack-Regular.ttf");
    context->loadFont(FontType::CodeBold, "sans-bold", "fonts/Hack-Bold.ttf");
    context->loadFont(FontType::CodeItalic, "sans-bold-italic",
                      "fonts/Hack-Italic.ttf");
    context->loadFont(FontType::CodeBoldItalic, "sans-bold-italic",
                      "fonts/Hack-BoldItalic.ttf");
    context->loadFont(FontType::Entypo, "entypo", "fonts/entypo.ttf");
    context->loadFont(FontType::Icon, "icons", "fonts/fontawesome.ttf");
    glfwSetWindowUserPointer(context->window, this);
    glfwSetWindowRefreshCallback(context->window,
    [](GLFWwindow * window ) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onWindowRefresh();
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetWindowFocusCallback(context->window,
    [](GLFWwindow * window, int focused ) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onWindowFocus(focused);
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetWindowSizeCallback(context->window,
    [](GLFWwindow * window, int width, int height ) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onWindowSize(width, height);
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetFramebufferSizeCallback(context->window,
    [](GLFWwindow * window, int width, int height) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onFrameBufferSize(width, height);
        }
        catch (...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetCharCallback(context->window,
    [](GLFWwindow * window, unsigned int codepoint ) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onChar(codepoint);
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetKeyCallback(context->window,
    [](GLFWwindow * window, int key, int scancode, int action, int mods) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onKey(key, scancode,action,mods);
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetMouseButtonCallback(context->window,
    [](GLFWwindow * window, int button, int action,int mods) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onMouseButton(button, action,mods);
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetCursorPosCallback(context->window,
    [](GLFWwindow * window, double xpos, double ypos ) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onCursorPos(xpos, ypos);
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetCursorEnterCallback(context->window,
    [](GLFWwindow * window, int enter) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onCursorEnter(enter);
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    glfwSetScrollCallback(context->window,
    [](GLFWwindow * window, double xoffset, double yoffset ) {
        Application* app = (Application *)(glfwGetWindowUserPointer(window));
        try {
            app->onScroll(xoffset, yoffset);
        }
        catch(...) {
            app->throwException(std::current_exception());
        }
    });
    imageShader = std::shared_ptr<ImageShader>(
                      new ImageShader(ImageShader::Filter::NONE, true, context));
    uiFrameBuffer = std::shared_ptr<GLFrameBuffer>(
                        new GLFrameBuffer(true, context));
    uiFrameBuffer->initialize(context->viewSize.x, context->viewSize.y);
}