UofC Large Display Framework Part II: Toolkit & Usage Fabrício Anastácio September, 2007.

Slides:



Advertisements
Similar presentations
2D Graphics Drawing Things. Graphics In your GUI, you might want to draw graphics E.g. draw lines, circles, shapes, draw strings etc The Graphics class.
Advertisements

1 Drawing C Sc 335 Object-Oriented Programming and Design Rick Mercer.
More Java Drawing in 2D Animations with Timer. Drawing Review A simple two-dimensional coordinate system exists for each graphics context or drawing surface.
Chapter 14 Graph class design John Keyser’s Modifications of Slides by Bjarne Stroustrup
CMSC 341 Building Java GUIs. 09/26/2007 CMSC 341 GUI 2 Why Java GUI Development? Course is about Data Structures, not GUIs. We are giving you the opportunity.
Object Oriented Programming Chapter 7 Programming Languages by Ravi Sethi.
1 Inheritance. 2 One class inherits from another if it describes a specialized subset of objects Terminology: inheritschild class subclass –the class.
1 Frameworks. 2 Framework Set of cooperating classes/interfaces –Structure essential mechanisms of a problem domain –Programmer can extend framework classes,
Chapter 6 Graphical User Interface (GUI) and Object-Oriented Design (OOD)
Graphics Programming. In this class, we will cover: The difference between AWT and Swing Creating a frame Frame positioning Displaying information in.
OOP in Java Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
The Composite Pattern.. Composite Pattern Intent –Compose objects into tree structures to represent part-whole hierarchies. –Composite lets clients treat.
Chapter 10 Classes Continued
OOP in Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Design Patterns academy.zariba.com 1. Lecture Content 1.What are Design Patterns? 2.Creational 3.Structural 4.Behavioral 5.Architectural 6.Design Patterns.
Abstraction: Polymorphism, pt. 1 Abstracting Objects.
Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. The Factory Method Design Pattern (1) –A creational design.
PROG Mobile Java Application Development PROG Mobile Java Application Development Event Handling Creating Menus.
Computer Programming and Basic Software Engineering 9 Building Graphical User Interface A Brief Introduction to GDI+ S.R.G. Fraser, Pro Visual C++/CLI.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
Robert Fourer, Jun Ma, Kipp Martin Optimization Services Instance Language (OSiL), Solvers, and Modeling Languages Kipp Martin University of Chicago
Lecture 3 Casting Abstract Classes and Methods Interfaces.
Tutorial 2 Drawing Text, Adding Shapes, and Creating Symbols.
GLWidget Description Jason Goffeney 3/8/2006. GLWidget The GLWidget class extends the Qt QGLWidget. The QGLWidget is a Qt Widget that happens to have.
Java Programming: From Problem Analysis to Program Design, Second Edition1  Learn about basic GUI components.  Explore how the GUI components JFrame,
1 Java Inheritance. 2 Inheritance On the surface, inheritance is a code re-use issue. –we can extend code that is already written in a manageable manner.
Lecture 5: Interaction 1  Principles of Interactive Graphics  CMSCD2012  Dr David England, Room 711,  ex 2271 
CSE 219 Computer Science III Images. HW1 Has been posted on Blackboard Making a Game of Life with limited options.
The Java Inheritance Hierarchy CSIS 3701: Advanced Object Oriented Programming.
1 Input and Interaction. 2 Input Devices Physical input devices Keyboard devices and pointing devices Logical input devices.
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved Event Driven Programming, The.
QML Qt Quick with QML and you can use JavaScript for engine along C++ Started to be released since late 2009 (Qt 4.7) Nokia focused on that for the Symbian/Meego.
Ch 3-4: GUI Basics Java Software Solutions Foundations of Program Design Sixth Edition by Lewis & Loftus Coming up: GUI Components.
More on Hierarchies 1. When an object of a subclass is instantiated, is memory allocated for only the data members of the subclass or also for the members.
Graphic User Interface. Graphic User Interface (GUI) Most of us interact with computers using GUIs. GUIs are visual representations of the actions you.
CSC 205 – Java Programming II Applet. Types of Java Programs Applets Applications Console applications Graphics applications Applications are stand-alone.
Dr. Ken Hoganson, Kennesaw State University Introduction to the Torque Game Development System.
Chapter 5: Ball Worlds Features 2 classes, constant data fields, constructors, extension through inheritance, graphics.
Programming in Java CSCI-2220 Object Oriented Programming.
© Copyright by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. 1 Outline 21.1 Test-Driving the Painter Application.
Chapter 6 Introduction to Defining Classes. Objectives: Design and implement a simple class from user requirements. Organize a program in terms of a view.
Simple Classes. ADTs A specification for a real world data item –defines types and valid ranges –defines valid operations on the data. Specification is.
Object Oriented Programming.  Interface  Event Handling.
Programming with Java © 2002 The McGraw-Hill Companies, Inc. All rights reserved. 1 McGraw-Hill/Irwin Chapter 5 Creating Classes.
Object Oriented Analysis & Design Game Patterns. Contents  What patterns are  Delegation  Game Loop  Scene Graph  Double Buffering  Component 
Class Builder Tutorial Presented By- Amit Singh & Sylendra Prasad.
Graphics Concepts CS 2302, Fall /17/20142 Drawing in Android.
 Objects versus Class  Three main concepts of OOP ◦ Encapsulation ◦ Inheritance ◦ Polymorphism  Method ◦ Parameterized ◦ Value-Returning.
