crude initial start of gtk-2.0 port of pstats server
This commit is contained in:
parent
f71601ce86
commit
d1f039f707
|
|
@ -1,27 +1,33 @@
|
|||
#define BUILD_DIRECTORY $[and $[HAVE_GTKMM],$[HAVE_NET]]
|
||||
#define USE_PACKAGES net gtkmm
|
||||
#define BUILD_DIRECTORY $[and $[HAVE_GTK],$[HAVE_NET]]
|
||||
#define USE_PACKAGES net gtk
|
||||
|
||||
#begin bin_target
|
||||
#define TARGET gtk-stats
|
||||
// We rename TARGET to gtk-pstats on Windows, so it won't compete
|
||||
// with Windows-native pstats.
|
||||
#define TARGET $[if $[WINDOWS_PLATFORM],gtk-pstats,pstats]
|
||||
#define LOCAL_LIBS \
|
||||
gtkbase progbase pstatserver
|
||||
progbase pstatserver
|
||||
#define OTHER_LIBS \
|
||||
pstatclient:c linmath:c putil:c net:c express:c panda:m \
|
||||
interrogatedb:c dtoolutil:c dtoolbase:c prc:c dconfig:c dtoolconfig:m dtool:m
|
||||
#define UNIX_SYS_LIBS \
|
||||
m
|
||||
pstatclient:c linmath:c putil:c net:c express:c pandaexpress:m panda:m \
|
||||
dtoolutil:c dtoolbase:c prc:c dconfig:c dtoolconfig:m dtool:m \
|
||||
pystub
|
||||
|
||||
#define SOURCES \
|
||||
gtkStats.cxx gtkStats.h \
|
||||
gtkStatsBadVersionWindow.cxx gtkStatsBadVersionWindow.h \
|
||||
gtkStatsGuide.cxx gtkStatsGuide.h \
|
||||
gtkStatsLabel.cxx gtkStatsLabel.h gtkStatsMainWindow.cxx \
|
||||
gtkStatsMainWindow.h gtkStatsMonitor.cxx gtkStatsMonitor.h \
|
||||
gtkStatsPianoRoll.I gtkStatsPianoRoll.cxx gtkStatsPianoRoll.h \
|
||||
gtkStatsPianoWindow.cxx gtkStatsPianoWindow.h gtkStatsServer.cxx \
|
||||
gtkStatsServer.h gtkStatsStripChart.I gtkStatsStripChart.cxx \
|
||||
gtkStatsStripChart.h gtkStatsStripWindow.cxx gtkStatsStripWindow.h \
|
||||
gtkStatsWindow.cxx gtkStatsWindow.h
|
||||
gtkStats.cxx \
|
||||
gtkStatsGraph.cxx gtkStatsGraph.h \
|
||||
gtkStatsLabel.cxx gtkStatsLabel.h \
|
||||
gtkStatsLabelStack.cxx gtkStatsLabelStack.h \
|
||||
gtkStatsMenuId.h \
|
||||
gtkStatsMonitor.cxx gtkStatsMonitor.h gtkStatsMonitor.I \
|
||||
gtkStatsServer.cxx gtkStatsServer.h \
|
||||
gtkStatsStripChart.cxx gtkStatsStripChart.h
|
||||
|
||||
// gtkStatsChartMenu.cxx gtkStatsChartMenu.h \
|
||||
// gtkStatsPianoRoll.cxx gtkStatsPianoRoll.h \
|
||||
|
||||
#if $[DEVELOP_GTKSTATS]
|
||||
#define EXTRA_CDEFS $[EXTRA_CDEFS] DEVELOP_GTKSTATS
|
||||
#endif
|
||||
|
||||
#end bin_target
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStats.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -16,67 +16,85 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "gtkStats.h"
|
||||
#include "gtkStatsMainWindow.h"
|
||||
|
||||
#include "pStatServer.h"
|
||||
#include "gtkStatsServer.h"
|
||||
#include "config_pstats.h"
|
||||
|
||||
#include <signal.h>
|
||||
GtkWidget *main_window;
|
||||
static GtkStatsServer *server = NULL;
|
||||
|
||||
GtkStatsMainWindow *GtkStats::_main_window = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStats::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStats::
|
||||
GtkStats() {
|
||||
set_program_description
|
||||
("This is a fancy GUI PStats server that listens on a TCP port for a "
|
||||
"connection from a PStatClient in a Panda player. It will then "
|
||||
"draw strip charts illustrating the performance stats as reported "
|
||||
"by the player.");
|
||||
|
||||
add_option
|
||||
("p", "port", 0,
|
||||
"Specify the TCP port to listen for connections on. By default, this "
|
||||
"is taken from the pstats-host Config variable.",
|
||||
&GtkStats::dispatch_int, NULL, &_port);
|
||||
|
||||
_port = pstats_port;
|
||||
static gboolean
|
||||
delete_event(GtkWidget *widget,
|
||||
GdkEvent *event, gpointer data) {
|
||||
// Returning FALSE to indicate we should destroy the main window
|
||||
// when the user selects "close".
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStats::run
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStats::
|
||||
run() {
|
||||
new GtkStatsMainWindow(_port);
|
||||
|
||||
main_loop();
|
||||
static void
|
||||
destroy(GtkWidget *widget, gpointer data) {
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStats::quit
|
||||
// Access: Public, Static
|
||||
// Description: Call this to cleanly shut down the program.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStats::
|
||||
quit() {
|
||||
if (_main_window != (GtkStatsMainWindow *)NULL) {
|
||||
_main_window->destruct();
|
||||
static gboolean
|
||||
timer(gpointer data) {
|
||||
server->poll();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
gtk_window_set_title(GTK_WINDOW(main_window), "PStats");
|
||||
|
||||
// Connect the delete and destroy events, so the user can exit the
|
||||
// application by closing the main window.
|
||||
g_signal_connect(G_OBJECT(main_window), "delete_event",
|
||||
G_CALLBACK(delete_event), NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(main_window), "destroy",
|
||||
G_CALLBACK(destroy), NULL);
|
||||
|
||||
ostringstream stream;
|
||||
stream << "Listening on port " << pstats_port;
|
||||
string str = stream.str();
|
||||
GtkWidget *label = gtk_label_new(str.c_str());
|
||||
gtk_container_add(GTK_CONTAINER(main_window), label);
|
||||
gtk_widget_show(label);
|
||||
|
||||
// Create the server object.
|
||||
server = new GtkStatsServer;
|
||||
if (!server->listen()) {
|
||||
ostringstream stream;
|
||||
stream
|
||||
<< "Unable to open port " << pstats_port
|
||||
<< ". Try specifying a different\n"
|
||||
<< "port number using pstats-port in your Config file.";
|
||||
string str = stream.str();
|
||||
|
||||
GtkWidget *dialog =
|
||||
gtk_message_dialog_new(GTK_WINDOW(main_window),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
str.c_str());
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
exit(1);
|
||||
}
|
||||
Gtk::Main::quit();
|
||||
}
|
||||
|
||||
gtk_widget_show(main_window);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
GtkStats prog;
|
||||
prog.parse_command_line(argc, argv);
|
||||
prog.run();
|
||||
return 0;
|
||||
// Set up a timer to poll the pstats every so often.
|
||||
g_timeout_add(200, timer, NULL);
|
||||
|
||||
// Now get lost in the message loop.
|
||||
gtk_main();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStats.h
|
||||
// Created by: drose (14Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -19,27 +19,11 @@
|
|||
#ifndef GTKSTATS_H
|
||||
#define GTKSTATS_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "pStatServer.h"
|
||||
|
||||
#include "gtkBase.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
class GtkStatsMainWindow;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStats
|
||||
// Description : A fancy graphical pstats server written using gtk+
|
||||
// (actually, Gtk--, the C++ layer over gtk+).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStats : public GtkBase {
|
||||
public:
|
||||
GtkStats();
|
||||
|
||||
void run();
|
||||
static void quit();
|
||||
|
||||
int _port;
|
||||
static GtkStatsMainWindow *_main_window;
|
||||
};
|
||||
extern GtkWidget *main_window;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
// Filename: gtkStatsBadVersionWindow.cxx
|
||||
// Created by: drose (18May01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsBadVersionWindow.h"
|
||||
#include "gtkStatsMonitor.h"
|
||||
|
||||
#include "string_utils.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsBadVersionWindow::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsBadVersionWindow::
|
||||
GtkStatsBadVersionWindow(GtkStatsMonitor *monitor,
|
||||
int client_major, int client_minor,
|
||||
int server_major, int server_minor) {
|
||||
set_title("Bad client");
|
||||
|
||||
Gtk::VBox *box1 = new Gtk::VBox;
|
||||
box1->show();
|
||||
box1->set_border_width(8);
|
||||
add(*manage(box1));
|
||||
|
||||
string message =
|
||||
"Rejected connection by " +
|
||||
monitor->get_client_progname() + " from " +
|
||||
monitor->get_client_hostname() + ".\nClient uses PStats version " +
|
||||
format_string(client_major) + "." + format_string(client_minor) +
|
||||
",\nwhile server expects PStats version " +
|
||||
format_string(server_major) + "." + format_string(server_minor) + ".";
|
||||
|
||||
Gtk::Label *label = new Gtk::Label(message);
|
||||
label->show();
|
||||
box1->pack_start(*manage(label), true, false, 8);
|
||||
|
||||
Gtk::HBox *box2 = new Gtk::HBox;
|
||||
box2->show();
|
||||
box1->pack_start(*manage(box2), false, false, 0);
|
||||
|
||||
Gtk::Button *close = new Gtk::Button("Close");
|
||||
close->set_usize(80, 30);
|
||||
close->show();
|
||||
box2->pack_start(*manage(close), true, false, 0);
|
||||
close->clicked.connect(slot(this, &GtkStatsBadVersionWindow::close_clicked));
|
||||
|
||||
setup();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsBadVersionWindow::close_clicked
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsBadVersionWindow::
|
||||
close_clicked() {
|
||||
destruct();
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
// Filename: gtkStatsBadVersionWindow.h
|
||||
// Created by: drose (18May01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKSTATSBADVERSIONWINDOW_H
|
||||
#define GTKSTATSBADVERSIONWINDOW_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "basicGtkWindow.h"
|
||||
|
||||
class GtkStatsMonitor;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsBadVersionWindow
|
||||
// Description : This window is popped up to indicated an attempted
|
||||
// connection from an invalid client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsBadVersionWindow : public BasicGtkWindow {
|
||||
public:
|
||||
GtkStatsBadVersionWindow(GtkStatsMonitor *monitor,
|
||||
int client_major, int client_minor,
|
||||
int server_major, int server_minor);
|
||||
|
||||
private:
|
||||
void close_clicked();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
// Filename: gtkStatsChartMenu.cxx
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsChartMenu.h"
|
||||
#include "gtkStatsMonitor.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsChartMenu::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsChartMenu::
|
||||
GtkStatsChartMenu(GtkStatsMonitor *monitor, int thread_index) :
|
||||
_monitor(monitor),
|
||||
_thread_index(thread_index)
|
||||
{
|
||||
_menu = CreatePopupMenu();
|
||||
do_update();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsChartMenu::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsChartMenu::
|
||||
~GtkStatsChartMenu() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsChartMenu::get_menu_handle
|
||||
// Access: Public
|
||||
// Description: Returns the Windows menu handle for this particular
|
||||
// menu.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
HMENU GtkStatsChartMenu::
|
||||
get_menu_handle() {
|
||||
return _menu;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsChartMenu::add_to_menu_bar
|
||||
// Access: Public
|
||||
// Description: Adds the menu to the end of the indicated menu bar.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsChartMenu::
|
||||
add_to_menu_bar(HMENU menu_bar, int before_menu_id) {
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
string thread_name;
|
||||
if (_thread_index == 0) {
|
||||
// A special case for the main thread.
|
||||
thread_name = "Graphs";
|
||||
} else {
|
||||
thread_name = client_data->get_thread_name(_thread_index);
|
||||
}
|
||||
|
||||
MENUITEMINFO mii;
|
||||
memset(&mii, 0, sizeof(mii));
|
||||
mii.cbSize = sizeof(mii);
|
||||
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
|
||||
mii.fType = MFT_STRING;
|
||||
mii.hSubMenu = _menu;
|
||||
mii.dwTypeData = (char *)thread_name.c_str();
|
||||
InsertMenuItem(menu_bar, before_menu_id, FALSE, &mii);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsChartMenu::check_update
|
||||
// Access: Public
|
||||
// Description: Checks to see if the menu needs to be updated
|
||||
// (e.g. because of new data from the client), and
|
||||
// updates it if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsChartMenu::
|
||||
check_update() {
|
||||
PStatView &view = _monitor->get_view(_thread_index);
|
||||
if (view.get_level_index() != _last_level_index) {
|
||||
do_update();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsChartMenu::do_update
|
||||
// Access: Public
|
||||
// Description: Unconditionally updates the menu with the latest data
|
||||
// from the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsChartMenu::
|
||||
do_update() {
|
||||
PStatView &view = _monitor->get_view(_thread_index);
|
||||
_last_level_index = view.get_level_index();
|
||||
|
||||
// First, remove all of the old entries from the menu.
|
||||
int num_items = GetMenuItemCount(_menu);
|
||||
for (int i = num_items - 1; i >= 0; i--) {
|
||||
DeleteMenu(_menu, i, MF_BYPOSITION);
|
||||
}
|
||||
|
||||
// Now rebuild the menu with the new set of entries.
|
||||
|
||||
// The menu item(s) for the thread's frame time goes first.
|
||||
add_view(_menu, view.get_top_level(), false);
|
||||
|
||||
bool needs_separator = true;
|
||||
MENUITEMINFO mii;
|
||||
memset(&mii, 0, sizeof(mii));
|
||||
mii.cbSize = sizeof(mii);
|
||||
|
||||
// And then the menu item(s) for each of the level values.
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
int num_toplevel_collectors = client_data->get_num_toplevel_collectors();
|
||||
for (int tc = 0; tc < num_toplevel_collectors; tc++) {
|
||||
int collector = client_data->get_toplevel_collector(tc);
|
||||
if (client_data->has_collector(collector) &&
|
||||
client_data->get_collector_has_level(collector)) {
|
||||
|
||||
// We put a separator between the above frame collector and the
|
||||
// first level collector.
|
||||
if (needs_separator) {
|
||||
mii.fMask = MIIM_FTYPE;
|
||||
mii.fType = MFT_SEPARATOR;
|
||||
InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
|
||||
|
||||
needs_separator = false;
|
||||
}
|
||||
|
||||
PStatView &level_view = _monitor->get_level_view(collector, _thread_index);
|
||||
add_view(_menu, level_view.get_top_level(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Also a menu item for a piano roll (following a separator).
|
||||
mii.fMask = MIIM_FTYPE;
|
||||
mii.fType = MFT_SEPARATOR;
|
||||
InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
|
||||
|
||||
GtkStatsMonitor::MenuDef menu_def(_thread_index, -1, false);
|
||||
int menu_id = _monitor->get_menu_id(menu_def);
|
||||
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
|
||||
mii.fType = MFT_STRING;
|
||||
mii.wID = menu_id;
|
||||
mii.dwTypeData = "Piano Roll";
|
||||
InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsChartMenu::add_view
|
||||
// Access: Private
|
||||
// Description: Adds a new entry or entries to the menu for the
|
||||
// indicated view and its children.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsChartMenu::
|
||||
add_view(HMENU parent_menu, const PStatViewLevel *view_level, bool show_level) {
|
||||
int collector = view_level->get_collector();
|
||||
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
string collector_name = client_data->get_collector_name(collector);
|
||||
|
||||
GtkStatsMonitor::MenuDef menu_def(_thread_index, collector, show_level);
|
||||
int menu_id = _monitor->get_menu_id(menu_def);
|
||||
|
||||
MENUITEMINFO mii;
|
||||
memset(&mii, 0, sizeof(mii));
|
||||
mii.cbSize = sizeof(mii);
|
||||
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
|
||||
mii.fType = MFT_STRING;
|
||||
mii.wID = menu_id;
|
||||
mii.dwTypeData = (char *)collector_name.c_str();
|
||||
InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
|
||||
|
||||
int num_children = view_level->get_num_children();
|
||||
if (num_children > 1) {
|
||||
// If the collector has more than one child, add a menu entry to go
|
||||
// directly to each of its children.
|
||||
HMENU submenu = CreatePopupMenu();
|
||||
string submenu_name = collector_name + " components";
|
||||
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
|
||||
mii.fType = MFT_STRING;
|
||||
mii.hSubMenu = submenu;
|
||||
mii.dwTypeData = (char *)submenu_name.c_str();
|
||||
InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
|
||||
|
||||
// Reverse the order since the menus are listed from the top down;
|
||||
// we want to be visually consistent with the graphs, which list
|
||||
// these labels from the bottom up.
|
||||
for (int c = num_children - 1; c >= 0; c--) {
|
||||
add_view(submenu, view_level->get_child(c), show_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
pandatool/src/gtk-stats/gtkStatsPianoWindow.h → pandatool/src/gtk-stats/gtkStatsChartMenu.h
Normal file → Executable file
45
pandatool/src/gtk-stats/gtkStatsPianoWindow.h → pandatool/src/gtk-stats/gtkStatsChartMenu.h
Normal file → Executable file
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsPianoWindow.h
|
||||
// Created by: drose (18Jul00)
|
||||
// Filename: gtkStatsChartMenu.h
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -16,42 +16,43 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKSTATSPIANOWINDOW_H
|
||||
#define GTKSTATSPIANOWINDOW_H
|
||||
#ifndef GTKSTATSCHARTMENU_H
|
||||
#define GTKSTATSCHARTMENU_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "gtkStatsMonitor.h"
|
||||
#include "gtkStatsWindow.h"
|
||||
#include <windows.h>
|
||||
|
||||
class GtkStatsPianoRoll;
|
||||
class GtkStatsMonitor;
|
||||
class PStatView;
|
||||
class PStatViewLevel;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsPianoWindow
|
||||
// Description : A window that contains a GtkStatsPianoRoll.
|
||||
// Class : GtkStatsChartMenu
|
||||
// Description : A pulldown menu of charts available for a particular
|
||||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsPianoWindow : public GtkStatsWindow {
|
||||
class GtkStatsChartMenu {
|
||||
public:
|
||||
GtkStatsPianoWindow(GtkStatsMonitor *monitor, int thread_index,
|
||||
int chart_xsize, int chart_ysize);
|
||||
GtkStatsChartMenu(GtkStatsMonitor *monitor, int thread_index);
|
||||
~GtkStatsChartMenu();
|
||||
|
||||
virtual void mark_dead();
|
||||
virtual void idle();
|
||||
HMENU get_menu_handle();
|
||||
void add_to_menu_bar(HMENU menu_bar, int before_menu_id);
|
||||
|
||||
protected:
|
||||
virtual void setup_menu();
|
||||
virtual void menu_new_window();
|
||||
void menu_hscale(float hz);
|
||||
void check_update();
|
||||
void do_update();
|
||||
|
||||
private:
|
||||
void layout_window(int chart_xsize, int chart_ysize);
|
||||
void add_view(HMENU parent_menu, const PStatViewLevel *view_level,
|
||||
bool show_level);
|
||||
|
||||
private:
|
||||
GtkStatsMonitor *_monitor;
|
||||
int _thread_index;
|
||||
|
||||
GtkStatsPianoRoll *_chart;
|
||||
int _last_level_index;
|
||||
HMENU _menu;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,395 @@
|
|||
// Filename: gtkStatsGraph.cxx
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsGraph.h"
|
||||
#include "gtkStatsMonitor.h"
|
||||
#include "gtkStatsLabelStack.h"
|
||||
|
||||
const GdkColor GtkStatsGraph::rgb_white = {
|
||||
0, 0xffff, 0xffff, 0xffff
|
||||
};
|
||||
const GdkColor GtkStatsGraph::rgb_light_gray = {
|
||||
0, 0x9a9a, 0x9a9a, 0x9a9a,
|
||||
};
|
||||
const GdkColor GtkStatsGraph::rgb_dark_gray = {
|
||||
0, 0x3333, 0x3333, 0x3333,
|
||||
};
|
||||
const GdkColor GtkStatsGraph::rgb_black = {
|
||||
0, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
const GdkColor GtkStatsGraph::rgb_user_guide_bar = {
|
||||
0, 0x8282, 0x9696, 0xffff
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsGraph::
|
||||
GtkStatsGraph(GtkStatsMonitor *monitor, int thread_index) :
|
||||
_monitor(monitor),
|
||||
_thread_index(thread_index)
|
||||
{
|
||||
_parent_window = NULL;
|
||||
_window = NULL;
|
||||
_graph_window = NULL;
|
||||
// _sizewe_cursor = LoadCursor(NULL, IDC_SIZEWE);
|
||||
// _hand_cursor = LoadCursor(NULL, IDC_HAND);
|
||||
_pixmap = 0;
|
||||
_pixmap_gc = 0;
|
||||
|
||||
_graph_left = 0;
|
||||
_graph_top = 0;
|
||||
_pixmap_xsize = 0;
|
||||
_pixmap_ysize = 0;
|
||||
|
||||
_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
GtkWidget *parent_window = monitor->get_window();
|
||||
|
||||
gtk_window_set_transient_for(GTK_WINDOW(_window), GTK_WINDOW(parent_window));
|
||||
gtk_window_set_destroy_with_parent(GTK_WINDOW(_window), TRUE);
|
||||
g_signal_connect(G_OBJECT(_window), "delete_event",
|
||||
G_CALLBACK(window_delete_event), this);
|
||||
g_signal_connect(G_OBJECT(_window), "destroy",
|
||||
G_CALLBACK(window_destroy), this);
|
||||
|
||||
_graph_window = gtk_drawing_area_new();
|
||||
g_signal_connect(G_OBJECT(_graph_window), "expose_event",
|
||||
G_CALLBACK(expose_event_callback), this);
|
||||
g_signal_connect(G_OBJECT(_graph_window), "configure_event",
|
||||
G_CALLBACK(configure_event_callback), this);
|
||||
|
||||
gtk_widget_set_size_request(_graph_window, 400, 100);
|
||||
|
||||
_drag_mode = DM_none;
|
||||
_potential_drag_mode = DM_none;
|
||||
_drag_scale_start = 0.0f;
|
||||
|
||||
_pause = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsGraph::
|
||||
~GtkStatsGraph() {
|
||||
_monitor = (GtkStatsMonitor *)NULL;
|
||||
release_pixmap();
|
||||
|
||||
/*
|
||||
DeleteObject(_dark_pen);
|
||||
DeleteObject(_light_pen);
|
||||
DeleteObject(_user_guide_bar_pen);
|
||||
*/
|
||||
|
||||
Brushes::iterator bi;
|
||||
for (bi = _brushes.begin(); bi != _brushes.end(); ++bi) {
|
||||
GdkGC *gc = (*bi).second;
|
||||
g_object_unref(gc);
|
||||
}
|
||||
|
||||
if (_graph_window != NULL) {
|
||||
gtk_widget_destroy(_graph_window);
|
||||
_graph_window = NULL;
|
||||
}
|
||||
|
||||
if (_window != NULL) {
|
||||
gtk_widget_destroy(_window);
|
||||
_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::get_thread_index
|
||||
// Access: Public
|
||||
// Description: Returns the thread index associated with this
|
||||
// particular graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsGraph::
|
||||
get_thread_index() const {
|
||||
return _thread_index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::new_collector
|
||||
// Access: Public, Virtual
|
||||
// Description: Called whenever a new Collector definition is
|
||||
// received from the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
new_collector(int new_collector) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::new_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Called whenever new data arrives.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
new_data(int thread_index, int frame_number) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::force_redraw
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when it is necessary to redraw the entire graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
force_redraw() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::changed_graph_size
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user has resized the window, forcing
|
||||
// a resize of the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
changed_graph_size(int graph_xsize, int graph_ysize) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::set_time_units
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user selects a new time units from
|
||||
// the monitor pulldown menu, this should adjust the
|
||||
// units for the graph to the indicated mask if it is a
|
||||
// time-based graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
set_time_units(int unit_mask) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::set_scroll_speed
|
||||
// Access: Public
|
||||
// Description: Called when the user selects a new scroll speed from
|
||||
// the monitor pulldown menu, this should adjust the
|
||||
// speed for the graph to the indicated value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
set_scroll_speed(float scroll_speed) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::set_pause
|
||||
// Access: Public
|
||||
// Description: Changes the pause flag for the graph. When this flag
|
||||
// is true, the graph does not update in response to new
|
||||
// data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
set_pause(bool pause) {
|
||||
_pause = pause;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::user_guide_bars_changed
|
||||
// Access: Public
|
||||
// Description: Called when the user guide bars have been changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
user_guide_bars_changed() {
|
||||
/*
|
||||
InvalidateRect(_window, NULL, TRUE);
|
||||
InvalidateRect(_graph_window, NULL, TRUE);
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::clicked_label
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user single-clicks on a label.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
clicked_label(int collector_index) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::close
|
||||
// Access: Protected
|
||||
// Description: Should be called when the user closes the associated
|
||||
// window. This tells the monitor to remove the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
close() {
|
||||
GtkStatsMonitor *monitor = _monitor;
|
||||
_monitor = (GtkStatsMonitor *)NULL;
|
||||
if (monitor != (GtkStatsMonitor *)NULL) {
|
||||
monitor->remove_graph(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::get_collector_gc
|
||||
// Access: Protected
|
||||
// Description: Returns a GC suitable for drawing in the indicated
|
||||
// collector's color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GdkGC *GtkStatsGraph::
|
||||
get_collector_gc(int collector_index) {
|
||||
Brushes::iterator bi;
|
||||
bi = _brushes.find(collector_index);
|
||||
if (bi != _brushes.end()) {
|
||||
return (*bi).second;
|
||||
}
|
||||
|
||||
// Ask the monitor what color this guy should be.
|
||||
RGBColorf rgb = _monitor->get_collector_color(collector_index);
|
||||
|
||||
GdkColor c;
|
||||
c.red = (int)(rgb[0] * 65535.0f);
|
||||
c.green = (int)(rgb[1] * 65535.0f);
|
||||
c.blue = (int)(rgb[2] * 65535.0f);
|
||||
GdkGC *gc = gdk_gc_new(_pixmap);
|
||||
g_object_ref(gc);
|
||||
gdk_gc_set_rgb_fg_color(gc, &c);
|
||||
|
||||
_brushes[collector_index] = gc;
|
||||
return gc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::consider_drag_start
|
||||
// Access: Protected, Virtual
|
||||
// Description: Based on the mouse position within the window's
|
||||
// client area, look for draggable things the mouse
|
||||
// might be hovering over and return the apprioprate
|
||||
// DragMode enum or DM_none if nothing is indicated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsGraph::DragMode GtkStatsGraph::
|
||||
consider_drag_start(int mouse_x, int mouse_y, int width, int height) {
|
||||
if (mouse_x >= _left_margin - 2 && mouse_x <= _left_margin + 2) {
|
||||
return DM_left_margin;
|
||||
} else if (mouse_x >= width - _right_margin - 2 && mouse_x <= width - _right_margin + 2) {
|
||||
return DM_right_margin;
|
||||
}
|
||||
|
||||
return DM_none;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::set_drag_mode
|
||||
// Access: Protected, Virtual
|
||||
// Description: This should be called whenever the drag mode needs to
|
||||
// change state. It provides hooks for a derived class
|
||||
// to do something special.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
set_drag_mode(GtkStatsGraph::DragMode drag_mode) {
|
||||
_drag_mode = drag_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::setup_pixmap
|
||||
// Access: Private
|
||||
// Description: Sets up a backing-store bitmap of the indicated size.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
setup_pixmap(int xsize, int ysize) {
|
||||
release_pixmap();
|
||||
|
||||
_pixmap_xsize = max(xsize, 0);
|
||||
_pixmap_ysize = max(ysize, 0);
|
||||
|
||||
_pixmap = gdk_pixmap_new(_graph_window->window, _pixmap_xsize, _pixmap_ysize, -1);
|
||||
g_object_ref(_pixmap);
|
||||
_pixmap_gc = gdk_gc_new(_pixmap);
|
||||
g_object_ref(_pixmap_gc);
|
||||
|
||||
gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
|
||||
gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, 0, 0,
|
||||
_pixmap_xsize, _pixmap_ysize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::release_pixmap
|
||||
// Access: Private
|
||||
// Description: Frees the backing-store bitmap created by
|
||||
// setup_pixmap().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
release_pixmap() {
|
||||
if (_pixmap != NULL) {
|
||||
g_object_unref(_pixmap);
|
||||
g_object_unref(_pixmap_gc);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::window_delete_event
|
||||
// Access: Private, Static
|
||||
// Description: Callback when the window is closed by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gboolean GtkStatsGraph::
|
||||
window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
|
||||
// Returning FALSE to indicate we should destroy the window
|
||||
// when the user selects "close".
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::window_delete_event
|
||||
// Access: Private, Static
|
||||
// Description: Callback when the window is destroyed by the system
|
||||
// (or by delete_event).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsGraph::
|
||||
window_destroy(GtkWidget *widget, gpointer data) {
|
||||
GtkStatsGraph *self = (GtkStatsGraph *)data;
|
||||
self->close();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::expose_event_callback
|
||||
// Access: Private, Static
|
||||
// Description: Fills in the graph window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gboolean GtkStatsGraph::
|
||||
expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
|
||||
GtkStatsGraph *self = (GtkStatsGraph *)data;
|
||||
|
||||
if (self->_pixmap != NULL) {
|
||||
gdk_draw_drawable(self->_graph_window->window,
|
||||
self->_graph_window->style->fg_gc[0],
|
||||
self->_pixmap, 0, 0, 0, 0,
|
||||
self->_pixmap_xsize, self->_pixmap_ysize);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGraph::configure_event_callback
|
||||
// Access: Private, Static
|
||||
// Description: Changes the size of the graph window
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gboolean GtkStatsGraph::
|
||||
configure_event_callback(GtkWidget *widget, GdkEventConfigure *event,
|
||||
gpointer data) {
|
||||
GtkStatsGraph *self = (GtkStatsGraph *)data;
|
||||
|
||||
self->changed_graph_size(event->width, event->height);
|
||||
self->setup_pixmap(event->width, event->height);
|
||||
self->force_redraw();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
// Filename: gtkStatsGraph.h
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKSTATSGRAPH_H
|
||||
#define GTKSTATSGRAPH_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "gtkStatsLabelStack.h"
|
||||
#include "pmap.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
class GtkStatsMonitor;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsGraph
|
||||
// Description : This is just an abstract base class to provide a
|
||||
// common pointer type for the various kinds of graphs
|
||||
// that may be created for a GtkStatsMonitor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsGraph {
|
||||
public:
|
||||
// What is the user adjusting by dragging the mouse in a window?
|
||||
enum DragMode {
|
||||
DM_none,
|
||||
DM_scale,
|
||||
DM_left_margin,
|
||||
DM_right_margin,
|
||||
DM_guide_bar,
|
||||
DM_new_guide_bar,
|
||||
DM_sizing,
|
||||
};
|
||||
|
||||
public:
|
||||
GtkStatsGraph(GtkStatsMonitor *monitor, int thread_index);
|
||||
virtual ~GtkStatsGraph();
|
||||
|
||||
int get_thread_index() const;
|
||||
|
||||
virtual void new_collector(int collector_index);
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
virtual void force_redraw();
|
||||
virtual void changed_graph_size(int graph_xsize, int graph_ysize);
|
||||
|
||||
virtual void set_time_units(int unit_mask);
|
||||
virtual void set_scroll_speed(float scroll_speed);
|
||||
void set_pause(bool pause);
|
||||
|
||||
void user_guide_bars_changed();
|
||||
virtual void clicked_label(int collector_index);
|
||||
|
||||
protected:
|
||||
void close();
|
||||
GdkGC *get_collector_gc(int collector_index);
|
||||
|
||||
/*
|
||||
virtual void additional_window_paint(HDC hdc);
|
||||
virtual void additional_graph_window_paint(HDC hdc);
|
||||
*/
|
||||
virtual DragMode consider_drag_start(int mouse_x, int mouse_y,
|
||||
int width, int height);
|
||||
virtual void set_drag_mode(DragMode drag_mode);
|
||||
|
||||
protected:
|
||||
// Table of GC's for our various collectors.
|
||||
typedef pmap<int, GdkGC *> Brushes;
|
||||
Brushes _brushes;
|
||||
|
||||
GtkStatsMonitor *_monitor;
|
||||
int _thread_index;
|
||||
GtkWidget *_parent_window;
|
||||
GtkWidget *_window;
|
||||
GtkWidget *_graph_window;
|
||||
GtkStatsLabelStack _label_stack;
|
||||
|
||||
/*
|
||||
HCURSOR _sizewe_cursor;
|
||||
HCURSOR _hand_cursor;
|
||||
*/
|
||||
|
||||
GdkPixmap *_pixmap;
|
||||
GdkGC *_pixmap_gc;
|
||||
|
||||
int _graph_left, _graph_top;
|
||||
int _pixmap_xsize, _pixmap_ysize;
|
||||
int _left_margin, _right_margin;
|
||||
int _top_margin, _bottom_margin;
|
||||
|
||||
/*
|
||||
COLORREF _dark_color;
|
||||
COLORREF _light_color;
|
||||
COLORREF _user_guide_bar_color;
|
||||
HPEN _dark_pen;
|
||||
HPEN _light_pen;
|
||||
HPEN _user_guide_bar_pen;
|
||||
*/
|
||||
|
||||
DragMode _drag_mode;
|
||||
DragMode _potential_drag_mode;
|
||||
int _drag_start_x, _drag_start_y;
|
||||
float _drag_scale_start;
|
||||
int _drag_guide_bar;
|
||||
|
||||
bool _pause;
|
||||
|
||||
static const GdkColor rgb_white;
|
||||
static const GdkColor rgb_light_gray;
|
||||
static const GdkColor rgb_dark_gray;
|
||||
static const GdkColor rgb_black;
|
||||
static const GdkColor rgb_user_guide_bar;
|
||||
|
||||
private:
|
||||
void setup_pixmap(int xsize, int ysize);
|
||||
void release_pixmap();
|
||||
void create_graph_window();
|
||||
|
||||
static gboolean window_delete_event(GtkWidget *widget, GdkEvent *event,
|
||||
gpointer data);
|
||||
static void window_destroy(GtkWidget *widget, gpointer data);
|
||||
static gboolean expose_event_callback(GtkWidget *widget,
|
||||
GdkEventExpose *event, gpointer data);
|
||||
static gboolean configure_event_callback(GtkWidget *widget,
|
||||
GdkEventConfigure *event, gpointer data);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
// Filename: gtkStatsGuide.cxx
|
||||
// Created by: drose (16Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsGuide.h"
|
||||
|
||||
#include "pStatStripChart.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGuide::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsGuide::
|
||||
GtkStatsGuide(PStatStripChart *chart) :
|
||||
_chart(chart)
|
||||
{
|
||||
set_events(GDK_EXPOSURE_MASK);
|
||||
|
||||
// Choose a suitable minimum width. This requires knowing what the
|
||||
// font will be.
|
||||
Gdk_Font font = get_style()->gtkobj()->font;
|
||||
int text_width = font.string_width("0000");
|
||||
set_usize(text_width, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGuide::configure_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description: Creates a new backing pixmap of the appropriate size.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsGuide::
|
||||
configure_event_impl(GdkEventConfigure *) {
|
||||
Gdk_Window window = get_window();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsGuide::expose_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description: Redraw the text. We don't bother with clipping
|
||||
// regions here, but just draw the whole thing every
|
||||
// time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsGuide::
|
||||
expose_event_impl(GdkEventExpose *event) {
|
||||
Gdk_GC fg_gc =
|
||||
get_style()->gtkobj()->fg_gc[GTK_WIDGET_STATE (GTK_WIDGET(gtkobj()))];
|
||||
Gdk_GC bg_gc =
|
||||
get_style()->gtkobj()->bg_gc[GTK_WIDGET_STATE (GTK_WIDGET(gtkobj()))];
|
||||
|
||||
if (fg_gc && bg_gc) {
|
||||
Gdk_Window window = get_window();
|
||||
window.draw_rectangle(bg_gc, true, 0, 0, width(), height());
|
||||
|
||||
Gdk_Font font = fg_gc.get_font();
|
||||
int text_ascent = font.ascent();
|
||||
|
||||
int num_guide_bars = _chart->get_num_guide_bars();
|
||||
for (int i = 0; i < num_guide_bars; i++) {
|
||||
const PStatStripChart::GuideBar &bar = _chart->get_guide_bar(i);
|
||||
int y = _chart->height_to_pixel(bar._height);
|
||||
|
||||
if (y >= 5) {
|
||||
// Only draw it if it's not too close to the top.
|
||||
window.draw_string(font, fg_gc, 0, y + text_ascent / 2,
|
||||
bar._label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// Filename: gtkStatsGuide.h
|
||||
// Created by: drose (16Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKSTATSGUIDE_H
|
||||
#define GTKSTATSGUIDE_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include <gtk--.h>
|
||||
|
||||
class PStatStripChart;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsGuide
|
||||
// Description : A widget designed to be drawn next to a
|
||||
// GtkStatsStripChart that shows the labels associated
|
||||
// with the strip chart's guide bars.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsGuide : public Gtk::DrawingArea {
|
||||
public:
|
||||
GtkStatsGuide(PStatStripChart *chart);
|
||||
|
||||
private:
|
||||
virtual gint configure_event_impl(GdkEventConfigure *event);
|
||||
virtual gint expose_event_impl(GdkEventExpose *event);
|
||||
|
||||
private:
|
||||
PStatStripChart *_chart;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsLabel.cxx
|
||||
// Created by: drose (15Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -18,27 +18,40 @@
|
|||
|
||||
#include "gtkStatsLabel.h"
|
||||
#include "gtkStatsMonitor.h"
|
||||
#include "gtkStatsGraph.h"
|
||||
|
||||
#include "pStatClientData.h"
|
||||
#include "pStatMonitor.h"
|
||||
int GtkStatsLabel::_left_margin = 2;
|
||||
int GtkStatsLabel::_right_margin = 2;
|
||||
int GtkStatsLabel::_top_margin = 2;
|
||||
int GtkStatsLabel::_bottom_margin = 2;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::Constructor
|
||||
// Access: Public
|
||||
// Description: This constructor automatically figures out the
|
||||
// appropriate name and color for the label.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsLabel::
|
||||
GtkStatsLabel(PStatMonitor *monitor, int collector_index,
|
||||
Gdk_Font font) :
|
||||
_collector_index(collector_index),
|
||||
_font(font)
|
||||
GtkStatsLabel(GtkStatsMonitor *monitor, GtkStatsGraph *graph,
|
||||
int thread_index, int collector_index, bool use_fullname) :
|
||||
_monitor(monitor),
|
||||
_graph(graph),
|
||||
_thread_index(thread_index),
|
||||
_collector_index(collector_index)
|
||||
{
|
||||
set_events(GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
|
||||
_widget = NULL;
|
||||
if (use_fullname) {
|
||||
_text = _monitor->get_client_data()->get_collector_fullname(_collector_index);
|
||||
} else {
|
||||
_text = _monitor->get_client_data()->get_collector_name(_collector_index);
|
||||
}
|
||||
|
||||
_text = monitor->get_client_data()->get_collector_name(_collector_index);
|
||||
RGBColorf rgb = monitor->get_collector_color(_collector_index);
|
||||
_bg_color.set_rgb_p(rgb[0], rgb[1], rgb[2]);
|
||||
/*
|
||||
RGBColorf rgb = _monitor->get_collector_color(_collector_index);
|
||||
int r = (int)(rgb[0] * 255.0f);
|
||||
int g = (int)(rgb[1] * 255.0f);
|
||||
int b = (int)(rgb[2] * 255.0f);
|
||||
_bg_color = RGB(r, g, b);
|
||||
_bg_brush = CreateSolidBrush(RGB(r, g, b));
|
||||
|
||||
// Should our foreground be black or white?
|
||||
float bright =
|
||||
|
|
@ -47,96 +60,103 @@ GtkStatsLabel(PStatMonitor *monitor, int collector_index,
|
|||
rgb[2] * 0.114;
|
||||
|
||||
if (bright >= 0.5) {
|
||||
_fg_color.set_rgb_p(0, 0, 0);
|
||||
_fg_color = RGB(0, 0, 0);
|
||||
_highlight_brush = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
||||
} else {
|
||||
_fg_color.set_rgb_p(1, 1, 1);
|
||||
_fg_color = RGB(255, 255, 255);
|
||||
_highlight_brush = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
||||
}
|
||||
*/
|
||||
|
||||
Gdk_Colormap::get_system().alloc(_fg_color);
|
||||
Gdk_Colormap::get_system().alloc(_bg_color);
|
||||
|
||||
int text_width = _font.string_width(_text);
|
||||
int text_height = _font.height();
|
||||
|
||||
_height = text_height + 4;
|
||||
_width = text_width + 4;
|
||||
|
||||
set_usize(_width, _height);
|
||||
_highlight = false;
|
||||
_mouse_within = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::get_width
|
||||
// Function: GtkStatsLabel::Destructor
|
||||
// Access: Public
|
||||
// Description: Returns the width of the widget as we requested it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsLabel::
|
||||
get_width() const {
|
||||
return _width;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::get_height
|
||||
// Access: Public
|
||||
// Description: Returns the height of the widget as we requested it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsLabel::
|
||||
get_height() const {
|
||||
return _height;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::configure_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description: Creates a new backing pixmap of the appropriate size.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsLabel::
|
||||
configure_event_impl(GdkEventConfigure *) {
|
||||
Gdk_Window window = get_window();
|
||||
|
||||
_gc = Gdk_GC(window);
|
||||
_gc.set_foreground(_fg_color);
|
||||
_gc.set_background(_bg_color);
|
||||
_gc.set_font(_font);
|
||||
|
||||
_reverse_gc = Gdk_GC(window);
|
||||
_reverse_gc.set_foreground(_bg_color);
|
||||
_reverse_gc.set_background(_fg_color);
|
||||
_reverse_gc.set_font(_font);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::expose_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description: Redraw the text. We don't bother with clipping
|
||||
// regions here, but just draw the whole text every
|
||||
// time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsLabel::
|
||||
expose_event_impl(GdkEventExpose *event) {
|
||||
int text_width = _font.string_width(_text);
|
||||
int text_height = _font.height();
|
||||
|
||||
Gdk_Window window = get_window();
|
||||
|
||||
window.draw_rectangle(_reverse_gc, true, 0, 0, width(), height());
|
||||
window.draw_string(_font, _gc, width() - text_width - 2,
|
||||
height() - (height() - text_height) / 2 - _font.descent(),
|
||||
_text);
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::button_press_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsLabel::
|
||||
button_press_event_impl(GdkEventButton *button) {
|
||||
if (button->type == GDK_2BUTTON_PRESS && button->button == 1) {
|
||||
collector_picked(_collector_index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
GtkStatsLabel::
|
||||
~GtkStatsLabel() {
|
||||
// DeleteObject(_bg_brush);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::setup
|
||||
// Access: Public
|
||||
// Description: Creates the actual widget.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkWidget *GtkStatsLabel::
|
||||
setup() {
|
||||
_widget = gtk_event_box_new();
|
||||
GtkWidget *label = gtk_label_new(_text.c_str());
|
||||
gtk_container_add(GTK_CONTAINER(_widget), label);
|
||||
gtk_widget_show(label);
|
||||
gtk_widget_show(_widget);
|
||||
|
||||
return _widget;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::get_widget
|
||||
// Access: Public
|
||||
// Description: Returns the widget for this label.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkWidget *GtkStatsLabel::
|
||||
get_widget() const {
|
||||
return _widget;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::get_collector_index
|
||||
// Access: Public
|
||||
// Description: Returns the collector this label represents.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsLabel::
|
||||
get_collector_index() const {
|
||||
return _collector_index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::set_highlight
|
||||
// Access: Public
|
||||
// Description: Enables or disables the visual highlight for this
|
||||
// label.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsLabel::
|
||||
set_highlight(bool highlight) {
|
||||
if (_highlight != highlight) {
|
||||
_highlight = highlight;
|
||||
/*
|
||||
InvalidateRect(_widget, NULL, TRUE);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::get_highlight
|
||||
// Access: Public
|
||||
// Description: Returns true if the visual highlight for this
|
||||
// label is enabled.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GtkStatsLabel::
|
||||
get_highlight() const {
|
||||
return _highlight;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabel::set_mouse_within
|
||||
// Access: Private
|
||||
// Description: Used internally to indicate whether the mouse is
|
||||
// within the label's widget.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsLabel::
|
||||
set_mouse_within(bool mouse_within) {
|
||||
if (_mouse_within != mouse_within) {
|
||||
_mouse_within = mouse_within;
|
||||
/*
|
||||
InvalidateRect(_widget, NULL, TRUE);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsLabel.h
|
||||
// Created by: drose (15Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -21,47 +21,54 @@
|
|||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include <gtk--.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
class PStatMonitor;
|
||||
class GtkStatsMonitor;
|
||||
class GtkStatsGraph;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsLabel
|
||||
// Description : A text label that will draw in color appropriate for
|
||||
// a particular collector, instead of referring to some
|
||||
// dumb Gtk::Style. It also throws a signal when the
|
||||
// user double-clicks on it, passing in the collector
|
||||
// index. This is handy for putting colored labels on
|
||||
// strip charts.
|
||||
// a particular collector. It also responds when the
|
||||
// user double-clicks on it. This is handy for putting
|
||||
// colored labels on strip charts.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsLabel : public Gtk::DrawingArea {
|
||||
class GtkStatsLabel {
|
||||
public:
|
||||
GtkStatsLabel(PStatMonitor *monitor, int collector_index,
|
||||
Gdk_Font font);
|
||||
GtkStatsLabel(GtkStatsMonitor *monitor, GtkStatsGraph *graph,
|
||||
int thread_index, int collector_index, bool use_fullname);
|
||||
~GtkStatsLabel();
|
||||
|
||||
int get_width() const;
|
||||
int get_height() const;
|
||||
GtkWidget *setup();
|
||||
GtkWidget *get_widget() const;
|
||||
|
||||
SigC::Signal1<void, int> collector_picked;
|
||||
int get_collector_index() const;
|
||||
|
||||
void set_highlight(bool highlight);
|
||||
bool get_highlight() const;
|
||||
|
||||
private:
|
||||
virtual gint configure_event_impl (GdkEventConfigure *event);
|
||||
virtual gint expose_event_impl (GdkEventExpose *event);
|
||||
virtual gint button_press_event_impl(GdkEventButton *button);
|
||||
void set_mouse_within(bool mouse_within);
|
||||
|
||||
private:
|
||||
GtkStatsMonitor *_monitor;
|
||||
GtkStatsGraph *_graph;
|
||||
int _thread_index;
|
||||
int _collector_index;
|
||||
|
||||
string _text;
|
||||
Gdk_Font _font;
|
||||
Gdk_Color _fg_color;
|
||||
Gdk_Color _bg_color;
|
||||
GtkWidget *_widget;
|
||||
|
||||
int _width;
|
||||
int _height;
|
||||
/*
|
||||
COLORREF _bg_color;
|
||||
COLORREF _fg_color;
|
||||
HBRUSH _bg_brush;
|
||||
HBRUSH _highlight_brush;
|
||||
*/
|
||||
|
||||
Gdk_GC _gc;
|
||||
Gdk_GC _reverse_gc;
|
||||
bool _highlight;
|
||||
bool _mouse_within;
|
||||
|
||||
static int _left_margin, _right_margin;
|
||||
static int _top_margin, _bottom_margin;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
// Filename: gtkStatsLabelStack.cxx
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsLabelStack.h"
|
||||
#include "gtkStatsLabel.h"
|
||||
#include "notify.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsLabelStack::
|
||||
GtkStatsLabelStack() {
|
||||
_widget = NULL;
|
||||
|
||||
_highlight_label = -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsLabelStack::
|
||||
~GtkStatsLabelStack() {
|
||||
clear_labels();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::setup
|
||||
// Access: Public
|
||||
// Description: Creates the actual widget object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkWidget *GtkStatsLabelStack::
|
||||
setup() {
|
||||
if (_widget == NULL) {
|
||||
_widget = gtk_vbox_new(FALSE, 0);
|
||||
}
|
||||
|
||||
return _widget;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::is_setup
|
||||
// Access: Public
|
||||
// Description: Returns true if the label stack has been set up,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GtkStatsLabelStack::
|
||||
is_setup() const {
|
||||
return (_widget != NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::get_label_collector_index
|
||||
// Access: Public
|
||||
// Description: Returns the collector index associated with the
|
||||
// indicated label.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsLabelStack::
|
||||
get_label_collector_index(int label_index) const {
|
||||
nassertr(label_index >= 0 && label_index < (int)_labels.size(), -1);
|
||||
return _labels[label_index]->get_collector_index();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::clear_labels
|
||||
// Access: Public
|
||||
// Description: Removes the set of labels and starts a new set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsLabelStack::
|
||||
clear_labels() {
|
||||
Labels::iterator li;
|
||||
for (li = _labels.begin(); li != _labels.end(); ++li) {
|
||||
GtkStatsLabel *label = (*li);
|
||||
gtk_container_remove(GTK_CONTAINER(_widget), label->get_widget());
|
||||
delete (*li);
|
||||
}
|
||||
_labels.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::add_label
|
||||
// Access: Public
|
||||
// Description: Adds a new label to the top of the stack; returns the
|
||||
// new label index.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsLabelStack::
|
||||
add_label(GtkStatsMonitor *monitor, GtkStatsGraph *graph,
|
||||
int thread_index, int collector_index, bool use_fullname) {
|
||||
GtkStatsLabel *label =
|
||||
new GtkStatsLabel(monitor, graph, thread_index, collector_index, use_fullname);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(_widget), label->setup(),
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
int label_index = (int)_labels.size();
|
||||
_labels.push_back(label);
|
||||
|
||||
return label_index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::get_num_labels
|
||||
// Access: Public
|
||||
// Description: Returns the number of labels in the stack.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsLabelStack::
|
||||
get_num_labels() const {
|
||||
return _labels.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsLabelStack::highlight_label
|
||||
// Access: Public
|
||||
// Description: Draws a highlight around the label representing the
|
||||
// indicated collector, and removes the highlight from
|
||||
// any other label. Specify -1 to remove the highlight
|
||||
// from all labels.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsLabelStack::
|
||||
highlight_label(int collector_index) {
|
||||
if (_highlight_label != collector_index) {
|
||||
_highlight_label = collector_index;
|
||||
Labels::iterator li;
|
||||
for (li = _labels.begin(); li != _labels.end(); ++li) {
|
||||
GtkStatsLabel *label = (*li);
|
||||
label->set_highlight(label->get_collector_index() == _highlight_label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// Filename: gtkStatsLabelStack.h
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKSTATSLABELSTACK_H
|
||||
#define GTKSTATSLABELSTACK_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "pvector.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
class GtkStatsLabel;
|
||||
class GtkStatsMonitor;
|
||||
class GtkStatsGraph;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsLabelStack
|
||||
// Description : A widget that contains a stack of labels from bottom
|
||||
// to top.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsLabelStack {
|
||||
public:
|
||||
GtkStatsLabelStack();
|
||||
~GtkStatsLabelStack();
|
||||
|
||||
GtkWidget *setup();
|
||||
bool is_setup() const;
|
||||
|
||||
int get_label_collector_index(int label_index) const;
|
||||
|
||||
void clear_labels();
|
||||
int add_label(GtkStatsMonitor *monitor, GtkStatsGraph *graph,
|
||||
int thread_index, int collector_index, bool use_fullname);
|
||||
int get_num_labels() const;
|
||||
|
||||
void highlight_label(int collector_index);
|
||||
|
||||
private:
|
||||
GtkWidget *_widget;
|
||||
int _highlight_label;
|
||||
|
||||
typedef pvector<GtkStatsLabel *> Labels;
|
||||
Labels _labels;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
// Filename: gtkStatsMainWindow.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsMainWindow.h"
|
||||
#include "gtkStats.h"
|
||||
#include "gtkStatsServer.h"
|
||||
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
static bool user_interrupted = false;
|
||||
|
||||
// This simple signal handler lets us know when the user has pressed
|
||||
// control-C, so we can clean up nicely.
|
||||
static void signal_handler(int) {
|
||||
user_interrupted = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMainWindow::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsMainWindow::
|
||||
GtkStatsMainWindow(int port) : _port(port) {
|
||||
nassertv(GtkStats::_main_window == (GtkStatsMainWindow *)NULL);
|
||||
GtkStats::_main_window = this;
|
||||
|
||||
// Set up a global signal handler to catch Interrupt (Control-C) so
|
||||
// we can clean up nicely if the user stops us.
|
||||
signal(SIGINT, &signal_handler);
|
||||
|
||||
_server = new GtkStatsServer;
|
||||
if (!_server->listen(_port)) {
|
||||
nout << "Unable to open port.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
layout_window();
|
||||
setup();
|
||||
|
||||
Gtk::Main::timeout.
|
||||
connect(slot(this, &GtkStatsMainWindow::idle_callback), 200);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMainWindow::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsMainWindow::
|
||||
~GtkStatsMainWindow() {
|
||||
nassertv(GtkStats::_main_window == this);
|
||||
GtkStats::_main_window = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMainWindow::destruct
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GtkStatsMainWindow::
|
||||
destruct() {
|
||||
if (BasicGtkWindow::destruct()) {
|
||||
nassertr(_server != (GtkStatsServer *)NULL, false);
|
||||
delete _server;
|
||||
GtkStats::quit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMainWindow::layout_window
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMainWindow::
|
||||
layout_window() {
|
||||
set_title("Gtk Stats");
|
||||
|
||||
Gtk::VBox *box1 = new Gtk::VBox;
|
||||
box1->show();
|
||||
box1->set_border_width(8);
|
||||
add(*manage(box1));
|
||||
|
||||
Gtk::Label *listening =
|
||||
new Gtk::Label("Listening on port " + format_string(_port));
|
||||
listening->show();
|
||||
box1->pack_start(*manage(listening), true, false, 8);
|
||||
|
||||
Gtk::HBox *box2 = new Gtk::HBox;
|
||||
box2->show();
|
||||
box1->pack_start(*manage(box2), false, false, 0);
|
||||
|
||||
Gtk::Button *close = new Gtk::Button("Close");
|
||||
close->set_usize(80, 30);
|
||||
close->show();
|
||||
box2->pack_start(*manage(close), true, false, 0);
|
||||
close->clicked.connect(slot(this, &GtkStatsMainWindow::close_clicked));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMainWindow::close_clicked
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMainWindow::
|
||||
close_clicked() {
|
||||
destruct();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMainWindow::idle_callback
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsMainWindow::
|
||||
idle_callback() {
|
||||
if (user_interrupted) {
|
||||
destruct();
|
||||
return false;
|
||||
}
|
||||
_server->poll();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Filename: gtkStatsMainWindow.h
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKSTATSMAINWINDOW_H
|
||||
#define GTKSTATSMAINWINDOW_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "basicGtkWindow.h"
|
||||
|
||||
class GtkStatsServer;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsMainWindow
|
||||
// Description : This is the main window that's opened up and stays up
|
||||
// all the time when you run gtk-stats. It just shows
|
||||
// that it's running.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsMainWindow : public BasicGtkWindow {
|
||||
public:
|
||||
GtkStatsMainWindow(int port);
|
||||
virtual ~GtkStatsMainWindow();
|
||||
virtual bool destruct();
|
||||
|
||||
private:
|
||||
void layout_window();
|
||||
void close_clicked();
|
||||
gint idle_callback();
|
||||
|
||||
int _port;
|
||||
GtkStatsServer *_server;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
42
pandatool/src/gtkbase/gtkBase.h → pandatool/src/gtk-stats/gtkStatsMenuId.h
Normal file → Executable file
42
pandatool/src/gtkbase/gtkBase.h → pandatool/src/gtk-stats/gtkStatsMenuId.h
Normal file → Executable file
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkBase.h
|
||||
// Created by: drose (14Jul00)
|
||||
// Filename: gtkStatsMenuId.h
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -16,32 +16,32 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKBASE_H
|
||||
#define GTKBASE_H
|
||||
#ifndef GTKSTATSMENUID_H
|
||||
#define GTKSTATSMENUID_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "programBase.h"
|
||||
|
||||
#include <gtk--.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkBase
|
||||
// Description : This is a specialization of ProgramBase for programs
|
||||
// that use the Gtk-- GUI toolkit.
|
||||
// Enum : GtkStatsMenuId
|
||||
// Description : The enumerated values here are used for menu ID's for
|
||||
// the various pulldown menus in the application.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkBase : public ProgramBase {
|
||||
public:
|
||||
GtkBase();
|
||||
~GtkBase();
|
||||
enum GtkStatsMenuId {
|
||||
MI_none,
|
||||
MI_time_ms,
|
||||
MI_time_hz,
|
||||
MI_frame_rate_label,
|
||||
MI_speed_1,
|
||||
MI_speed_2,
|
||||
MI_speed_3,
|
||||
MI_speed_6,
|
||||
MI_speed_12,
|
||||
MI_pause,
|
||||
|
||||
virtual void parse_command_line(int argc, char *argv[]);
|
||||
void main_loop();
|
||||
|
||||
public:
|
||||
static Gtk::Main *_gtk;
|
||||
// This one is last and represents the beginning of the range for
|
||||
// the various "new chart" menu options.
|
||||
MI_new_chart
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Filename: gtkStatsMonitor.I
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::MenuDef::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsMonitor::MenuDef::
|
||||
MenuDef(int thread_index, int collector_index, bool show_level) :
|
||||
_thread_index(thread_index),
|
||||
_collector_index(collector_index),
|
||||
_show_level(show_level)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::MenuDef::operator <
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GtkStatsMonitor::MenuDef::
|
||||
operator < (const MenuDef &other) const {
|
||||
if (_thread_index != other._thread_index) {
|
||||
return _thread_index < other._thread_index;
|
||||
}
|
||||
if (_collector_index != other._collector_index) {
|
||||
return _collector_index < other._collector_index;
|
||||
}
|
||||
return (int)_show_level < (int)other._show_level;
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsMonitor.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -17,15 +17,36 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsMonitor.h"
|
||||
#include "gtkStatsWindow.h"
|
||||
#include "gtkStatsStripWindow.h"
|
||||
#include "gtkStatsBadVersionWindow.h"
|
||||
#include "gtkStats.h"
|
||||
#include "gtkStatsServer.h"
|
||||
|
||||
#include "luse.h"
|
||||
#include "gtkStatsStripChart.h"
|
||||
/*
|
||||
#include "gtkStatsPianoRoll.h"
|
||||
#include "gtkStatsChartMenu.h"
|
||||
*/
|
||||
#include "gtkStatsMenuId.h"
|
||||
#include "pStatGraph.h"
|
||||
#include "pStatCollectorDef.h"
|
||||
#include "indent.h"
|
||||
|
||||
typedef void vc();
|
||||
|
||||
GtkItemFactoryEntry GtkStatsMonitor::menu_entries[] = {
|
||||
{ "/Options", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/Options/Units", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/Options/Units/ms", NULL, (vc *)&handle_menu_command, MI_time_ms, "<RadioItem>" },
|
||||
{ "/Options/Units/Hz", NULL, (vc *)&handle_menu_command, MI_time_hz, "/Options/Units/ms" },
|
||||
{ "/Speed", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/Speed/1", NULL, (vc *)&handle_menu_command, MI_speed_1, "<RadioItem>" },
|
||||
{ "/Speed/2", NULL, (vc *)&handle_menu_command, MI_speed_2, "/Speed/1" },
|
||||
{ "/Speed/3", NULL, (vc *)&handle_menu_command, MI_speed_3, "/Speed/1" },
|
||||
{ "/Speed/6", NULL, (vc *)&handle_menu_command, MI_speed_6, "/Speed/1" },
|
||||
{ "/Speed/12", NULL, (vc *)&handle_menu_command, MI_speed_12, "/Speed/1" },
|
||||
{ "/Speed/sep", NULL, NULL, 0, "<Separator>" },
|
||||
{ "/Speed/pause", NULL, (vc *)&handle_menu_command, MI_pause, "<CheckItem>" },
|
||||
};
|
||||
int GtkStatsMonitor::num_menu_entries = sizeof(menu_entries) / sizeof(GtkItemFactoryEntry);
|
||||
|
||||
#include <gdk--.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::Constructor
|
||||
|
|
@ -34,44 +55,45 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsMonitor::
|
||||
GtkStatsMonitor(GtkStatsServer *server) : PStatMonitor(server) {
|
||||
_destructing = false;
|
||||
_new_collector = false;
|
||||
_window = NULL;
|
||||
_item_factory = NULL;
|
||||
|
||||
// These will be filled in later when the menu is created.
|
||||
_time_units = 0;
|
||||
_scroll_speed = 0.0;
|
||||
_pause = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::Destructor
|
||||
// Access: Public
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsMonitor::
|
||||
~GtkStatsMonitor() {
|
||||
_destructing = true;
|
||||
|
||||
Windows::iterator wi;
|
||||
for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
|
||||
GtkStatsWindow *window = (*wi);
|
||||
window->destruct();
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
delete (*gi);
|
||||
}
|
||||
}
|
||||
_graphs.clear();
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::close_all_windows
|
||||
// Access: Public
|
||||
// Description: Closes all the windows associated with this client.
|
||||
// This returns a PointerTo itself, just to guarantee
|
||||
// that the monitor won't destruct until the function
|
||||
// returns (as it might, if there were no other pointers
|
||||
// to it).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PStatMonitor) GtkStatsMonitor::
|
||||
close_all_windows() {
|
||||
PT(PStatMonitor) temp = this;
|
||||
Windows::iterator wi;
|
||||
for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
|
||||
GtkStatsWindow *window = (*wi);
|
||||
window->destruct();
|
||||
/*
|
||||
ChartMenus::iterator mi;
|
||||
for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
|
||||
delete (*mi);
|
||||
}
|
||||
return temp;
|
||||
_chart_menus.clear();
|
||||
*/
|
||||
|
||||
if (_window != NULL) {
|
||||
gtk_widget_destroy(_window);
|
||||
_window = NULL;
|
||||
}
|
||||
|
||||
#ifdef DEVELOP_GTKSTATS
|
||||
// For Gtkstats developers, exit when the first monitor closes.
|
||||
gtk_main_quit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -82,7 +104,7 @@ close_all_windows() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
string GtkStatsMonitor::
|
||||
get_monitor_name() {
|
||||
return "Gtk Stats";
|
||||
return "GtkStats";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -98,8 +120,6 @@ get_monitor_name() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
initialized() {
|
||||
// Create a default window: a strip chart for the main thread.
|
||||
new GtkStatsStripWindow(this, 0, 0, false, 400, 100);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -111,10 +131,8 @@ initialized() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
got_hello() {
|
||||
Windows::iterator wi;
|
||||
for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
|
||||
(*wi)->update_title();
|
||||
}
|
||||
create_window();
|
||||
open_strip_chart(0, 0, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -131,9 +149,29 @@ got_hello() {
|
|||
void GtkStatsMonitor::
|
||||
got_bad_version(int client_major, int client_minor,
|
||||
int server_major, int server_minor) {
|
||||
new GtkStatsBadVersionWindow(this, client_major, client_minor,
|
||||
server_major, server_minor);
|
||||
close_all_windows();
|
||||
ostringstream str;
|
||||
str << "Unable to honor connection attempt from "
|
||||
<< get_client_progname() << " on " << get_client_hostname()
|
||||
<< ": unsupported PStats version "
|
||||
<< client_major << "." << client_minor;
|
||||
|
||||
if (server_minor == 0) {
|
||||
str << " (server understands version " << server_major
|
||||
<< "." << server_minor << " only).";
|
||||
} else {
|
||||
str << " (server understands versions " << server_major
|
||||
<< ".0 through " << server_major << "." << server_minor << ").";
|
||||
}
|
||||
|
||||
string message = str.str();
|
||||
GtkWidget *dialog =
|
||||
gtk_message_dialog_new(GTK_WINDOW(main_window),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
message.c_str());
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -148,8 +186,41 @@ got_bad_version(int client_major, int client_minor,
|
|||
// definitions midstream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
new_collector(int) {
|
||||
_new_collector = true;
|
||||
new_collector(int collector_index) {
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
GtkStatsGraph *graph = (*gi);
|
||||
graph->new_collector(collector_index);
|
||||
}
|
||||
|
||||
/*
|
||||
// We might need to update our menus.
|
||||
ChartMenus::iterator mi;
|
||||
for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
|
||||
(*mi)->do_update();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::new_thread
|
||||
// Access: Public, Virtual
|
||||
// Description: Called whenever a new Thread definition is
|
||||
// received from the client. Generally, the client will
|
||||
// send all of its threads over shortly after
|
||||
// connecting, but there's no guarantee that they will
|
||||
// all be received before the first frames are received.
|
||||
// The monitor should be prepared to accept new Thread
|
||||
// definitions midstream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
new_thread(int thread_index) {
|
||||
/*
|
||||
GtkStatsChartMenu *chart_menu = new GtkStatsChartMenu(this, thread_index);
|
||||
chart_menu->add_to_menu_bar(_menu_bar, MI_frame_rate_label);
|
||||
_chart_menus.push_back(chart_menu);
|
||||
DrawMenuBar(_window);
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -163,6 +234,11 @@ new_collector(int) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
new_data(int thread_index, int frame_number) {
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
GtkStatsGraph *graph = (*gi);
|
||||
graph->new_data(thread_index, frame_number);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -176,9 +252,11 @@ new_data(int thread_index, int frame_number) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
lost_connection() {
|
||||
Windows::iterator wi;
|
||||
for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
|
||||
(*wi)->mark_dead();
|
||||
nout << "Lost connection to " << get_client_hostname() << "\n";
|
||||
|
||||
if (_window != NULL) {
|
||||
gtk_widget_destroy(_window);
|
||||
_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,11 +269,29 @@ lost_connection() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
idle() {
|
||||
Windows::iterator wi;
|
||||
for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
|
||||
(*wi)->idle();
|
||||
/*
|
||||
// Check if any of our chart menus need updating.
|
||||
ChartMenus::iterator mi;
|
||||
for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
|
||||
(*mi)->check_update();
|
||||
}
|
||||
_new_collector = false;
|
||||
|
||||
// Update the frame rate label from the main thread (thread 0).
|
||||
const PStatThreadData *thread_data = get_client_data()->get_thread_data(0);
|
||||
float frame_rate = thread_data->get_frame_rate();
|
||||
if (frame_rate != 0.0f) {
|
||||
char buffer[128];
|
||||
sprintf(buffer, "%0.1f ms / %0.1f Hz", 1000.0f / frame_rate, frame_rate);
|
||||
|
||||
MENUITEMINFO mii;
|
||||
memset(&mii, 0, sizeof(mii));
|
||||
mii.cbSize = sizeof(mii);
|
||||
mii.fMask = MIIM_STRING;
|
||||
mii.dwTypeData = buffer;
|
||||
SetMenuItemInfo(_menu_bar, MI_frame_rate_label, FALSE, &mii);
|
||||
DrawMenuBar(_window);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -210,52 +306,339 @@ has_idle() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::is_thread_safe
|
||||
// Function: GtkStatsMonitor::user_guide_bars_changed
|
||||
// Access: Public, Virtual
|
||||
// Description: Should be redefined to return true if this monitor
|
||||
// class can handle running in a sub-thread.
|
||||
//
|
||||
// This is not related to the question of whether it can
|
||||
// handle multiple different PStatThreadDatas; this is
|
||||
// strictly a question of whether or not the monitor
|
||||
// itself wants to run in a sub-thread.
|
||||
// Description: Called when the user guide bars have been changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GtkStatsMonitor::
|
||||
is_thread_safe() {
|
||||
return true;
|
||||
void GtkStatsMonitor::
|
||||
user_guide_bars_changed() {
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
GtkStatsGraph *graph = (*gi);
|
||||
graph->user_guide_bars_changed();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::add_window
|
||||
// Function: GtkStatsMonitor::get_window
|
||||
// Access: Public
|
||||
// Description: Called only from the GtkStatsWindow constructor, this
|
||||
// indicates a new window that we should track.
|
||||
// Description: Returns the window handle to the monitor's window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
add_window(GtkStatsWindow *window) {
|
||||
nassertv(!_destructing);
|
||||
bool inserted = _windows.insert(window).second;
|
||||
nassertv(inserted);
|
||||
GtkWidget *GtkStatsMonitor::
|
||||
get_window() const {
|
||||
return _window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::remove_window
|
||||
// Function: GtkStatsMonitor::open_strip_chart
|
||||
// Access: Public
|
||||
// Description: Called only from the GtkStatsWindow destructor, this
|
||||
// indicates the end of a window that we should now no
|
||||
// longer track.
|
||||
//
|
||||
// When the last window is deleted, this automatically
|
||||
// closes the connection.
|
||||
// Description: Opens a new strip chart showing the indicated data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
remove_window(GtkStatsWindow *window) {
|
||||
if (!_destructing) {
|
||||
bool removed = (_windows.erase(window) != 0);
|
||||
nassertv(removed);
|
||||
open_strip_chart(int thread_index, int collector_index, bool show_level) {
|
||||
GtkStatsStripChart *graph =
|
||||
new GtkStatsStripChart(this, thread_index, collector_index, show_level);
|
||||
add_graph(graph);
|
||||
|
||||
if (_windows.empty()) {
|
||||
close();
|
||||
graph->set_time_units(_time_units);
|
||||
graph->set_scroll_speed(_scroll_speed);
|
||||
graph->set_pause(_pause);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::open_piano_roll
|
||||
// Access: Public
|
||||
// Description: Opens a new piano roll showing the indicated data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
open_piano_roll(int thread_index) {
|
||||
/*
|
||||
GtkStatsPianoRoll *graph = new GtkStatsPianoRoll(this, thread_index);
|
||||
add_graph(graph);
|
||||
|
||||
graph->set_time_units(_time_units);
|
||||
graph->set_scroll_speed(_scroll_speed);
|
||||
graph->set_pause(_pause);
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::lookup_menu
|
||||
// Access: Public
|
||||
// Description: Returns the MenuDef properties associated with the
|
||||
// indicated menu ID. This specifies what we expect to
|
||||
// do when the given menu has been selected.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const GtkStatsMonitor::MenuDef &GtkStatsMonitor::
|
||||
lookup_menu(int menu_id) const {
|
||||
static MenuDef invalid(0, 0, false);
|
||||
int menu_index = menu_id - MI_new_chart;
|
||||
nassertr(menu_index >= 0 && menu_index < (int)_menu_by_id.size(), invalid);
|
||||
return _menu_by_id[menu_index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::get_menu_id
|
||||
// Access: Public
|
||||
// Description: Returns the menu ID that is reserved for the
|
||||
// indicated MenuDef properties. If this is the first
|
||||
// time these particular properties have been requested,
|
||||
// a new menu ID is returned; otherwise, the existing
|
||||
// menu ID is returned.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsMonitor::
|
||||
get_menu_id(const MenuDef &menu_def) {
|
||||
MenuByDef::iterator mi;
|
||||
mi = _menu_by_def.find(menu_def);
|
||||
if (mi != _menu_by_def.end()) {
|
||||
return (*mi).second;
|
||||
}
|
||||
|
||||
// Slot a new id.
|
||||
int menu_id = (int)_menu_by_id.size() + MI_new_chart;
|
||||
_menu_by_id.push_back(menu_def);
|
||||
_menu_by_def[menu_def] = menu_id;
|
||||
|
||||
return menu_id;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::set_time_units
|
||||
// Access: Public
|
||||
// Description: Called when the user selects a new time units from
|
||||
// the monitor pulldown menu, this should adjust the
|
||||
// units for all graphs to the indicated mask if it is a
|
||||
// time-based graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
set_time_units(int unit_mask) {
|
||||
_time_units = unit_mask;
|
||||
|
||||
// First, change all of the open graphs appropriately.
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
GtkStatsGraph *graph = (*gi);
|
||||
graph->set_time_units(_time_units);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::set_scroll_speed
|
||||
// Access: Public
|
||||
// Description: Called when the user selects a new scroll speed from
|
||||
// the monitor pulldown menu, this should adjust the
|
||||
// speeds for all graphs to the indicated value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
set_scroll_speed(float scroll_speed) {
|
||||
_scroll_speed = scroll_speed;
|
||||
|
||||
// First, change all of the open graphs appropriately.
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
GtkStatsGraph *graph = (*gi);
|
||||
graph->set_scroll_speed(_scroll_speed);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::set_pause
|
||||
// Access: Public
|
||||
// Description: Called when the user selects a pause on or pause off
|
||||
// option from the menu.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
set_pause(bool pause) {
|
||||
_pause = pause;
|
||||
|
||||
// First, change all of the open graphs appropriately.
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
GtkStatsGraph *graph = (*gi);
|
||||
graph->set_pause(_pause);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::add_graph
|
||||
// Access: Private
|
||||
// Description: Adds the newly-created graph to the list of managed
|
||||
// graphs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
add_graph(GtkStatsGraph *graph) {
|
||||
_graphs.insert(graph);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::remove_graph
|
||||
// Access: Private
|
||||
// Description: Deletes the indicated graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
remove_graph(GtkStatsGraph *graph) {
|
||||
Graphs::iterator gi = _graphs.find(graph);
|
||||
if (gi != _graphs.end()) {
|
||||
_graphs.erase(gi);
|
||||
delete graph;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::create_window
|
||||
// Access: Private
|
||||
// Description: Creates the window for this monitor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
create_window() {
|
||||
if (_window != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
g_signal_connect(G_OBJECT(_window), "delete_event",
|
||||
G_CALLBACK(window_delete_event), this);
|
||||
g_signal_connect(G_OBJECT(_window), "destroy",
|
||||
G_CALLBACK(window_destroy), this);
|
||||
|
||||
_window_title = get_client_progname() + " on " + get_client_hostname();
|
||||
gtk_window_set_title(GTK_WINDOW(_window), _window_title.c_str());
|
||||
|
||||
gtk_window_set_default_size(GTK_WINDOW(_window), 500, 360);
|
||||
|
||||
// Set up the menu.
|
||||
GtkAccelGroup *accel_group = gtk_accel_group_new();
|
||||
_item_factory =
|
||||
gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<PStats>", accel_group);
|
||||
gtk_item_factory_create_items(_item_factory, num_menu_entries, menu_entries,
|
||||
this);
|
||||
gtk_window_add_accel_group(GTK_WINDOW(_window), accel_group);
|
||||
GtkWidget *menubar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
|
||||
|
||||
/*
|
||||
ChartMenus::iterator mi;
|
||||
for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
|
||||
(*mi)->add_to_menu_bar(_menu_bar, MI_frame_rate_label);
|
||||
}
|
||||
*/
|
||||
|
||||
// Pack the menu into the window.
|
||||
GtkWidget *main_vbox = gtk_vbox_new(FALSE, 1);
|
||||
// gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 1);
|
||||
gtk_container_add(GTK_CONTAINER(_window), main_vbox);
|
||||
gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
|
||||
|
||||
gtk_widget_show_all(_window);
|
||||
gtk_widget_show(_window);
|
||||
|
||||
set_time_units(PStatGraph::GBU_ms);
|
||||
set_scroll_speed(3);
|
||||
set_pause(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::window_delete_event
|
||||
// Access: Private, Static
|
||||
// Description: Callback when the window is closed by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gboolean GtkStatsMonitor::
|
||||
window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
|
||||
// Returning FALSE to indicate we should destroy the window
|
||||
// when the user selects "close".
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::window_delete_event
|
||||
// Access: Private, Static
|
||||
// Description: Callback when the window is destroyed by the system
|
||||
// (or by delete_event).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
window_destroy(GtkWidget *widget, gpointer data) {
|
||||
GtkStatsMonitor *self = (GtkStatsMonitor *)data;
|
||||
self->close();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::setup_frame_rate_label
|
||||
// Access: Private
|
||||
// Description: Creates the frame rate label on the right end of the
|
||||
// menu bar. This is used as a text label to display
|
||||
// the main thread's frame rate to the user, although it
|
||||
// is implemented as a right-justified toplevel menu
|
||||
// item that doesn't open to anything.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
setup_frame_rate_label() {
|
||||
/*
|
||||
MENUITEMINFO mii;
|
||||
memset(&mii, 0, sizeof(mii));
|
||||
mii.cbSize = sizeof(mii);
|
||||
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
|
||||
mii.fType = MFT_STRING | MFT_RIGHTJUSTIFY;
|
||||
mii.wID = MI_frame_rate_label;
|
||||
mii.dwTypeData = "";
|
||||
InsertMenuItem(_menu_bar, GetMenuItemCount(_menu_bar), TRUE, &mii);
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsMonitor::handle_menu_command
|
||||
// Access: Private, Static
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsMonitor::
|
||||
handle_menu_command(gpointer callback_data, guint menu_id, GtkWidget *widget) {
|
||||
GtkStatsMonitor *self = (GtkStatsMonitor *)callback_data;
|
||||
switch (menu_id) {
|
||||
case MI_none:
|
||||
break;
|
||||
|
||||
case MI_time_ms:
|
||||
self->set_time_units(PStatGraph::GBU_ms);
|
||||
break;
|
||||
|
||||
case MI_time_hz:
|
||||
self->set_time_units(PStatGraph::GBU_hz);
|
||||
break;
|
||||
|
||||
case MI_speed_1:
|
||||
self->set_scroll_speed(1);
|
||||
break;
|
||||
|
||||
case MI_speed_2:
|
||||
self->set_scroll_speed(2);
|
||||
break;
|
||||
|
||||
case MI_speed_3:
|
||||
self->set_scroll_speed(3);
|
||||
break;
|
||||
|
||||
case MI_speed_6:
|
||||
self->set_scroll_speed(6);
|
||||
break;
|
||||
|
||||
case MI_speed_12:
|
||||
self->set_scroll_speed(12);
|
||||
break;
|
||||
|
||||
case MI_pause:
|
||||
self->set_pause(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (menu_id >= MI_new_chart) {
|
||||
const MenuDef &menu_def = self->lookup_menu(menu_id);
|
||||
if (menu_def._collector_index < 0) {
|
||||
self->open_piano_roll(menu_def._thread_index);
|
||||
} else {
|
||||
self->open_strip_chart(menu_def._thread_index,
|
||||
menu_def._collector_index,
|
||||
menu_def._show_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsMonitor.h
|
||||
// Created by: drose (14Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -21,25 +21,37 @@
|
|||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "gtkStatsGraph.h"
|
||||
#include "pStatMonitor.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
#include "pset.h"
|
||||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
class GtkStatsServer;
|
||||
class GtkStatsWindow;
|
||||
class Gdk_Color;
|
||||
class GtkStatsChartMenu;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsMonitor
|
||||
// Description :
|
||||
// Description : This class represents a connection to a PStatsClient
|
||||
// and manages the data exchange with the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsMonitor : public PStatMonitor {
|
||||
public:
|
||||
GtkStatsMonitor(GtkStatsServer *server);
|
||||
~GtkStatsMonitor();
|
||||
class MenuDef {
|
||||
public:
|
||||
INLINE MenuDef(int thread_index, int collector_index, bool show_level);
|
||||
INLINE bool operator < (const MenuDef &other) const;
|
||||
|
||||
PT(PStatMonitor) close_all_windows();
|
||||
int _thread_index;
|
||||
int _collector_index;
|
||||
bool _show_level;
|
||||
};
|
||||
|
||||
GtkStatsMonitor(GtkStatsServer *server);
|
||||
virtual ~GtkStatsMonitor();
|
||||
|
||||
virtual string get_monitor_name();
|
||||
|
||||
|
|
@ -48,21 +60,61 @@ public:
|
|||
virtual void got_bad_version(int client_major, int client_minor,
|
||||
int server_major, int server_minor);
|
||||
virtual void new_collector(int collector_index);
|
||||
virtual void new_thread(int thread_index);
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
virtual void lost_connection();
|
||||
virtual void idle();
|
||||
virtual bool has_idle();
|
||||
virtual bool is_thread_safe();
|
||||
|
||||
public:
|
||||
void add_window(GtkStatsWindow *window);
|
||||
void remove_window(GtkStatsWindow *window);
|
||||
virtual void user_guide_bars_changed();
|
||||
|
||||
typedef pset<GtkStatsWindow *> Windows;
|
||||
Windows _windows;
|
||||
GtkWidget *get_window() const;
|
||||
void open_strip_chart(int thread_index, int collector_index, bool show_level);
|
||||
void open_piano_roll(int thread_index);
|
||||
|
||||
bool _destructing;
|
||||
bool _new_collector;
|
||||
const MenuDef &lookup_menu(int menu_id) const;
|
||||
int get_menu_id(const MenuDef &menu_def);
|
||||
|
||||
void set_time_units(int unit_mask);
|
||||
void set_scroll_speed(float scroll_speed);
|
||||
void set_pause(bool pause);
|
||||
|
||||
private:
|
||||
void add_graph(GtkStatsGraph *graph);
|
||||
void remove_graph(GtkStatsGraph *graph);
|
||||
|
||||
void create_window();
|
||||
static gboolean window_delete_event(GtkWidget *widget, GdkEvent *event,
|
||||
gpointer data);
|
||||
static void window_destroy(GtkWidget *widget, gpointer data);
|
||||
void setup_frame_rate_label();
|
||||
|
||||
static void handle_menu_command(gpointer callback_data, guint menu_id, GtkWidget *widget);
|
||||
|
||||
typedef pset<GtkStatsGraph *> Graphs;
|
||||
Graphs _graphs;
|
||||
|
||||
typedef pvector<GtkStatsChartMenu *> ChartMenus;
|
||||
ChartMenus _chart_menus;
|
||||
|
||||
typedef pvector<MenuDef> MenuById;
|
||||
typedef pmap<MenuDef, int> MenuByDef;
|
||||
MenuById _menu_by_id;
|
||||
MenuByDef _menu_by_def;
|
||||
|
||||
GtkWidget *_window;
|
||||
GtkItemFactory *_item_factory;
|
||||
string _window_title;
|
||||
int _time_units;
|
||||
float _scroll_speed;
|
||||
bool _pause;
|
||||
|
||||
static GtkItemFactoryEntry menu_entries[];
|
||||
static int num_menu_entries;
|
||||
|
||||
friend class GtkStatsGraph;
|
||||
};
|
||||
|
||||
#include "gtkStatsMonitor.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
// Filename: gtkStatsPianoRoll.I
|
||||
// Created by: drose (18Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsPianoRoll.cxx
|
||||
// Created by: drose (18Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -17,16 +17,14 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsPianoRoll.h"
|
||||
#include "gtkStatsLabel.h"
|
||||
#include "gtkStatsGuide.h"
|
||||
#include "gtkStatsMonitor.h"
|
||||
#include "numeric_types.h"
|
||||
|
||||
#include "request_initial_size.h"
|
||||
#include "pStatThreadData.h"
|
||||
#include "pStatFrameData.h"
|
||||
#include "pStatView.h"
|
||||
|
||||
#include <algorithm>
|
||||
static const int default_piano_roll_width = 400;
|
||||
static const int default_piano_roll_height = 200;
|
||||
|
||||
bool GtkStatsPianoRoll::_window_class_registered = false;
|
||||
const char * const GtkStatsPianoRoll::_window_class_name = "piano";
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::Constructor
|
||||
|
|
@ -34,115 +32,147 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsPianoRoll::
|
||||
GtkStatsPianoRoll(GtkStatsMonitor *monitor, int thread_index,
|
||||
int xsize, int ysize) :
|
||||
PStatPianoRoll(monitor, thread_index, xsize, ysize)
|
||||
GtkStatsPianoRoll(GtkStatsMonitor *monitor, int thread_index) :
|
||||
PStatPianoRoll(monitor, thread_index,
|
||||
default_piano_roll_width,
|
||||
default_piano_roll_height),
|
||||
GtkStatsGraph(monitor, thread_index)
|
||||
{
|
||||
_is_dead = false;
|
||||
set_events(GDK_EXPOSURE_MASK);
|
||||
_left_margin = 128;
|
||||
_right_margin = 8;
|
||||
_top_margin = 16;
|
||||
_bottom_margin = 8;
|
||||
|
||||
_label_align = manage(new Gtk::Alignment(1.0, 1.0));
|
||||
_label_align->show();
|
||||
// Let's show the units on the guide bar labels. There's room.
|
||||
set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
|
||||
|
||||
_label_box = NULL;
|
||||
pack_labels();
|
||||
|
||||
request_initial_size(*this, get_xsize(), get_ysize());
|
||||
create_window();
|
||||
clear_region();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::mark_dead
|
||||
// Access: Public
|
||||
// Description: Called when the client's connection has been lost,
|
||||
// this should update the window in some obvious way to
|
||||
// indicate that the window is no longer live.
|
||||
// Function: GtkStatsPianoRoll::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsPianoRoll::
|
||||
~GtkStatsPianoRoll() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::idle
|
||||
// Access: Public, Virtual
|
||||
// Description: Called as each frame's data is made available. There
|
||||
// is no gurantee the frames will arrive in order, or
|
||||
// that all of them will arrive at all. The monitor
|
||||
// should be prepared to accept frames received
|
||||
// out-of-order or missing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
mark_dead() {
|
||||
_is_dead = true;
|
||||
|
||||
setup_white_gc();
|
||||
force_redraw();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::get_labels
|
||||
// Access: Public
|
||||
// Description: Returns an alignment widget that contains all of the
|
||||
// labels appropriate to this chart, already formatted
|
||||
// and stacked up bottom-to-top. The window should pack
|
||||
// this widget suitably near the strip chart.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Gtk::Alignment *GtkStatsPianoRoll::
|
||||
get_labels() {
|
||||
return _label_align;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::get_collector_gc
|
||||
// Access: Public
|
||||
// Description: Returns a graphics context suitable for drawing in
|
||||
// the indicated collector's color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Gdk_GC GtkStatsPianoRoll::
|
||||
get_collector_gc(int collector_index) {
|
||||
GCs::iterator gi;
|
||||
gi = _gcs.find(collector_index);
|
||||
if (gi != _gcs.end()) {
|
||||
return (*gi).second;
|
||||
new_data(int thread_index, int frame_number) {
|
||||
if (!_pause) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
// Ask the monitor what color this guy should be.
|
||||
RGBColorf rgb = get_monitor()->get_collector_color(collector_index);
|
||||
Gdk_Color color;
|
||||
color.set_rgb_p(rgb[0], rgb[1], rgb[2]);
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::force_redraw
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when it is necessary to redraw the entire graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
force_redraw() {
|
||||
PStatPianoRoll::force_redraw();
|
||||
}
|
||||
|
||||
// Now allocate the color from the system colormap.
|
||||
Gdk_Colormap::get_system().alloc(color);
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::changed_graph_size
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user has resized the window, forcing
|
||||
// a resize of the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
changed_graph_size(int graph_xsize, int graph_ysize) {
|
||||
PStatPianoRoll::changed_size(graph_xsize, graph_ysize);
|
||||
}
|
||||
|
||||
// Allocate a new graphics context.
|
||||
Gdk_GC gc(_pixmap);
|
||||
gc.set_foreground(color);
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::set_time_units
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user selects a new time units from
|
||||
// the monitor pulldown menu, this should adjust the
|
||||
// units for the graph to the indicated mask if it is a
|
||||
// time-based graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
set_time_units(int unit_mask) {
|
||||
int old_unit_mask = get_guide_bar_units();
|
||||
if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) {
|
||||
unit_mask = unit_mask & (GBU_hz | GBU_ms);
|
||||
unit_mask |= (old_unit_mask & GBU_show_units);
|
||||
set_guide_bar_units(unit_mask);
|
||||
|
||||
_gcs[collector_index] = gc;
|
||||
return gc;
|
||||
RECT rect;
|
||||
GetClientRect(_window, &rect);
|
||||
rect.left = _right_margin;
|
||||
InvalidateRect(_window, &rect, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::clicked_label
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user single-clicks on a label.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
clicked_label(int collector_index) {
|
||||
if (collector_index >= 0) {
|
||||
GtkStatsGraph::_monitor->open_strip_chart(GtkStatsGraph::_thread_index, collector_index, false);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::set_horizontal_scale
|
||||
// Access: Public
|
||||
// Description: Changes the amount of time the width of the
|
||||
// horizontal axis represents. This may force a redraw.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
set_horizontal_scale(float time_width) {
|
||||
PStatPianoRoll::set_horizontal_scale(time_width);
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(_window, &rect);
|
||||
rect.bottom = _top_margin;
|
||||
InvalidateRect(_window, &rect, TRUE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::clear_region
|
||||
// Access: Protected
|
||||
// Description: Erases the chart area.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
clear_region() {
|
||||
RECT rect = { 0, 0, get_xsize(), get_ysize() };
|
||||
FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::begin_draw
|
||||
// Access: Protected, Virtual
|
||||
// Description: Erases the chart area in preparation for drawing it
|
||||
// full of bars.
|
||||
// Description: Erases the chart area in preparation for drawing a
|
||||
// bunch of bars.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
begin_draw() {
|
||||
_pixmap.draw_rectangle(_white_gc, true, 0, 0, get_xsize(), get_ysize());
|
||||
|
||||
Gdk_Font font = get_style()->gtkobj()->font;
|
||||
int text_height = font.height();
|
||||
clear_region();
|
||||
|
||||
// Draw in the guide bars.
|
||||
int num_guide_bars = get_num_guide_bars();
|
||||
for (int i = 0; i < num_guide_bars; i++) {
|
||||
const GuideBar &bar = get_guide_bar(i);
|
||||
int x = (int)((float)get_xsize() * bar._height / get_horizontal_scale());
|
||||
|
||||
if (x >= 5 && x <= get_xsize() - 5) {
|
||||
// Only draw it if it's not too close to either edge.
|
||||
switch (bar._style) {
|
||||
case GBS_target:
|
||||
_pixmap.draw_line(_light_gc, x, text_height + 4, x, get_ysize());
|
||||
break;
|
||||
|
||||
case GBS_normal:
|
||||
default:
|
||||
_pixmap.draw_line(_dark_gc, x, text_height + 4, x, get_ysize());
|
||||
break;
|
||||
}
|
||||
}
|
||||
draw_guide_bar(_bitmap_dc, get_guide_bar(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -152,10 +182,17 @@ begin_draw() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
draw_bar(int row, int from_x, int to_x) {
|
||||
if (row >= 0 && row < (int)_y_positions.size()) {
|
||||
int y = height() - _y_positions[row];
|
||||
_pixmap.draw_rectangle(get_collector_gc(get_label_collector(row)),
|
||||
true, from_x, y - 6, to_x - from_x, 12);
|
||||
if (row >= 0 && row < _label_stack.get_num_labels()) {
|
||||
int y = _label_stack.get_label_y(row) - _graph_top;
|
||||
int height = _label_stack.get_label_height(row);
|
||||
|
||||
RECT rect = {
|
||||
from_x, y - height + 2,
|
||||
to_x, y - 2,
|
||||
};
|
||||
int collector_index = get_label_collector(row);
|
||||
HBRUSH brush = get_collector_brush(collector_index);
|
||||
FillRect(_bitmap_dc, &rect, brush);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -167,31 +204,7 @@ draw_bar(int row, int from_x, int to_x) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
end_draw() {
|
||||
// Draw in the labels for the guide bars. We do this in end_draw()
|
||||
// instead of in begin_draw() so the labels will appear on top of
|
||||
// any of the color bars.
|
||||
Gdk_Font font = get_style()->gtkobj()->font;
|
||||
int text_ascent = font.ascent();
|
||||
|
||||
int num_guide_bars = get_num_guide_bars();
|
||||
for (int i = 0; i < num_guide_bars; i++) {
|
||||
const GuideBar &bar = get_guide_bar(i);
|
||||
int x = (int)((float)get_xsize() * bar._height / get_horizontal_scale());
|
||||
|
||||
if (x >= 5 && x <= get_xsize() - 5) {
|
||||
// Only draw it if it's not too close to either edge.
|
||||
int width = font.string_measure(bar._label);
|
||||
_pixmap.draw_string(font, _black_gc, x - width / 2, text_ascent + 2,
|
||||
bar._label);
|
||||
}
|
||||
}
|
||||
|
||||
GdkRectangle update_rect;
|
||||
update_rect.x = 0;
|
||||
update_rect.y = 0;
|
||||
update_rect.width = get_xsize();
|
||||
update_rect.height = get_ysize();
|
||||
draw(&update_rect);
|
||||
InvalidateRect(_graph_window, NULL, FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -202,126 +215,430 @@ end_draw() {
|
|||
void GtkStatsPianoRoll::
|
||||
idle() {
|
||||
if (_labels_changed) {
|
||||
pack_labels();
|
||||
update_labels();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::configure_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description: Creates a new backing pixmap of the appropriate size.
|
||||
// Function: GtkStatsPianoRoll::window_proc
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsPianoRoll::
|
||||
configure_event_impl(GdkEventConfigure *) {
|
||||
if (width() != get_xsize() || height() != get_ysize() ||
|
||||
_pixmap.gdkobj() == (GdkDrawable *)NULL) {
|
||||
if (_pixmap) {
|
||||
_pixmap.release();
|
||||
LONG GtkStatsPianoRoll::
|
||||
window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN:
|
||||
if (_potential_drag_mode == DM_new_guide_bar) {
|
||||
set_drag_mode(DM_new_guide_bar);
|
||||
SetCapture(_graph_window);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return GtkStatsGraph::window_proc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::graph_window_proc
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG GtkStatsPianoRoll::
|
||||
graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN:
|
||||
if (_potential_drag_mode == DM_none) {
|
||||
set_drag_mode(DM_scale);
|
||||
PN_int16 x = LOWORD(lparam);
|
||||
_drag_scale_start = pixel_to_height(x);
|
||||
SetCapture(_graph_window);
|
||||
return 0;
|
||||
|
||||
} else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) {
|
||||
set_drag_mode(DM_guide_bar);
|
||||
PN_int16 x = LOWORD(lparam);
|
||||
_drag_start_x = x;
|
||||
SetCapture(_graph_window);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if (_drag_mode == DM_none && _potential_drag_mode == DM_none) {
|
||||
// When the mouse is over a color bar, highlight it.
|
||||
PN_int16 x = LOWORD(lparam);
|
||||
PN_int16 y = HIWORD(lparam);
|
||||
_label_stack.highlight_label(get_collector_under_pixel(x, y));
|
||||
|
||||
// Now we want to get a WM_MOUSELEAVE when the mouse leaves the
|
||||
// graph window.
|
||||
TRACKMOUSEEVENT tme = {
|
||||
sizeof(TRACKMOUSEEVENT),
|
||||
TME_LEAVE,
|
||||
_graph_window,
|
||||
0
|
||||
};
|
||||
TrackMouseEvent(&tme);
|
||||
|
||||
} else {
|
||||
// If the mouse is in some drag mode, stop highlighting.
|
||||
_label_stack.highlight_label(-1);
|
||||
}
|
||||
|
||||
_pixmap.create(get_window(), width(), height());
|
||||
if (_drag_mode == DM_scale) {
|
||||
PN_int16 x = LOWORD(lparam);
|
||||
float ratio = (float)x / (float)get_xsize();
|
||||
if (ratio > 0.0f) {
|
||||
set_horizontal_scale(_drag_scale_start / ratio);
|
||||
}
|
||||
return 0;
|
||||
|
||||
Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
|
||||
} else if (_drag_mode == DM_new_guide_bar) {
|
||||
// We haven't created the new guide bar yet; we won't until the
|
||||
// mouse comes within the graph's region.
|
||||
PN_int16 x = LOWORD(lparam);
|
||||
if (x >= 0 && x < get_xsize()) {
|
||||
set_drag_mode(DM_guide_bar);
|
||||
_drag_guide_bar = add_user_guide_bar(pixel_to_height(x));
|
||||
return 0;
|
||||
}
|
||||
|
||||
_white_gc = Gdk_GC(_pixmap);
|
||||
setup_white_gc();
|
||||
} else if (_drag_mode == DM_guide_bar) {
|
||||
PN_int16 x = LOWORD(lparam);
|
||||
move_user_guide_bar(_drag_guide_bar, pixel_to_height(x));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
_black_gc = Gdk_GC(_pixmap);
|
||||
_black_gc.set_foreground(system_colormap.black());
|
||||
case WM_MOUSELEAVE:
|
||||
// When the mouse leaves the graph, stop highlighting.
|
||||
_label_stack.highlight_label(-1);
|
||||
break;
|
||||
|
||||
_dark_gc = Gdk_GC(_pixmap);
|
||||
Gdk_Color dark;
|
||||
dark.set_grey_p(0.2);
|
||||
system_colormap.alloc(dark);
|
||||
_dark_gc.set_foreground(dark);
|
||||
case WM_LBUTTONUP:
|
||||
if (_drag_mode == DM_scale) {
|
||||
set_drag_mode(DM_none);
|
||||
ReleaseCapture();
|
||||
return 0;
|
||||
|
||||
_light_gc = Gdk_GC(_pixmap);
|
||||
Gdk_Color light;
|
||||
light.set_grey_p(0.6);
|
||||
system_colormap.alloc(light);
|
||||
_light_gc.set_foreground(light);
|
||||
} else if (_drag_mode == DM_guide_bar) {
|
||||
PN_int16 x = LOWORD(lparam);
|
||||
if (x < 0 || x >= get_xsize()) {
|
||||
remove_user_guide_bar(_drag_guide_bar);
|
||||
} else {
|
||||
move_user_guide_bar(_drag_guide_bar, pixel_to_height(x));
|
||||
}
|
||||
set_drag_mode(DM_none);
|
||||
ReleaseCapture();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
_pixmap.draw_rectangle(_white_gc, true, 0, 0, width(), height());
|
||||
case WM_LBUTTONDBLCLK:
|
||||
{
|
||||
// Double-clicking on a color bar in the graph is the same as
|
||||
// double-clicking on the corresponding label.
|
||||
PN_int16 x = LOWORD(lparam);
|
||||
PN_int16 y = HIWORD(lparam);
|
||||
clicked_label(get_collector_under_pixel(x, y));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
changed_size(width(), height());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
return GtkStatsGraph::graph_window_proc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::expose_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description: Redraw the screen from the backing pixmap.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsPianoRoll::
|
||||
expose_event_impl(GdkEventExpose *event) {
|
||||
get_window().draw_pixmap(_white_gc, _pixmap,
|
||||
event->area.x, event->area.y,
|
||||
event->area.x, event->area.y,
|
||||
event->area.width, event->area.height);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::pack_labels
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Function: GtkStatsPianoRoll::additional_window_paint
|
||||
// Access: Protected, Virtual
|
||||
// Description: This is called during the servicing of WM_PAINT; it
|
||||
// gives a derived class opportunity to do some further
|
||||
// painting into the window (the outer window, not the
|
||||
// graph window).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
pack_labels() {
|
||||
// First, remove the old labels.
|
||||
_label_align->remove();
|
||||
additional_window_paint(HDC hdc) {
|
||||
// Draw in the labels for the guide bars.
|
||||
HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
|
||||
SelectObject(hdc, hfnt);
|
||||
SetTextAlign(hdc, TA_LEFT | TA_BOTTOM);
|
||||
SetBkMode(hdc, TRANSPARENT);
|
||||
|
||||
// Now add the new labels back in.
|
||||
_label_box = manage(new Gtk::VBox);
|
||||
_label_box->show();
|
||||
_label_align->add(*_label_box);
|
||||
int y = _top_margin;
|
||||
|
||||
Gdk_Font font = get_style()->gtkobj()->font;
|
||||
int num_labels = get_num_labels();
|
||||
|
||||
while ((int)_y_positions.size() < num_labels) {
|
||||
_y_positions.push_back(0);
|
||||
int i;
|
||||
int num_guide_bars = get_num_guide_bars();
|
||||
for (i = 0; i < num_guide_bars; i++) {
|
||||
draw_guide_label(hdc, y, get_guide_bar(i));
|
||||
}
|
||||
|
||||
int y = 0;
|
||||
for (int i = 0; i < num_labels; i++) {
|
||||
int collector_index = get_label_collector(i);
|
||||
GtkStatsLabel *label =
|
||||
new GtkStatsLabel(get_monitor(), collector_index, font);
|
||||
label->show();
|
||||
int num_user_guide_bars = get_num_user_guide_bars();
|
||||
for (i = 0; i < num_user_guide_bars; i++) {
|
||||
draw_guide_label(hdc, y, get_user_guide_bar(i));
|
||||
}
|
||||
}
|
||||
|
||||
_label_box->pack_end(*manage(label), false, false);
|
||||
_y_positions[i] = y + label->get_height() / 2;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::additional_graph_window_paint
|
||||
// Access: Protected, Virtual
|
||||
// Description: This is called during the servicing of WM_PAINT; it
|
||||
// gives a derived class opportunity to do some further
|
||||
// painting into the window (the outer window, not the
|
||||
// graph window).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
additional_graph_window_paint(HDC hdc) {
|
||||
int num_user_guide_bars = get_num_user_guide_bars();
|
||||
for (int i = 0; i < num_user_guide_bars; i++) {
|
||||
draw_guide_bar(hdc, get_user_guide_bar(i));
|
||||
}
|
||||
}
|
||||
|
||||
y += label->get_height();
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::consider_drag_start
|
||||
// Access: Protected, Virtual
|
||||
// Description: Based on the mouse position within the window's
|
||||
// client area, look for draggable things the mouse
|
||||
// might be hovering over and return the apprioprate
|
||||
// DragMode enum or DM_none if nothing is indicated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsGraph::DragMode GtkStatsPianoRoll::
|
||||
consider_drag_start(int mouse_x, int mouse_y, int width, int height) {
|
||||
if (mouse_y >= _graph_top && mouse_y < _graph_top + get_ysize()) {
|
||||
if (mouse_x >= _graph_left && mouse_x < _graph_left + get_xsize()) {
|
||||
// See if the mouse is over a user-defined guide bar.
|
||||
int x = mouse_x - _graph_left;
|
||||
float from_height = pixel_to_height(x - 2);
|
||||
float to_height = pixel_to_height(x + 2);
|
||||
_drag_guide_bar = find_user_guide_bar(from_height, to_height);
|
||||
if (_drag_guide_bar >= 0) {
|
||||
return DM_guide_bar;
|
||||
}
|
||||
|
||||
} else if (mouse_x < _left_margin - 2 ||
|
||||
mouse_x > width - _right_margin + 2) {
|
||||
// The mouse is left or right of the graph; maybe create a new
|
||||
// guide bar.
|
||||
return DM_new_guide_bar;
|
||||
}
|
||||
}
|
||||
|
||||
return GtkStatsGraph::consider_drag_start(mouse_x, mouse_y, width, height);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::get_collector_under_pixel
|
||||
// Access: Private
|
||||
// Description: Returns the collector index associated with the
|
||||
// indicated vertical row, or -1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GtkStatsPianoRoll::
|
||||
get_collector_under_pixel(int xpoint, int ypoint) {
|
||||
if (_label_stack.get_num_labels() == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Assume all of the labels are the same height.
|
||||
int height = _label_stack.get_label_height(0);
|
||||
int row = (get_ysize() - ypoint) / height;
|
||||
if (row >= 0 && row < _label_stack.get_num_labels()) {
|
||||
return _label_stack.get_label_collector_index(row);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::update_labels
|
||||
// Access: Private
|
||||
// Description: Resets the list of labels.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
update_labels() {
|
||||
_label_stack.clear_labels();
|
||||
for (int i = 0; i < get_num_labels(); i++) {
|
||||
int label_index =
|
||||
_label_stack.add_label(GtkStatsGraph::_monitor, this,
|
||||
GtkStatsGraph::_thread_index,
|
||||
get_label_collector(i), true);
|
||||
}
|
||||
_labels_changed = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::setup_white_gc
|
||||
// Function: GtkStatsPianoRoll::draw_guide_bar
|
||||
// Access: Private
|
||||
// Description: Sets the color on _white_gc to be either actually
|
||||
// white (if the chart is still alive) or a light gray
|
||||
// (if the chart is dead).
|
||||
// Description: Draws the line for the indicated guide bar on the
|
||||
// graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
setup_white_gc() {
|
||||
Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
|
||||
draw_guide_bar(HDC hdc, const PStatGraph::GuideBar &bar) {
|
||||
int x = height_to_pixel(bar._height);
|
||||
|
||||
if (_is_dead) {
|
||||
Gdk_Color death;
|
||||
death.set_grey_p(0.8);
|
||||
system_colormap.alloc(death);
|
||||
if (x > 0 && x < get_xsize() - 1) {
|
||||
// Only draw it if it's not too close to either edge.
|
||||
switch (bar._style) {
|
||||
case GBS_target:
|
||||
SelectObject(hdc, _light_pen);
|
||||
break;
|
||||
|
||||
_white_gc.set_foreground(death);
|
||||
|
||||
} else {
|
||||
_white_gc.set_foreground(system_colormap.white());
|
||||
case GBS_user:
|
||||
SelectObject(hdc, _user_guide_bar_pen);
|
||||
break;
|
||||
|
||||
case GBS_normal:
|
||||
SelectObject(hdc, _dark_pen);
|
||||
break;
|
||||
}
|
||||
MoveToEx(hdc, x, 0, NULL);
|
||||
LineTo(hdc, x, get_ysize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::draw_guide_label
|
||||
// Access: Private
|
||||
// Description: Draws the text for the indicated guide bar label at
|
||||
// the top of the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
draw_guide_label(HDC hdc, int y, const PStatGraph::GuideBar &bar) {
|
||||
switch (bar._style) {
|
||||
case GBS_target:
|
||||
SetTextColor(hdc, _light_color);
|
||||
break;
|
||||
|
||||
case GBS_user:
|
||||
SetTextColor(hdc, _user_guide_bar_color);
|
||||
break;
|
||||
|
||||
case GBS_normal:
|
||||
SetTextColor(hdc, _dark_color);
|
||||
break;
|
||||
}
|
||||
|
||||
int x = height_to_pixel(bar._height);
|
||||
const string &label = bar._label;
|
||||
SIZE size;
|
||||
GetTextExtentPoint32(hdc, label.data(), label.length(), &size);
|
||||
|
||||
if (bar._style != GBS_user) {
|
||||
float from_height = pixel_to_height(x - size.cx);
|
||||
float to_height = pixel_to_height(x + size.cx);
|
||||
if (find_user_guide_bar(from_height, to_height) >= 0) {
|
||||
// Omit the label: there's a user-defined guide bar in the same space.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int this_x = _graph_left + x - size.cx / 2;
|
||||
if (x >= 0 && x < get_xsize()) {
|
||||
TextOut(hdc, this_x, y,
|
||||
label.data(), label.length());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::create_window
|
||||
// Access: Private
|
||||
// Description: Creates the window for this strip chart.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
create_window() {
|
||||
if (_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
HINSTANCE application = GetModuleHandle(NULL);
|
||||
register_window_class(application);
|
||||
|
||||
const PStatClientData *client_data =
|
||||
GtkStatsGraph::_monitor->get_client_data();
|
||||
string thread_name = client_data->get_thread_name(GtkStatsGraph::_thread_index);
|
||||
string window_title = thread_name + " thread piano roll";
|
||||
|
||||
|
||||
RECT win_rect = {
|
||||
0, 0,
|
||||
_left_margin + get_xsize() + _right_margin,
|
||||
_top_margin + get_ysize() + _bottom_margin
|
||||
};
|
||||
|
||||
// compute window size based on desired client area size
|
||||
AdjustWindowRect(&win_rect, graph_window_style, FALSE);
|
||||
|
||||
_window =
|
||||
CreateWindow(_window_class_name, window_title.c_str(), graph_window_style,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
win_rect.right - win_rect.left,
|
||||
win_rect.bottom - win_rect.top,
|
||||
GtkStatsGraph::_monitor->get_window(), NULL, application, 0);
|
||||
if (!_window) {
|
||||
nout << "Could not create PianoRoll window!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SetWindowLongPtr(_window, 0, (LONG_PTR)this);
|
||||
setup_label_stack();
|
||||
|
||||
// Ensure that the window is on top of the stack.
|
||||
SetWindowPos(_window, HWND_TOP, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::register_window_class
|
||||
// Access: Private, Static
|
||||
// Description: Registers the window class for the pianoRoll window, if
|
||||
// it has not already been registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoRoll::
|
||||
register_window_class(HINSTANCE application) {
|
||||
if (_window_class_registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
WNDCLASS wc;
|
||||
|
||||
ZeroMemory(&wc, sizeof(WNDCLASS));
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = (WNDPROC)static_window_proc;
|
||||
wc.hInstance = application;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = _window_class_name;
|
||||
|
||||
// Reserve space to associate the this pointer with the window.
|
||||
wc.cbWndExtra = sizeof(GtkStatsPianoRoll *);
|
||||
|
||||
if (!RegisterClass(&wc)) {
|
||||
nout << "Could not register PianoRoll window class!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_window_class_registered = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoRoll::static_window_proc
|
||||
// Access: Private, Static
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG WINAPI GtkStatsPianoRoll::
|
||||
static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
GtkStatsPianoRoll *self = (GtkStatsPianoRoll *)GetWindowLongPtr(hwnd, 0);
|
||||
if (self != (GtkStatsPianoRoll *)NULL && self->_window == hwnd) {
|
||||
return self->window_proc(hwnd, msg, wparam, lparam);
|
||||
} else {
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsPianoRoll.h
|
||||
// Created by: drose (18Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -21,72 +21,61 @@
|
|||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "gtkStatsMonitor.h"
|
||||
|
||||
#include "gtkStatsGraph.h"
|
||||
#include "pStatPianoRoll.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
#include <gtk--.h>
|
||||
#include "pmap.h"
|
||||
#include <windows.h>
|
||||
|
||||
class PStatView;
|
||||
class GtkStatsGuide;
|
||||
class GtkStatsMonitor;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsPianoRoll
|
||||
// Description : A special widget that draws a piano-roll style chart,
|
||||
// Description : A window that draws a piano-roll style chart,
|
||||
// which shows the collectors explicitly stopping and
|
||||
// starting, one frame at a time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsPianoRoll : public Gtk::DrawingArea, public PStatPianoRoll {
|
||||
class GtkStatsPianoRoll : public PStatPianoRoll, public GtkStatsGraph {
|
||||
public:
|
||||
GtkStatsPianoRoll(GtkStatsMonitor *monitor, int thread_index,
|
||||
int xsize, int ysize);
|
||||
GtkStatsPianoRoll(GtkStatsMonitor *monitor, int thread_index);
|
||||
virtual ~GtkStatsPianoRoll();
|
||||
|
||||
void mark_dead();
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
virtual void force_redraw();
|
||||
virtual void changed_graph_size(int graph_xsize, int graph_ysize);
|
||||
|
||||
Gtk::Alignment *get_labels();
|
||||
virtual void set_time_units(int unit_mask);
|
||||
virtual void clicked_label(int collector_index);
|
||||
void set_horizontal_scale(float time_width);
|
||||
|
||||
Gdk_GC get_collector_gc(int collector_index);
|
||||
|
||||
private:
|
||||
protected:
|
||||
void clear_region();
|
||||
virtual void begin_draw();
|
||||
virtual void draw_bar(int row, int from_x, int to_x);
|
||||
virtual void end_draw();
|
||||
virtual void idle();
|
||||
|
||||
virtual gint configure_event_impl(GdkEventConfigure *event);
|
||||
virtual gint expose_event_impl(GdkEventExpose *event);
|
||||
|
||||
void pack_labels();
|
||||
void setup_white_gc();
|
||||
LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
virtual LONG graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
virtual void additional_window_paint(HDC hdc);
|
||||
virtual void additional_graph_window_paint(HDC hdc);
|
||||
virtual DragMode consider_drag_start(int mouse_x, int mouse_y,
|
||||
int width, int height);
|
||||
|
||||
private:
|
||||
// Backing pixmap for drawing area.
|
||||
Gdk_Pixmap _pixmap;
|
||||
int get_collector_under_pixel(int xpoint, int ypoint);
|
||||
void update_labels();
|
||||
void draw_guide_bar(HDC hdc, const GuideBar &bar);
|
||||
void draw_guide_label(HDC hdc, int y, const PStatGraph::GuideBar &bar);
|
||||
|
||||
// Graphics contexts for fg/bg. We don't use the contexts defined
|
||||
// in the style, because that would probably interfere with the
|
||||
// visibility of the chart.
|
||||
Gdk_GC _white_gc;
|
||||
Gdk_GC _black_gc;
|
||||
Gdk_GC _dark_gc;
|
||||
Gdk_GC _light_gc;
|
||||
void create_window();
|
||||
static void register_window_class(HINSTANCE application);
|
||||
|
||||
// Table of graphics contexts for our various collectors.
|
||||
typedef pmap<int, Gdk_GC> GCs;
|
||||
GCs _gcs;
|
||||
static LONG GTKAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
// Table of Y-positions for each of our rows, measured from the
|
||||
// bottom.
|
||||
vector_int _y_positions;
|
||||
|
||||
Gtk::Alignment *_label_align;
|
||||
Gtk::VBox *_label_box;
|
||||
bool _is_dead;
|
||||
static bool _window_class_registered;
|
||||
static const char * const _window_class_name;
|
||||
};
|
||||
|
||||
#include "gtkStatsPianoRoll.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,164 +0,0 @@
|
|||
// Filename: gtkStatsPianoWindow.cxx
|
||||
// Created by: drose (18Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsPianoWindow.h"
|
||||
#include "gtkStatsPianoRoll.h"
|
||||
|
||||
using Gtk::Menu_Helpers::MenuElem;
|
||||
using Gtk::Menu_Helpers::SeparatorElem;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoWindow::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsPianoWindow::
|
||||
GtkStatsPianoWindow(GtkStatsMonitor *monitor, int thread_index,
|
||||
int chart_xsize, int chart_ysize) :
|
||||
GtkStatsWindow(monitor),
|
||||
_thread_index(thread_index)
|
||||
{
|
||||
setup_menu();
|
||||
layout_window(chart_xsize, chart_ysize);
|
||||
show();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoWindow::mark_dead
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the client's connection has been lost,
|
||||
// this should update the window in some obvious way to
|
||||
// indicate that the window is no longer live.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoWindow::
|
||||
mark_dead() {
|
||||
GtkStatsWindow::mark_dead();
|
||||
_chart->mark_dead();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoWindow::idle
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoWindow::
|
||||
idle() {
|
||||
GtkStatsWindow::idle();
|
||||
_chart->update();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoWindow::setup_menu
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoWindow::
|
||||
setup_menu() {
|
||||
GtkStatsWindow::setup_menu();
|
||||
|
||||
Gtk::Menu *scale_menu = new Gtk::Menu;
|
||||
|
||||
scale_menu->items().push_back
|
||||
(MenuElem("0.1 Hz",
|
||||
bind(slot(this, &GtkStatsPianoWindow::menu_hscale), 0.1f)));
|
||||
scale_menu->items().push_back
|
||||
(MenuElem("1 Hz",
|
||||
bind(slot(this, &GtkStatsPianoWindow::menu_hscale), 1.0f)));
|
||||
scale_menu->items().push_back
|
||||
(MenuElem("5 Hz",
|
||||
bind(slot(this, &GtkStatsPianoWindow::menu_hscale), 5.0f)));
|
||||
scale_menu->items().push_back
|
||||
(MenuElem("10 Hz",
|
||||
bind(slot(this, &GtkStatsPianoWindow::menu_hscale), 10.0f)));
|
||||
scale_menu->items().push_back
|
||||
(MenuElem("20 Hz",
|
||||
bind(slot(this, &GtkStatsPianoWindow::menu_hscale), 20.0f)));
|
||||
scale_menu->items().push_back
|
||||
(MenuElem("30 Hz",
|
||||
bind(slot(this, &GtkStatsPianoWindow::menu_hscale), 30.0f)));
|
||||
scale_menu->items().push_back
|
||||
(MenuElem("60 Hz",
|
||||
bind(slot(this, &GtkStatsPianoWindow::menu_hscale), 60.0f)));
|
||||
scale_menu->items().push_back
|
||||
(MenuElem("120 Hz",
|
||||
bind(slot(this, &GtkStatsPianoWindow::menu_hscale), 120.0f)));
|
||||
|
||||
_menu->items().push_back(MenuElem("Scale", *manage(scale_menu)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoWindow::menu_new_window
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoWindow::
|
||||
menu_new_window() {
|
||||
new GtkStatsPianoWindow(_monitor, _thread_index,
|
||||
_chart->get_xsize(), _chart->get_ysize());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoWindow::menu_hscale
|
||||
// Access: Protected
|
||||
// Description: Selects a new horizontal scale for the piano roll.
|
||||
// This is done from the menu called "Scale".
|
||||
//
|
||||
// The units is in Hz.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoWindow::
|
||||
menu_hscale(float hz) {
|
||||
_chart->set_horizontal_scale(1.0 / hz);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsPianoWindow::layout_window
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsPianoWindow::
|
||||
layout_window(int chart_xsize, int chart_ysize) {
|
||||
Gtk::HBox *hbox = new Gtk::HBox;
|
||||
hbox = new Gtk::HBox;
|
||||
hbox->show();
|
||||
_main_box->pack_start(*manage(hbox), true, true, 8);
|
||||
|
||||
Gtk::Table *chart_table = new Gtk::Table(1, 2);
|
||||
chart_table->show();
|
||||
hbox->pack_start(*manage(chart_table), true, true, 8);
|
||||
|
||||
Gtk::Frame *frame = new Gtk::Frame;
|
||||
frame->set_shadow_type(GTK_SHADOW_ETCHED_OUT);
|
||||
frame->show();
|
||||
chart_table->attach(*manage(frame), 1, 2, 0, 1);
|
||||
|
||||
_chart = new GtkStatsPianoRoll(_monitor, _thread_index,
|
||||
chart_xsize, chart_ysize);
|
||||
frame->add(*manage(_chart));
|
||||
|
||||
// We put the labels in a frame, too, so they'll line up vertically.
|
||||
Gtk::Frame *label_frame = new Gtk::Frame;
|
||||
label_frame->set_shadow_type(GTK_SHADOW_NONE);
|
||||
label_frame->show();
|
||||
label_frame->add(*manage(_chart->get_labels()));
|
||||
|
||||
chart_table->attach(*manage(label_frame), 0, 1, 0, 1,
|
||||
0, (GTK_FILL|GTK_EXPAND), 4, 0);
|
||||
|
||||
_chart->show();
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsServer.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -19,7 +19,6 @@
|
|||
#include "gtkStatsServer.h"
|
||||
#include "gtkStatsMonitor.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsServer::make_monitor
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsServer.h
|
||||
// Created by: drose (14Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -20,13 +20,12 @@
|
|||
#define GTKSTATSSERVER_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "pStatServer.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsServer
|
||||
// Description :
|
||||
// Description : The class that owns the main loop, waiting for client
|
||||
// connections.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsServer : public PStatServer {
|
||||
public:
|
||||
|
|
@ -34,3 +33,4 @@ public:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
// Filename: gtkStatsStripChart.I
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsStripChart.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -17,16 +17,12 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsStripChart.h"
|
||||
#include "gtkStatsLabel.h"
|
||||
#include "gtkStatsGuide.h"
|
||||
|
||||
#include "request_initial_size.h"
|
||||
#include "pStatThreadData.h"
|
||||
#include "pStatFrameData.h"
|
||||
#include "pStatView.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "gtkStatsMonitor.h"
|
||||
#include "pStatCollectorDef.h"
|
||||
#include "numeric_types.h"
|
||||
|
||||
static const int default_strip_chart_width = 400;
|
||||
static const int default_strip_chart_height = 100;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::Constructor
|
||||
|
|
@ -34,99 +30,234 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsStripChart::
|
||||
GtkStatsStripChart(GtkStatsMonitor *monitor, PStatView &view,
|
||||
int collector_index, int xsize, int ysize) :
|
||||
PStatStripChart(monitor, view, collector_index, xsize, ysize)
|
||||
GtkStatsStripChart(GtkStatsMonitor *monitor, int thread_index,
|
||||
int collector_index, bool show_level) :
|
||||
PStatStripChart(monitor,
|
||||
show_level ? monitor->get_level_view(collector_index, thread_index) : monitor->get_view(thread_index),
|
||||
collector_index,
|
||||
default_strip_chart_width,
|
||||
default_strip_chart_height),
|
||||
GtkStatsGraph(monitor, thread_index)
|
||||
{
|
||||
_is_dead = false;
|
||||
set_events(GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
|
||||
_brush_origin = 0;
|
||||
|
||||
_label_align = manage(new Gtk::Alignment(1.0, 1.0));
|
||||
_label_align->show();
|
||||
_left_margin = 96;
|
||||
_right_margin = 32;
|
||||
_top_margin = 16;
|
||||
_bottom_margin = 8;
|
||||
|
||||
_label_box = NULL;
|
||||
pack_labels();
|
||||
if (show_level) {
|
||||
// If it's a level-type graph, show the appropriate units.
|
||||
if (_unit_name.empty()) {
|
||||
set_guide_bar_units(GBU_named);
|
||||
} else {
|
||||
set_guide_bar_units(GBU_named | GBU_show_units);
|
||||
}
|
||||
|
||||
_guide = manage(new GtkStatsGuide(this));
|
||||
_guide->show();
|
||||
} else {
|
||||
// If it's a time-type graph, show the ms/Hz units.
|
||||
set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
|
||||
}
|
||||
|
||||
request_initial_size(*this, get_xsize(), get_ysize());
|
||||
_smooth_check_box = 0;
|
||||
|
||||
GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), _label_stack.setup(),
|
||||
FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), _graph_window,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(_window), hbox);
|
||||
|
||||
gtk_widget_show_all(_window);
|
||||
gtk_widget_show(_window);
|
||||
|
||||
clear_region();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::mark_dead
|
||||
// Access: Public
|
||||
// Description: Called when the client's connection has been lost,
|
||||
// this should update the window in some obvious way to
|
||||
// indicate that the window is no longer live.
|
||||
// Function: GtkStatsStripChart::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsStripChart::
|
||||
~GtkStatsStripChart() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::new_collector
|
||||
// Access: Public, Virtual
|
||||
// Description: Called whenever a new Collector definition is
|
||||
// received from the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
mark_dead() {
|
||||
_is_dead = true;
|
||||
new_collector(int collector_index) {
|
||||
GtkStatsGraph::new_collector(collector_index);
|
||||
}
|
||||
|
||||
setup_white_gc();
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::new_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Called as each frame's data is made available. There
|
||||
// is no gurantee the frames will arrive in order, or
|
||||
// that all of them will arrive at all. The monitor
|
||||
// should be prepared to accept frames received
|
||||
// out-of-order or missing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
new_data(int thread_index, int frame_number) {
|
||||
if (is_title_unknown()) {
|
||||
string window_title = get_title_text();
|
||||
if (!is_title_unknown()) {
|
||||
gtk_window_set_title(GTK_WINDOW(_window), window_title.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!_pause) {
|
||||
update();
|
||||
|
||||
/*
|
||||
string text = format_number(get_average_net_value(), get_guide_bar_units(), get_guide_bar_unit_name());
|
||||
if (_net_value_text != text) {
|
||||
_net_value_text = text;
|
||||
RECT rect;
|
||||
GetClientRect(_window, &rect);
|
||||
rect.bottom = _top_margin;
|
||||
InvalidateRect(_window, &rect, TRUE);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::force_redraw
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when it is necessary to redraw the entire graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
force_redraw() {
|
||||
PStatStripChart::force_redraw();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::changed_graph_size
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user has resized the window, forcing
|
||||
// a resize of the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
changed_graph_size(int graph_xsize, int graph_ysize) {
|
||||
PStatStripChart::changed_size(graph_xsize, graph_ysize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::set_time_units
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user selects a new time units from
|
||||
// the monitor pulldown menu, this should adjust the
|
||||
// units for the graph to the indicated mask if it is a
|
||||
// time-based graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
set_time_units(int unit_mask) {
|
||||
int old_unit_mask = get_guide_bar_units();
|
||||
if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) {
|
||||
unit_mask = unit_mask & (GBU_hz | GBU_ms);
|
||||
unit_mask |= (old_unit_mask & GBU_show_units);
|
||||
set_guide_bar_units(unit_mask);
|
||||
|
||||
/*
|
||||
RECT rect;
|
||||
GetClientRect(_window, &rect);
|
||||
rect.left = _right_margin;
|
||||
InvalidateRect(_window, &rect, TRUE);
|
||||
|
||||
GetClientRect(_window, &rect);
|
||||
rect.bottom = _top_margin;
|
||||
InvalidateRect(_window, &rect, TRUE);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::set_scroll_speed
|
||||
// Access: Public
|
||||
// Description: Called when the user selects a new scroll speed from
|
||||
// the monitor pulldown menu, this should adjust the
|
||||
// speed for the graph to the indicated value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
set_scroll_speed(float scroll_speed) {
|
||||
// The speed factor indicates chart widths per minute.
|
||||
if (scroll_speed != 0.0f) {
|
||||
set_horizontal_scale(60.0f / scroll_speed);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::clicked_label
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the user single-clicks on a label.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
clicked_label(int collector_index) {
|
||||
if (collector_index < 0) {
|
||||
// Clicking on whitespace in the graph is the same as clicking on
|
||||
// the top label.
|
||||
collector_index = get_collector_index();
|
||||
}
|
||||
|
||||
if (collector_index == get_collector_index() && collector_index != 0) {
|
||||
// Clicking on the top label means to go up to the parent level.
|
||||
const PStatClientData *client_data =
|
||||
GtkStatsGraph::_monitor->get_client_data();
|
||||
if (client_data->has_collector(collector_index)) {
|
||||
const PStatCollectorDef &def =
|
||||
client_data->get_collector_def(collector_index);
|
||||
if (def._parent_index == 0 && get_view().get_show_level()) {
|
||||
// Unless the parent is "Frame", and we're not a time collector.
|
||||
} else {
|
||||
set_collector_index(def._parent_index);
|
||||
}
|
||||
}
|
||||
|
||||
if (!first_data()) {
|
||||
force_redraw();
|
||||
} else {
|
||||
clear_region();
|
||||
// Clicking on any other label means to focus on that.
|
||||
set_collector_index(collector_index);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::get_labels
|
||||
// Function: GtkStatsStripChart::set_vertical_scale
|
||||
// Access: Public
|
||||
// Description: Returns an alignment widget that contains all of the
|
||||
// labels appropriate to this chart, already formatted
|
||||
// and stacked up bottom-to-top. The window should pack
|
||||
// this widget suitably near the strip chart.
|
||||
// Description: Changes the value the height of the vertical axis
|
||||
// represents. This may force a redraw.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Gtk::Alignment *GtkStatsStripChart::
|
||||
get_labels() {
|
||||
return _label_align;
|
||||
void GtkStatsStripChart::
|
||||
set_vertical_scale(float value_height) {
|
||||
PStatStripChart::set_vertical_scale(value_height);
|
||||
|
||||
GdkRectangle rect = {
|
||||
0, 0, get_xsize(), get_ysize()
|
||||
};
|
||||
gdk_window_invalidate_rect(_graph_window->window, &rect, FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::get_guide
|
||||
// Access: Public
|
||||
// Description: Returns a widget that contains the numeric labels for
|
||||
// the guide bars. The window should pack this widget
|
||||
// suitably near the strip chart.
|
||||
// Function: GtkStatsStripChart::update_labels
|
||||
// Access: Protected, Virtual
|
||||
// Description: Resets the list of labels.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsGuide *GtkStatsStripChart::
|
||||
get_guide() {
|
||||
return _guide;
|
||||
}
|
||||
void GtkStatsStripChart::
|
||||
update_labels() {
|
||||
PStatStripChart::update_labels();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::get_collector_gc
|
||||
// Access: Public
|
||||
// Description: Returns a graphics context suitable for drawing in
|
||||
// the indicated collector's color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Gdk_GC GtkStatsStripChart::
|
||||
get_collector_gc(int collector_index) {
|
||||
GCs::iterator gi;
|
||||
gi = _gcs.find(collector_index);
|
||||
if (gi != _gcs.end()) {
|
||||
return (*gi).second;
|
||||
_label_stack.clear_labels();
|
||||
for (int i = 0; i < get_num_labels(); i++) {
|
||||
_label_stack.add_label(GtkStatsGraph::_monitor, this, _thread_index,
|
||||
get_label_collector(i), false);
|
||||
}
|
||||
|
||||
// Ask the monitor what color this guy should be.
|
||||
RGBColorf rgb = get_monitor()->get_collector_color(collector_index);
|
||||
Gdk_Color color;
|
||||
color.set_rgb_p(rgb[0], rgb[1], rgb[2]);
|
||||
|
||||
// Now allocate the color from the system colormap.
|
||||
Gdk_Colormap::get_system().alloc(color);
|
||||
|
||||
// Allocate a new graphics context.
|
||||
Gdk_GC gc(_pixmap);
|
||||
gc.set_foreground(color);
|
||||
|
||||
_gcs[collector_index] = gc;
|
||||
return gc;
|
||||
_labels_changed = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -136,8 +267,9 @@ get_collector_gc(int collector_index) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
clear_region() {
|
||||
_pixmap.draw_rectangle(_white_gc, true, 0, 0, get_xsize(), get_ysize());
|
||||
end_draw(0, get_xsize());
|
||||
gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
|
||||
gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, 0, 0,
|
||||
get_xsize(), get_ysize());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -149,28 +281,19 @@ clear_region() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
copy_region(int start_x, int end_x, int dest_x) {
|
||||
_pixmap.copy_area(_white_gc, 0, 0,
|
||||
_pixmap, start_x, 0,
|
||||
end_x - start_x + 1, get_ysize());
|
||||
gdk_draw_drawable(_pixmap, _pixmap_gc, _pixmap,
|
||||
start_x, 0, dest_x, 0,
|
||||
end_x - start_x, get_ysize());
|
||||
|
||||
// Also shift the brush origin over, so we still get proper
|
||||
// dithering.
|
||||
_brush_origin += (dest_x - start_x);
|
||||
// SetBrushOrgEx(_bitmap_dc, _brush_origin, 0, NULL);
|
||||
|
||||
// We could make a window-to-window copy to implement scrolling in
|
||||
// the window. But this leads to trouble if the scrolling window
|
||||
// isn't on top. Instead, we'll just do the scroll in the pixmap,
|
||||
// and then blt the pixmap back out--in principle, this ought to be
|
||||
// just as fast.
|
||||
/*
|
||||
Gdk_Window window = get_window();
|
||||
window.copy_area(_white_gc, 0, 0,
|
||||
window, start_x, 0,
|
||||
end_x - start_x + 1, get_ysize());
|
||||
*/
|
||||
|
||||
GdkRectangle update_rect;
|
||||
update_rect.x = dest_x;
|
||||
update_rect.y = 0;
|
||||
update_rect.width = end_x - start_x + 1;
|
||||
update_rect.height = get_ysize();
|
||||
draw(&update_rect);
|
||||
GdkRectangle rect = {
|
||||
dest_x, 0, end_x - start_x, get_ysize()
|
||||
};
|
||||
gdk_window_invalidate_rect(_graph_window->window, &rect, FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -182,32 +305,32 @@ copy_region(int start_x, int end_x, int dest_x) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
draw_slice(int x, int w, const PStatStripChart::FrameData &fdata) {
|
||||
while (w > 0) {
|
||||
// Start by clearing the band first.
|
||||
_pixmap.draw_line(_white_gc, x, 0, x, get_ysize());
|
||||
// Start by clearing the band first.
|
||||
gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
|
||||
gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, x, 0,
|
||||
w + 1, get_ysize());
|
||||
|
||||
float overall_time = 0.0;
|
||||
int y = get_ysize();
|
||||
float overall_time = 0.0;
|
||||
int y = get_ysize();
|
||||
|
||||
FrameData::const_iterator fi;
|
||||
for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
|
||||
const ColorData &cd = (*fi);
|
||||
overall_time += cd._net_value;
|
||||
FrameData::const_iterator fi;
|
||||
for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
|
||||
const ColorData &cd = (*fi);
|
||||
overall_time += cd._net_value;
|
||||
GdkGC *gc = get_collector_gc(cd._collector_index);
|
||||
|
||||
if (overall_time > get_vertical_scale()) {
|
||||
// Off the top. Go ahead and clamp it by hand, in case it's so
|
||||
// far off the top we'd overflow the 16-bit pixel value.
|
||||
_pixmap.draw_line(get_collector_gc(cd._collector_index), x, y, x, 0);
|
||||
// And we can consider ourselves done now.
|
||||
break;
|
||||
}
|
||||
if (overall_time > get_vertical_scale()) {
|
||||
// Off the top. Go ahead and clamp it by hand, in case it's so
|
||||
// far off the top we'd overflow the 16-bit pixel value.
|
||||
gdk_draw_rectangle(_pixmap, gc, TRUE, x, 0, w + 1, y);
|
||||
|
||||
int top_y = height_to_pixel(overall_time);
|
||||
_pixmap.draw_line(get_collector_gc(cd._collector_index), x, y, x, top_y);
|
||||
y = top_y;
|
||||
// And we can consider ourselves done now.
|
||||
return;
|
||||
}
|
||||
x++;
|
||||
w--;
|
||||
|
||||
int top_y = height_to_pixel(overall_time);
|
||||
gdk_draw_rectangle(_pixmap, gc, TRUE, x, top_y, w + 1, y);
|
||||
y = top_y;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,11 +341,9 @@ draw_slice(int x, int w, const PStatStripChart::FrameData &fdata) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
draw_empty(int x, int w) {
|
||||
while (w > 0) {
|
||||
_pixmap.draw_line(_white_gc, x, 0, x, get_ysize());
|
||||
x++;
|
||||
w--;
|
||||
}
|
||||
gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
|
||||
gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, x, 0,
|
||||
w + 1, get_ysize());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -232,7 +353,8 @@ draw_empty(int x, int w) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
draw_cursor(int x) {
|
||||
_pixmap.draw_line(_black_gc, x, 0, x, get_ysize());
|
||||
gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_black);
|
||||
gdk_draw_line(_pixmap, _pixmap_gc, x, 0, x, get_ysize());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -248,181 +370,103 @@ end_draw(int from_x, int to_x) {
|
|||
// Draw in the guide bars.
|
||||
int num_guide_bars = get_num_guide_bars();
|
||||
for (int i = 0; i < num_guide_bars; i++) {
|
||||
const GuideBar &bar = get_guide_bar(i);
|
||||
int y = height_to_pixel(bar._height);
|
||||
|
||||
if (y >= 5) {
|
||||
// Only draw it if it's not too close to the top.
|
||||
switch (bar._style) {
|
||||
case GBS_target:
|
||||
_pixmap.draw_line(_light_gc, from_x, y, to_x, y);
|
||||
break;
|
||||
|
||||
case GBS_normal:
|
||||
default:
|
||||
_pixmap.draw_line(_dark_gc, from_x, y, to_x, y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
draw_guide_bar(from_x, to_x, get_guide_bar(i));
|
||||
}
|
||||
|
||||
GdkRectangle update_rect;
|
||||
update_rect.x = from_x;
|
||||
update_rect.y = 0;
|
||||
update_rect.width = to_x - from_x + 1;
|
||||
update_rect.height = get_ysize();
|
||||
draw(&update_rect);
|
||||
GdkRectangle rect = {
|
||||
from_x, 0, to_x - from_x + 1, get_ysize()
|
||||
};
|
||||
gdk_window_invalidate_rect(_graph_window->window, &rect, FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::idle
|
||||
// Function: GtkStatsStripChart::consider_drag_start
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called at the end of the draw cycle.
|
||||
// Description: Based on the mouse position within the window's
|
||||
// client area, look for draggable things the mouse
|
||||
// might be hovering over and return the apprioprate
|
||||
// DragMode enum or DM_none if nothing is indicated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
idle() {
|
||||
if (_labels_changed) {
|
||||
pack_labels();
|
||||
}
|
||||
if (_guide_bars_changed) {
|
||||
GdkRectangle update_rect;
|
||||
update_rect.x = 0;
|
||||
update_rect.y = 0;
|
||||
update_rect.width = _guide->width();
|
||||
update_rect.height = _guide->height();
|
||||
_guide->draw(&update_rect);
|
||||
_guide_bars_changed = false;
|
||||
}
|
||||
}
|
||||
GtkStatsGraph::DragMode GtkStatsStripChart::
|
||||
consider_drag_start(int mouse_x, int mouse_y, int width, int height) {
|
||||
if (mouse_x >= _graph_left && mouse_x < _graph_left + get_xsize()) {
|
||||
if (mouse_y >= _graph_top && mouse_y < _graph_top + get_ysize()) {
|
||||
// See if the mouse is over a user-defined guide bar.
|
||||
int y = mouse_y - _graph_top;
|
||||
float from_height = pixel_to_height(y + 2);
|
||||
float to_height = pixel_to_height(y - 2);
|
||||
_drag_guide_bar = find_user_guide_bar(from_height, to_height);
|
||||
if (_drag_guide_bar >= 0) {
|
||||
return DM_guide_bar;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::configure_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description: Creates a new backing pixmap of the appropriate size.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsStripChart::
|
||||
configure_event_impl(GdkEventConfigure *) {
|
||||
if (width() != get_xsize() || height() != get_ysize() ||
|
||||
_pixmap.gdkobj() == (GdkDrawable *)NULL) {
|
||||
bool is_initial = true;
|
||||
if (_pixmap) {
|
||||
is_initial = false;
|
||||
_pixmap.release();
|
||||
} else {
|
||||
// The mouse is above or below the graph; maybe create a new
|
||||
// guide bar.
|
||||
return DM_new_guide_bar;
|
||||
}
|
||||
|
||||
_pixmap.create(get_window(), width(), height());
|
||||
|
||||
Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
|
||||
|
||||
_white_gc = Gdk_GC(_pixmap);
|
||||
setup_white_gc();
|
||||
|
||||
_black_gc = Gdk_GC(_pixmap);
|
||||
_black_gc.set_foreground(system_colormap.black());
|
||||
|
||||
_dark_gc = Gdk_GC(_pixmap);
|
||||
Gdk_Color dark;
|
||||
dark.set_grey_p(0.2);
|
||||
system_colormap.alloc(dark);
|
||||
_dark_gc.set_foreground(dark);
|
||||
|
||||
_light_gc = Gdk_GC(_pixmap);
|
||||
Gdk_Color light;
|
||||
light.set_grey_p(0.6);
|
||||
system_colormap.alloc(light);
|
||||
_light_gc.set_foreground(light);
|
||||
|
||||
_pixmap.draw_rectangle(_white_gc, true, 0, 0, width(), height());
|
||||
|
||||
changed_size(width(), height());
|
||||
}
|
||||
return true;
|
||||
|
||||
return GtkStatsGraph::consider_drag_start(mouse_x, mouse_y, width, height);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::expose_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description: Redraw the screen from the backing pixmap.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsStripChart::
|
||||
expose_event_impl(GdkEventExpose *event) {
|
||||
get_window().draw_pixmap(_white_gc, _pixmap,
|
||||
event->area.x, event->area.y,
|
||||
event->area.x, event->area.y,
|
||||
event->area.width, event->area.height);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::button_press_event_impl
|
||||
// Access: Private, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint GtkStatsStripChart::
|
||||
button_press_event_impl(GdkEventButton *button) {
|
||||
if (button->type == GDK_2BUTTON_PRESS && button->button == 1) {
|
||||
int collector_index = get_collector_under_pixel((int)button->x, (int)button->y);
|
||||
collector_picked(collector_index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::pack_labels
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Function: GtkStatsStripChart::set_drag_mode
|
||||
// Access: Protected, Virtual
|
||||
// Description: This should be called whenever the drag mode needs to
|
||||
// change state. It provides hooks for a derived class
|
||||
// to do something special.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
pack_labels() {
|
||||
// First, remove the old labels.
|
||||
_label_align->remove();
|
||||
set_drag_mode(GtkStatsGraph::DragMode drag_mode) {
|
||||
GtkStatsGraph::set_drag_mode(drag_mode);
|
||||
|
||||
// Now add the new labels back in.
|
||||
_label_box = manage(new Gtk::VBox);
|
||||
_label_box->show();
|
||||
_label_align->add(*_label_box);
|
||||
switch (_drag_mode) {
|
||||
case DM_scale:
|
||||
case DM_left_margin:
|
||||
case DM_right_margin:
|
||||
case DM_sizing:
|
||||
// Disable smoothing for these expensive operations.
|
||||
set_average_mode(false);
|
||||
break;
|
||||
|
||||
Gdk_Font font = get_style()->gtkobj()->font;
|
||||
|
||||
int num_labels = get_num_labels();
|
||||
for (int i = 0; i < num_labels; i++) {
|
||||
int collector_index = get_label_collector(i);
|
||||
GtkStatsLabel *label =
|
||||
new GtkStatsLabel(get_monitor(), collector_index, font);
|
||||
label->show();
|
||||
|
||||
label->collector_picked.connect(collector_picked.slot());
|
||||
|
||||
_label_box->pack_end(*manage(label), false, false);
|
||||
default:
|
||||
// Restore smoothing according to the current setting of the check
|
||||
// box.
|
||||
/*
|
||||
int result = SendMessage(_smooth_check_box, BM_GETCHECK, 0, 0);
|
||||
set_average_mode(result == BST_CHECKED);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
_labels_changed = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripChart::setup_white_gc
|
||||
// Function: GtkStatsStripChart::draw_guide_bar
|
||||
// Access: Private
|
||||
// Description: Sets the color on _white_gc to be either actually
|
||||
// white (if the chart is still alive) or a light gray
|
||||
// (if the chart is dead).
|
||||
// Description: Draws the line for the indicated guide bar on the
|
||||
// graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripChart::
|
||||
setup_white_gc() {
|
||||
Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
|
||||
draw_guide_bar(int from_x, int to_x,
|
||||
const PStatGraph::GuideBar &bar) {
|
||||
int y = height_to_pixel(bar._height);
|
||||
|
||||
if (_is_dead) {
|
||||
Gdk_Color death;
|
||||
death.set_grey_p(0.8);
|
||||
system_colormap.alloc(death);
|
||||
if (y > 0) {
|
||||
// Only draw it if it's not too close to the top.
|
||||
switch (bar._style) {
|
||||
case GBS_target:
|
||||
gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_light_gray);
|
||||
break;
|
||||
|
||||
_white_gc.set_foreground(death);
|
||||
|
||||
} else {
|
||||
_white_gc.set_foreground(system_colormap.white());
|
||||
case GBS_user:
|
||||
gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_user_guide_bar);
|
||||
break;
|
||||
|
||||
case GBS_normal:
|
||||
gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_dark_gray);
|
||||
break;
|
||||
}
|
||||
gdk_draw_line(_pixmap, _pixmap_gc, from_x, y, to_x, y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: gtkStatsStripChart.h
|
||||
// Created by: drose (14Jul00)
|
||||
// Created by: drose (16Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -21,40 +21,37 @@
|
|||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "gtkStatsMonitor.h"
|
||||
|
||||
#include "gtkStatsGraph.h"
|
||||
#include "pStatStripChart.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
#include <gtk--.h>
|
||||
#include "pmap.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
class PStatView;
|
||||
class GtkStatsGuide;
|
||||
class GtkStatsMonitor;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsStripChart
|
||||
// Description : A special widget that draws a strip chart, given a
|
||||
// view.
|
||||
// Description : A window that draws a strip chart, given a view.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsStripChart : public Gtk::DrawingArea, public PStatStripChart {
|
||||
class GtkStatsStripChart : public PStatStripChart, public GtkStatsGraph {
|
||||
public:
|
||||
GtkStatsStripChart(GtkStatsMonitor *monitor,
|
||||
PStatView &view, int collector_index,
|
||||
int xsize, int ysize);
|
||||
int thread_index, int collector_index, bool show_level);
|
||||
virtual ~GtkStatsStripChart();
|
||||
|
||||
void mark_dead();
|
||||
virtual void new_collector(int collector_index);
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
virtual void force_redraw();
|
||||
virtual void changed_graph_size(int graph_xsize, int graph_ysize);
|
||||
|
||||
Gtk::Alignment *get_labels();
|
||||
GtkStatsGuide *get_guide();
|
||||
virtual void set_time_units(int unit_mask);
|
||||
virtual void set_scroll_speed(float scroll_speed);
|
||||
virtual void clicked_label(int collector_index);
|
||||
void set_vertical_scale(float value_height);
|
||||
|
||||
Gdk_GC get_collector_gc(int collector_index);
|
||||
protected:
|
||||
virtual void update_labels();
|
||||
|
||||
// This signal is thrown when the user float-clicks on a label or
|
||||
// on a band of color.
|
||||
SigC::Signal1<void, int> collector_picked;
|
||||
|
||||
private:
|
||||
virtual void clear_region();
|
||||
virtual void copy_region(int start_x, int end_x, int dest_x);
|
||||
virtual void draw_slice(int x, int w,
|
||||
|
|
@ -62,38 +59,25 @@ private:
|
|||
virtual void draw_empty(int x, int w);
|
||||
virtual void draw_cursor(int x);
|
||||
virtual void end_draw(int from_x, int to_x);
|
||||
virtual void idle();
|
||||
|
||||
virtual gint configure_event_impl(GdkEventConfigure *event);
|
||||
virtual gint expose_event_impl(GdkEventExpose *event);
|
||||
virtual gint button_press_event_impl(GdkEventButton *button);
|
||||
|
||||
void pack_labels();
|
||||
void setup_white_gc();
|
||||
virtual DragMode consider_drag_start(int mouse_x, int mouse_y,
|
||||
int width, int height);
|
||||
virtual void set_drag_mode(DragMode drag_mode);
|
||||
|
||||
private:
|
||||
// Backing pixmap for drawing area.
|
||||
Gdk_Pixmap _pixmap;
|
||||
void draw_guide_bar(int from_x, int to_x,
|
||||
const PStatGraph::GuideBar &bar);
|
||||
|
||||
// Graphics contexts for fg/bg. We don't use the contexts defined
|
||||
// in the style, because that would probably interfere with the
|
||||
// visibility of the strip chart.
|
||||
Gdk_GC _white_gc;
|
||||
Gdk_GC _black_gc;
|
||||
Gdk_GC _dark_gc;
|
||||
Gdk_GC _light_gc;
|
||||
private:
|
||||
|
||||
// Table of graphics contexts for our various collectors.
|
||||
typedef pmap<int, Gdk_GC> GCs;
|
||||
GCs _gcs;
|
||||
int _brush_origin;
|
||||
string _net_value_text;
|
||||
|
||||
Gtk::Alignment *_label_align;
|
||||
Gtk::VBox *_label_box;
|
||||
GtkStatsGuide *_guide;
|
||||
bool _is_dead;
|
||||
GtkWidget *_smooth_check_box;
|
||||
|
||||
static bool _window_class_registered;
|
||||
static const char * const _window_class_name;
|
||||
};
|
||||
|
||||
#include "gtkStatsStripChart.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,459 +0,0 @@
|
|||
// Filename: gtkStatsStripWindow.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsStripWindow.h"
|
||||
#include "gtkStatsStripChart.h"
|
||||
#include "gtkStatsGuide.h"
|
||||
|
||||
#include "pStatCollectorDef.h"
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <stdio.h> // for sprintf
|
||||
|
||||
|
||||
using Gtk::Menu_Helpers::MenuElem;
|
||||
using Gtk::Menu_Helpers::CheckMenuElem;
|
||||
using Gtk::Menu_Helpers::SeparatorElem;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsStripWindow::
|
||||
GtkStatsStripWindow(GtkStatsMonitor *monitor, int thread_index,
|
||||
int collector_index, bool show_level,
|
||||
int chart_xsize, int chart_ysize) :
|
||||
GtkStatsWindow(monitor),
|
||||
_thread_index(thread_index),
|
||||
_collector_index(collector_index),
|
||||
_show_level(show_level)
|
||||
{
|
||||
_title_unknown = false;
|
||||
_setup_scale_menu = false;
|
||||
_smooth = false;
|
||||
|
||||
setup_menu();
|
||||
layout_window(chart_xsize, chart_ysize);
|
||||
|
||||
new_collector(); // To set up the menus in case we can.
|
||||
show();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::mark_dead
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the client's connection has been lost,
|
||||
// this should update the window in some obvious way to
|
||||
// indicate that the window is no longer live.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
mark_dead() {
|
||||
GtkStatsWindow::mark_dead();
|
||||
_chart->mark_dead();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::new_collector
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when a new collector has become known.
|
||||
//
|
||||
// For the GtkStatsStripWindow, this forces a rebuild of
|
||||
// the menu that selects the collectors available for
|
||||
// picking levels.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
new_collector() {
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
|
||||
// Determine the set of collectors that display level data. We'll
|
||||
// want to put these on the "Levels" pull-down menu.
|
||||
|
||||
pset<int> levels;
|
||||
|
||||
int num_collectors = client_data->get_num_collectors();
|
||||
for (int i = 0; i < num_collectors; i++) {
|
||||
if (client_data->has_collector(i) &&
|
||||
client_data->get_collector_has_level(i)) {
|
||||
// We only put top-level entries on the menu. Thus, walk up
|
||||
// from this collector to its top level (the one below Frame).
|
||||
int collector_index = i;
|
||||
const PStatCollectorDef &def =
|
||||
client_data->get_collector_def(collector_index);
|
||||
int parent_index = def._parent_index;
|
||||
|
||||
while (parent_index != 0) {
|
||||
collector_index = parent_index;
|
||||
const PStatCollectorDef &def =
|
||||
client_data->get_collector_def(collector_index);
|
||||
parent_index = def._parent_index;
|
||||
}
|
||||
|
||||
levels.insert(collector_index);
|
||||
}
|
||||
}
|
||||
|
||||
// Now put the collectors we found on the menu.
|
||||
_levels_menu->items().clear();
|
||||
pset<int>::const_iterator li;
|
||||
for (li = levels.begin(); li != levels.end(); ++li) {
|
||||
int collector_index = (*li);
|
||||
_levels_menu->items().push_back
|
||||
(MenuElem(client_data->get_collector_name(collector_index),
|
||||
bind(slot(this, &GtkStatsStripWindow::menu_show_levels), collector_index)));
|
||||
}
|
||||
|
||||
// Also re-set-up the scale menu, in case the properties have changed.
|
||||
setup_scale_menu();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::idle
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
idle() {
|
||||
GtkStatsWindow::idle();
|
||||
_chart->update();
|
||||
|
||||
const PStatThreadData *thread_data = _chart->get_view().get_thread_data();
|
||||
if (!thread_data->is_empty()) {
|
||||
float frame_rate = thread_data->get_frame_rate();
|
||||
char buffer[128];
|
||||
sprintf(buffer, "Frame rate: %0.1f Hz", frame_rate);
|
||||
_frame_rate_label->set_text(buffer);
|
||||
}
|
||||
|
||||
if (_title_unknown) {
|
||||
_title_label->set_text(get_title_text());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::setup_menu
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
setup_menu() {
|
||||
GtkStatsWindow::setup_menu();
|
||||
|
||||
Gtk::Menu *speed_menu = new Gtk::Menu;
|
||||
|
||||
speed_menu->items().push_back
|
||||
(MenuElem("1", // 1 chart width scrolls by per minute.
|
||||
bind(slot(this, &GtkStatsStripWindow::menu_hscale), 1.0f)));
|
||||
speed_menu->items().push_back
|
||||
(MenuElem("2", // 2 chart widths scroll by per minute.
|
||||
bind(slot(this, &GtkStatsStripWindow::menu_hscale), 2.0f)));
|
||||
speed_menu->items().push_back
|
||||
(MenuElem("3",
|
||||
bind(slot(this, &GtkStatsStripWindow::menu_hscale), 3.0f)));
|
||||
speed_menu->items().push_back
|
||||
(MenuElem("6",
|
||||
bind(slot(this, &GtkStatsStripWindow::menu_hscale), 6.0f)));
|
||||
speed_menu->items().push_back
|
||||
(MenuElem("12",
|
||||
bind(slot(this, &GtkStatsStripWindow::menu_hscale), 12.0f)));
|
||||
|
||||
_menu->items().push_back(MenuElem("Speed", *manage(speed_menu)));
|
||||
|
||||
_scale_menu = new Gtk::Menu;
|
||||
_scale_menu->items().push_back
|
||||
(CheckMenuElem("Smooth",
|
||||
slot(this, &GtkStatsStripWindow::menu_smooth)));
|
||||
_scale_menu->items().push_back(SeparatorElem());
|
||||
_scale_menu->items().push_back
|
||||
(MenuElem("Auto scale",
|
||||
slot(this, &GtkStatsStripWindow::menu_auto_vscale)));
|
||||
|
||||
_menu->items().push_back(MenuElem("Scale", *manage(_scale_menu)));
|
||||
|
||||
_levels_menu = new Gtk::Menu;
|
||||
_menu->items().push_back(MenuElem("Levels", *manage(_levels_menu)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::setup_scale_menu
|
||||
// Access: Protected
|
||||
// Description: Sets up the options on the scale menu. We can't do
|
||||
// this until we have initialized the _chart member and
|
||||
// we have gotten our first collector_index.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
setup_scale_menu() {
|
||||
if (_setup_scale_menu) {
|
||||
// Already done it.
|
||||
return;
|
||||
}
|
||||
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
if (!client_data->has_collector(_collector_index)) {
|
||||
// Can't set up the scale menu yet.
|
||||
return;
|
||||
}
|
||||
|
||||
const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
|
||||
float base_scale = 1.0;
|
||||
string unit_name = def._level_units;
|
||||
|
||||
if (_show_level) {
|
||||
_chart->set_guide_bar_unit_name(unit_name);
|
||||
_chart->set_guide_bar_units(PStatGraph::GBU_named);
|
||||
|
||||
} else {
|
||||
_chart->set_guide_bar_units(PStatGraph::GBU_ms);
|
||||
}
|
||||
|
||||
if (def._suggested_scale != 0.0) {
|
||||
base_scale = def._suggested_scale;
|
||||
} else if (!_show_level) {
|
||||
base_scale = 1.0 / _chart->get_target_frame_rate();
|
||||
}
|
||||
|
||||
static const float scales[] = {
|
||||
50.0,
|
||||
10.0,
|
||||
5.0,
|
||||
2.0,
|
||||
1.0,
|
||||
0.5,
|
||||
0.2,
|
||||
0.1,
|
||||
0.02,
|
||||
};
|
||||
static const int num_scales = sizeof(scales) / sizeof(float);
|
||||
|
||||
for (int i = 0; i < num_scales; i++) {
|
||||
float scale = base_scale * scales[i];
|
||||
string label;
|
||||
|
||||
if (_show_level) {
|
||||
label = _chart->format_number(scale, PStatGraph::GBU_named | PStatGraph::GBU_show_units, unit_name);
|
||||
} else {
|
||||
label = _chart->format_number(scale, PStatGraph::GBU_ms | PStatGraph::GBU_hz | PStatGraph::GBU_show_units);
|
||||
}
|
||||
|
||||
_scale_menu->items().push_back
|
||||
(MenuElem(label,
|
||||
bind(slot(this, &GtkStatsStripWindow::menu_vscale), scale)));
|
||||
}
|
||||
|
||||
_setup_scale_menu = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::menu_new_window
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
menu_new_window() {
|
||||
new GtkStatsStripWindow(_monitor, _thread_index, _collector_index,
|
||||
_show_level,
|
||||
_chart->get_xsize(), _chart->get_ysize());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::menu_hscale
|
||||
// Access: Protected
|
||||
// Description: Selects a new horizontal scale for the strip chart.
|
||||
// This is done from the menu called "Speed", since
|
||||
// changing the horizontal scale most obviously affects
|
||||
// the scrolling speed.
|
||||
//
|
||||
// The units is in chart width per minute.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
menu_hscale(float wpm) {
|
||||
_chart->set_horizontal_scale(60.0 / wpm);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::menu_vscale
|
||||
// Access: Protected
|
||||
// Description: Selects a new vertical scale for the strip chart.
|
||||
// This is done from the menu called "Scale".
|
||||
//
|
||||
// The units is in seconds, or whatever the units
|
||||
// of choice are.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
menu_vscale(float max_height) {
|
||||
_chart->set_vertical_scale(max_height);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::menu_smooth
|
||||
// Access: Protected
|
||||
// Description: Toggles the "smooth" state of the check menu.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
menu_smooth() {
|
||||
_smooth = !_smooth;
|
||||
|
||||
_chart->set_average_mode(_smooth);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::menu_auto_vscale
|
||||
// Access: Protected
|
||||
// Description: Selects a suitable vertical scale based on the data
|
||||
// already visible in the chart.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
menu_auto_vscale() {
|
||||
_chart->set_auto_vertical_scale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::menu_show_levels
|
||||
// Access: Protected
|
||||
// Description: Shows the level values known for the indicated
|
||||
// collector.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
menu_show_levels(int collector_index) {
|
||||
new GtkStatsStripWindow(_monitor, _thread_index, collector_index,
|
||||
true,
|
||||
_chart->get_xsize(), _chart->get_ysize());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::open_subchart
|
||||
// Access: Protected
|
||||
// Description: This is called in response to the collector_picked
|
||||
// signal from the strip chart, which is generated when
|
||||
// the user double-clicks on a band of color or a label.
|
||||
//
|
||||
// This opens up a new window focusing just on the
|
||||
// indicated collector.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
open_subchart(int collector_index) {
|
||||
new GtkStatsStripWindow(_monitor, _thread_index, collector_index,
|
||||
_show_level,
|
||||
_chart->get_xsize(), _chart->get_ysize());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::layout_window
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsStripWindow::
|
||||
layout_window(int chart_xsize, int chart_ysize) {
|
||||
Gtk::HBox *hbox = new Gtk::HBox;
|
||||
hbox = new Gtk::HBox;
|
||||
hbox->show();
|
||||
_main_box->pack_start(*manage(hbox), true, true, 8);
|
||||
|
||||
Gtk::Table *chart_table = new Gtk::Table(3, 2);
|
||||
chart_table->show();
|
||||
hbox->pack_start(*manage(chart_table), true, true, 8);
|
||||
|
||||
Gtk::HBox *title_hbox = new Gtk::HBox;
|
||||
title_hbox->show();
|
||||
chart_table->attach(*manage(title_hbox), 1, 2, 0, 1,
|
||||
(GTK_FILL|GTK_EXPAND), 0);
|
||||
|
||||
_title_label = new Gtk::Label(get_title_text());
|
||||
if (_collector_index != 0 || _thread_index != 0) {
|
||||
_title_label->show();
|
||||
_title_label->set_alignment(0.0, 0.5);
|
||||
title_hbox->pack_start(*manage(_title_label), true, true);
|
||||
}
|
||||
|
||||
_frame_rate_label = new Gtk::Label;
|
||||
if (_collector_index == 0) {
|
||||
_frame_rate_label->show();
|
||||
_frame_rate_label->set_alignment(1.0, 0.5);
|
||||
title_hbox->pack_start(*manage(_frame_rate_label), true, true);
|
||||
}
|
||||
|
||||
Gtk::Frame *frame = new Gtk::Frame;
|
||||
frame->set_shadow_type(GTK_SHADOW_ETCHED_OUT);
|
||||
frame->show();
|
||||
chart_table->attach(*manage(frame), 1, 2, 1, 2);
|
||||
|
||||
if (_show_level) {
|
||||
_chart = new GtkStatsStripChart(_monitor,
|
||||
_monitor->get_level_view(_collector_index, _thread_index),
|
||||
_collector_index,
|
||||
chart_xsize, chart_ysize);
|
||||
} else {
|
||||
_chart = new GtkStatsStripChart(_monitor,
|
||||
_monitor->get_view(_thread_index),
|
||||
_collector_index,
|
||||
chart_xsize, chart_ysize);
|
||||
}
|
||||
|
||||
_chart->collector_picked.
|
||||
connect(slot(this, &GtkStatsStripWindow::open_subchart));
|
||||
frame->add(*manage(_chart));
|
||||
|
||||
chart_table->attach(*_chart->get_labels(), 0, 1, 1, 2,
|
||||
0, (GTK_FILL|GTK_EXPAND), 4, 0);
|
||||
chart_table->attach(*_chart->get_guide(), 2, 3, 1, 2,
|
||||
0, (GTK_FILL|GTK_EXPAND), 4, 0);
|
||||
_chart->show();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsStripWindow::get_title_text
|
||||
// Access: Private
|
||||
// Description: Returns the text suitable for the title label on the
|
||||
// top line.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string GtkStatsStripWindow::
|
||||
get_title_text() {
|
||||
string text;
|
||||
|
||||
_title_unknown = false;
|
||||
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
if (client_data->has_collector(_collector_index)) {
|
||||
const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
|
||||
if (_show_level) {
|
||||
if (def._level_units.empty()) {
|
||||
text = def._name;
|
||||
} else {
|
||||
text = def._name + " (" + def._level_units + ")";
|
||||
}
|
||||
} else {
|
||||
text = def._name + " time";
|
||||
}
|
||||
} else {
|
||||
_title_unknown = true;
|
||||
}
|
||||
|
||||
if (_thread_index != 0) {
|
||||
if (client_data->has_thread(_thread_index)) {
|
||||
text += "(" + client_data->get_thread_name(_thread_index) + " thread)";
|
||||
} else {
|
||||
_title_unknown = true;
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
// Filename: gtkStatsStripWindow.h
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKSTATSSTRIPWINDOW_H
|
||||
#define GTKSTATSSTRIPWINDOW_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "gtkStatsMonitor.h"
|
||||
#include "gtkStatsWindow.h"
|
||||
|
||||
class GtkStatsStripChart;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsStripWindow
|
||||
// Description : A window that contains your basic one-thread,
|
||||
// one-level strip chart.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsStripWindow : public GtkStatsWindow {
|
||||
public:
|
||||
GtkStatsStripWindow(GtkStatsMonitor *monitor, int thread_index,
|
||||
int collector_index, bool show_level,
|
||||
int chart_xsize, int chart_ysize);
|
||||
|
||||
virtual void mark_dead();
|
||||
virtual void new_collector();
|
||||
virtual void idle();
|
||||
|
||||
protected:
|
||||
virtual void setup_menu();
|
||||
void setup_scale_menu();
|
||||
virtual void menu_new_window();
|
||||
void menu_hscale(float wpm);
|
||||
void menu_vscale(float max_height);
|
||||
void menu_smooth();
|
||||
void menu_auto_vscale();
|
||||
void menu_show_levels(int collector_index);
|
||||
void open_subchart(int collector_index);
|
||||
|
||||
private:
|
||||
void layout_window(int chart_xsize, int chart_ysize);
|
||||
string get_title_text();
|
||||
|
||||
private:
|
||||
int _thread_index;
|
||||
int _collector_index;
|
||||
bool _show_level;
|
||||
bool _title_unknown;
|
||||
bool _setup_scale_menu;
|
||||
|
||||
Gtk::Label *_title_label;
|
||||
Gtk::Label *_frame_rate_label;
|
||||
GtkStatsStripChart *_chart;
|
||||
|
||||
Gtk::Menu *_scale_menu;
|
||||
Gtk::Menu *_levels_menu;
|
||||
|
||||
bool _smooth;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
// Filename: gtkStatsWindow.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkStatsWindow.h"
|
||||
#include "gtkStatsMonitor.h"
|
||||
#include "gtkStatsStripWindow.h"
|
||||
#include "gtkStatsPianoWindow.h"
|
||||
|
||||
using Gtk::Menu_Helpers::MenuElem;
|
||||
using Gtk::Menu_Helpers::SeparatorElem;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkStatsWindow::
|
||||
GtkStatsWindow(GtkStatsMonitor *monitor) : _monitor(monitor) {
|
||||
_monitor->add_window(this);
|
||||
update_title();
|
||||
setup();
|
||||
|
||||
_main_box = new Gtk::VBox;
|
||||
_main_box->show();
|
||||
add(*manage(_main_box));
|
||||
|
||||
_menu = manage(new Gtk::MenuBar);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::destruct
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GtkStatsWindow::
|
||||
destruct() {
|
||||
if (BasicGtkWindow::destruct()) {
|
||||
_monitor->remove_window(this);
|
||||
_monitor.clear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::update_title
|
||||
// Access: Public, Virtual
|
||||
// Description: Sets the title bar appropriately, once the client's
|
||||
// information is known.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
update_title() {
|
||||
if (_monitor->is_client_known()) {
|
||||
string title =
|
||||
_monitor->get_client_progname() + " from " + _monitor->get_client_hostname();
|
||||
if (!_monitor->is_alive()) {
|
||||
title += " (closed)";
|
||||
}
|
||||
set_title(title);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::mark_dead
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the client's connection has been lost,
|
||||
// this should update the window in some obvious way to
|
||||
// indicate that the window is no longer live.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
mark_dead() {
|
||||
update_title();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::new_collector
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when a new collector has become known, in case
|
||||
// the window cares.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
new_collector() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::idle
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
idle() {
|
||||
if (_monitor->_new_collector) {
|
||||
new_collector();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::setup_menu
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
setup_menu() {
|
||||
_file_menu = new Gtk::Menu;
|
||||
|
||||
_file_menu->items().push_back
|
||||
(MenuElem("New strip chart",
|
||||
slot(this, &GtkStatsWindow::menu_open_strip_chart)));
|
||||
_file_menu->items().push_back
|
||||
(MenuElem("New piano roll",
|
||||
slot(this, &GtkStatsWindow::menu_open_piano_roll)));
|
||||
|
||||
/*
|
||||
_file_menu->items().push_back
|
||||
(MenuElem("New window",
|
||||
slot(this, &GtkStatsWindow::menu_new_window)));
|
||||
*/
|
||||
|
||||
_file_menu->items().push_back(SeparatorElem());
|
||||
|
||||
_file_menu->items().push_back
|
||||
(MenuElem("Disconnect from client",
|
||||
slot(this, &GtkStatsWindow::menu_disconnect)));
|
||||
_file_menu->items().push_back
|
||||
(MenuElem("Close window",
|
||||
slot(this, &GtkStatsWindow::menu_close_window)));
|
||||
_file_menu->items().push_back
|
||||
(MenuElem("Close all windows this client",
|
||||
slot(this, &GtkStatsWindow::menu_close_all_windows)));
|
||||
|
||||
_menu->items().push_back(MenuElem("File", *manage(_file_menu)));
|
||||
_menu->show();
|
||||
_main_box->pack_start(*_menu, false, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::menu_open_strip_chart
|
||||
// Access: Protected
|
||||
// Description: Open up a new strip-chart style window for the main
|
||||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
menu_open_strip_chart() {
|
||||
new GtkStatsStripWindow(_monitor, 0, 0, false, 400, 100);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::menu_open_piano_roll
|
||||
// Access: Protected
|
||||
// Description: Open up a new piano-roll style window for the main
|
||||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
menu_open_piano_roll() {
|
||||
new GtkStatsPianoWindow(_monitor, 0, 400, 100);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::menu_new_window
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
menu_new_window() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::menu_close_window
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
menu_close_window() {
|
||||
destruct();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::menu_close_all_windows
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
menu_close_all_windows() {
|
||||
_monitor->close_all_windows();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkStatsWindow::menu_disconnect
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkStatsWindow::
|
||||
menu_disconnect() {
|
||||
_monitor->close();
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
// Filename: gtkStatsWindow.h
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GTKSTATSWINDOW_H
|
||||
#define GTKSTATSWINDOW_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "gtkStatsMonitor.h"
|
||||
|
||||
#include "basicGtkWindow.h"
|
||||
|
||||
#include "pointerTo.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GtkStatsWindow
|
||||
// Description : This is the base class for a family of windows that
|
||||
// are associated with one particular stats client.
|
||||
// Each window keeps a pointer back to the
|
||||
// GtkStatsMonitor object, which in turn knows about all
|
||||
// of the windows; when the last window is closed, the
|
||||
// monitor object goes away and ends the session.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class GtkStatsWindow : public BasicGtkWindow {
|
||||
public:
|
||||
GtkStatsWindow(GtkStatsMonitor *monitor);
|
||||
virtual bool destruct();
|
||||
|
||||
virtual void update_title();
|
||||
virtual void mark_dead();
|
||||
virtual void new_collector();
|
||||
virtual void idle();
|
||||
|
||||
protected:
|
||||
virtual void setup_menu();
|
||||
|
||||
void menu_open_strip_chart();
|
||||
void menu_open_piano_roll();
|
||||
virtual void menu_new_window();
|
||||
void menu_close_window();
|
||||
void menu_close_all_windows();
|
||||
void menu_disconnect();
|
||||
|
||||
protected:
|
||||
PT(GtkStatsMonitor) _monitor;
|
||||
|
||||
Gtk::VBox *_main_box;
|
||||
Gtk::MenuBar *_menu;
|
||||
Gtk::Menu *_file_menu;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#include "gtkStats.cxx"
|
||||
#include "gtkStatsChartMenu.cxx"
|
||||
#include "gtkStatsGraph.cxx"
|
||||
#include "gtkStatsLabel.cxx"
|
||||
#include "gtkStatsLabelStack.cxx"
|
||||
#include "gtkStatsMonitor.cxx"
|
||||
#include "gtkStatsPianoRoll.cxx"
|
||||
#include "gtkStatsServer.cxx"
|
||||
#include "gtkStatsStripChart.cxx"
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
|
||||
|
||||
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
/* Modifed for gtk-- by sac@transmeta.com */
|
||||
/* Modified (slightly) for gdk-- by freyd@uni-muenster.de */
|
||||
#include <gtk--/main.h>
|
||||
#include <gtk--/style.h>
|
||||
#include <gtk--/window.h>
|
||||
#include <gtk--/button.h>
|
||||
#include <gtk--/box.h>
|
||||
#include <gtk--/drawingarea.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
class ScribbleDrawingArea : public Gtk::DrawingArea
|
||||
{
|
||||
/* Backing pixmap for drawing area */
|
||||
|
||||
Gdk_Pixmap pixmap;
|
||||
Gdk_GC gc;
|
||||
Gdk_Window win;
|
||||
Gdk_Visual visual;
|
||||
|
||||
virtual gint configure_event_impl (GdkEventConfigure *event);
|
||||
virtual gint expose_event_impl (GdkEventExpose *event);
|
||||
virtual gint button_press_event_impl (GdkEventButton *event);
|
||||
virtual gint motion_notify_event_impl (GdkEventMotion *event);
|
||||
void draw_brush (gdouble x, gdouble y);
|
||||
|
||||
public:
|
||||
ScribbleDrawingArea ();
|
||||
|
||||
};
|
||||
|
||||
ScribbleDrawingArea::ScribbleDrawingArea()
|
||||
: Gtk::DrawingArea(), pixmap (0)
|
||||
{
|
||||
set_events (GDK_EXPOSURE_MASK
|
||||
| GDK_LEAVE_NOTIFY_MASK
|
||||
| GDK_BUTTON_PRESS_MASK
|
||||
| GDK_POINTER_MOTION_MASK
|
||||
| GDK_POINTER_MOTION_HINT_MASK);
|
||||
}
|
||||
|
||||
|
||||
/* Create a new backing pixmap of the appropriate size */
|
||||
int ScribbleDrawingArea::configure_event_impl (GdkEventConfigure * /* event */)
|
||||
{
|
||||
win = get_window();
|
||||
visual = win.get_visual();
|
||||
|
||||
if (pixmap)
|
||||
pixmap.release();
|
||||
gc = get_style()->gtkobj()->white_gc;
|
||||
// Gtk::Style has no access to its data members, so use gtk objekt.
|
||||
// Some access functions would be nice like GtkStyle::get_white_gc() etc.
|
||||
pixmap.create(get_window(), width(), height());
|
||||
|
||||
pixmap.draw_rectangle (gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
width(),
|
||||
height());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Redraw the screen from the backing pixmap */
|
||||
int ScribbleDrawingArea::expose_event_impl (GdkEventExpose *event)
|
||||
{
|
||||
|
||||
gc = get_style()->gtkobj()->fg_gc[GTK_WIDGET_STATE (GTK_WIDGET(gtkobj()))];
|
||||
// Same like above, + Gtk::Widget has set_state function but no get_state
|
||||
// function.
|
||||
win.draw_pixmap(gc ,
|
||||
pixmap,
|
||||
event->area.x, event->area.y,
|
||||
event->area.x, event->area.y,
|
||||
event->area.width, event->area.height);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Draw a rectangle on the screen */
|
||||
void ScribbleDrawingArea::draw_brush (gdouble x, gdouble y)
|
||||
{
|
||||
GdkRectangle update_rect;
|
||||
update_rect.x = (int)x - 5;
|
||||
update_rect.y = (int)y - 5;
|
||||
update_rect.width = 10;
|
||||
update_rect.height = 10;
|
||||
gc = get_style()->gtkobj()->black_gc;
|
||||
pixmap.draw_rectangle(
|
||||
gc,
|
||||
TRUE,
|
||||
update_rect.x, update_rect.y,
|
||||
update_rect.width, update_rect.height);
|
||||
draw(&update_rect);
|
||||
//draw (&update_rect);
|
||||
}
|
||||
|
||||
gint ScribbleDrawingArea::button_press_event_impl (GdkEventButton *event)
|
||||
{
|
||||
if (event->button == 1 && pixmap)
|
||||
draw_brush (event->x, event->y);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint ScribbleDrawingArea::motion_notify_event_impl (GdkEventMotion *event)
|
||||
{
|
||||
int x, y;
|
||||
GdkModifierType state;
|
||||
if (event->is_hint)
|
||||
gdk_window_get_pointer (event->window, &x, &y, &state);
|
||||
else
|
||||
{
|
||||
x = (int)event->x;
|
||||
y = (int)event->y;
|
||||
state = (GdkModifierType) event->state;
|
||||
}
|
||||
|
||||
if (state & GDK_BUTTON1_MASK && pixmap)
|
||||
draw_brush (x, y);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
class ScribbleWindow : public Gtk::Window
|
||||
{
|
||||
|
||||
Gtk::VBox vbox;
|
||||
ScribbleDrawingArea drawing_area;
|
||||
Gtk::Button button;
|
||||
void quit ();
|
||||
public:
|
||||
ScribbleWindow ();
|
||||
};
|
||||
|
||||
void ScribbleWindow::quit ()
|
||||
{
|
||||
Gtk::Main::quit();
|
||||
}
|
||||
|
||||
ScribbleWindow::ScribbleWindow ()
|
||||
: Gtk::Window(GTK_WINDOW_TOPLEVEL),
|
||||
vbox (FALSE, 0),
|
||||
button ("quit")
|
||||
{
|
||||
add (vbox);
|
||||
|
||||
/* Create the drawing area */
|
||||
drawing_area.size (400, 400);
|
||||
vbox.pack_start (drawing_area, TRUE, TRUE, 0);
|
||||
|
||||
|
||||
/* Add the button */
|
||||
vbox.pack_start (button, FALSE, FALSE, 0);
|
||||
|
||||
button.clicked.connect(slot(*this, &ScribbleWindow::quit));
|
||||
destroy.connect(slot(*this, &ScribbleWindow::quit));
|
||||
|
||||
drawing_area.show();
|
||||
button.show();
|
||||
vbox.show();
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
ScribbleWindow *window;
|
||||
Gtk::Main myapp(argc, argv);
|
||||
|
||||
window = new ScribbleWindow;
|
||||
window->show();
|
||||
|
||||
myapp.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#define BUILD_DIRECTORY $[HAVE_GTKMM]
|
||||
#define USE_PACKAGES gtkmm
|
||||
|
||||
#begin ss_lib_target
|
||||
#define TARGET gtkbase
|
||||
#define LOCAL_LIBS \
|
||||
progbase
|
||||
|
||||
#define SOURCES \
|
||||
basicGtkDialog.cxx basicGtkDialog.h basicGtkWindow.cxx \
|
||||
basicGtkWindow.h gtkBase.cxx gtkBase.h request_initial_size.cxx \
|
||||
request_initial_size.h
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
basicGtkDialog.h basicGtkWindow.h gtkBase.h request_initial_size.h
|
||||
|
||||
#end ss_lib_target
|
||||
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
// Filename: basicGtkDialog.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "basicGtkDialog.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkDialog::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BasicGtkDialog::
|
||||
BasicGtkDialog(bool free_store) : BasicGtkWindow(free_store) {
|
||||
_vbox = manage(new Gtk::VBox);
|
||||
_action_area = manage(new Gtk::HBox);
|
||||
|
||||
Gtk::VBox *box0 = manage(new Gtk::VBox);
|
||||
Gtk::HSeparator *hsep = manage(new Gtk::HSeparator);
|
||||
|
||||
add(*box0);
|
||||
box0->show();
|
||||
box0->pack_start(*_vbox);
|
||||
_vbox->show();
|
||||
|
||||
box0->pack_start(*hsep);
|
||||
hsep->show();
|
||||
|
||||
_action_area->set_border_width(10);
|
||||
box0->pack_start(*_action_area, false);
|
||||
_action_area->show();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkDialog::get_vbox
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the main part of the dialog
|
||||
// window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Gtk::VBox *BasicGtkDialog::
|
||||
get_vbox() const {
|
||||
return _vbox;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkDialog::get_action_area
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to part of the dialog reserved for
|
||||
// action buttons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Gtk::HBox *BasicGtkDialog::
|
||||
get_action_area() const {
|
||||
return _action_area;
|
||||
}
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
// Filename: basicGtkDialog.h
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BASICGTKDIALOG_H
|
||||
#define BASICGTKDIALOG_H
|
||||
|
||||
#include "basicGtkWindow.h"
|
||||
|
||||
#include <gtk--.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : BasicGtkDialog
|
||||
// Description : This looks like a wrapper around Gtk::Dialog.
|
||||
// Actually, it doesn't inherit from Gtk::Dialog at all,
|
||||
// but instead (indirectly) from Gtk::Window; it just
|
||||
// duplicates the default functionality of Gtk::Dialog
|
||||
// by defining get_vbox() and a get_action_area().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class BasicGtkDialog : public BasicGtkWindow {
|
||||
public:
|
||||
BasicGtkDialog(bool free_store = true);
|
||||
|
||||
Gtk::VBox *get_vbox() const;
|
||||
Gtk::HBox *get_action_area() const;
|
||||
|
||||
private:
|
||||
Gtk::VBox *_vbox;
|
||||
Gtk::HBox *_action_area;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
// Filename: basicGtkWindow.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "basicGtkWindow.h"
|
||||
#include "gtkBase.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkWindow::Constructor
|
||||
// Access: Public
|
||||
// Description: The free_store parameter should be true if the window
|
||||
// object has been allocated from the free store (using
|
||||
// new) and can be safely deleted using delete when the
|
||||
// window is destroyed by the user, or false if this is
|
||||
// not the case.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BasicGtkWindow::
|
||||
BasicGtkWindow(bool free_store) : _free_store(free_store) {
|
||||
_destroyed = false;
|
||||
_state = S_virgin;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkWindow::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BasicGtkWindow::
|
||||
~BasicGtkWindow() {
|
||||
destruct();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkWindow::setup
|
||||
// Access: Public
|
||||
// Description: Call this after initializing the window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BasicGtkWindow::
|
||||
setup() {
|
||||
_state = S_setup;
|
||||
_destroy_connection =
|
||||
destroy.connect(slot(this, &BasicGtkWindow::window_destroyed));
|
||||
show();
|
||||
|
||||
// Calling show() sets in motion some X events that must flow
|
||||
// completely through the queue before we can safely hide() the
|
||||
// thing again. To measure when this has happened, we'll drop our
|
||||
// own event into the queue. When this event makes it through the
|
||||
// queue, we'll assume all relevant X events have also, and it will
|
||||
// be safe to hide the window.
|
||||
Gtk::Main::idle.connect(slot(this, &BasicGtkWindow::idle_event));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkWindow::destruct
|
||||
// Access: Public, Virtual
|
||||
// Description: Call this to remove the window, etc. It's not tied
|
||||
// directly to the real destructor because that seems to
|
||||
// just lead to trouble. This returns true if it
|
||||
// actually destructed, or false if it had already
|
||||
// destructed previously and did nothing this time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BasicGtkWindow::
|
||||
destruct() {
|
||||
if (_state != S_gone) {
|
||||
// We must hide the window before we destruct, or it won't disappear
|
||||
// from the screen. Strange. But we also don't want to try to hide
|
||||
// the window if we're destructing because of a window_destroyed
|
||||
// event, so we check our little flag.
|
||||
if (!_destroyed && _state != S_virgin) {
|
||||
// Now, in case the window was never completely shown, we must
|
||||
// wait for that to happen before we can hide it.
|
||||
while (!_destroyed && _state == S_setup) {
|
||||
GtkBase::_gtk->iteration();
|
||||
}
|
||||
|
||||
if (!_destroyed) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
_state = S_gone;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkWindow::delete_self
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BasicGtkWindow::
|
||||
delete_self() {
|
||||
destruct();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkWindow::window_destroyed
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BasicGtkWindow::
|
||||
window_destroyed() {
|
||||
_destroyed = true;
|
||||
destruct();
|
||||
|
||||
// We should probably also delete the pointer here. But maybe not.
|
||||
// Gtk-- is very mysterious about this, so we'll just let it maybe
|
||||
// leak.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BasicGtkWindow::idle_event
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
gint BasicGtkWindow::
|
||||
idle_event() {
|
||||
// Now, we're finally a bona fide window with all rights thereunto
|
||||
// appertaining.
|
||||
_state = S_ready;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
// Filename: basicGtkWindow.h
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BASICGTKWINDOW_H
|
||||
#define BASICGTKWINDOW_H
|
||||
|
||||
#include <gtk--.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : BasicGtkWindow
|
||||
// Description : This is just a handy wrapper around Gtk::Window that
|
||||
// provides some convenient setup functions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class BasicGtkWindow : public Gtk::Window {
|
||||
public:
|
||||
BasicGtkWindow(bool free_store = true);
|
||||
virtual ~BasicGtkWindow();
|
||||
void setup();
|
||||
virtual bool destruct();
|
||||
|
||||
protected:
|
||||
void delete_self();
|
||||
static gint static_delete(BasicGtkWindow *window);
|
||||
|
||||
private:
|
||||
void window_destroyed();
|
||||
gint idle_event();
|
||||
|
||||
enum State {
|
||||
S_virgin,
|
||||
S_setup,
|
||||
S_ready,
|
||||
S_gone,
|
||||
};
|
||||
|
||||
bool _destroyed;
|
||||
bool _free_store;
|
||||
State _state;
|
||||
SigC::Connection _destroy_connection;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
// Filename: gtkBase.cxx
|
||||
// Created by: drose (14Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtkBase.h"
|
||||
|
||||
#include "notify.h"
|
||||
|
||||
Gtk::Main *GtkBase::_gtk = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkBase::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkBase::
|
||||
GtkBase() {
|
||||
if (_gtk != (Gtk::Main *)NULL) {
|
||||
nout << "Invalid attempt to create multiple instances of GtkBase!\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkBase::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GtkBase::
|
||||
~GtkBase() {
|
||||
nassertv(_gtk != (Gtk::Main *)NULL);
|
||||
delete _gtk;
|
||||
_gtk = NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkBase::parse_command_line
|
||||
// Access: Public, Virtual
|
||||
// Description: This is overridden for GtkBase to give Gtk a chance
|
||||
// to pull out its X-related parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkBase::
|
||||
parse_command_line(int argc, char *argv[]) {
|
||||
nassertv(_gtk == (Gtk::Main *)NULL);
|
||||
_gtk = new Gtk::Main(argc, argv);
|
||||
ProgramBase::parse_command_line(argc, argv);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GtkBase::main_loop
|
||||
// Access: Public
|
||||
// Description: Call this after all is set up to yield control of the
|
||||
// main loop to Gtk. This normally doesn't return.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GtkBase::
|
||||
main_loop() {
|
||||
nassertv(_gtk != NULL);
|
||||
|
||||
_gtk->run();
|
||||
}
|
||||
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
// Filename: request_initial_size.cxx
|
||||
// Created by: drose (15Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "request_initial_size.h"
|
||||
|
||||
static int
|
||||
restore_usize(Gtk::Widget *widget) {
|
||||
widget->set_usize(0, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: request_initial_size
|
||||
// Description: Gtk-- hack to request an initial size for a widget,
|
||||
// while still allowing the user to resize it smaller.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
request_initial_size(Gtk::Widget &widget, int xsize, int ysize) {
|
||||
if (xsize != 0 || ysize != 0) {
|
||||
// I can't find a way to request an initial size for a general
|
||||
// widget. The best I can do is specify its minimum size.
|
||||
widget.set_usize(xsize, ysize);
|
||||
|
||||
// However, I don't want the minimum size to be enforced forever;
|
||||
// the user should be able to resize the window smaller if he wants
|
||||
// to. Thus, this ugly hack: at the first idle signal, we return
|
||||
// the usize to 0.
|
||||
Gtk::Main::idle.connect(bind(slot(&restore_usize), &widget));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// Filename: request_initial_size.h
|
||||
// Created by: drose (15Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef REQUEST_INITIAL_SIZE_H
|
||||
#define REQUEST_INITIAL_SIZE_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include <gtk--.h>
|
||||
|
||||
void request_initial_size(Gtk::Widget &widget, int xsize, int ysize);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue