VIZ++ Class: OpenGLMainView
|
Source code
/*
* OpenGLMainView.h
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*/
//2015/08/02 Updated to enable GWFW callbacks.
//2015/08/03 Added methods depending on Win32 API.
#pragma once
#include <viz++/Object.h>
#include <viz++/Exception.h>
#include <viz++/opengl/OpenGLApplet.h>
#include <viz++/opengl/OpenGLWaitableApplet.h>
#include <viz++/opengl/OpenGLIView.h>
#include <viz++/opengl/OpenGLMenuBar.h>
#include <viz++/StringT.h>
#include <viz++/ModuleFileName.h>
#include <viz++/opengl/MenuId.h>
//2015/08/03
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3native.h>
#ifdef TRACE
#define trace printf
#else
#define trace
#endif
namespace VIZ {
static const char* GLFW_WINDOW = "GLFW_WINDOW";
static WNDPROC glfwWndProc = NULL;
class OpenGLMainView :public OpenGLIView {
private:
StringT<char> title;
GLFWwindow* window;
SmartPtr<OpenGLMenuBar> menubar;
int width;
int height;
public:
static OpenGLMainView* getView(GLFWwindow* window)
{
return (OpenGLMainView*)glfwGetWindowUserPointer(window);
}
static void setView(GLFWwindow* window, OpenGLMainView* view)
{
glfwSetWindowUserPointer(window, view);
}
private:
/////////////////////////////////////////////////////
//Private static GLFW callback functions start.
//1 Get a pointer to OpenGLMainView from GLFWwindow by using a static member function 'getView'.
//2 Call a virtual member funnction of the OpenGLMainView.
static void windowposFun(GLFWwindow* window, int xpos, int ypos)
{
OpenGLMainView* view = getView(window);
view -> posCallback(xpos, ypos);
}
static void windowsizeFun(GLFWwindow* window, int width, int height)
{
OpenGLMainView* view = getView(window);
view -> sizeCallback(width, height);
}
static void windowcloseFun(GLFWwindow* window)
{
OpenGLMainView* view = getView(window);
view -> closeCallback();
}
static void windowrefreshFun(GLFWwindow* window)
{
OpenGLMainView* view = getView(window);
view -> refreshCallback();
}
static void windowfocusFun(GLFWwindow* window, int focused)
{
OpenGLMainView* view = getView(window);
view -> focusCallback(focused);
}
static void windowiconifyFun(GLFWwindow* window, int iconified)
{
OpenGLMainView* view = getView(window);
view -> iconifyCallback(iconified);
}
static void framebuffersizeFun(GLFWwindow* window, int width, int height)
{
OpenGLMainView* view = getView(window);
view -> frameBufferSizeCallback(width, height);
}
static void mousebuttonFun(GLFWwindow* window, int button, int action, int mods)
{
OpenGLMainView* view = getView(window);
view -> mouseButtonCallback(button, action, mods);
}
static void cursorposFun(GLFWwindow* window, double xpos, double ypos)
{
OpenGLMainView* view = getView(window);
view -> cursorPosCallback(xpos, ypos);
}
static void cursorenterFun(GLFWwindow* window, int entered)
{
OpenGLMainView* view = getView(window);
view -> cursorEnterCallback(entered);
}
static void scrollFun(GLFWwindow* window, double xoffset, double yoffset)
{
OpenGLMainView* view = getView(window);
view -> scrollCallback(xoffset, yoffset);
}
static void keyFun(GLFWwindow* window, int key, int scancode, int action, int mods)
{
OpenGLMainView* view = getView(window);
view -> keyCallback(key, scancode, action, mods);
}
static void charFun(GLFWwindow* window,unsigned int codepoint)
{
OpenGLMainView* view = getView(window);
view -> charCallback(codepoint);
}
static void charmodsFun(GLFWwindow* window,unsigned int codepoint,int mods)
{
OpenGLMainView* view = getView(window);
view -> charModsCallback(codepoint, mods);
}
static void dropFun(GLFWwindow* window, int count, const char** paths)
{
OpenGLMainView* view = getView(window);
view -> dropCallback(count, paths);
}
//Please define your own method in your subclass derived from this class.
virtual void menuCallback(WORD menuId)
{
HWND hwnd = getHwnd();
char message[1024];
sprintf_s(message, CountOf(message), "Default menu callback. MenuId(%d)", menuId);
switch (menuId) {
case IDM_EXIT:
{
int rc = MessageBox(hwnd, "Are you sure to want to exit this program?", "Confirmation", MB_OKCANCEL|MB_ICONINFORMATION);
if (rc == IDOK) {
::PostQuitMessage(0);
}
}
break;
case IDM_VERSION:
MessageBox(hwnd, "VIZ++ 1.0 Library Copyright (c) 2017 Antillia.com", "Version", MB_OK|MB_ICONINFORMATION);
break;
default:
MessageBox(hwnd, message, "MenuCallback", MB_OK|MB_ICONINFORMATION);
}
}
//Please define your own method in your subclass derived from this class.
virtual void acceleratorCallback(WORD accelId)
{
trace("acceleratorCallback: accelId=%d \n", accelId);
}
//Please define your own method in your subclass derived from this class.
virtual void controlCallback(WORD notifyId, WORD controlId, HWND controlHwnd)
{
trace("controlCallback: notifyId=%d controlId=%d controlHwnd=%ld",
notifyId, controlId, controlHwnd);
}
//2017/02/10
static LRESULT commandFunc(GLFWwindow* window, WPARAM wParam, LPARAM lParam)
{
OpenGLMainView* view = (OpenGLMainView*)getView(window);
WORD hi = HIWORD(wParam);
WORD menuId = LOWORD(wParam);
if (hi == 0) {
view -> menuCallback(menuId);
} else if (hi == 1){
WORD accelId = LOWORD(wParam);
view -> acceleratorCallback(accelId);
} else {
WORD notifyId = HIWORD(wParam);
WORD controlId = LOWORD(wParam);
HWND controlHwnd = (HWND)lParam;
view -> controlCallback(notifyId, controlId, controlHwnd);
}
return 0L;
}
//Private GLFW callback functions end.
/////////////////////////////////////////////////////
//VIZ++ specific Window procedure.
//
static LRESULT CALLBACK vizWndProc(HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam)
{
switch(msg) {
case WM_COMMAND:
{
GLFWwindow* window = (GLFWwindow* )GetProp(hwnd, GLFW_WINDOW);
if (window) {
commandFunc(window, wParam, lParam);
}
return 0;
}
break;
//Add your own message handling code below.
default:
break;
}
if (glfwWndProc) {
//Call the original GLFW window procedure glfwWndProc
return CallWindowProc(glfwWndProc , hwnd , msg , wParam , lParam);
} else {
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
//2015/08/22
public:
static const int LEFT_BUTTON = GLFW_MOUSE_BUTTON_1;
static const int RIGHT_BUTTON = GLFW_MOUSE_BUTTON_2;
static const int BUTTON_DOWN = 1;
static const int BUTTON_UP = 0;
private:
OpenGLMainView()
:window(NULL)
{
}
public:
//////////////////////////////////////////////////////////
//Creates a window and its associated context.
OpenGLMainView(OpenGLApplet& applet, int width, int height, const char* title,
GLFWmonitor* monitor = NULL, GLFWwindow* share = NULL)
:window(NULL),
width(0),
height(0),
title(title)
{
window = glfwCreateWindow (width, height, title, monitor, share);
if (window == NULL) {
throw IException("Failed to glfwCreateWindow");
}
//2015/07/28
setView(window, this);
applet.setWindow(this);
makeContextCurrent();
//2017/02/10
menubar = new OpenGLMenuBar(this, title);
HWND hwnd = getHwnd();
//The following is a subclassing process in the sence of Windows.
//Replace GLWwindow's orignal window proc by VIZ++ specific WNDPROC vizWndProc
SetProp(hwnd, GLFW_WINDOW, (HANDLE)window);
glfwWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG)vizWndProc);
}
//Destroys the specified getWindow() and its context.
~OpenGLMainView()
{
if (window) {
glfwMakeContextCurrent(NULL);
glfwDestroyWindow (window);
window = NULL;
}
}
GLFWwindow* getWindow()
{
if (window == NULL) {
throw IException("Window is NULL");
}
return window;
}
const char* getTitle()
{
return (const char*)title;
}
void makeContextCurrent()
{
glfwMakeContextCurrent(getWindow());
}
/////////////////////////////////////////////////
//Enable callbacks start.
void enableWindowPosCallback()
{
setWindowPosCallback(&OpenGLMainView::windowposFun);
}
void enableWindowSizeCallback()
{
setWindowSizeCallback(&OpenGLMainView::windowsizeFun);
}
void enableWindowCloseCallback()
{
setWindowCloseCallback(&OpenGLMainView::windowcloseFun);
}
void enableWindowRefreshCallback()
{
setWindowRefreshCallback(&OpenGLMainView::windowrefreshFun);
}
void enableWindowFocusCallback()
{
setWindowFocusCallback(&OpenGLMainView::windowfocusFun);
}
void enableWindowIconifyCallback()
{
setWindowIconifyCallback(&OpenGLMainView::windowiconifyFun);
}
void enableFramebufferSizeCallback()
{
setFramebufferSizeCallback(&OpenGLMainView::framebuffersizeFun);
}
void enableKeyCallback()
{
setKeyCallback(&OpenGLMainView::keyFun);
}
void enableCharCallback()
{
setCharCallback(&OpenGLMainView::charFun);
}
void enableCharModsCallback()
{
setCharModsCallback(&OpenGLMainView::charmodsFun);
}
void enableMouseButtonCallback()
{
setMouseButtonCallback(&OpenGLMainView::mousebuttonFun);
}
void enableCursorEnterCallback()
{
setCursorEnterCallback(&OpenGLMainView::cursorenterFun);
}
void enableDropCallback()
{
setDropCallback(&OpenGLMainView::dropFun);
}
//Enable callbacks end.
/////////////////////////////////////////////////
void enableAllCallbacks()
{
setWindowPosCallback(&OpenGLMainView::windowposFun);
setWindowSizeCallback(&OpenGLMainView::windowsizeFun);
setWindowCloseCallback(&OpenGLMainView::windowcloseFun);
setWindowRefreshCallback(&OpenGLMainView::windowrefreshFun);
setWindowFocusCallback(&OpenGLMainView::windowfocusFun);
setWindowIconifyCallback(&OpenGLMainView::windowiconifyFun);
setFramebufferSizeCallback(&OpenGLMainView::framebuffersizeFun);
setKeyCallback(&OpenGLMainView::keyFun);
setCharCallback(&OpenGLMainView::charFun);
setCharModsCallback(&OpenGLMainView::charmodsFun);
setMouseButtonCallback(&OpenGLMainView::mousebuttonFun);
setCursorEnterCallback(&OpenGLMainView::cursorenterFun);
setDropCallback(&OpenGLMainView::dropFun);
}
//Checks the close flag of the specified window.
int shouldClose()
{
return glfwWindowShouldClose (getWindow());
}
//Sets the close flag of the specified window.
void setWindowShouldClose (int value)
{
glfwSetWindowShouldClose (getWindow(), value);
}
//Sets the title of the specified window.
void setWindowTitle (const char *title)
{
glfwSetWindowTitle (getWindow(), title);
}
//Retrieves the position of the client area of the specified window.
void getWindowPos (int& xpos, int& ypos)
{
glfwGetWindowPos (getWindow(), &xpos, &ypos);
}
//Sets the position of the client area of the specified window.
void setWindowPos (int xpos, int ypos)
{
glfwSetWindowPos (getWindow(), xpos, ypos);
}
//Retrieves the size of the client area of the specified window.
void getWindowSize (int& width, int& height)
{
glfwGetWindowSize (getWindow(), &width, &height);
}
//Sets the size of the client area of the specified window.
void setWindowSize (int width, int height)
{
glfwSetWindowSize (getWindow(), width, height);
}
//Retrieves the size of the framebuffer of the specified window.
void getFramebufferSize (int& width, int& height)
{
glfwGetFramebufferSize (getWindow(), &width, &height);
}
//Retrieves the size of the frame of the window.
void getWindowFrameSize (int& left, int& top, int& right, int& bottom)
{
glfwGetWindowFrameSize (getWindow(), &left, &top, &right, &bottom);
}
//Iconifies the specified window.
void iconify()
{
glfwIconifyWindow (getWindow());
}
//Restores the specified window.
void restore ()
{
glfwRestoreWindow (getWindow());
}
//Makes the specified window visible.
void showWindow ()
{
glfwShowWindow (getWindow());
}
//2015/08/02
void realize()
{
showWindow();
//
activate();
}
//Hides the specified window.
void hideWindow ()
{
glfwHideWindow (getWindow());
}
//Returns the monitor that the window uses for full screen mode.
GLFWmonitor* getWindowMonitor ()
{
return glfwGetWindowMonitor (getWindow());
}
//Returns an attribute of the specified window.
int getWindowAttribute (int attrib)
{
return glfwGetWindowAttrib (getWindow(), attrib);
}
//Sets the user pointer of the specified window.
void setWindowUserPointer (void *pointer)
{
glfwSetWindowUserPointer (getWindow(), pointer);
}
//Returns the user pointer of the specified window.
void * getWindowUserPointer ()
{
return glfwGetWindowUserPointer (getWindow());
}
GLFWwindowposfun setWindowPosCallback(GLFWwindowposfun cbfun)
{
return glfwSetWindowPosCallback(getWindow(), cbfun);
}
GLFWwindowsizefun setWindowSizeCallback(GLFWwindowsizefun cbfun)
{
return glfwSetWindowSizeCallback(getWindow(), cbfun);
}
GLFWwindowclosefun setWindowCloseCallback(GLFWwindowclosefun cbfun)
{
return glfwSetWindowCloseCallback(getWindow(), cbfun);
}
GLFWwindowrefreshfun setWindowRefreshCallback(GLFWwindowrefreshfun cbfun)
{
return glfwSetWindowRefreshCallback(getWindow(), cbfun);
}
GLFWwindowfocusfun setWindowFocusCallback(GLFWwindowfocusfun cbfun)
{
return glfwSetWindowFocusCallback(getWindow(), cbfun);
}
GLFWwindowiconifyfun setWindowIconifyCallback(GLFWwindowiconifyfun cbfun)
{
return glfwSetWindowIconifyCallback(getWindow(), cbfun);
}
GLFWframebuffersizefun setFramebufferSizeCallback(GLFWframebuffersizefun cbfun)
{
return glfwSetFramebufferSizeCallback(getWindow(), cbfun);
}
GLFWkeyfun setKeyCallback(GLFWkeyfun cbfun)
{
return glfwSetKeyCallback(getWindow(), cbfun);
}
GLFWcharfun setCharCallback(GLFWcharfun cbfun)
{
return glfwSetCharCallback(getWindow(), cbfun);
}
GLFWcharmodsfun setCharModsCallback(GLFWcharmodsfun cbfun)
{
return glfwSetCharModsCallback(getWindow(), cbfun);
}
GLFWmousebuttonfun setMouseButtonCallback(GLFWmousebuttonfun cbfun)
{
return glfwSetMouseButtonCallback(getWindow(), cbfun);
}
GLFWcursorenterfun setCursorEnterCallback(GLFWcursorenterfun cbfun)
{
return glfwSetCursorEnterCallback(getWindow(), cbfun);
}
//GLFW 3.1.
GLFWdropfun setDropCallback(GLFWdropfun cbfun)
{
return glfwSetDropCallback(getWindow(), cbfun);
}
//Swaps the front and back buffers of the specified window.
void swapBuffers ()
{
glfwSwapBuffers (getWindow());
}
void setClipboardString(const char* string)
{
glfwSetClipboardString(getWindow(), string);
}
const char* getClipboardString()
{
return glfwGetClipboardString(getWindow());
}
virtual void reshape()
{
int w = 0;
int h = 0;
glfwGetFramebufferSize(getWindow(), &w, &h);
if (w != width || h != height) {
glViewport(0, 0, w, h);
resize(w, h);
}
width = w;
height = h;
}
void setViewprt(int width, int height)
{
glViewport(0, 0, width, height);
}
//Please define your own method in a subclass derived from this class
virtual void initialize()
{
}
//Please define your own method in a subclass derived from this class
virtual void resize(int width, int height)
{
}
//Please define your own method in a subclass derived from this class
virtual void idle()
{
}
//Please define your own method in a subclass derived from this class
virtual void display()
{
}
public:
//////////////////////////////////////////////
// Public virtual instance callbacks (methods) start.
// Please define your own methods in your subclass derived from this class
// for The follwing virtual functions
virtual void posCallback(int xpos, int ypos)
{
trace("posCallback: xpos=%d ypos=%d\n", xpos, ypos);
}
virtual void sizeCallback(int width, int height)
{
trace("sizeCallback: width=%d height=%d\n", width, height);
}
virtual void closeCallback()
{
trace("closeCallback\n");
}
virtual void refreshCallback()
{
trace("refreshCallback\n");
}
virtual void focusCallback(int focused)
{
trace("focusCallback: focused=%d\n", focused);
}
virtual void iconifyCallback(int iconified)
{
trace("iconifyCallback: iconified=%d\n", iconified);
}
virtual void frameBufferSizeCallback(int width, int height)
{
trace("frameBuferSizeCallback: width=%d height=%d\n", width, height);
}
virtual void mouseButtonCallback(int button, int action, int mods)
{
trace("mouseButtonCallback: button=%d, action=%d, mods=%d\n",
button, action, mods);
}
virtual void cursorPosCallback(double xpos, double ypos)
{
trace("cursorPosCallback: xpos=%lf, ypos=%lf\n", xpos, ypos);
}
virtual void cursorEnterCallback(int entered)
{
trace("cursorEnterCallback: entered=%d\n", entered);
}
virtual void scrollCallback(double xoffset, double yoffset)
{
trace("scrollCallback: xoffset=%lf, yoffset=%lf\n", xoffset, yoffset);
}
virtual void keyCallback(int key, int scancode, int action, int mods)
{
trace("keyCallback: key=%d, scancode=%d, action=%d, mods%d\n",
key, scancode, action, mods);
}
virtual void charCallback(unsigned int codepoint)
{
trace("charCallback: codepoint=%d\n", codepoint);
}
virtual void charModsCallback(unsigned int codepoint,int mods)
{
trace("charModsCallback: codepoint=%d, mods=%d\n",
codepoint, mods);
}
virtual void dropCallback(int count, const char** paths)
{
trace("dropCallback: count %d\n", count);
for (int i = 0; i<count; i++) {
trace("dropfiles %d %s\n", i, paths[i]);
}
}
void closeWindow()
{
setWindowShouldClose(1);
}
// Public virtual instance callbacks (methods) end.
//////////////////////////////////////////////
// The following methods depend on Win32 API
public:
HWND getHwnd()
{
return glfwGetWin32Window(getWindow());
}
void activate()
{
HWND hwnd = getHwnd();
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE);
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
}
DWORD getModuleFolderName(StringT<char>& folderName)
{
char moduleName[MAX_PATH];
DWORD rc = GetModuleFileName(NULL, moduleName, sizeof(moduleName));
char* name = moduleName;
char* lastSlash = strrchr(moduleName, '\\');
if (lastSlash) {
lastSlash++;
*lastSlash = '\0';
}
folderName = moduleName;
return rc;
}
DWORD getModuleFileName(StringT<char>& fileName)
{
char moduleName[MAX_PATH];
DWORD rc = GetModuleFileName(NULL, moduleName, sizeof(moduleName));
fileName = moduleName;
return rc;
}
//2017/02/10
virtual void getClientSize(int& width, int& height)
{
HWND hwnd = getHwnd();
RECT r;
::GetClientRect(hwnd, &r);
width = r.right - r.left;
height = r.bottom - r.top;
}
virtual void getClientRect(RECT* rect)
{
HWND hwnd = getHwnd();
::GetClientRect(hwnd, rect);
}
void getWindowRect(RECT* rect)
{
HWND hwnd = getHwnd();
::GetWindowRect(hwnd, rect);
}
/* void getWindowSize(int& width, int& height)
{
HWND hwnd = getHwnd();
RECT r;
::GetWindowRect(hwnd, &r);
width = r.right - r.left;
height = r.bottom - r.top;
}
*/
Boolean redraw(const RECT* rect, HRGN rgn, UINT flags)
{
HWND hwnd = getHwnd();
return ::RedrawWindow(hwnd, rect, rgn, flags);
}
Boolean validate(const RECT* r)
{
HWND hwnd = getHwnd();
return ::ValidateRect(hwnd, r);
}
Boolean validate(HRGN r)
{
HWND hwnd = getHwnd();
return ::ValidateRgn(hwnd, r);
}
Boolean send(UINT message, WPARAM wParam, LPARAM lParam,
SENDASYNCPROC callback, DWORD data)
{
HWND hwnd = getHwnd();
return ::SendMessageCallback(hwnd, message,
wParam, lParam, callback, data);
}
long send(UINT message, WPARAM wParam, LPARAM lParam,
UINT flags, UINT timeOut, DWORD* result)
{
HWND hwnd = getHwnd();
return ::SendMessageTimeout(hwnd, message,
wParam, lParam, flags, timeOut, result);
}
long sendNotify(UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hwnd = getHwnd();
return ::SendNotifyMessage(hwnd, message,
wParam, lParam);
}
Boolean invalidateAll()
{
HWND hwnd = getHwnd();
RECT r;
getClientRect(&r);
return ::InvalidateRect(hwnd, &r, TRUE);
}
Boolean invalidate(const RECT* rect, Boolean flag = TRUE)
{
HWND hwnd = getHwnd();
return ::InvalidateRect(hwnd, rect, flag);
}
Boolean invalidate(HRGN r, Boolean flag = TRUE)
{
HWND hwnd = getHwnd();
return ::InvalidateRgn(hwnd, r, flag);
}
long post(UINT message, WPARAM wParam=0, LPARAM lParam=0)
{
HWND hwnd = getHwnd();
return ::PostMessage(hwnd, message, wParam, lParam);
}
int getWidth()
{
HWND hwnd = getHwnd();
RECT r;
::GetClientRect(hwnd, &r);
return r.right - r.left;
}
int getHeight()
{
HWND hwnd = getHwnd();
RECT r;
::GetClientRect(hwnd, &r);
return r.bottom - r.top;
}
virtual void postResizeRequest(int w, int h)
{
post(WM_SIZE, 0, MAKELONG(w, h));
}
virtual void postRenderRequest()
{
post(WM_PAINT, 0, 0);
}
};
}
Last modified: 10 Feb 2017
Copyright (c) 2009-2017 Antillia.com ALL RIGHTS RESERVED.