Swing - 2 Session 13. Swing - 2 / 2 of 38 Objectives (1) Discuss trees and tables Discuss progress bars Discuss MVC architecture Describe menus.
 In the java programming language, a keyword is one of 50 reserved words which have a predefined meaning in the language; because of this,
Classes, Interfaces and Packages
Lecture 7 Midterm Review. OpenGL Libraries gl: Basic OpenGL library, e.g. primitives. glu: OpenGL Utility library, a set of functions to create texture.
Variations on Inheritance Object-Oriented Programming Spring
Compound Data Types Part13dbg. 2 Point A Point is a simple built-in struct that stores a pair of screen coordinates. Instantiate a Point: Point aPoint.
Chapter 6 Graphical User Interface (GUI) and Object-Oriented Design (OOD)
Basic 2D Graphics in Android. Android Graphics Programming There are many ways to do graphics programming in Android – 2D vs. 3D – static vs. dynamic.
Chapter 9: Continuing Classes By Matt Hirsch. Table Of Contents 1.Static Fields and Methods 2.Inheritance I. Recycle Code with Inheritance II. Overriding.
Chapter 5 Introduction to Defining Classes Fundamentals of Java.
©TheMcGraw-Hill Companies, Inc. Permission required for reproduction or display. Chapter 7 Event-Driven Programming and Basic GUI Objects.
Inheritance Modern object-oriented (OO) programming languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design,
7.1 What Is An Object Object-oriented program - Description or simulation of application Object-oriented programming is done by adopting or extending an.
UofC Large Display Framework
Flash Interface, Commands and Functions
12 Data abstraction Packages and encapsulation
Miscellaneous Topics #6: Polygons GUI Components and Event Handlers
Java Programming Language
DREAMWEAVER MX 2004 Chapter 7 Working with Layers
More on Widgets, Misc. Topics
UofC Large Display Framework
Presentation transcript:

UofC Large Display Framework Part II: Toolkit & Usage Fabrício Anastácio September, 2007

Outline Part I: –Basic Concepts –Objectives –New Structure –I-Buffer Layer –Framework Layer –Framework Classes Part II: –Toolkit Layer –Interface with the Framework –Extending the Framework Classes –Types of Strategies –Some Toolkit Strategies –Creating an Application –Conclusion

Toolkit Layer Separated DLL, depends on the Framework and IBuffer DLLs Provides a set of classes that can be used by an application Uses Qt, SBSDK, and OpenGL by default Allows an application to focus on content creation I-Buffer Large Display Framework Component Toolkit Specific Application

Interfacing with the Framework IBuffer TouchIndicator LargeDisplayManagerVisComponentStrategy VisComponentStateCompositeNodeVisComponent IBufferProxy FrameTimer VectorTemplate Point3f

Extending the LargeDisplayManager class Functions to implement (pure virtual in the parent): –void initComponents() –void initTouchIndicators() –unsigned long pickComponent(unsigned int x, unsigned int y) –unsigned long pickContainer(unsigned int x, unsigned int y, unsigned long excludeComponentId) Optionally: –void resize(unsigned int width, unsigned int height) A default manager (DefaultManager class) is provided, which implements all these methods but initComponents()

LargeDisplayManager initComponents() It is where the root and the other components initially available/visible to the user are created Creating a component: –Instantiate a VisComponent object in a pointer: VisComponent* component = new VisComponent(); –Set the component properties, like position, width, height, rotation angle, etc. –Create strategies for the component: RNTStrategy* rnt = new RNTStrategy(); –Push the strategies into the component: component->pushStrategy(rnt); –If the component is a leaf, set its leaf flag: component->setLeaf(true); –Add the component to the manager: addComponent(component);

LargeDisplayManager initTouchIndicators() Creates a TouchIndicator object for each user: –RoundTouchIndicator* indicatorUser1 = new RoundTouchIndicator(); Adds it to the list of touch indicators in the manager: –touchIndicators.push_back(indicatorUser1);

LargeDisplayManager pickComponent() Provides the rendering API-dependent routine for picking a component It takes the x and y values of the screen coordinates (with origin in the lower left corner) and returns the ID of the picked component or 0, if none was picked The default implementation: –Renders all the components in picking mode (i.e., in a specific color obtained from the component’s ID) in the back buffer –Reads the color of the pixel at the position given as parameter –Converts the color back to a component ID value and returns it It is should be called by the framework and not by the application

LargeDisplayManager pickContainer() Provides the rendering API-dependent routine for picking a container It takes the x and y values of the screen coordinates (with origin in the lower left corner) and the ID of a container to be excluded from rendering (if any); and returns the ID of the picked container or 0, if none was picked It is implemented in the same way as the pickComponent() method with the difference that, instead of rendering all components, it renders only the containers (with the specified exception) in picking mode It is should be called by the framework and not by the application

LargeDisplayManager resize() Defines what should be done when the application is resized Should only be over-ridden if additional behavior is necessary The LargeDisplayManager implementation already takes care of updating the values for the screen dimensions and forwarding the call to the root component In the DefaultManager, the root component is also centralized in the resized screen

Extending the TouchIndicator class Functions to implement (pure virtual in the parent): –void drawIndicator() –void drawExtent() These functions implement the rendering API- specific routines that draw the indicator and its extent (e.g., its bounding rectangle) The toolkit provides a circular touch indicator with color gradient in the RoundTouchIndicator class

Extending the FrameTimer class Functions to implement (pure virtual in the parent): –unsigned long getCurrentTime() –double calculateFrameRate() The getCurrentTime() function is only an interface for getting the value of the current system time The calculateFrameRate() function returns the number of frames per second calculated from the average frame interval duration (obtained from the superclass) and the time unit used by the specific OS The toolkit provides a MS Windows class (WindowsFrameTimer) that uses the GetTickCount() method from the Windows API and calculates the frame rate by converting clock ticks to seconds

Extending the VisComponentStrategy class Functions to implement (pure virtual in the parent): –void initProperties() –void draw(const std::vector & selectedIds) –void drawForPicking() –void pressIn(unsigned int x, unsigned int y) –void pressOut(unsigned int x, unsigned int y) –void drag(unsigned int x, unsigned int y) –void release(unsigned int x, unsigned int y) –void pointIn(unsigned int x, unsigned int y) –void pointOut(unsigned int x, unsigned int y) –void resize(unsigned int width, unsigned int height) –bool drop(bool parentChanged) –void readPassiveBuffers(const std::vector & types) –void readAllPassiveBuffers() –void readAllPickingPassiveBuffers()

VisComponentStrategy initProperties() Creates and initializes active, passive, and/or private buffers for a component Creating an active buffer: –Instantiate a IBufferProxy object: IBufferProxy* bufferProxy = new BufferProxy(); –Set the buffer type: bufferProxy->setType(BufferConstants::SCALE_BUFFER); –Create the buffer: IBuffer * buffer = new IBuffer(BufferConstants::SCALE_BUFFER, nChannels, component->getWidth(), component->getHeight(), component->getWidth(), component->getHeight()); –Fill the buffer (a private function can be created for that): fillScaleBuffer(buffer); –Set the buffer to the proxy object: bufferProxy->setBuffer(buffer); –Add the buffer to the component: component->addActiveBuffer(bufferProxy);

VisComponentStrategy initProperties() Creating a passive buffer: –Instantiate a IBufferProxy object: IBufferProxy* bufferProxy = new BufferProxy(); –Set the buffer type: bufferProxy->setType(BufferConstants::SCALE_BUFFER); –Set the buffer of the proxy object as null: bufferProxy->setBuffer(NULL); –Add the buffer to the component: component->addPassiveBuffer(bufferProxy); For private buffers, the IBufferProxy object is not necessary and the IBuffer<> instance is a private (or protected) instance variable. It is not necessary to add it to the component either

VisComponentStrategy draw() & drawForPicking() These functions implement the rendering API-specific routines to draw a component (or its decoration) for displaying and picking In the toolkit, OpenGL is used as the rendering API The draw() method has the list of selected IDs as parameter so that it can apply different rendering rules to selected components (highlighting) In the drawForPicking() function, the component (or decoration) should be rendered in the color obtained from its ID value: unsigned char pickingColor[3] = { 0, 0, 0 }; component->getIdColor(pickingColor); To improve performance, its strongly suggested that the rendering routines should be implemented as OpenGL display lists, which are initialized by the strategy constructor and called by the drawing methods

VisComponentStrategy Device Functions pressIn(): called when the device is pressed inside the bounds of the associated component pressOut(): called when the device is pressed outside the bounds of the associated component drag(): called when the component is dragged by the device release(): called when the device is release from the associated component pointIn(): called when the device cursor is over the associated component pointOut(): called when the device cursor is not over the associated component

VisComponentStrategy resize() The resize() function is more commonly used to propagate the resizing of an associated component to the active or private buffers managed by the strategy For example: if (component) { IBufferProxy* bufferProxy = component->getActiveBufferByType( BufferConstants::SCALE_BUFFER); if (bufferProxy && bufferProxy->getBuffer()) { IBuffer * buffer = (IBuffer *) bufferProxy->getBuffer(); buffer->resize(width, height, width, height); fillSizeBuffer(buffer); } }

VisComponentStrategy drop() The drop() function defines what should be done when the associated component is “dropped” inside a container It usually defines some “decorative” behavior such as triggering animations The parameter parentChanged indicates if the component’s parent (container) changed with the “dropping” It should return true if the associated component is under a container for which an animation is triggered An animation for adding a component in a container is triggered by calling the animateAdding() method in the VisComponent class, defining the type of the buffers that should be read by the component (for state changes) and what states should be left unchanged by the animation: component->animateAdding(bufferTypes, VisComponent::POSITION | VisComponent::ROTATION_ANGLE);

VisComponentStrategy Buffer Reading Functions readPassiveBuffers(): goes over the list of buffer types passed as parameter and checks if it has any of the types of the passive buffers watched by this strategy. If it does, these buffers are read for the current component position readAllPassiveBuffers(): reads all the passive buffers watched by this strategy for the current component position readAllPickingPassiveBuffers(): reads all the passive buffers watched by this strategy for the current component position that are relevant for picking rendering

Buffer Reading Example Case I: IBufferProxy* bufferProxy = component-> getPassiveBufferByType(BufferConstants::SCALE_BUFFER); if (bufferProxy && bufferProxy->getBuffer()) { IBuffer * buffer = (IBuffer *) bufferProxy->getBuffer(); double bufferX = 0, bufferY = 0; bufferProxy->getOwner()->convertGlobalToBufferCoords( component->getPosition().x, component->getPosition().y, bufferX, bufferY); if (buffer->isInsideActualBuffer(bufferX, bufferY)) { float s = buffer->getValue(bufferX, bufferY); component->setScaleFactor(s); } }

Buffer Reading Example Case II: if (component) { try { float s = component->getPassiveBufferValue ( BufferConstants::SCALE_BUFFER, component->getPosition().x, component->getPosition().y); component->setScaleFactor(s); } catch (std::exception e) {} } Case II is nicer than Case I, but, in initial evaluations, made the test application approximately 10 times slower!

