mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
auto_start (wip)
This commit is contained in:
parent
6d1facae8c
commit
76679a765f
@ -19,14 +19,39 @@ class coreapi(solo):
|
|||||||
# single .dll (or dylib, or whatever).
|
# single .dll (or dylib, or whatever).
|
||||||
file('p3d_plugin.dll')
|
file('p3d_plugin.dll')
|
||||||
|
|
||||||
class splash(solo):
|
class images(package):
|
||||||
# We also store the default splash image, as "solo". Well, it
|
# The default startup images are stored as their own package.
|
||||||
# has to go somewhere.
|
names = ['download', 'play_click', 'play_ready', 'play_rollover',
|
||||||
splashFilename = Filename('maps/panda_splash.jpg')
|
'auth_click', 'auth_ready', 'auth_rollover']
|
||||||
if splashFilename.resolveFilename(getModelPath().getValue()):
|
configDict = {}
|
||||||
file(splashFilename, newName = 'splash.jpg')
|
for name in names:
|
||||||
else:
|
# Look for a png image first.
|
||||||
print "Could not locate %s" % (splashFilename)
|
basename = '%s.png' % (name)
|
||||||
|
filename = Filename('plugin_images/%s' % (basename))
|
||||||
|
found = filename.resolveFilename(getModelPath().getValue())
|
||||||
|
if not found:
|
||||||
|
# Then try a jpeg image.
|
||||||
|
basename = '%s.jpg' % (name)
|
||||||
|
filename = Filename('plugin_images/%s' % (basename))
|
||||||
|
found = filename.resolveFilename(getModelPath().getValue())
|
||||||
|
|
||||||
|
if found:
|
||||||
|
# Add the image file to the package
|
||||||
|
file(filename, newName = basename, extract = True)
|
||||||
|
|
||||||
|
# And set the config variable to reference it.
|
||||||
|
token = '%s_img' % (name)
|
||||||
|
configDict[token] = basename
|
||||||
|
else:
|
||||||
|
print "Could not locate %s" % (filename)
|
||||||
|
|
||||||
|
# Also make a few special cases. We use the same default image
|
||||||
|
# for both download and launch.
|
||||||
|
download = configDict.get('download_img', None)
|
||||||
|
if download:
|
||||||
|
configDict['launch_img'] = download
|
||||||
|
|
||||||
|
config(**configDict)
|
||||||
|
|
||||||
class panda3d(package):
|
class panda3d(package):
|
||||||
# The core Panda3D package. Contains Python and most of the graphics
|
# The core Panda3D package. Contains Python and most of the graphics
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#define BUILD_DIRECTORY $[and $[HAVE_P3D_PLUGIN],$[HAVE_TINYXML],$[HAVE_OPENSSL],$[HAVE_ZLIB]]
|
#define BUILD_DIRECTORY $[and $[HAVE_P3D_PLUGIN],$[HAVE_TINYXML],$[HAVE_OPENSSL],$[HAVE_ZLIB]]
|
||||||
|
|
||||||
#begin lib_target
|
#begin lib_target
|
||||||
#define BUILD_TARGET $[HAVE_JPEG]
|
#define BUILD_TARGET $[and $[HAVE_JPEG],$[HAVE_PNG]]
|
||||||
#define USE_PACKAGES tinyxml openssl zlib jpeg x11
|
#define USE_PACKAGES tinyxml openssl zlib jpeg png x11
|
||||||
#define TARGET p3d_plugin
|
#define TARGET p3d_plugin
|
||||||
#define LIB_PREFIX
|
#define LIB_PREFIX
|
||||||
|
|
||||||
@ -111,7 +111,7 @@
|
|||||||
interrogatedb:c dconfig:c dtoolconfig:m \
|
interrogatedb:c dconfig:c dtoolconfig:m \
|
||||||
express:c pandaexpress:m \
|
express:c pandaexpress:m \
|
||||||
prc:c pstatclient:c pandabase:c linmath:c putil:c \
|
prc:c pstatclient:c pandabase:c linmath:c putil:c \
|
||||||
pipeline:c event:c nativenet:c net:c panda:m
|
pipeline:c event:c nativenet:c net:c display:c panda:m
|
||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
binaryXml.cxx binaryXml.h \
|
binaryXml.cxx binaryXml.h \
|
||||||
@ -138,7 +138,7 @@
|
|||||||
interrogatedb:c dconfig:c dtoolconfig:m \
|
interrogatedb:c dconfig:c dtoolconfig:m \
|
||||||
express:c pandaexpress:m \
|
express:c pandaexpress:m \
|
||||||
prc:c pstatclient:c pandabase:c linmath:c putil:c \
|
prc:c pstatclient:c pandabase:c linmath:c putil:c \
|
||||||
pipeline:c event:c nativenet:c net:c panda:m
|
pipeline:c event:c nativenet:c net:c display:c panda:m
|
||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
binaryXml.cxx binaryXml.h \
|
binaryXml.cxx binaryXml.h \
|
||||||
|
@ -94,3 +94,38 @@ inline bool P3DInstance::
|
|||||||
is_started() const {
|
is_started() const {
|
||||||
return (_session != NULL);
|
return (_session != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::ImageFile::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline P3DInstance::ImageFile::
|
||||||
|
ImageFile() {
|
||||||
|
_use_standard_image = true;
|
||||||
|
_temp_filename = NULL;
|
||||||
|
_image_placement = P3DSplashWindow::IP_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::ImageFile::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline P3DInstance::ImageFile::
|
||||||
|
~ImageFile() {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::ImageFile::cleanup
|
||||||
|
// Access: Public
|
||||||
|
// Description: Removes the temporary file, if any.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline void P3DInstance::ImageFile::
|
||||||
|
cleanup() {
|
||||||
|
if (_temp_filename != NULL) {
|
||||||
|
delete _temp_filename;
|
||||||
|
_temp_filename = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -45,6 +45,19 @@ typedef P3DX11SplashWindow SplashWindowType;
|
|||||||
typedef P3DSplashWindow SplashWindowType;
|
typedef P3DSplashWindow SplashWindowType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// These are the various image files we might download for use in the
|
||||||
|
// splash window. This list must match the ImageType enum.
|
||||||
|
const char *P3DInstance::_image_type_names[P3DInstance::IT_num_image_types] = {
|
||||||
|
"download",
|
||||||
|
"ready",
|
||||||
|
"failed",
|
||||||
|
"launch",
|
||||||
|
"play_ready",
|
||||||
|
"play_rollover",
|
||||||
|
"play_click",
|
||||||
|
"none", // Not really used.
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::Constructor
|
// Function: P3DInstance::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -62,8 +75,9 @@ P3DInstance(P3D_request_ready_func *func,
|
|||||||
_user_data = user_data;
|
_user_data = user_data;
|
||||||
_request_pending = false;
|
_request_pending = false;
|
||||||
_temp_p3d_filename = NULL;
|
_temp_p3d_filename = NULL;
|
||||||
_splash_package = NULL;
|
_image_package = NULL;
|
||||||
_temp_splash_image = NULL;
|
_current_background_image = IT_none;
|
||||||
|
_current_button_image = IT_none;
|
||||||
_got_fparams = false;
|
_got_fparams = false;
|
||||||
_got_wparams = false;
|
_got_wparams = false;
|
||||||
|
|
||||||
@ -74,6 +88,7 @@ P3DInstance(P3D_request_ready_func *func,
|
|||||||
_instance_id = inst_mgr->get_unique_id();
|
_instance_id = inst_mgr->get_unique_id();
|
||||||
_hidden = false;
|
_hidden = false;
|
||||||
_allow_python_dev = false;
|
_allow_python_dev = false;
|
||||||
|
_auto_start = false;
|
||||||
_session = NULL;
|
_session = NULL;
|
||||||
_panda3d = NULL;
|
_panda3d = NULL;
|
||||||
_splash_window = NULL;
|
_splash_window = NULL;
|
||||||
@ -124,9 +139,9 @@ P3DInstance::
|
|||||||
(*pi)->remove_instance(this);
|
(*pi)->remove_instance(this);
|
||||||
}
|
}
|
||||||
_packages.clear();
|
_packages.clear();
|
||||||
if (_splash_package != NULL) {
|
if (_image_package != NULL) {
|
||||||
_splash_package->remove_instance(this);
|
_image_package->remove_instance(this);
|
||||||
_splash_package = NULL;
|
_image_package = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_splash_window != NULL) {
|
if (_splash_window != NULL) {
|
||||||
@ -139,11 +154,6 @@ P3DInstance::
|
|||||||
_temp_p3d_filename = NULL;
|
_temp_p3d_filename = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_temp_splash_image != NULL) {
|
|
||||||
delete _temp_splash_image;
|
|
||||||
_temp_splash_image = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (_frame_timer != NULL) {
|
if (_frame_timer != NULL) {
|
||||||
CFRunLoopTimerInvalidate(_frame_timer);
|
CFRunLoopTimerInvalidate(_frame_timer);
|
||||||
@ -221,7 +231,6 @@ set_p3d_url(const string &p3d_url) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
set_p3d_filename(const string &p3d_filename) {
|
set_p3d_filename(const string &p3d_filename) {
|
||||||
_got_fparams = true;
|
|
||||||
_fparams.set_p3d_filename(p3d_filename);
|
_fparams.set_p3d_filename(p3d_filename);
|
||||||
|
|
||||||
_panda_script_object->set_float_property("instanceDownloadProgress", 1.0);
|
_panda_script_object->set_float_property("instanceDownloadProgress", 1.0);
|
||||||
@ -238,6 +247,9 @@ set_p3d_filename(const string &p3d_filename) {
|
|||||||
sstream.seekg(0);
|
sstream.seekg(0);
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
sstream >> doc;
|
sstream >> doc;
|
||||||
|
|
||||||
|
// This also starts required packages downloading. When all
|
||||||
|
// packages have been installed, we will start the instance.
|
||||||
scan_app_desc_file(&doc);
|
scan_app_desc_file(&doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,13 +260,23 @@ set_p3d_filename(const string &p3d_filename) {
|
|||||||
strm << inst_mgr->get_unique_id();
|
strm << inst_mgr->get_unique_id();
|
||||||
_session_key = strm.str();
|
_session_key = strm.str();
|
||||||
|
|
||||||
|
// Until we've done all of the above processing, we haven't fully
|
||||||
|
// committed to having fparams. (Setting this flag down here
|
||||||
|
// instead of up there avoids starting the instance in
|
||||||
|
// scan_app_desc_file(), before we've had a chance to finish
|
||||||
|
// processing this method.)
|
||||||
|
_got_fparams = true;
|
||||||
|
|
||||||
// Generate a special notification: onpluginload, indicating the
|
// Generate a special notification: onpluginload, indicating the
|
||||||
// plugin has read its parameters and is ready to be queried (even
|
// plugin has read its parameters and is ready to be queried (even
|
||||||
// if Python has not yet started).
|
// if Python has not yet started).
|
||||||
send_notify("onpluginload");
|
send_notify("onpluginload");
|
||||||
|
|
||||||
// Now we're ready to start.
|
// Now that we're all set up, start the instance if we're fully
|
||||||
inst_mgr->start_instance(this);
|
// downloaded.
|
||||||
|
if (get_packages_ready() && _got_wparams) {
|
||||||
|
ready_to_start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -331,6 +353,10 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
|
|
||||||
_session->send_command(doc);
|
_session->send_command(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_packages_ready() && _got_fparams) {
|
||||||
|
ready_to_start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -607,14 +633,14 @@ handle_event(P3D_event_data event) {
|
|||||||
// convert the mouse coordinates successfully via
|
// convert the mouse coordinates successfully via
|
||||||
// GlobalToLocal().
|
// GlobalToLocal().
|
||||||
GrafPtr out_port = _wparams.get_parent_window()._port;
|
GrafPtr out_port = _wparams.get_parent_window()._port;
|
||||||
GrafPtr portSave = NULL;
|
GrafPtr port_save = NULL;
|
||||||
Boolean portChanged = QDSwapPort(out_port, &portSave);
|
Boolean port_changed = QDSwapPort(out_port, &port_save);
|
||||||
|
|
||||||
Point pt = er->where;
|
Point pt = er->where;
|
||||||
GlobalToLocal(&pt);
|
GlobalToLocal(&pt);
|
||||||
|
|
||||||
if (portChanged) {
|
if (port_changed) {
|
||||||
QDSwapPort(portSave, NULL);
|
QDSwapPort(port_save, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SubprocessWindowBuffer::Event swb_event;
|
SubprocessWindowBuffer::Event swb_event;
|
||||||
@ -698,12 +724,16 @@ add_package(P3DPackage *package) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_packages.push_back(package);
|
|
||||||
package->add_instance(this);
|
|
||||||
|
|
||||||
if (package->get_package_name() == "panda3d") {
|
if (package->get_package_name() == "panda3d") {
|
||||||
_panda3d = package;
|
_panda3d = package;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_packages.push_back(package);
|
||||||
|
|
||||||
|
// This call must be at the end of this method, because it might
|
||||||
|
// ultimately start the application before it returns (if this was
|
||||||
|
// the last required package).
|
||||||
|
package->add_instance(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -864,6 +894,22 @@ make_xml() {
|
|||||||
return xinstance;
|
return xinstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::splash_button_clicked
|
||||||
|
// Access: Public
|
||||||
|
// Description: Called by the P3DSplashWindow code when the user
|
||||||
|
// clicks the play button visible on the splash window.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
splash_button_clicked() {
|
||||||
|
// If we haven't launched yet, launch now.
|
||||||
|
if (_session == NULL) {
|
||||||
|
set_background_image(IT_launch);
|
||||||
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
inst_mgr->start_instance(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::scan_app_desc_file
|
// Function: P3DInstance::scan_app_desc_file
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -872,6 +918,7 @@ make_xml() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
scan_app_desc_file(TiXmlDocument *doc) {
|
scan_app_desc_file(TiXmlDocument *doc) {
|
||||||
|
cerr << "scan_app_desc_file\n";
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
|
||||||
TiXmlElement *xpackage = doc->FirstChildElement("package");
|
TiXmlElement *xpackage = doc->FirstChildElement("package");
|
||||||
@ -895,8 +942,23 @@ scan_app_desc_file(TiXmlDocument *doc) {
|
|||||||
if (xconfig->QueryIntAttribute("allow_python_dev", &allow_python_dev) == TIXML_SUCCESS) {
|
if (xconfig->QueryIntAttribute("allow_python_dev", &allow_python_dev) == TIXML_SUCCESS) {
|
||||||
_allow_python_dev = (allow_python_dev != 0);
|
_allow_python_dev = (allow_python_dev != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int auto_start = 0;
|
||||||
|
if (xconfig->QueryIntAttribute("auto_start", &auto_start) == TIXML_SUCCESS) {
|
||||||
|
_auto_start = (auto_start != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auto_start is true if it is set in the application itself, or in
|
||||||
|
// the web tokens.
|
||||||
|
if (_fparams.lookup_token_int("auto_start") != 0) {
|
||||||
|
_auto_start = true;
|
||||||
|
}
|
||||||
|
nout << "_auto_start = " << _auto_start << "\n";
|
||||||
|
|
||||||
|
// But auto_start will be set false if the p3d file has not been
|
||||||
|
// signed by an approved signature. TODO.
|
||||||
|
|
||||||
if (_hidden && _got_wparams) {
|
if (_hidden && _got_wparams) {
|
||||||
_wparams.set_window_type(P3D_WT_hidden);
|
_wparams.set_window_type(P3D_WT_hidden);
|
||||||
}
|
}
|
||||||
@ -1069,9 +1131,8 @@ handle_notify_request(const string &message) {
|
|||||||
_splash_window = NULL;
|
_splash_window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_temp_splash_image != NULL) {
|
for (int i = 0; i < (int)IT_num_image_types; ++i) {
|
||||||
delete _temp_splash_image;
|
_image_files[i].cleanup();
|
||||||
_temp_splash_image = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_panda_script_object->set_string_property("status", "open");
|
_panda_script_object->set_string_property("status", "open");
|
||||||
@ -1206,11 +1267,13 @@ make_splash_window() {
|
|||||||
// We're hidden, and so is the splash window.
|
// We're hidden, and so is the splash window.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* temp removing: hack for debugging.
|
||||||
if (_wparams.get_window_type() != P3D_WT_embedded && !_stuff_to_download) {
|
if (_wparams.get_window_type() != P3D_WT_embedded && !_stuff_to_download) {
|
||||||
// If it's a toplevel or fullscreen window, then we don't want a
|
// If it's a toplevel or fullscreen window, then we don't want a
|
||||||
// splash window until we have stuff to download.
|
// splash window until we have stuff to download.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
_splash_window = new SplashWindowType(this);
|
_splash_window = new SplashWindowType(this);
|
||||||
_splash_window->set_wparams(_wparams);
|
_splash_window->set_wparams(_wparams);
|
||||||
@ -1218,34 +1281,117 @@ make_splash_window() {
|
|||||||
|
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
|
||||||
if (!_fparams.has_token("splash_img")) {
|
// Direct the "download" image to the background slot on the splash
|
||||||
// No specific splash image is specified; get the default splash
|
// window for now, while we perform the download.
|
||||||
// image. We do this via the P3DPackage interface, so we can
|
set_background_image(IT_download);
|
||||||
// use the cached version on disk if it's good.
|
|
||||||
P3DHost *host = inst_mgr->get_host(PANDA_PACKAGE_HOST_URL);
|
|
||||||
_splash_package = host->get_package("splash", "");
|
|
||||||
_splash_package->add_instance(this);
|
|
||||||
|
|
||||||
} else {
|
// Go get the required images.
|
||||||
// We have an explicit splash image specified, so just download it
|
for (int i = 0; i < (int)IT_none; ++i) {
|
||||||
// directly. This one won't be cached locally (though the browser
|
string token_keyword = string(_image_type_names[i]) + "_img";
|
||||||
// might be free to cache it).
|
if (!_fparams.has_token(token_keyword)) {
|
||||||
string splash_image_url = _fparams.lookup_token("splash_img");
|
// No specific image for this type is specified; get the default
|
||||||
if (splash_image_url.empty()) {
|
// image. We do this via the P3DPackage interface, so we can
|
||||||
// No splash image. Never mind.
|
// use the cached version on disk if it's good.
|
||||||
return;
|
_image_files[i]._use_standard_image = true;
|
||||||
|
if (_image_package == NULL) {
|
||||||
|
P3DHost *host = inst_mgr->get_host(PANDA_PACKAGE_HOST_URL);
|
||||||
|
_image_package = host->get_package("images", "");
|
||||||
|
_image_package->add_instance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// We have an explicit image specified for this slot, so just
|
||||||
|
// download it directly. This one won't be cached locally
|
||||||
|
// (though the browser might be free to cache it).
|
||||||
|
_image_files[i]._use_standard_image = false;
|
||||||
|
string image_url = _fparams.lookup_token(token_keyword);
|
||||||
|
if (image_url.empty()) {
|
||||||
|
// No splash image. Never mind.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a temporary file to receive the splash image.
|
||||||
|
assert(_image_files[i]._temp_filename == NULL);
|
||||||
|
_image_files[i]._temp_filename = new P3DTemporaryFile(".jpg");
|
||||||
|
|
||||||
|
// Start downloading the requested image.
|
||||||
|
ImageDownload *download = new ImageDownload(this, i);
|
||||||
|
download->set_url(image_url);
|
||||||
|
download->set_filename(_image_files[i]._temp_filename->get_filename());
|
||||||
|
|
||||||
|
start_download(download);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::set_background_image
|
||||||
|
// Access: Private
|
||||||
|
// Description: Specifies the particular image that should be
|
||||||
|
// displayed as the background image in the splash
|
||||||
|
// window. Specify IT_none to take the background image
|
||||||
|
// away.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
set_background_image(ImageType image_type) {
|
||||||
|
if (image_type != _current_background_image) {
|
||||||
|
// Remove the previous image.
|
||||||
|
_image_files[_current_background_image]._image_placement = P3DSplashWindow::IP_none;
|
||||||
|
|
||||||
|
// Install the new image.
|
||||||
|
_current_background_image = image_type;
|
||||||
|
if (_current_background_image != IT_none) {
|
||||||
|
_image_files[_current_background_image]._image_placement = P3DSplashWindow::IP_background;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a temporary file to receive the splash image.
|
// Update the splash window.
|
||||||
assert(_temp_splash_image == NULL);
|
if (_splash_window != NULL) {
|
||||||
_temp_splash_image = new P3DTemporaryFile(".jpg");
|
_splash_window->set_image_filename(_image_files[_current_background_image]._filename, P3DSplashWindow::IP_background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start downloading the requested splash image.
|
////////////////////////////////////////////////////////////////////
|
||||||
SplashDownload *download = new SplashDownload(this);
|
// Function: P3DInstance::set_button_image
|
||||||
download->set_url(splash_image_url);
|
// Access: Private
|
||||||
download->set_filename(_temp_splash_image->get_filename());
|
// Description: Specifies the particular image that should be
|
||||||
|
// displayed as the button image in the splash
|
||||||
|
// window. Specify IT_none to take the button image
|
||||||
|
// away.
|
||||||
|
//
|
||||||
|
// This actually defines a trilogy of button images:
|
||||||
|
// ready, rollover, click.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
set_button_image(ImageType image_type) {
|
||||||
|
if (image_type != _current_button_image) {
|
||||||
|
// Remove the previous image.
|
||||||
|
_image_files[_current_button_image]._image_placement = P3DSplashWindow::IP_none;
|
||||||
|
if (_current_button_image != IT_none) {
|
||||||
|
_image_files[_current_button_image + 1]._image_placement = P3DSplashWindow::IP_none;
|
||||||
|
_image_files[_current_button_image + 2]._image_placement = P3DSplashWindow::IP_none;
|
||||||
|
}
|
||||||
|
|
||||||
start_download(download);
|
// Install the new image.
|
||||||
|
_current_button_image = image_type;
|
||||||
|
if (_current_button_image != IT_none) {
|
||||||
|
_image_files[_current_button_image]._image_placement = P3DSplashWindow::IP_button_ready;
|
||||||
|
_image_files[_current_button_image + 1]._image_placement = P3DSplashWindow::IP_button_rollover;
|
||||||
|
_image_files[_current_button_image + 2]._image_placement = P3DSplashWindow::IP_button_click;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the splash window.
|
||||||
|
if (_splash_window != NULL) {
|
||||||
|
if (_current_button_image != IT_none) {
|
||||||
|
_splash_window->set_image_filename(_image_files[_current_button_image]._filename, P3DSplashWindow::IP_button_ready);
|
||||||
|
_splash_window->set_image_filename(_image_files[_current_button_image + 1]._filename, P3DSplashWindow::IP_button_rollover);
|
||||||
|
_splash_window->set_image_filename(_image_files[_current_button_image + 2]._filename, P3DSplashWindow::IP_button_click);
|
||||||
|
} else {
|
||||||
|
_splash_window->set_image_filename(string(), P3DSplashWindow::IP_button_ready);
|
||||||
|
_splash_window->set_image_filename(string(), P3DSplashWindow::IP_button_rollover);
|
||||||
|
_splash_window->set_image_filename(string(), P3DSplashWindow::IP_button_click);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,13 +1404,10 @@ make_splash_window() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
report_package_info_ready(P3DPackage *package) {
|
report_package_info_ready(P3DPackage *package) {
|
||||||
if (package == _splash_package) {
|
if (package == _image_package) {
|
||||||
// A special case: we just downloaded the splash image, via the
|
// A special case: the image package gets immediately downloaded,
|
||||||
// package interface.
|
// without waiting for anything else.
|
||||||
if (_splash_window != NULL) {
|
package->activate_download();
|
||||||
string filename = package->get_desc_file_pathname();
|
|
||||||
_splash_window->set_image_filename(filename, false);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1361,10 +1504,36 @@ start_next_download() {
|
|||||||
send_notify("ondownloadcomplete");
|
send_notify("ondownloadcomplete");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the session also.
|
// Take down the download progress bar.
|
||||||
if (_session != NULL) {
|
if (_splash_window != NULL) {
|
||||||
_session->report_packages_done(this, true);
|
_splash_window->set_install_progress(0.0);
|
||||||
|
_splash_window->set_install_label("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_got_wparams && _got_fparams) {
|
||||||
|
ready_to_start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::ready_to_start
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called internally when we have got the wparams and
|
||||||
|
// fparams and we have downloaded all required packages.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
ready_to_start() {
|
||||||
|
if (_auto_start) {
|
||||||
|
set_background_image(IT_launch);
|
||||||
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
inst_mgr->start_instance(this);
|
||||||
|
|
||||||
|
} else if (_splash_window != NULL) {
|
||||||
|
// We're fully downloaded, and waiting for the user to click play.
|
||||||
|
set_background_image(IT_ready);
|
||||||
|
set_button_image(IT_play_ready);
|
||||||
|
_splash_window->set_button_active(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,6 +1609,41 @@ void P3DInstance::
|
|||||||
report_package_done(P3DPackage *package, bool success) {
|
report_package_done(P3DPackage *package, bool success) {
|
||||||
nout << "Done downloading " << package->get_package_name()
|
nout << "Done downloading " << package->get_package_name()
|
||||||
<< ": success = " << success << "\n";
|
<< ": success = " << success << "\n";
|
||||||
|
|
||||||
|
if (package == _image_package) {
|
||||||
|
// A special case: we just downloaded the image package, so get
|
||||||
|
// the image files out of it and point them to the splash window.
|
||||||
|
string package_dir = package->get_package_dir();
|
||||||
|
const TiXmlElement *xconfig = package->get_xconfig();
|
||||||
|
if (xconfig == NULL) {
|
||||||
|
nout << "No <config> entry in image package\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < (int)IT_none; ++i) {
|
||||||
|
if (_image_files[i]._use_standard_image) {
|
||||||
|
// This image indexes into the package. Go get the standard
|
||||||
|
// image filename.
|
||||||
|
string token = string(_image_type_names[i]) + "_img";
|
||||||
|
const string *basename = xconfig->Attribute(token);
|
||||||
|
if (basename == NULL) {
|
||||||
|
nout << "No entry in image package for " << token << "\n";
|
||||||
|
} else {
|
||||||
|
string image_filename = package_dir + "/" + *basename;
|
||||||
|
_image_files[i]._filename = image_filename;
|
||||||
|
|
||||||
|
// If the image should be on the window now, and the window
|
||||||
|
// still exists, put it up.
|
||||||
|
if (_splash_window != NULL &&
|
||||||
|
_image_files[i]._image_placement != P3DSplashWindow::IP_none) {
|
||||||
|
P3DSplashWindow::ImagePlacement image_placement = _image_files[i]._image_placement;
|
||||||
|
_splash_window->set_image_filename(image_filename, image_placement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
report_package_progress(package, 1.0);
|
report_package_progress(package, 1.0);
|
||||||
start_next_download();
|
start_next_download();
|
||||||
@ -1615,8 +1819,8 @@ paint_window() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GrafPtr out_port = _wparams.get_parent_window()._port;
|
GrafPtr out_port = _wparams.get_parent_window()._port;
|
||||||
GrafPtr portSave = NULL;
|
GrafPtr port_save = NULL;
|
||||||
Boolean portChanged = QDSwapPort(out_port, &portSave);
|
Boolean port_changed = QDSwapPort(out_port, &port_save);
|
||||||
|
|
||||||
// Make sure the clipping rectangle isn't in the way. Is there a
|
// Make sure the clipping rectangle isn't in the way. Is there a
|
||||||
// better way to eliminate the cliprect from consideration?
|
// better way to eliminate the cliprect from consideration?
|
||||||
@ -1627,8 +1831,8 @@ paint_window() {
|
|||||||
GetPortBitMapForCopyBits(out_port),
|
GetPortBitMapForCopyBits(out_port),
|
||||||
&src_rect, &ddrc_rect, srcCopy, 0);
|
&src_rect, &ddrc_rect, srcCopy, 0);
|
||||||
|
|
||||||
if (portChanged) {
|
if (port_changed) {
|
||||||
QDSwapPort(portSave, NULL);
|
QDSwapPort(port_save, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
DisposeGWorld(pGWorld);
|
DisposeGWorld(pGWorld);
|
||||||
@ -1677,33 +1881,39 @@ timer_callback(CFRunLoopTimerRef timer, void *info) {
|
|||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::SplashDownload::Constructor
|
// Function: P3DInstance::ImageDownload::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DInstance::SplashDownload::
|
P3DInstance::ImageDownload::
|
||||||
SplashDownload(P3DInstance *inst) :
|
ImageDownload(P3DInstance *inst, int index) :
|
||||||
_inst(inst)
|
_inst(inst),
|
||||||
|
_index(index)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::SplashDownload::download_finished
|
// Function: P3DInstance::ImageDownload::download_finished
|
||||||
// Access: Protected, Virtual
|
// Access: Protected, Virtual
|
||||||
// Description: Intended to be overloaded to generate a callback
|
// Description: Intended to be overloaded to generate a callback
|
||||||
// when the download finishes, either successfully or
|
// when the download finishes, either successfully or
|
||||||
// otherwise. The bool parameter is true if the
|
// otherwise. The bool parameter is true if the
|
||||||
// download was successful.
|
// download was successful.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::SplashDownload::
|
void P3DInstance::ImageDownload::
|
||||||
download_finished(bool success) {
|
download_finished(bool success) {
|
||||||
P3DFileDownload::download_finished(success);
|
P3DFileDownload::download_finished(success);
|
||||||
if (success) {
|
if (success) {
|
||||||
// We've successfully downloaded the splash image (directly, not
|
// We've successfully downloaded the image (directly, not via the
|
||||||
// via the package interface). Put it onscreen if our splash
|
// package interface).
|
||||||
// window still exists.
|
_inst->_image_files[_index]._filename = get_filename();
|
||||||
if (_inst->_splash_window != NULL) {
|
|
||||||
_inst->_splash_window->set_image_filename(get_filename(), true);
|
// Put it onscreen if it's supposed to be onscreen now, and our
|
||||||
|
// splash window still exists.
|
||||||
|
if (_inst->_splash_window != NULL &&
|
||||||
|
_inst->_image_files[_index]._image_placement != P3DSplashWindow::IP_none) {
|
||||||
|
P3DSplashWindow::ImagePlacement image_placement = _inst->_image_files[_index]._image_placement;
|
||||||
|
_inst->_splash_window->set_image_filename(get_filename(), image_placement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include "p3dFileParams.h"
|
#include "p3dFileParams.h"
|
||||||
#include "p3dWindowParams.h"
|
#include "p3dWindowParams.h"
|
||||||
#include "p3dReferenceCount.h"
|
#include "p3dReferenceCount.h"
|
||||||
|
#include "p3dSplashWindow.h"
|
||||||
|
#include "p3dTemporaryFile.h"
|
||||||
#include "get_tinyxml.h"
|
#include "get_tinyxml.h"
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -98,15 +100,17 @@ public:
|
|||||||
void request_refresh();
|
void request_refresh();
|
||||||
|
|
||||||
TiXmlElement *make_xml();
|
TiXmlElement *make_xml();
|
||||||
|
void splash_button_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class SplashDownload : public P3DFileDownload {
|
class ImageDownload : public P3DFileDownload {
|
||||||
public:
|
public:
|
||||||
SplashDownload(P3DInstance *inst);
|
ImageDownload(P3DInstance *inst, int index);
|
||||||
protected:
|
protected:
|
||||||
virtual void download_finished(bool success);
|
virtual void download_finished(bool success);
|
||||||
private:
|
private:
|
||||||
P3DInstance *_inst;
|
P3DInstance *_inst;
|
||||||
|
int _index;
|
||||||
};
|
};
|
||||||
class InstanceDownload : public P3DFileDownload {
|
class InstanceDownload : public P3DFileDownload {
|
||||||
public:
|
public:
|
||||||
@ -118,6 +122,20 @@ private:
|
|||||||
P3DInstance *_inst;
|
P3DInstance *_inst;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The different kinds of image files we download for the splash
|
||||||
|
// window.
|
||||||
|
enum ImageType {
|
||||||
|
IT_download,
|
||||||
|
IT_ready,
|
||||||
|
IT_failed,
|
||||||
|
IT_launch,
|
||||||
|
IT_play_ready,
|
||||||
|
IT_play_rollover,
|
||||||
|
IT_play_click,
|
||||||
|
IT_none, // Must be the last value
|
||||||
|
IT_num_image_types, // Not a real value
|
||||||
|
};
|
||||||
|
|
||||||
void scan_app_desc_file(TiXmlDocument *doc);
|
void scan_app_desc_file(TiXmlDocument *doc);
|
||||||
|
|
||||||
void send_browser_script_object();
|
void send_browser_script_object();
|
||||||
@ -127,8 +145,11 @@ private:
|
|||||||
const string &property_name, P3D_object *value,
|
const string &property_name, P3D_object *value,
|
||||||
bool needs_response, int unique_id);
|
bool needs_response, int unique_id);
|
||||||
void make_splash_window();
|
void make_splash_window();
|
||||||
|
void set_background_image(ImageType image_type);
|
||||||
|
void set_button_image(ImageType image_type);
|
||||||
void report_package_info_ready(P3DPackage *package);
|
void report_package_info_ready(P3DPackage *package);
|
||||||
void start_next_download();
|
void start_next_download();
|
||||||
|
void ready_to_start();
|
||||||
void report_instance_progress(double progress);
|
void report_instance_progress(double progress);
|
||||||
void report_package_progress(P3DPackage *package, double progress);
|
void report_package_progress(P3DPackage *package, double progress);
|
||||||
void report_package_done(P3DPackage *package, bool progress);
|
void report_package_done(P3DPackage *package, bool progress);
|
||||||
@ -148,8 +169,25 @@ private:
|
|||||||
P3DMainObject *_panda_script_object;
|
P3DMainObject *_panda_script_object;
|
||||||
|
|
||||||
P3DTemporaryFile *_temp_p3d_filename;
|
P3DTemporaryFile *_temp_p3d_filename;
|
||||||
P3DPackage *_splash_package;
|
|
||||||
P3DTemporaryFile *_temp_splash_image;
|
// For downloading the various images used by the splash window.
|
||||||
|
P3DPackage *_image_package;
|
||||||
|
static const char *_image_type_names[IT_num_image_types];
|
||||||
|
|
||||||
|
class ImageFile {
|
||||||
|
public:
|
||||||
|
inline ImageFile();
|
||||||
|
inline ~ImageFile();
|
||||||
|
inline void cleanup();
|
||||||
|
|
||||||
|
bool _use_standard_image;
|
||||||
|
P3DTemporaryFile *_temp_filename;
|
||||||
|
string _filename;
|
||||||
|
P3DSplashWindow::ImagePlacement _image_placement;
|
||||||
|
};
|
||||||
|
ImageFile _image_files[IT_num_image_types];
|
||||||
|
ImageType _current_background_image;
|
||||||
|
ImageType _current_button_image;
|
||||||
|
|
||||||
bool _got_fparams;
|
bool _got_fparams;
|
||||||
P3DFileParams _fparams;
|
P3DFileParams _fparams;
|
||||||
@ -162,6 +200,7 @@ private:
|
|||||||
string _log_basename;
|
string _log_basename;
|
||||||
bool _hidden;
|
bool _hidden;
|
||||||
bool _allow_python_dev;
|
bool _allow_python_dev;
|
||||||
|
bool _auto_start;
|
||||||
|
|
||||||
P3DSession *_session;
|
P3DSession *_session;
|
||||||
|
|
||||||
@ -220,7 +259,7 @@ private:
|
|||||||
BakedRequests _baked_requests;
|
BakedRequests _baked_requests;
|
||||||
|
|
||||||
friend class P3DSession;
|
friend class P3DSession;
|
||||||
friend class SplashDownload;
|
friend class ImageDownload;
|
||||||
friend class P3DWindowParams;
|
friend class P3DWindowParams;
|
||||||
friend class P3DPackage;
|
friend class P3DPackage;
|
||||||
};
|
};
|
||||||
|
@ -12,3 +12,28 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DOsxSplashWindow::OsxImageData::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline P3DOsxSplashWindow::OsxImageData::
|
||||||
|
OsxImageData() {
|
||||||
|
_raw_data = NULL;
|
||||||
|
_image = NULL;
|
||||||
|
_color_space = NULL;
|
||||||
|
_provider = NULL;
|
||||||
|
_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DOsxSplashWindow::OsxImageData::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline P3DOsxSplashWindow::OsxImageData::
|
||||||
|
~OsxImageData() {
|
||||||
|
dump_image();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -27,10 +27,9 @@ P3DOsxSplashWindow::
|
|||||||
P3DOsxSplashWindow(P3DInstance *inst) :
|
P3DOsxSplashWindow(P3DInstance *inst) :
|
||||||
P3DSplashWindow(inst)
|
P3DSplashWindow(inst)
|
||||||
{
|
{
|
||||||
_image = NULL;
|
|
||||||
_image_data = NULL;
|
|
||||||
_install_progress = 0;
|
_install_progress = 0;
|
||||||
_got_wparams = false;
|
_got_wparams = false;
|
||||||
|
_mouse_active = false;
|
||||||
_toplevel_window = NULL;
|
_toplevel_window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,15 +46,6 @@ P3DOsxSplashWindow::
|
|||||||
DisposeWindow(_toplevel_window);
|
DisposeWindow(_toplevel_window);
|
||||||
_toplevel_window = NULL;
|
_toplevel_window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_image != NULL) {
|
|
||||||
DisposeGWorld(_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_image_data != NULL) {
|
|
||||||
delete[] _image_data;
|
|
||||||
_image_data = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -83,8 +73,8 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
r.left = 10;
|
r.left = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
r.right = r.left + _wparams.get_win_width();
|
r.right = r.left + _win_width;
|
||||||
r.bottom = r.top + _wparams.get_win_height();
|
r.bottom = r.top + _win_height;
|
||||||
WindowAttributes attrib =
|
WindowAttributes attrib =
|
||||||
kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute;
|
kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute;
|
||||||
CreateNewWindow(kDocumentWindowClass, attrib, &r, &_toplevel_window);
|
CreateNewWindow(kDocumentWindowClass, attrib, &r, &_toplevel_window);
|
||||||
@ -93,6 +83,10 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
EventTypeSpec list1[] = {
|
EventTypeSpec list1[] = {
|
||||||
{ kEventClassWindow, kEventWindowDrawContent },
|
{ kEventClassWindow, kEventWindowDrawContent },
|
||||||
//{ kEventClassWindow, kEventWindowUpdate },
|
//{ kEventClassWindow, kEventWindowUpdate },
|
||||||
|
{ kEventClassMouse, kEventMouseUp },
|
||||||
|
{ kEventClassMouse, kEventMouseDown },
|
||||||
|
{ kEventClassMouse, kEventMouseMoved },
|
||||||
|
{ kEventClassMouse, kEventMouseDragged },
|
||||||
};
|
};
|
||||||
|
|
||||||
EventHandlerUPP gEvtHandler = NewEventHandlerUPP(st_event_callback);
|
EventHandlerUPP gEvtHandler = NewEventHandlerUPP(st_event_callback);
|
||||||
@ -113,67 +107,27 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
// Function: P3DOsxSplashWindow::set_image_filename
|
// Function: P3DOsxSplashWindow::set_image_filename
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: Specifies the name of a JPEG image file that is
|
// Description: Specifies the name of a JPEG image file that is
|
||||||
// displayed in the center of the splash window. If
|
// displayed in the center of the splash window.
|
||||||
// image_filename_temp is true, the file is immediately
|
|
||||||
// deleted after it has been read.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DOsxSplashWindow::
|
void P3DOsxSplashWindow::
|
||||||
set_image_filename(const string &image_filename,
|
set_image_filename(const string &image_filename, ImagePlacement image_placement) {
|
||||||
bool image_filename_temp) {
|
switch (image_placement) {
|
||||||
int num_channels;
|
case IP_background:
|
||||||
string data;
|
load_image(_background_image, image_filename);
|
||||||
if (!read_image(image_filename, image_filename_temp,
|
break;
|
||||||
_image_height, _image_width, num_channels, data)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDErr err;
|
case IP_button_ready:
|
||||||
Rect src_rect = { 0, 0, _image_height, _image_width };
|
load_image(_button_ready_image, image_filename);
|
||||||
|
set_button_range(_button_ready_image);
|
||||||
|
break;
|
||||||
|
|
||||||
if (_image != NULL) {
|
case IP_button_rollover:
|
||||||
DisposeGWorld(_image);
|
load_image(_button_rollover_image, image_filename);
|
||||||
_image = NULL;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (_image_data != NULL) {
|
case IP_button_click:
|
||||||
delete[] _image_data;
|
load_image(_button_click_image, image_filename);
|
||||||
_image_data = NULL;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
// Now we need to copy from the RGB source image into the BGRA target image.
|
|
||||||
int row_stride = _image_width * num_channels;
|
|
||||||
int new_row_stride = _image_width * 4;
|
|
||||||
_image_data = new char[new_row_stride * _image_height];
|
|
||||||
for (int yi = 0; yi < _image_height; ++yi) {
|
|
||||||
char *dest = _image_data + yi * new_row_stride;
|
|
||||||
const char *source = data.data() + yi * row_stride;
|
|
||||||
for (int xi = 0; xi < _image_width; ++xi) {
|
|
||||||
char r = source[0];
|
|
||||||
char g = source[1];
|
|
||||||
char b = source[2];
|
|
||||||
#ifndef __BIG_ENDIAN__
|
|
||||||
// Little-endian.
|
|
||||||
dest[0] = b;
|
|
||||||
dest[1] = g;
|
|
||||||
dest[2] = r;
|
|
||||||
dest[3] = 0xff;
|
|
||||||
#else // __BIG_ENDIAN__
|
|
||||||
// Big-endian.
|
|
||||||
dest[0] = 0xff;
|
|
||||||
dest[1] = r;
|
|
||||||
dest[2] = g;
|
|
||||||
dest[3] = b;
|
|
||||||
#endif // __BIG_ENDIAN__
|
|
||||||
source += 3;
|
|
||||||
dest += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = NewGWorldFromPtr(&_image, k32BGRAPixelFormat, &src_rect, 0, 0, 0,
|
|
||||||
_image_data, new_row_stride);
|
|
||||||
if (err != noErr) {
|
|
||||||
nout << " error in NewGWorldFromPtr, called from set_image_filename()\n";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
@ -215,24 +169,58 @@ set_install_progress(double install_progress) {
|
|||||||
bool P3DOsxSplashWindow::
|
bool P3DOsxSplashWindow::
|
||||||
handle_event(P3D_event_data event) {
|
handle_event(P3D_event_data event) {
|
||||||
EventRecord *er = event._event;
|
EventRecord *er = event._event;
|
||||||
if (er->what == updateEvt) {
|
|
||||||
paint_window();
|
// Need to ensure we have the correct port set, in order to
|
||||||
|
// convert the mouse coordinates successfully via
|
||||||
|
// GlobalToLocal().
|
||||||
|
GrafPtr out_port = _wparams.get_parent_window()._port;
|
||||||
|
GrafPtr port_save = NULL;
|
||||||
|
Boolean port_changed = QDSwapPort(out_port, &port_save);
|
||||||
|
|
||||||
|
Point pt = er->where;
|
||||||
|
GlobalToLocal(&pt);
|
||||||
|
|
||||||
|
if (port_changed) {
|
||||||
|
QDSwapPort(port_save, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (er->what) {
|
||||||
|
case updateEvt:
|
||||||
|
paint_window();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mouseDown:
|
||||||
|
set_mouse_data(_mouse_x, _mouse_y, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mouseUp:
|
||||||
|
set_mouse_data(_mouse_x, _mouse_y, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case activateEvt:
|
||||||
|
_mouse_active = ((er->modifiers & 1) != 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mouse_active) {
|
||||||
|
set_mouse_data(pt.h, pt.v, _mouse_down);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DOsxSplashWindow::refresh
|
// Function: P3DOsxSplashWindow::refresh
|
||||||
// Access: Private
|
// Access: Protected, Virtual
|
||||||
// Description: Requests that the window will be repainted.
|
// Description: Requests that the window will be repainted.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DOsxSplashWindow::
|
void P3DOsxSplashWindow::
|
||||||
refresh() {
|
refresh() {
|
||||||
if (_toplevel_window != NULL) {
|
if (_toplevel_window != NULL) {
|
||||||
int win_width = _wparams.get_win_width();
|
Rect r = { 0, 0, _win_height, _win_width };
|
||||||
int win_height = _wparams.get_win_height();
|
|
||||||
|
|
||||||
Rect r = { 0, 0, win_height, win_width };
|
|
||||||
InvalWindowRect(_toplevel_window, &r);
|
InvalWindowRect(_toplevel_window, &r);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -263,60 +251,34 @@ paint_window() {
|
|||||||
portChanged = QDSwapPort(out_port, &portSave);
|
portChanged = QDSwapPort(out_port, &portSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
int win_width = _wparams.get_win_width();
|
Rect r = { 0, 0, _win_height, _win_width };
|
||||||
int win_height = _wparams.get_win_height();
|
|
||||||
|
|
||||||
Rect r = { 0, 0, win_height, win_width };
|
|
||||||
ClipRect(&r);
|
ClipRect(&r);
|
||||||
EraseRect(&r);
|
EraseRect(&r);
|
||||||
|
|
||||||
if (_image != NULL) {
|
paint_image(out_port, _background_image);
|
||||||
Rect src_rect = { 0, 0, _image_height, _image_width };
|
|
||||||
Rect dest_rect;
|
|
||||||
|
|
||||||
// Determine the relative size of image and window.
|
switch (_bstate) {
|
||||||
int win_cx = win_width / 2;
|
case BS_hidden:
|
||||||
int win_cy = win_height / 2;
|
break;
|
||||||
|
case BS_ready:
|
||||||
if (_image_width <= win_width && _image_height <= win_height) {
|
paint_image(out_port, _button_ready_image);
|
||||||
// The bitmap fits within the window; center it.
|
break;
|
||||||
|
case BS_rollover:
|
||||||
// This is the top-left corner of the bitmap in window coordinates.
|
if (!paint_image(out_port, _button_rollover_image)) {
|
||||||
int p_x = win_cx - _image_width / 2;
|
paint_image(out_port, _button_ready_image);
|
||||||
int p_y = win_cy - _image_height / 2;
|
|
||||||
|
|
||||||
dest_rect.left = p_x;
|
|
||||||
dest_rect.top = p_y;
|
|
||||||
dest_rect.right = p_x + _image_width;
|
|
||||||
dest_rect.bottom = p_y + _image_height;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// The bitmap is larger than the window; scale it down.
|
|
||||||
double x_scale = (double)win_width / (double)_image_width;
|
|
||||||
double y_scale = (double)win_height / (double)_image_height;
|
|
||||||
double scale = min(x_scale, y_scale);
|
|
||||||
int sc_width = (int)(_image_width * scale);
|
|
||||||
int sc_height = (int)(_image_height * scale);
|
|
||||||
|
|
||||||
int p_x = win_cx - sc_width / 2;
|
|
||||||
int p_y = win_cy - sc_height / 2;
|
|
||||||
|
|
||||||
dest_rect.left = p_x;
|
|
||||||
dest_rect.top = p_y;
|
|
||||||
dest_rect.right = p_x + sc_width;
|
|
||||||
dest_rect.bottom = p_y + sc_height;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
CopyBits(GetPortBitMapForCopyBits(_image),
|
case BS_click:
|
||||||
GetPortBitMapForCopyBits(out_port),
|
if (!paint_image(out_port, _button_click_image)) {
|
||||||
&src_rect, &dest_rect, srcCopy, 0);
|
paint_image(out_port, _button_ready_image);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the progress bar. We don't draw this bar at all unless we
|
// Draw the progress bar. We don't draw this bar at all unless we
|
||||||
// have nonzero progress.
|
// have nonzero progress.
|
||||||
int bar_x, bar_y, bar_width, bar_height;
|
int bar_x, bar_y, bar_width, bar_height;
|
||||||
get_bar_placement(win_width, win_height,
|
get_bar_placement(bar_x, bar_y, bar_width, bar_height);
|
||||||
bar_x, bar_y, bar_width, bar_height);
|
|
||||||
|
|
||||||
if (_install_progress != 0.0) {
|
if (_install_progress != 0.0) {
|
||||||
Rect rbar = { bar_y, bar_x, bar_y + bar_height, bar_x + bar_width };
|
Rect rbar = { bar_y, bar_x, bar_y + bar_height, bar_x + bar_width };
|
||||||
@ -351,7 +313,7 @@ paint_window() {
|
|||||||
int descent = font_info.descent * numer.v / denom.v;
|
int descent = font_info.descent * numer.v / denom.v;
|
||||||
|
|
||||||
int text_width = TextWidth(_install_label.data(), 0, _install_label.size());
|
int text_width = TextWidth(_install_label.data(), 0, _install_label.size());
|
||||||
int text_x = (win_width - text_width) / 2;
|
int text_x = (_win_width - text_width) / 2;
|
||||||
int text_y = bar_y - descent - 8;
|
int text_y = bar_y - descent - 8;
|
||||||
|
|
||||||
Rect rtext = { text_y - ascent - 2, text_x - 2,
|
Rect rtext = { text_y - ascent - 2, text_x - 2,
|
||||||
@ -370,6 +332,155 @@ paint_window() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DOsxSplashWindow::load_image
|
||||||
|
// Access: Private
|
||||||
|
// Description: Loads the named image file into an OsxImageData object.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DOsxSplashWindow::
|
||||||
|
load_image(OsxImageData &image, const string &image_filename) {
|
||||||
|
image.dump_image();
|
||||||
|
string string_data;
|
||||||
|
if (!read_image_data(image, string_data, image_filename)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we need to copy from the RGB (or RGBA) source image into the
|
||||||
|
// BGRA target image.
|
||||||
|
int row_stride = image._width * image._num_channels;
|
||||||
|
int new_row_stride = image._width * 4;
|
||||||
|
image._raw_data = new char[new_row_stride * image._height];
|
||||||
|
for (int yi = 0; yi < image._height; ++yi) {
|
||||||
|
char *dest = image._raw_data + yi * new_row_stride;
|
||||||
|
const char *source = string_data.data() + yi * row_stride;
|
||||||
|
if (image._num_channels == 3) {
|
||||||
|
// Source is RGB.
|
||||||
|
for (int xi = 0; xi < image._width; ++xi) {
|
||||||
|
char r = source[0];
|
||||||
|
char g = source[1];
|
||||||
|
char b = source[2];
|
||||||
|
#ifndef __BIG_ENDIAN__
|
||||||
|
// Little-endian.
|
||||||
|
dest[0] = b;
|
||||||
|
dest[1] = g;
|
||||||
|
dest[2] = r;
|
||||||
|
dest[3] = 0xff;
|
||||||
|
#else // __BIG_ENDIAN__
|
||||||
|
// Big-endian.
|
||||||
|
dest[0] = 0xff;
|
||||||
|
dest[1] = r;
|
||||||
|
dest[2] = g;
|
||||||
|
dest[3] = b;
|
||||||
|
#endif // __BIG_ENDIAN__
|
||||||
|
source += 3;
|
||||||
|
dest += 4;
|
||||||
|
}
|
||||||
|
} else if (image._num_channels == 4) {
|
||||||
|
// Source is RGBA.
|
||||||
|
for (int xi = 0; xi < image._width; ++xi) {
|
||||||
|
char r = source[0];
|
||||||
|
char g = source[1];
|
||||||
|
char b = source[2];
|
||||||
|
char a = source[3];
|
||||||
|
#ifndef __BIG_ENDIAN__
|
||||||
|
// Little-endian.
|
||||||
|
dest[0] = b;
|
||||||
|
dest[1] = g;
|
||||||
|
dest[2] = r;
|
||||||
|
dest[3] = a;
|
||||||
|
#else // __BIG_ENDIAN__
|
||||||
|
// Big-endian.
|
||||||
|
dest[0] = a;
|
||||||
|
dest[1] = r;
|
||||||
|
dest[2] = g;
|
||||||
|
dest[3] = b;
|
||||||
|
#endif // __BIG_ENDIAN__
|
||||||
|
source += 4;
|
||||||
|
dest += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
image._data =
|
||||||
|
CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)image._raw_data,
|
||||||
|
image._height * new_row_stride, kCFAllocatorNull);
|
||||||
|
image._provider = CGDataProviderCreateWithCFData(image._data);
|
||||||
|
image._color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
||||||
|
|
||||||
|
image._image =
|
||||||
|
CGImageCreate(image._width, image._height, 8, 32,
|
||||||
|
new_row_stride, image._color_space,
|
||||||
|
kCGImageAlphaFirst | kCGBitmapByteOrder32Little,
|
||||||
|
image._provider, NULL, false, kCGRenderingIntentDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DOsxSplashWindow::paint_image
|
||||||
|
// Access: Private
|
||||||
|
// Description: Draws the indicated image, centered within the
|
||||||
|
// window. Returns true on success, false if the image
|
||||||
|
// is not defined.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DOsxSplashWindow::
|
||||||
|
paint_image(GrafPtr out_port, const OsxImageData &image) {
|
||||||
|
if (image._image == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGContextRef context;
|
||||||
|
QDErr err = QDBeginCGContext(out_port, &context);
|
||||||
|
if (err != noErr) {
|
||||||
|
nout << "Error: QDBeginCGContext\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have to rely on the clipping rectangle having been set up
|
||||||
|
// correctly in order to get the proper location to draw the image.
|
||||||
|
// This isn't completely right, because if the image is slightly
|
||||||
|
// offscreen, the top left of the clipping rectangle will no longer
|
||||||
|
// correspond to the top left of the original image.
|
||||||
|
CGRect rect = CGContextGetClipBoundingBox(context);
|
||||||
|
|
||||||
|
// Determine the relative size of image and window.
|
||||||
|
int win_cx = _win_width / 2;
|
||||||
|
int win_cy = _win_height / 2;
|
||||||
|
|
||||||
|
if (image._width <= _win_width && image._height <= _win_height) {
|
||||||
|
// The bitmap fits within the window; center it.
|
||||||
|
|
||||||
|
// This is the top-left corner of the bitmap in window coordinates.
|
||||||
|
int p_x = win_cx - image._width / 2;
|
||||||
|
int p_y = win_cy - image._height / 2;
|
||||||
|
|
||||||
|
rect.origin.x += p_x;
|
||||||
|
rect.origin.y += p_y;
|
||||||
|
rect.size.width = image._width;
|
||||||
|
rect.size.height = image._height;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// The bitmap is larger than the window; scale it down.
|
||||||
|
double x_scale = (double)_win_width / (double)image._width;
|
||||||
|
double y_scale = (double)_win_height / (double)image._height;
|
||||||
|
double scale = min(x_scale, y_scale);
|
||||||
|
int sc_width = (int)(image._width * scale);
|
||||||
|
int sc_height = (int)(image._height * scale);
|
||||||
|
|
||||||
|
int p_x = win_cx - sc_width / 2;
|
||||||
|
int p_y = win_cy - sc_height / 2;
|
||||||
|
|
||||||
|
rect.origin.x += p_x;
|
||||||
|
rect.origin.y += p_y;
|
||||||
|
rect.size.width = sc_width;
|
||||||
|
rect.size.height = sc_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGContextDrawImage(context, rect, image._image);
|
||||||
|
|
||||||
|
QDEndCGContext(out_port, &context);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DOsxSplashWindow::st_event_callback
|
// Function: P3DOsxSplashWindow::st_event_callback
|
||||||
// Access: Private, Static
|
// Access: Private, Static
|
||||||
@ -402,11 +513,75 @@ event_callback(EventHandlerCallRef my_handler, EventRef event) {
|
|||||||
case kEventWindowDrawContent:
|
case kEventWindowDrawContent:
|
||||||
paint_window();
|
paint_window();
|
||||||
result = noErr;
|
result = noErr;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kEventClassMouse:
|
||||||
|
switch (kind) {
|
||||||
|
case kEventMouseUp:
|
||||||
|
set_mouse_data(_mouse_x, _mouse_y, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kEventMouseDown:
|
||||||
|
set_mouse_data(_mouse_x, _mouse_y, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kEventMouseMoved:
|
||||||
|
case kEventMouseDragged:
|
||||||
|
{
|
||||||
|
Point point;
|
||||||
|
GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL,
|
||||||
|
sizeof(Point), NULL, (void *)&point);
|
||||||
|
|
||||||
|
GrafPtr port = _wparams.get_parent_window()._port;
|
||||||
|
if (_toplevel_window != NULL) {
|
||||||
|
port = GetWindowPort(_toplevel_window);
|
||||||
|
}
|
||||||
|
GrafPtr port_save = NULL;
|
||||||
|
Boolean port_changed = QDSwapPort(port, &port_save);
|
||||||
|
GlobalToLocal(&point);
|
||||||
|
if (port_changed) {
|
||||||
|
QDSwapPort(port_save, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mouse_data(point.h, point.v, _mouse_down);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DOsxSplashWindow::OsxImageData::dump_image
|
||||||
|
// Access: Public
|
||||||
|
// Description: Frees the previous image data.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DOsxSplashWindow::OsxImageData::
|
||||||
|
dump_image() {
|
||||||
|
if (_image != NULL) {
|
||||||
|
CGImageRelease(_image);
|
||||||
|
_image = NULL;
|
||||||
|
}
|
||||||
|
if (_color_space != NULL) {
|
||||||
|
CGColorSpaceRelease(_color_space);
|
||||||
|
_color_space = NULL;
|
||||||
|
}
|
||||||
|
if (_provider != NULL) {
|
||||||
|
CGDataProviderRelease(_provider);
|
||||||
|
_provider = NULL;
|
||||||
|
}
|
||||||
|
if (_data != NULL) {
|
||||||
|
CFRelease(_data);
|
||||||
|
_data = NULL;
|
||||||
|
}
|
||||||
|
if (_raw_data != NULL) {
|
||||||
|
delete[] _raw_data;
|
||||||
|
_raw_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
@ -35,15 +35,21 @@ public:
|
|||||||
|
|
||||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||||
virtual void set_image_filename(const string &image_filename,
|
virtual void set_image_filename(const string &image_filename,
|
||||||
bool image_filename_temp);
|
ImagePlacement image_placement);
|
||||||
virtual void set_install_label(const string &install_label);
|
virtual void set_install_label(const string &install_label);
|
||||||
virtual void set_install_progress(double install_progress);
|
virtual void set_install_progress(double install_progress);
|
||||||
|
|
||||||
virtual bool handle_event(P3D_event_data event);
|
virtual bool handle_event(P3D_event_data event);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void refresh();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refresh();
|
|
||||||
void paint_window();
|
void paint_window();
|
||||||
|
class OsxImageData;
|
||||||
|
|
||||||
|
void load_image(OsxImageData &image, const string &image_filename);
|
||||||
|
bool paint_image(GrafPtr out_port, const OsxImageData &image);
|
||||||
|
|
||||||
static pascal OSStatus
|
static pascal OSStatus
|
||||||
st_event_callback(EventHandlerCallRef my_handler, EventRef event,
|
st_event_callback(EventHandlerCallRef my_handler, EventRef event,
|
||||||
@ -52,13 +58,32 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool _got_wparams;
|
bool _got_wparams;
|
||||||
GWorldPtr _image;
|
|
||||||
char *_image_data;
|
class OsxImageData : public ImageData {
|
||||||
int _image_height, _image_width;
|
public:
|
||||||
|
inline OsxImageData();
|
||||||
|
inline ~OsxImageData();
|
||||||
|
void dump_image();
|
||||||
|
|
||||||
|
char *_raw_data;
|
||||||
|
CFDataRef _data;
|
||||||
|
CGDataProviderRef _provider;
|
||||||
|
CGColorSpaceRef _color_space;
|
||||||
|
CGImageRef _image;
|
||||||
|
};
|
||||||
|
|
||||||
|
OsxImageData _background_image;
|
||||||
|
OsxImageData _button_ready_image;
|
||||||
|
OsxImageData _button_rollover_image;
|
||||||
|
OsxImageData _button_click_image;
|
||||||
|
|
||||||
string _install_label;
|
string _install_label;
|
||||||
double _install_progress;
|
double _install_progress;
|
||||||
|
|
||||||
|
// Used to track the mouse within the window in the embedded case.
|
||||||
|
bool _mouse_active;
|
||||||
|
|
||||||
|
// Filled only in the non-embedded case.
|
||||||
WindowRef _toplevel_window;
|
WindowRef _toplevel_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,23 +41,6 @@ get_download_size() const {
|
|||||||
return _download_size;
|
return _download_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: P3DPackage::activate_download
|
|
||||||
// Access: Public
|
|
||||||
// Description: Authorizes the package to begin downloading and
|
|
||||||
// unpacking the meat of its data. Until this is
|
|
||||||
// called, the package will download its file
|
|
||||||
// information only, and then wait.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
inline void P3DPackage::
|
|
||||||
activate_download() {
|
|
||||||
_allow_data_download = true;
|
|
||||||
|
|
||||||
if (_info_ready) {
|
|
||||||
begin_data_download();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DPackage::get_ready
|
// Function: P3DPackage::get_ready
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -140,6 +123,17 @@ get_package_display_name() const {
|
|||||||
return _package_display_name;
|
return _package_display_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DPackage::get_xconfig
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the <config> entry of the package desc file,
|
||||||
|
// if any, or NULL if it was not present.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline const TiXmlElement *P3DPackage::
|
||||||
|
get_xconfig() const {
|
||||||
|
return _xconfig;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DPackage::get_desc_file_pathname
|
// Function: P3DPackage::get_desc_file_pathname
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -54,6 +54,7 @@ P3DPackage(P3DHost *host, const string &package_name,
|
|||||||
// file, instead of an xml file and a multifile to unpack.
|
// file, instead of an xml file and a multifile to unpack.
|
||||||
_package_solo = false;
|
_package_solo = false;
|
||||||
|
|
||||||
|
_xconfig = NULL;
|
||||||
_temp_contents_file = NULL;
|
_temp_contents_file = NULL;
|
||||||
|
|
||||||
_info_ready = false;
|
_info_ready = false;
|
||||||
@ -78,6 +79,11 @@ P3DPackage::
|
|||||||
// Tell any pending callbacks that we're no good any more.
|
// Tell any pending callbacks that we're no good any more.
|
||||||
report_done(false);
|
report_done(false);
|
||||||
|
|
||||||
|
if (_xconfig != NULL) {
|
||||||
|
delete _xconfig;
|
||||||
|
_xconfig = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel any pending download.
|
// Cancel any pending download.
|
||||||
if (_active_download != NULL) {
|
if (_active_download != NULL) {
|
||||||
_active_download->cancel();
|
_active_download->cancel();
|
||||||
@ -93,6 +99,38 @@ P3DPackage::
|
|||||||
assert(_instances.empty());
|
assert(_instances.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DPackage::activate_download
|
||||||
|
// Access: Public
|
||||||
|
// Description: Authorizes the package to begin downloading and
|
||||||
|
// unpacking the meat of its data. Until this is
|
||||||
|
// called, the package will download its file
|
||||||
|
// information only, and then wait.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DPackage::
|
||||||
|
activate_download() {
|
||||||
|
if (_allow_data_download) {
|
||||||
|
// Already activated.
|
||||||
|
}
|
||||||
|
|
||||||
|
_allow_data_download = true;
|
||||||
|
|
||||||
|
if (_ready) {
|
||||||
|
// If we've already been downloaded, we can report that now.
|
||||||
|
Instances::iterator ii;
|
||||||
|
for (ii = _instances.begin(); ii != _instances.end(); ++ii) {
|
||||||
|
(*ii)->report_package_done(this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Otherwise, if we've already got the desc file, then start the
|
||||||
|
// download.
|
||||||
|
if (_info_ready) {
|
||||||
|
begin_data_download();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DPackage::add_instance
|
// Function: P3DPackage::add_instance
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -358,6 +396,9 @@ got_desc_file(TiXmlDocument *doc, bool freshly_downloaded) {
|
|||||||
if (display_name_cstr != NULL) {
|
if (display_name_cstr != NULL) {
|
||||||
_package_display_name = display_name_cstr;
|
_package_display_name = display_name_cstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the config entry within this class for others to query.
|
||||||
|
_xconfig = (TiXmlElement *)xconfig->Clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ public:
|
|||||||
inline bool get_info_ready() const;
|
inline bool get_info_ready() const;
|
||||||
inline size_t get_download_size() const;
|
inline size_t get_download_size() const;
|
||||||
|
|
||||||
inline void activate_download();
|
void activate_download();
|
||||||
inline bool get_ready() const;
|
inline bool get_ready() const;
|
||||||
inline bool get_failed() const;
|
inline bool get_failed() const;
|
||||||
inline P3DHost *get_host() const;
|
inline P3DHost *get_host() const;
|
||||||
@ -56,6 +56,7 @@ public:
|
|||||||
inline const string &get_package_name() const;
|
inline const string &get_package_name() const;
|
||||||
inline const string &get_package_version() const;
|
inline const string &get_package_version() const;
|
||||||
inline const string &get_package_display_name() const;
|
inline const string &get_package_display_name() const;
|
||||||
|
inline const TiXmlElement *get_xconfig() const;
|
||||||
|
|
||||||
inline const string &get_desc_file_pathname() const;
|
inline const string &get_desc_file_pathname() const;
|
||||||
inline string get_archive_file_pathname() const;
|
inline string get_archive_file_pathname() const;
|
||||||
@ -119,6 +120,7 @@ private:
|
|||||||
string _package_display_name;
|
string _package_display_name;
|
||||||
string _package_fullname;
|
string _package_fullname;
|
||||||
string _package_dir;
|
string _package_dir;
|
||||||
|
TiXmlElement *_xconfig;
|
||||||
|
|
||||||
P3DTemporaryFile *_temp_contents_file;
|
P3DTemporaryFile *_temp_contents_file;
|
||||||
|
|
||||||
|
@ -109,6 +109,7 @@ P3DPythonRun::
|
|||||||
// Close the write pipe, so the parent process will terminate us.
|
// Close the write pipe, so the parent process will terminate us.
|
||||||
_pipe_write.close();
|
_pipe_write.close();
|
||||||
|
|
||||||
|
// Shut down Python and Panda.
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
|
|
||||||
join_read_thread();
|
join_read_thread();
|
||||||
|
@ -229,15 +229,11 @@ start_instance(P3DInstance *inst) {
|
|||||||
send_command(doc);
|
send_command(doc);
|
||||||
inst->send_browser_script_object();
|
inst->send_browser_script_object();
|
||||||
|
|
||||||
if (inst->get_packages_ready()) {
|
// We shouldn't have gotten here unless the instance is fully
|
||||||
// If it's ready immediately, go ahead and start.
|
// downloaded and ready to start.
|
||||||
start_p3dpython(inst);
|
assert(inst->get_packages_ready());
|
||||||
|
|
||||||
} else {
|
start_p3dpython(inst);
|
||||||
// Otherwise, wait for the instance to download itself. We'll
|
|
||||||
// automatically get a callback to report_packages_done() when
|
|
||||||
// it's done.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -641,18 +637,6 @@ drop_p3dobj(int object_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: P3DSession::report_packages_done
|
|
||||||
// Access: Private
|
|
||||||
// Description: Notified when a child instance is fully downloaded.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void P3DSession::
|
|
||||||
report_packages_done(P3DInstance *inst, bool success) {
|
|
||||||
if (success) {
|
|
||||||
start_p3dpython(inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DSession::start_p3dpython
|
// Function: P3DSession::start_p3dpython
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -61,7 +61,6 @@ public:
|
|||||||
void drop_p3dobj(int object_id);
|
void drop_p3dobj(int object_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void report_packages_done(P3DInstance *inst, bool success);
|
|
||||||
void start_p3dpython(P3DInstance *inst);
|
void start_p3dpython(P3DInstance *inst);
|
||||||
|
|
||||||
void spawn_read_thread();
|
void spawn_read_thread();
|
||||||
|
@ -32,3 +32,15 @@ inline const P3DWindowParams &P3DSplashWindow::
|
|||||||
get_wparams() const {
|
get_wparams() const {
|
||||||
return _wparams;
|
return _wparams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::ImageData::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline P3DSplashWindow::ImageData::
|
||||||
|
ImageData() {
|
||||||
|
_width = 0;
|
||||||
|
_height = 0;
|
||||||
|
_num_channels = 0;
|
||||||
|
}
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "p3dSplashWindow.h"
|
#include "p3dSplashWindow.h"
|
||||||
|
|
||||||
|
// Stuff to use libpng.
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
// Stuff to use libjpeg.
|
// Stuff to use libjpeg.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -52,6 +54,16 @@ P3DSplashWindow(P3DInstance *inst) :
|
|||||||
_fparams(inst->get_fparams()),
|
_fparams(inst->get_fparams()),
|
||||||
_wparams(inst->get_wparams())
|
_wparams(inst->get_wparams())
|
||||||
{
|
{
|
||||||
|
_button_width = 0;
|
||||||
|
_button_height = 0;
|
||||||
|
_button_x = 0;
|
||||||
|
_button_y = 0;
|
||||||
|
_button_active = false;
|
||||||
|
_mouse_x = -1;
|
||||||
|
_mouse_y = -1;
|
||||||
|
_mouse_down = false;
|
||||||
|
_button_depressed = false;
|
||||||
|
_bstate = BS_hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -73,22 +85,23 @@ P3DSplashWindow::
|
|||||||
void P3DSplashWindow::
|
void P3DSplashWindow::
|
||||||
set_wparams(const P3DWindowParams &wparams) {
|
set_wparams(const P3DWindowParams &wparams) {
|
||||||
_wparams = wparams;
|
_wparams = wparams;
|
||||||
|
_win_width = _wparams.get_win_width();
|
||||||
|
_win_height = _wparams.get_win_height();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DSplashWindow::set_image_filename
|
// Function: P3DSplashWindow::set_image_filename
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: Specifies the name of a JPEG image file that is
|
// Description: Specifies the name of a JPEG or PNG image file that
|
||||||
// displayed in the center of the splash window. If
|
// is displayed in the center of the splash window.
|
||||||
// image_filename_temp is true, the file is immediately
|
//
|
||||||
// deleted after it has been read.
|
// image_placement defines the specific context in which
|
||||||
|
// this particular image is displayed. It is similar to
|
||||||
|
// the P3DInstance's image_type, but it is a more
|
||||||
|
// specific, lower-level usage.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DSplashWindow::
|
void P3DSplashWindow::
|
||||||
set_image_filename(const string &image_filename,
|
set_image_filename(const string &image_filename, ImagePlacement image_placement) {
|
||||||
bool image_filename_temp) {
|
|
||||||
if (image_filename_temp) {
|
|
||||||
unlink(image_filename.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -122,35 +135,84 @@ handle_event(P3D_event_data event) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::set_button_active
|
||||||
|
// Access: Public
|
||||||
|
// Description: Sets whether the button should be visible and active
|
||||||
|
// (true) or invisible and inactive (false). If active,
|
||||||
|
// the button image will be displayed in the window, and
|
||||||
|
// a click event will be generated when the user clicks
|
||||||
|
// the button.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DSplashWindow::
|
||||||
|
set_button_active(bool flag) {
|
||||||
|
_button_active = flag;
|
||||||
|
|
||||||
|
// Now light up the button according to the current mouse position.
|
||||||
|
set_mouse_data(_mouse_x, _mouse_y, _mouse_down);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DSplashWindow::read_image
|
// Function: P3DSplashWindow::read_image_data
|
||||||
// Access: Protected
|
// Access: Protected
|
||||||
// Description: Reads the image filename and sets image parameters
|
// Description: Reads the image filename and sets image parameters
|
||||||
// height, width, num_channels, and data. Returns true
|
// width, height, num_channels, and data. Returns true
|
||||||
// on success, false on failure. If image_filename_temp
|
// on success, false on failure.
|
||||||
// is true, the file will be deleted after reading.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool P3DSplashWindow::
|
bool P3DSplashWindow::
|
||||||
read_image(const string &image_filename, bool image_filename_temp,
|
read_image_data(ImageData &image, string &data,
|
||||||
int &height, int &width, int &num_channels,
|
const string &image_filename) {
|
||||||
string &data) {
|
image._width = 0;
|
||||||
height = 0;
|
image._height = 0;
|
||||||
width = 0;
|
image._num_channels = 0;
|
||||||
num_channels = 0;
|
|
||||||
data.clear();
|
data.clear();
|
||||||
|
|
||||||
// We currently only support JPEG images. Maybe that's all we'll
|
// We only support JPEG or PNG images.
|
||||||
// ever support.
|
|
||||||
FILE *fp = fopen(image_filename.c_str(), "rb");
|
FILE *fp = fopen(image_filename.c_str(), "rb");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
nout << "Couldn't open splash file image: " << image_filename << "\n";
|
nout << "Couldn't open splash file image: " << image_filename << "\n";
|
||||||
if (image_filename_temp) {
|
|
||||||
unlink(image_filename.c_str());
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the magic number to determine which image type we have.
|
||||||
|
static const size_t magic_number_len = 2;
|
||||||
|
char magic_number[magic_number_len];
|
||||||
|
if (fread(magic_number, 1, magic_number_len, fp) != magic_number_len) {
|
||||||
|
nout << "Empty file: " << image_filename << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Rewind to re-read the magic number below.
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
if ((char)magic_number[0] == (char)0xff &&
|
||||||
|
(char)magic_number[1] == (char)0xd8) {
|
||||||
|
// It's a jpeg image.
|
||||||
|
result = read_image_data_jpeg(image, data, fp, image_filename);
|
||||||
|
|
||||||
|
} else if (png_sig_cmp((png_bytep)magic_number, 0, magic_number_len) == 0) {
|
||||||
|
// It's a PNG image.
|
||||||
|
result = read_image_data_png(image, data, fp, image_filename);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nout << "Neither a JPEG nor a PNG image: " << image_filename << "\n";
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::read_image_data_jpeg
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Reads the image filename and sets image parameters
|
||||||
|
// width, height, num_channels, and data. Returns true
|
||||||
|
// on success, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DSplashWindow::
|
||||||
|
read_image_data_jpeg(ImageData &image, string &data,
|
||||||
|
FILE *fp, const string &image_filename) {
|
||||||
// We set up the normal JPEG error routines, then override error_exit.
|
// We set up the normal JPEG error routines, then override error_exit.
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
|
|
||||||
@ -167,15 +229,10 @@ read_image(const string &image_filename, bool image_filename_temp,
|
|||||||
|
|
||||||
// We need to clean up the JPEG object, close the input file, and return.
|
// We need to clean up the JPEG object, close the input file, and return.
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image_filename_temp) {
|
|
||||||
unlink(image_filename.c_str());
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,13 +247,13 @@ read_image(const string &image_filename, bool image_filename_temp,
|
|||||||
|
|
||||||
jpeg_start_decompress(&cinfo);
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
width = cinfo.output_width;
|
image._width = cinfo.output_width;
|
||||||
height = cinfo.output_height;
|
image._height = cinfo.output_height;
|
||||||
num_channels = cinfo.output_components;
|
image._num_channels = cinfo.output_components;
|
||||||
|
|
||||||
int row_stride = width * num_channels;
|
int row_stride = image._width * image._num_channels;
|
||||||
|
|
||||||
size_t buffer_size = height * row_stride;
|
size_t buffer_size = image._height * row_stride;
|
||||||
buffer = new JSAMPLE[buffer_size];
|
buffer = new JSAMPLE[buffer_size];
|
||||||
JSAMPLE *buffer_end = buffer + buffer_size;
|
JSAMPLE *buffer_end = buffer + buffer_size;
|
||||||
|
|
||||||
@ -209,17 +266,99 @@ read_image(const string &image_filename, bool image_filename_temp,
|
|||||||
|
|
||||||
jpeg_finish_decompress(&cinfo);
|
jpeg_finish_decompress(&cinfo);
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
if (image_filename_temp) {
|
|
||||||
unlink(image_filename.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
data.append((const char *)buffer, buffer_size);
|
data.append((const char *)buffer, buffer_size);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::read_image_data_png
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Reads the image filename and sets image parameters
|
||||||
|
// width, height, num_channels, and data. Returns true
|
||||||
|
// on success, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DSplashWindow::
|
||||||
|
read_image_data_png(ImageData &image, string &data,
|
||||||
|
FILE *fp, const string &image_filename) {
|
||||||
|
cerr << "read_image_data_png\n";
|
||||||
|
png_structp png;
|
||||||
|
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
||||||
|
png_error, png_warning);
|
||||||
|
if (png == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_infop info;
|
||||||
|
info = png_create_info_struct(png);
|
||||||
|
if (info == NULL) {
|
||||||
|
png_destroy_read_struct(&png, NULL, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmp_buf jmpbuf;
|
||||||
|
if (setjmp(jmpbuf)) {
|
||||||
|
// This is the ANSI C way to handle exceptions. If setjmp(),
|
||||||
|
// above, returns true, it means that libpng detected an exception
|
||||||
|
// while executing the code that reads the header info, below.
|
||||||
|
png_destroy_read_struct(&png, &info, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_init_io(png, fp);
|
||||||
|
int transforms = PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_SHIFT;
|
||||||
|
// transforms |= PNG_TRANSFORM_STRIP_ALPHA;
|
||||||
|
png_read_png(png, info, transforms, NULL);
|
||||||
|
|
||||||
|
png_uint_32 width;
|
||||||
|
png_uint_32 height;
|
||||||
|
int bit_depth;
|
||||||
|
int color_type;
|
||||||
|
|
||||||
|
png_get_IHDR(png, info, &width, &height,
|
||||||
|
&bit_depth, &color_type, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
cerr
|
||||||
|
<< "width = " << width << " height = " << height << " bit_depth = "
|
||||||
|
<< bit_depth << " color_type = " << color_type << "\n";
|
||||||
|
|
||||||
|
image._width = width;
|
||||||
|
image._height = height;
|
||||||
|
|
||||||
|
switch (color_type) {
|
||||||
|
case PNG_COLOR_TYPE_RGB:
|
||||||
|
cerr
|
||||||
|
<< "PNG_COLOR_TYPE_RGB\n";
|
||||||
|
image._num_channels = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||||
|
cerr
|
||||||
|
<< "PNG_COLOR_TYPE_RGB_ALPHA\n";
|
||||||
|
image._num_channels = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
cerr
|
||||||
|
<< "Unsupported color type: " << color_type << "\n";
|
||||||
|
png_destroy_read_struct(&png, &info, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int row_stride = image._width * image._num_channels;
|
||||||
|
png_bytep *row_pointers = png_get_rows(png, info);
|
||||||
|
for (int yi = 0; yi < image._height; ++yi) {
|
||||||
|
data.append((const char *)row_pointers[yi], row_stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
png_destroy_read_struct(&png, &info, NULL);
|
||||||
|
|
||||||
|
cerr << "successfully read\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DSplashWindow::get_bar_placement
|
// Function: P3DSplashWindow::get_bar_placement
|
||||||
// Access: Protected
|
// Access: Protected
|
||||||
@ -227,11 +366,128 @@ read_image(const string &image_filename, bool image_filename_temp,
|
|||||||
// rectangle in which to place the progress bar.
|
// rectangle in which to place the progress bar.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DSplashWindow::
|
void P3DSplashWindow::
|
||||||
get_bar_placement(int win_width, int win_height,
|
get_bar_placement(int &bar_x, int &bar_y,
|
||||||
int &bar_x, int &bar_y,
|
|
||||||
int &bar_width, int &bar_height) {
|
int &bar_width, int &bar_height) {
|
||||||
bar_width = min((int)(win_width * 0.6), 400);
|
bar_width = min((int)(_win_width * 0.6), 400);
|
||||||
bar_height = min((int)(win_height * 0.1), 24);
|
bar_height = min((int)(_win_height * 0.1), 24);
|
||||||
bar_x = (win_width - bar_width) / 2;
|
bar_x = (_win_width - bar_width) / 2;
|
||||||
bar_y = (win_height - bar_height * 2);
|
bar_y = (_win_height - bar_height * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::set_button_range
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Specifies the image that contains the "ready" button
|
||||||
|
// image, which in turn determines the clickable
|
||||||
|
// dimensions of the button within the window.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DSplashWindow::
|
||||||
|
set_button_range(const ImageData &image) {
|
||||||
|
// The clickable area has a certain minimum size, even if it's a
|
||||||
|
// very small image.
|
||||||
|
_button_width = max(image._width, 64);
|
||||||
|
_button_height = max(image._height, 64);
|
||||||
|
|
||||||
|
// But it can't be larger than the window itself.
|
||||||
|
_button_width = min(_button_width, _win_width);
|
||||||
|
_button_height = min(_button_height, _win_height);
|
||||||
|
|
||||||
|
// Compute the top-left corner of the button image in window
|
||||||
|
// coordinates.
|
||||||
|
_button_x = (_win_width - _button_width) / 2;
|
||||||
|
_button_y = (_win_height - _button_height) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::set_mouse_data
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Intended to be called by the subclasses as the mouse
|
||||||
|
// is tracked through the window, whether the button is
|
||||||
|
// currently active or not. This updates the internal
|
||||||
|
// state of the mouse pointer, and also (if the button
|
||||||
|
// is active) updates the button state appropriately,
|
||||||
|
// and generates the click event when the mouse button
|
||||||
|
// transitions from down to up over the button area.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DSplashWindow::
|
||||||
|
set_mouse_data(int mouse_x, int mouse_y, bool mouse_down) {
|
||||||
|
ButtonState orig_bstate = _bstate;
|
||||||
|
|
||||||
|
_mouse_x = mouse_x;
|
||||||
|
_mouse_y = mouse_y;
|
||||||
|
_mouse_down = mouse_down;
|
||||||
|
|
||||||
|
if (!_button_active) {
|
||||||
|
// The button isn't active, so it's hidden, regardless of the
|
||||||
|
// mouse position.
|
||||||
|
_bstate = BS_hidden;
|
||||||
|
} else {
|
||||||
|
// Is the mouse pointer within the button region?
|
||||||
|
bool is_within = (_mouse_x >= _button_x && _mouse_x < _button_x + _button_width &&
|
||||||
|
_mouse_y >= _button_y && _mouse_y < _button_y + _button_height);
|
||||||
|
if (is_within) {
|
||||||
|
// The mouse is within the button region. This means either
|
||||||
|
// click or rollover state, according to the mouse button.
|
||||||
|
if (_mouse_down) {
|
||||||
|
// We only count it mouse-down if you've clicked down while
|
||||||
|
// over the button (or you never released the button since the
|
||||||
|
// last time you clicked down). Clicking down somewhere else
|
||||||
|
// and dragging over the button doesn't count.
|
||||||
|
if (orig_bstate == BS_rollover || _button_depressed) {
|
||||||
|
_button_depressed = true;
|
||||||
|
_bstate = BS_click;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_button_depressed = false;
|
||||||
|
if (orig_bstate == BS_click) {
|
||||||
|
// If we just transitioned from mouse down to mouse up, this
|
||||||
|
// means a click. And the button automatically hides itself
|
||||||
|
// after a successful click.
|
||||||
|
_bstate = BS_hidden;
|
||||||
|
_button_active = false;
|
||||||
|
button_click_detected();
|
||||||
|
} else {
|
||||||
|
_bstate = BS_rollover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The mouse is not within the button region. This means ready
|
||||||
|
// state.
|
||||||
|
_bstate = BS_ready;
|
||||||
|
if (!_mouse_down) {
|
||||||
|
_button_depressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orig_bstate != _bstate) {
|
||||||
|
// If we've changed button states, we need to refresh the window.
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::button_click_detected
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Called when a button click by the user is detected in
|
||||||
|
// set_mouse_data(), this method simply turns around and
|
||||||
|
// notifies the instance. It's a virtual method to give
|
||||||
|
// subclasses a chance to redirect this message to the
|
||||||
|
// main thread or process, as necessary.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DSplashWindow::
|
||||||
|
button_click_detected() {
|
||||||
|
assert(_inst != NULL);
|
||||||
|
_inst->splash_button_clicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::refresh
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Requests that the window will be repainted. This may
|
||||||
|
// or may not be implemented for a particular
|
||||||
|
// specialization of P3DSplashWindow.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DSplashWindow::
|
||||||
|
refresh() {
|
||||||
}
|
}
|
||||||
|
@ -42,26 +42,72 @@ public:
|
|||||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||||
inline const P3DWindowParams &get_wparams() const;
|
inline const P3DWindowParams &get_wparams() const;
|
||||||
|
|
||||||
|
enum ImagePlacement {
|
||||||
|
IP_background,
|
||||||
|
IP_button_ready,
|
||||||
|
IP_button_rollover,
|
||||||
|
IP_button_click,
|
||||||
|
IP_none
|
||||||
|
};
|
||||||
|
|
||||||
virtual void set_image_filename(const string &image_filename,
|
virtual void set_image_filename(const string &image_filename,
|
||||||
bool image_filename_temp);
|
ImagePlacement image_placement);
|
||||||
virtual void set_install_label(const string &install_label);
|
virtual void set_install_label(const string &install_label);
|
||||||
virtual void set_install_progress(double install_progress);
|
virtual void set_install_progress(double install_progress);
|
||||||
|
|
||||||
virtual bool handle_event(P3D_event_data event);
|
virtual bool handle_event(P3D_event_data event);
|
||||||
|
|
||||||
void setup_splash_image();
|
void set_button_active(bool flag);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool read_image(const string &image_filename, bool image_filename_temp,
|
// This ImageData base class provides minimal functionality for
|
||||||
int &height, int &width, int &num_channels, string &data);
|
// storing a loaded image. Most of the real meat of this class is
|
||||||
void get_bar_placement(int win_width, int win_height,
|
// provided by the various subclasses.
|
||||||
int &bar_x, int &bar_y,
|
class ImageData {
|
||||||
|
public:
|
||||||
|
inline ImageData();
|
||||||
|
int _width, _height, _num_channels;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool read_image_data(ImageData &image, string &data,
|
||||||
|
const string &image_filename);
|
||||||
|
bool read_image_data_jpeg(ImageData &image, string &data,
|
||||||
|
FILE *fp, const string &image_filename);
|
||||||
|
bool read_image_data_png(ImageData &image, string &data,
|
||||||
|
FILE *fp, const string &image_filename);
|
||||||
|
void get_bar_placement(int &bar_x, int &bar_y,
|
||||||
int &bar_width, int &bar_height);
|
int &bar_width, int &bar_height);
|
||||||
|
void set_button_range(const ImageData &image);
|
||||||
|
void set_mouse_data(int mouse_x, int mouse_y, bool mouse_down);
|
||||||
|
|
||||||
|
virtual void button_click_detected();
|
||||||
|
virtual void refresh();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
P3DInstance *_inst;
|
P3DInstance *_inst;
|
||||||
P3DFileParams _fparams;
|
P3DFileParams _fparams;
|
||||||
P3DWindowParams _wparams;
|
P3DWindowParams _wparams;
|
||||||
|
int _win_width, _win_height;
|
||||||
|
|
||||||
|
// The region of the window for accepting button clicks.
|
||||||
|
int _button_width, _button_height;
|
||||||
|
int _button_x, _button_y;
|
||||||
|
bool _button_active;
|
||||||
|
|
||||||
|
// Tracking the mouse pointer within the window, for the purposes of
|
||||||
|
// clicking the button.
|
||||||
|
int _mouse_x, _mouse_y;
|
||||||
|
bool _mouse_down;
|
||||||
|
bool _button_depressed;
|
||||||
|
|
||||||
|
// The current visual state of the button.
|
||||||
|
enum ButtonState {
|
||||||
|
BS_hidden,
|
||||||
|
BS_ready,
|
||||||
|
BS_rollover,
|
||||||
|
BS_click,
|
||||||
|
};
|
||||||
|
ButtonState _bstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "p3dSplashWindow.I"
|
#include "p3dSplashWindow.I"
|
||||||
|
@ -35,7 +35,6 @@ P3DWinSplashWindow(P3DInstance *inst) :
|
|||||||
_text_label = NULL;
|
_text_label = NULL;
|
||||||
_thread_running = false;
|
_thread_running = false;
|
||||||
_image_filename_changed = false;
|
_image_filename_changed = false;
|
||||||
_image_filename_temp = false;
|
|
||||||
_install_label_changed = false;
|
_install_label_changed = false;
|
||||||
_install_progress = 0.0;
|
_install_progress = 0.0;
|
||||||
|
|
||||||
@ -74,18 +73,14 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
// Function: P3DWinSplashWindow::set_image_filename
|
// Function: P3DWinSplashWindow::set_image_filename
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: Specifies the name of a JPEG image file that is
|
// Description: Specifies the name of a JPEG image file that is
|
||||||
// displayed in the center of the splash window. If
|
// displayed in the center of the splash window.
|
||||||
// image_filename_temp is true, the file is immediately
|
|
||||||
// deleted after it has been read.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DWinSplashWindow::
|
void P3DWinSplashWindow::
|
||||||
set_image_filename(const string &image_filename,
|
set_image_filename(const string &image_filename, ImagePlacement image_placement) {
|
||||||
bool image_filename_temp) {
|
|
||||||
nout << "image_filename = " << image_filename << ", thread_id = " << _thread_id << "\n";
|
nout << "image_filename = " << image_filename << ", thread_id = " << _thread_id << "\n";
|
||||||
ACQUIRE_LOCK(_install_lock);
|
ACQUIRE_LOCK(_install_lock);
|
||||||
if (_image_filename != image_filename) {
|
if (_image_filename != image_filename) {
|
||||||
_image_filename = image_filename;
|
_image_filename = image_filename;
|
||||||
_image_filename_temp = image_filename_temp;
|
|
||||||
_image_filename_changed = true;
|
_image_filename_changed = true;
|
||||||
}
|
}
|
||||||
RELEASE_LOCK(_install_lock);
|
RELEASE_LOCK(_install_lock);
|
||||||
@ -264,7 +259,7 @@ thread_run() {
|
|||||||
ACQUIRE_LOCK(_install_lock);
|
ACQUIRE_LOCK(_install_lock);
|
||||||
double install_progress = _install_progress;
|
double install_progress = _install_progress;
|
||||||
if (_image_filename_changed) {
|
if (_image_filename_changed) {
|
||||||
update_image_filename(_image_filename, _image_filename_temp);
|
update_image_filename(_image_filename);
|
||||||
}
|
}
|
||||||
_image_filename_changed = false;
|
_image_filename_changed = false;
|
||||||
if (_install_label_changed && _progress_bar != NULL) {
|
if (_install_label_changed && _progress_bar != NULL) {
|
||||||
@ -395,14 +390,8 @@ make_progress_bar() {
|
|||||||
DWORD window_style =
|
DWORD window_style =
|
||||||
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||||
|
|
||||||
RECT rect;
|
|
||||||
GetClientRect(_hwnd, &rect);
|
|
||||||
int win_width = rect.right - rect.left;
|
|
||||||
int win_height = rect.bottom - rect.top;
|
|
||||||
|
|
||||||
int bar_x, bar_y, bar_width, bar_height;
|
int bar_x, bar_y, bar_width, bar_height;
|
||||||
get_bar_placement(win_width, win_height,
|
get_bar_placement(bar_x, bar_y, bar_width, bar_height);
|
||||||
bar_x, bar_y, bar_width, bar_height);
|
|
||||||
|
|
||||||
_progress_bar =
|
_progress_bar =
|
||||||
CreateWindowEx(0, PROGRESS_CLASS, "", window_style,
|
CreateWindowEx(0, PROGRESS_CLASS, "", window_style,
|
||||||
@ -450,18 +439,12 @@ update_install_label(const string &install_label) {
|
|||||||
DWORD window_style =
|
DWORD window_style =
|
||||||
SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||||
|
|
||||||
RECT rect;
|
|
||||||
GetClientRect(_hwnd, &rect);
|
|
||||||
int win_width = rect.right - rect.left;
|
|
||||||
int win_height = rect.bottom - rect.top;
|
|
||||||
|
|
||||||
int bar_x, bar_y, bar_width, bar_height;
|
int bar_x, bar_y, bar_width, bar_height;
|
||||||
get_bar_placement(win_width, win_height,
|
get_bar_placement(bar_x, bar_y, bar_width, bar_height);
|
||||||
bar_x, bar_y, bar_width, bar_height);
|
|
||||||
|
|
||||||
int text_width = text_size.cx + 4;
|
int text_width = text_size.cx + 4;
|
||||||
int text_height = text_size.cy + 2;
|
int text_height = text_size.cy + 2;
|
||||||
int text_x = (win_width - text_width) / 2;
|
int text_x = (_win_width - text_width) / 2;
|
||||||
int text_y = bar_y - text_height - 2;
|
int text_y = bar_y - text_height - 2;
|
||||||
|
|
||||||
_text_label = CreateWindowEx(0, "STATIC", text, window_style,
|
_text_label = CreateWindowEx(0, "STATIC", text, window_style,
|
||||||
@ -478,7 +461,7 @@ update_install_label(const string &install_label) {
|
|||||||
// sub-thread.
|
// sub-thread.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DWinSplashWindow::
|
void P3DWinSplashWindow::
|
||||||
update_image_filename(const string &image_filename, bool image_filename_temp) {
|
update_image_filename(const string &image_filename) {
|
||||||
// Clear the old image.
|
// Clear the old image.
|
||||||
if (_bitmap != NULL) {
|
if (_bitmap != NULL) {
|
||||||
DeleteObject(_bitmap);
|
DeleteObject(_bitmap);
|
||||||
@ -491,12 +474,16 @@ update_image_filename(const string &image_filename, bool image_filename_temp) {
|
|||||||
|
|
||||||
// Go read the image.
|
// Go read the image.
|
||||||
string data;
|
string data;
|
||||||
int num_channels;
|
ImageData image;
|
||||||
if (!read_image(image_filename, image_filename_temp,
|
if (!read_image_data(image, data, image_filename)) {
|
||||||
_bitmap_height, _bitmap_width, num_channels, data)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temp legacy support.
|
||||||
|
_bitmap_width = image._width;
|
||||||
|
_bitmap_height = image._height;
|
||||||
|
int num_channels =image._num_channels;
|
||||||
|
|
||||||
// Massage the data into Windows' conventions.
|
// Massage the data into Windows' conventions.
|
||||||
int row_stride = _bitmap_width * num_channels;
|
int row_stride = _bitmap_width * num_channels;
|
||||||
int new_row_stride = (_bitmap_width * 3);
|
int new_row_stride = (_bitmap_width * 3);
|
||||||
@ -591,8 +578,8 @@ void P3DWinSplashWindow::
|
|||||||
paint_window(HDC dc) {
|
paint_window(HDC dc) {
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetClientRect(_hwnd, &rect);
|
GetClientRect(_hwnd, &rect);
|
||||||
int win_width = rect.right - rect.left;
|
_win_width = rect.right - rect.left;
|
||||||
int win_height = rect.bottom - rect.top;
|
_win_height = rect.bottom - rect.top;
|
||||||
|
|
||||||
if (_bitmap != NULL) {
|
if (_bitmap != NULL) {
|
||||||
// Paint the background splash image.
|
// Paint the background splash image.
|
||||||
@ -603,10 +590,10 @@ paint_window(HDC dc) {
|
|||||||
int bm_width = _bitmap_width;
|
int bm_width = _bitmap_width;
|
||||||
int bm_height = _bitmap_height;
|
int bm_height = _bitmap_height;
|
||||||
|
|
||||||
int win_cx = win_width / 2;
|
int win_cx = _win_width / 2;
|
||||||
int win_cy = win_height / 2;
|
int win_cy = _win_height / 2;
|
||||||
|
|
||||||
if (bm_width <= win_width && bm_height <= win_height) {
|
if (bm_width <= _win_width && bm_height <= _win_height) {
|
||||||
// The bitmap fits within the window; center it.
|
// The bitmap fits within the window; center it.
|
||||||
|
|
||||||
// This is the top-left corner of the bitmap in window coordinates.
|
// This is the top-left corner of the bitmap in window coordinates.
|
||||||
@ -621,8 +608,8 @@ paint_window(HDC dc) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// The bitmap is larger than the window; scale it down.
|
// The bitmap is larger than the window; scale it down.
|
||||||
double x_scale = (double)win_width / (double)bm_width;
|
double x_scale = (double)_win_width / (double)bm_width;
|
||||||
double y_scale = (double)win_height / (double)bm_height;
|
double y_scale = (double)_win_height / (double)bm_height;
|
||||||
double scale = min(x_scale, y_scale);
|
double scale = min(x_scale, y_scale);
|
||||||
int sc_width = (int)(bm_width * scale);
|
int sc_width = (int)(bm_width * scale);
|
||||||
int sc_height = (int)(bm_height * scale);
|
int sc_height = (int)(bm_height * scale);
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
|
|
||||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||||
virtual void set_image_filename(const string &image_filename,
|
virtual void set_image_filename(const string &image_filename,
|
||||||
bool image_filename_temp);
|
ImagePlacement image_placement);
|
||||||
virtual void set_install_label(const string &install_label);
|
virtual void set_install_label(const string &install_label);
|
||||||
virtual void set_install_progress(double install_progress);
|
virtual void set_install_progress(double install_progress);
|
||||||
|
|
||||||
@ -55,8 +55,7 @@ private:
|
|||||||
void make_window();
|
void make_window();
|
||||||
void make_progress_bar();
|
void make_progress_bar();
|
||||||
void update_install_label(const string &install_label);
|
void update_install_label(const string &install_label);
|
||||||
void update_image_filename(const string &image_filename,
|
void update_image_filename(const string &image_filename);
|
||||||
bool image_filename_temp);
|
|
||||||
void close_window();
|
void close_window();
|
||||||
|
|
||||||
void paint_window(HDC dc);
|
void paint_window(HDC dc);
|
||||||
@ -67,7 +66,6 @@ private:
|
|||||||
bool _got_install;
|
bool _got_install;
|
||||||
bool _image_filename_changed;
|
bool _image_filename_changed;
|
||||||
string _image_filename;
|
string _image_filename;
|
||||||
bool _image_filename_temp;
|
|
||||||
bool _install_label_changed;
|
bool _install_label_changed;
|
||||||
string _install_label;
|
string _install_label;
|
||||||
double _install_progress;
|
double _install_progress;
|
||||||
|
@ -58,7 +58,6 @@ P3DX11SplashWindow(P3DInstance *inst) :
|
|||||||
_resized_height = 0;
|
_resized_height = 0;
|
||||||
_graphics_context = None;
|
_graphics_context = None;
|
||||||
_bar_context = None;
|
_bar_context = None;
|
||||||
_image_filename_temp = false;
|
|
||||||
_install_progress = 0.0;
|
_install_progress = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,13 +91,10 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
// Function: P3DX11SplashWindow::set_image_filename
|
// Function: P3DX11SplashWindow::set_image_filename
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: Specifies the name of a JPEG image file that is
|
// Description: Specifies the name of a JPEG image file that is
|
||||||
// displayed in the center of the splash window. If
|
// displayed in the center of the splash window.
|
||||||
// image_filename_temp is true, the file is immediately
|
|
||||||
// deleted after it has been read.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DX11SplashWindow::
|
void P3DX11SplashWindow::
|
||||||
set_image_filename(const string &image_filename,
|
set_image_filename(const string &image_filename, ImagePlacement image_placement) {
|
||||||
bool image_filename_temp) {
|
|
||||||
if (_subprocess_pid == -1) {
|
if (_subprocess_pid == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -107,7 +103,6 @@ set_image_filename(const string &image_filename,
|
|||||||
TiXmlElement *xcommand = new TiXmlElement("command");
|
TiXmlElement *xcommand = new TiXmlElement("command");
|
||||||
xcommand->SetAttribute("cmd", "set_image_filename");
|
xcommand->SetAttribute("cmd", "set_image_filename");
|
||||||
xcommand->SetAttribute("image_filename", image_filename);
|
xcommand->SetAttribute("image_filename", image_filename);
|
||||||
xcommand->SetAttribute("image_filename_temp", (int)image_filename_temp);
|
|
||||||
doc.LinkEndChild(xcommand);
|
doc.LinkEndChild(xcommand);
|
||||||
write_xml(_pipe_write, &doc, nout);
|
write_xml(_pipe_write, &doc, nout);
|
||||||
|
|
||||||
@ -367,7 +362,7 @@ subprocess_run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_image_filename != prev_image_filename) {
|
if (_image_filename != prev_image_filename) {
|
||||||
update_image_filename(_image_filename, _image_filename_temp);
|
update_image_filename(_image_filename);
|
||||||
needs_redraw = true;
|
needs_redraw = true;
|
||||||
prev_image_filename = _image_filename;
|
prev_image_filename = _image_filename;
|
||||||
}
|
}
|
||||||
@ -401,8 +396,7 @@ subprocess_run() {
|
|||||||
// some nonzero progress.
|
// some nonzero progress.
|
||||||
if (_install_progress != 0.0) {
|
if (_install_progress != 0.0) {
|
||||||
int bar_x, bar_y, bar_width, bar_height;
|
int bar_x, bar_y, bar_width, bar_height;
|
||||||
get_bar_placement(_width, _height,
|
get_bar_placement(bar_x, bar_y, bar_width, bar_height);
|
||||||
bar_x, bar_y, bar_width, bar_height);
|
|
||||||
|
|
||||||
if (needs_draw_label) {
|
if (needs_draw_label) {
|
||||||
int text_width = _install_label.size() * 6;
|
int text_width = _install_label.size() * 6;
|
||||||
@ -485,12 +479,9 @@ receive_command() {
|
|||||||
|
|
||||||
} else if (strcmp(cmd, "set_image_filename") == 0) {
|
} else if (strcmp(cmd, "set_image_filename") == 0) {
|
||||||
const char *str = xcommand->Attribute("image_filename");
|
const char *str = xcommand->Attribute("image_filename");
|
||||||
int image_filename_temp = 0;
|
|
||||||
xcommand->Attribute("image_filename_temp", &image_filename_temp);
|
|
||||||
if (str != NULL) {
|
if (str != NULL) {
|
||||||
if (_image_filename != string(str)) {
|
if (_image_filename != string(str)) {
|
||||||
_image_filename = str;
|
_image_filename = str;
|
||||||
_image_filename_temp = image_filename_temp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,11 +561,11 @@ make_window() {
|
|||||||
int x = _wparams.get_win_x();
|
int x = _wparams.get_win_x();
|
||||||
int y = _wparams.get_win_y();
|
int y = _wparams.get_win_y();
|
||||||
|
|
||||||
_width = 320;
|
_win_width = 320;
|
||||||
_height = 240;
|
_win_height = 240;
|
||||||
if (_wparams.get_win_width() != 0 && _wparams.get_win_height() != 0) {
|
if (_wparams.get_win_width() != 0 && _wparams.get_win_height() != 0) {
|
||||||
_width = _wparams.get_win_width();
|
_win_width = _wparams.get_win_width();
|
||||||
_height = _wparams.get_win_height();
|
_win_height = _wparams.get_win_height();
|
||||||
}
|
}
|
||||||
|
|
||||||
Window parent = 0;
|
Window parent = 0;
|
||||||
@ -602,7 +593,7 @@ make_window() {
|
|||||||
|
|
||||||
assert(_display != NULL);
|
assert(_display != NULL);
|
||||||
assert(parent != None);
|
assert(parent != None);
|
||||||
_window = XCreateSimpleWindow(_display, parent, x, y, _width, _height, 0, 0, -1);
|
_window = XCreateSimpleWindow(_display, parent, x, y, _win_width, _win_height, 0, 0, -1);
|
||||||
XMapWindow(_display, _window);
|
XMapWindow(_display, _window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,7 +689,7 @@ close_window() {
|
|||||||
// sub-thread.
|
// sub-thread.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DX11SplashWindow::
|
void P3DX11SplashWindow::
|
||||||
update_image_filename(const string &image_filename, bool image_filename_temp) {
|
update_image_filename(const string &image_filename) {
|
||||||
// Clear the old image.
|
// Clear the old image.
|
||||||
if (_image != NULL) {
|
if (_image != NULL) {
|
||||||
XDestroyImage(_image);
|
XDestroyImage(_image);
|
||||||
@ -711,12 +702,16 @@ update_image_filename(const string &image_filename, bool image_filename_temp) {
|
|||||||
|
|
||||||
// Go read the image.
|
// Go read the image.
|
||||||
string data;
|
string data;
|
||||||
int num_channels;
|
ImageData image;
|
||||||
if (!read_image(image_filename, image_filename_temp,
|
if (!read_image_data(image, data, image_filename)) {
|
||||||
_image_height, _image_width, num_channels, data)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temp legacy support.
|
||||||
|
_image_width = image._width;
|
||||||
|
_image_height = image._height;
|
||||||
|
int num_channels =image._num_channels;
|
||||||
|
|
||||||
Visual *dvisual = DefaultVisual(_display, _screen);
|
Visual *dvisual = DefaultVisual(_display, _screen);
|
||||||
double r_ratio = dvisual->red_mask / 255.0;
|
double r_ratio = dvisual->red_mask / 255.0;
|
||||||
double g_ratio = dvisual->green_mask / 255.0;
|
double g_ratio = dvisual->green_mask / 255.0;
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
|
|
||||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||||
virtual void set_image_filename(const string &image_filename,
|
virtual void set_image_filename(const string &image_filename,
|
||||||
bool image_filename_temp);
|
ImagePlacement image_placement);
|
||||||
virtual void set_install_label(const string &install_label);
|
virtual void set_install_label(const string &install_label);
|
||||||
virtual void set_install_progress(double install_progress);
|
virtual void set_install_progress(double install_progress);
|
||||||
|
|
||||||
@ -59,19 +59,16 @@ private:
|
|||||||
void redraw();
|
void redraw();
|
||||||
void make_window();
|
void make_window();
|
||||||
void setup_gc();
|
void setup_gc();
|
||||||
void update_image_filename(const string &image_filename,
|
void update_image_filename(const string &image_filename);
|
||||||
bool image_filename_temp);
|
|
||||||
void close_window();
|
void close_window();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Data members that are stored in the subprocess.
|
// Data members that are stored in the subprocess.
|
||||||
bool _subprocess_continue;
|
bool _subprocess_continue;
|
||||||
HandleStream _pipe_read;
|
HandleStream _pipe_read;
|
||||||
int _width, _height;
|
|
||||||
|
|
||||||
bool _own_display;
|
bool _own_display;
|
||||||
string _image_filename;
|
string _image_filename;
|
||||||
bool _image_filename_temp;
|
|
||||||
string _install_label;
|
string _install_label;
|
||||||
double _install_progress;
|
double _install_progress;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user