Types of Strategies Depending on their purpose, strategy classes can be classified as: –Behaviors: provide an interaction behavior to a component Ex.: RNT, translation, and tossing. –Containers: have properties that affect the components that are inside them Ex.: Friction surfaces and interface currents. –Observers: allow a component to respond to a certain type of buffer Ex.: Scale observer, rotation observer, and current observer. –Drawing: define how to draw a component or how it is decorated Ex.: Images, borders, and resizing handles –GUI: transform components into widgets Ex.: creators and destroyer buttons

Some Toolkit Strategies ImageStrategy (Drawing): –Draws a component as a quad with texture –Implements only the draw() and drawForPicking() methods –The OpenGL texture name should be passed to the constructor BorderStrategy (Drawing): –Draws a border around the component’s bounds –If the component is selected, draws the border in a different color –Implements only the draw() method

Some Toolkit Strategies ScaleObserverStrategy (Observer): –Changes the scale factor of the associated component with a value read from scale buffer –Implements the initProperties(), drop(), readPassiveBuffers(), readAllPassiveBuffers(), and readAllPickingPassiveBuffers() methods –A passive scale buffer is added by this strategy to the component in the initProperties() method –Animation of the scaling process is triggered by the drop() method

Some Toolkit Strategies RNTStrategy (Behavior): –Provides RNT (Rotation ‘N Translation) behavior to the component –Implements the draw(), pressIn(), drag(), and release() methods –The draw() function only renders the translation circle inside the component (which can be disabled) –The pressIn() function checks a button buffer (if present) before activating the behavior

Some Toolkit Strategies TossableStrategy (Behavior): –Allows a component to be tossed around –Implements the initProperties(), draw(), pressIn(), drag(), release(), readPassiveBuffers(), readAllPassiveBuffers(), and readAllPickingPassiveBuffers() methods –Looks for a friction buffer. If one is not found, user-defined default friction values are used –The draw() method is used to update the component position for every frame while the tossing lasts (no actual rendering) –After the tossing is over, the component is added to the manager’s update list to check if it ended up inside of a container and do the proper adjustments

Some Toolkit Strategies MagnifierLensStrategy (Behavior): –When the associated component is moved over a container that has a scale (active) buffer, it adds a value to the elements of this buffer at its position –Implements the initProperties(), pressIn(), drag(), release(), and resize() methods –Has a scale buffer as a passive buffer (although it writes to it) and has a private buffer filled with the values used to write to the scale buffer –To avoid leaving the scale buffer with the magnified values when the lens component is no longer at that position, when the component is moved the magnified values at the previous position are erased –The resize() method changes the dimensions of the private buffer –This strategy can be extended to have different shapes (e.g.: QuadMagnifierLensStrategy and RoundMagnifierLensStrategy) and different types of magnification (e.g.: GaussianLensStrategy)

Some Toolkit Strategies CreatorStrategy (GUI): –Extends the ImageStrategy class and needs a texture name as parameter of the constructor –Provides a base class for creating components that, when pressed, create another component –Implements only the pressIn() method –Defines a createComponent() pure virtual method that should be implemented by subclasses to provide the code for creation of a specific component DestroyerStrategy (GUI): –Extends the ImageStrategy class and needs a texture name as parameter of the constructor –Implements only the draw() method, adding code to remove and destroy all the current children of the associated component

Some Toolkit Strategies CurrentBeltContainerStrategy (Container): –Provides an implementation of the interface currents –It inherits from the BeltContainerStrategy, which in turn inherits from the BoundedContainerStrategy –The BoundedContainerStrategy provides a container with boundary defined by a spline curve; it has its own gradient border; and has a button buffer for controlling interaction –The BeltContainerStrategy adds an inner boundary to the container –The CurrentBeltContainerStrategy adds active buffers and their filling methods for absolute size, orientation, and movement direction to the container –This hierarchy implements the initProperties(), draw(), drawForPicking(), pressIn(), drag(), release(), and resize() methods

Some Toolkit Strategies CurrentObserverStrategy (Observer): –Provides a component with the ability to react to a current belt container –Observes three different types of buffer (absolute size, orientation, and movement direction) –Implements the initProperties(), drop(), readPassiveBuffers(), readAllPassiveBuffers(), and readAllPickingPassiveBuffers() methods

Creating an Application Auxiliary libraries should be used (e.g.: Qt and SBSDK) A main class should be created, opening a QApplication with a QGLWidget The QGLWidget subclass can be defined by the user or inherited from the QGLSBToolkitWidget class The QGLSBToolkitWidget class provides an implementation of a QGLWidget and a CSBSDK2EventHandler It provides OpenGL initialization, resizing, and drawing; Qt mouse/keyboard and SmartBoard event handlers; and multi-monitor full-screen setup for Windows A subclass of LargeDisplayManager should be passed to the QGLSBToolkit; it can be an extension of the DefaultManager class over-riding only the initComponents() method

Example of initComponents() void MyManager::initComponents() { float borderColor[4] = { 0.3, 0.5, 1.0, 1.0 }; float selectedColor[4] = { 0.8, 0.6, 0.1, 1.0 }; rootComponent->setPosition(Point3f(400, 300, 0)); rootComponent->setWidth(800); rootComponent->setHeight(600); FrictionSurfaceStrategy* friction = new FrictionSurfaceStrategy(); rootComponent->pushStrategy(friction); rootComponent->getStrategy()->initPropertiesComponent(); VisComponent* componentCurrent = new VisComponent(); componentCurrent->setPosition(350, 200); componentCurrent->setWidth(600); componentCurrent->setHeight(500); CurrentBeltContainerStrategy* currentBelt = new CurrentBeltContainerStrategy(150); componentCurrent->pushStrategy(currentBelt); currentBelt->initialize(); addComponent(componentCurrent); // A TextureManager (also from the toolkit) is created and // intialized with some textures here

Example of initComponents() for (int i = 0; i setPosition(currentBelt->getRandomInsidePoint()); float dimension = obtainRandomFloat(150, 30); c->setWidth(dimension); c->setHeight(dimension); c->setRotationAngle(obtainRandomFloat(90) * TO_RADIANS_FACTOR); ImageStrategy* imageStrategy = new ImageStrategy(texManager.getRandomTextureName()); c->pushStrategy(imageStrategy); BorderStrategy* border = new BorderStrategy(); border->setColor(borderColor); border->setSelectedColor(selectedColor); c->pushStrategy(border); TossableRNTStrategy* rnt = new TossableRNTStrategy(); rnt->setColor(selectedColor); c->pushStrategy(rnt); CurrentAwareStrategy* currentAware = new CurrentAwareStrategy(); c->pushStrategy(currentAware); c->setLeaf(true); addComponent(c); } }

Status Quo Currently, the toolkit layer is provided in a DLL (~40 classes) + some adjustments remaining Following steps: –Performance evaluation & Optimization –Further code clean-up –Documentation review –Beta testing & debugging –Simple example applications & tutorials –Toolkit layer expansion (if necessary) –Further refactoring

Special Interest Other rendering APIs: – Direct3D Other platforms: –MacOS –Linux Native usage of the set of DLLs by Java & C# Possible addition of a script layer as an alternative for simple content creation using the toolkit classes

Remembering: Objectives Keep the same functionality Make the framework independent of the applications that use it Make the buffer data structure independent of the framework Separate specialized components from the framework and individual applications Make large display applications easier to create Keep a good performance Add some new features (maybe)

Previous Meeting Dynamic definition of buffer types and button buffer values –BufferConstants class was converted into BufferHelper (a singleton class), providing a method to obtain/create replacements for the constants: unsigned int getBufferTypeIdentifier(std::string description) unsigned int getButtonBufferValue(std::string description) Conversion of the TouchIndicator into a special type of component (with a “TouchIndicatorStrategy”) –Waiting definition of possible framework changes Definition of a generic event handling mechanism (with a more strict implementation of the Strategy Pattern) –Alternative I: partially use the current approach (for drawing & buffers) and handle events in the application accessing the selected components –Alternative II: bypass the current approach (Strategy) and extend the VisComponent class

End of Part II