I have a tabbed web page and I would like to place two different instances of mxGraph, one on the 1st tab and the other one on the 2nd tab:
var editor1 = new mxEditor();
var editor2 = new mxEditor();
I would like to configure each instance in its own way, so the two editors should have different behaviours and properties. Unfortunately, mxGraph is based on lots of static constructs:
mxConstants.EDGE_SELECTION_COLOR = '#a8d6e1';
mxGraphView.prototype.updateFloatingTerminalPoint = function (...) { ... };
mxConnectionHandler.prototype.movePreviewAway = false;
...
It seems that placing two graphs on the same page isn't the right thing to do, since the latest configurations would override others and, maybe, one event can conflict with other ones.
What are you suggesting me?
I'm thinking at completely redrawing graph every time a tab gets focused, but: 1. performances? 2. does mxGraph have a global destroy or reset function? 3. any side effect?...
Related
Does anyone know of a way to have a central master template for google slide presentations that automatically cascades changes down to presentations using it ?
If not automatic then maybe there is something that can be done with google apps script to pull any changes to the master template down to the associated presentations ?
Here is a simple example of what I am trying to do:
Create master template/theme (M1) with layout (L1) with two placeholders and a company logo
Create new presentation (P1) importing theme M1 above using Layout L1
Amend master theme M1 Layout A with new company logo or new placeholder
How do i get this change to propagate to P1 without manually importing the template/theme again ? It would be ideal if P1 could subscribe to changes in M1 but i can't see any option for this so was wondering if I could script something ?
Thanks in advance
Greg
This is not possible in Apps Script right now
There is a feature request for this in the Issue Tracker, go give it a ☆!
https://issuetracker.google.com/issues/129457735
Maybe go and explain your use case for it too.
Possible avenue for workaround
The best workaround I can think of is something along the lines of this script:
function copyStyling() {
// This is a standalone script
let masterID = "1107dQEIAbZ8ipBi0wvU6cdy4OV7N2hURT5fjgOwm_vY";
let childID = "1XvGARRBzXofsjrFJkl8SCmt3tQJ2nkw1n9MG3tr9fhU";
// Master Slide Variables
let masterPresentation = SlidesApp.openById(masterID);
let masterSlide = masterPresentation.getSlides()[0];
let masterElements = masterSlide.getPageElements();
// Get style elements
let masterBackground = masterSlide.getBackground();
let masterSolidFill = masterBackground.getSolidFill().getColor();
// etc
// ...
// Child Slide Variables
let childPresentation = SlidesApp.openById(childID);
let childSlide = childPresentation.getSlides()[0];
let childElements = childSlide.getPageElements();
// Updating the stylings for the page
let childBackground = childSlide.getBackground();
childBackground.setSolidFill(masterSolidFill);
// etc
// ...
// Updating the stylings for each element on the page
masterElements.forEach((element, i) => {
childElements[i].setLeft(element.getLeft());
childElements[i].setTop(element.getTop());
// etc
// ...
});
}
This script works if both Master and Child presentations use the same theme (i.e. the master style sheets)
It works by having a single slide in a "Master presentation" which you modify and the Child presentations also have only a single slide.
It gets style info. This script gets the background of the slide (if its a solid fill) and the top left position of each element.
It then updates the child with this information.
It really depends on how many changes are going to happen to the child presentations. If no elements are going to change, and only limited style characteristics are going to change, then it shouldn't take too long to get a working script together. It would just involve going through the documentation and picking out the attributes you want to update.
If the number of elements are going to change, their positions going to be rearranged, with very different content from the placeholders, then it can get considerably more complex. Then it becomes a function of how many hours you can invest into it! Though hopefully this serves as a good starting point for that.
Ideally to this script would be added the width and height of each element to go along with the top and left position, their rotation, transformation, font, font color, font font style, direction, and minimal support for shapes. With these things I believe you could have quite a powerful tool.
Reference
Apps Script Slides Service
I'm writing a page where there are many components reside in single frame. In a sense, this is quite similar to concept of Single-Page Application. We have multiple components and slickGrid table is one of them. I'm trying to unify some interaction set into single vocabulary, each of them getting through its own channel.
However, when it comes to highlighting the row, things got complicated. I still haven't figured out the way to activate highlight function in slickgrid to highlight a specific row through javascript. Is it possible to do so?
Not quite sure which event you're after, but in the slickgrid source code there's a trigger function which is used to fire all slickgrid events, which you can use:
let trigger = (evt, args, e) => {
e = e || new Slick.EventData()
args = args || {}
args.grid = grid
return evt.notify(args, e, this.grid)
}
use it like:
trigger(grid.onMouseEnter, {...})
The only missing variable here is grid.
I have a menu with five buttons. Menu is visible all the time. there is click event for each menu item. which slides corresponding movie clip from left to right. each movie clip has different nature events and respective animation and activity. for example tab 1 brings the video page. and within that movie clip I have video events like play pause volume and on complete etc. events and code. tab 2 has button group for Time and another button group Features. depending on user selection code will calculate and show value on a animated counter. tab 3 has button group for Time and button group Source. as per the user selection it will calculate and show the values as animated graph. and so on.
Right now I have all the individual tab movie clip has its own time line code for its own events. and some crossover variables and references with other tabs. Everything is working as expected. No problem. I know time line code is not the best way to do any complex project.
So, I would like to get the entire coding as one class or more classes if that is the correct way.
I am beginner as far as class logic. I have already created Main as document class and could control the general navigation of tabs and their initial look. But stuck at tab specific button events and other such unique events for the specific tab.
Any help is greatly appreciated. Thanks in advance.
any similar example or suggestions.
First of all, thanks a lot for a prompt response. It seems like I am not even a beginner. I need to read a lot and probalbly grasp all fundamental concepts thoroughly. I have gone through both the links suggested in your comments. I am trying to digest the stuff slowly. I do not have any formal informal education regarding OOP or any sort of programming. To be honest, I have hard time understanding the code you have suggeted. Not because of your code but because of my level of caliber. I will have to spend some time to make myself clearer regarding events and sequence etc. different tab contents are as movieclips to main timeline and already placed on stage. It comes and goes to its corresponding tab button click event. I am not marking your answer as yes because I still need to my own homework based on your suggestion. Thanks a lot once again. I am sure I will ask few more questions later.
This is how I would design it:
I'd have a Menu Class, which only contains the buttons and "converts" clicks on them into more specific events. That might look something like this:
public Class Menu extends Sprite {
protected var buttons:Vector. = new Vector.();
public function Menu() {
super();
var loops:int = numChildren;
for (var i:int=0; i<loops; i++) {
var button:SimpleButton = getChildAt(i) as SimpleButton;
if (button) {
buttons[buttons.length] = button;
button.addEventListener(MouseEvent.CLICK, broadcastMenuEvent);
}
}
}
public function broadcastMenuEvent(e:Event):void {
var button:DisplayObject = e.currentTarget as DisplayObject;
dispatchEvent(new Event(button.name, true));//bubbling, can catch at any level
}
}
The way this is built, you can change the events that are being dispatched simply by changing the name you give the instance of the button on stage. Note that you need to apply Menu as the Base Class and not the Class for this to work if you have "declare instances automatically" unchecked, because doing it that way allows the compiler to generate those instance names for you in a way your base Class doesn't have to know about.
At this point, you can then deal with those events in another place--whether it's your main document Class or whether you have a separate Controller.
I would define each of the Views you described as a separate Class as well. If you have objects coming and going on the stage, you can use one of the techniques described here to handle that. Otherwise, it's fairly straightforward to address your timeline instances from the base Class instead of timeline code. Again, you can listen for those events in the main document Class or a dedicated Controller--the main point is to make sure your Views are not making any important decisions and usually they should not be editing data.
You can choose to have your Main Document orchestrate how the tabs get added and removed (I'm a big fan of using the timeline with goToAndStop, but not everyone shares this preference), or, again, you can separate this logic out to a dedicated Controller. I would suggest that if it's possible to generalize how your Views work to have them implement a single Interface. That way, you can give them a single instance name and manage them all with the same getter/setter pair (assuming you go the timeline route).
Note the Flash compiler isn't terribly sophisticated in this regard, so if you do this and your Views extend different parent Classes, you'll get compiler warnings. Just ignore these--they don't mean anything.
The thing you shoud try to root out of your code completely is the part where Views are referencing each other. The only time it's acceptable for one View to know about another is when it's a parent knowing about its child. Even then, try to have as little specific knowledge as possible. Notice in the Menu View I wrote as an example, the parent only knows there may be some SimpleButtons, but it has no specific knowledge of where they are on stage, what, specifically, is in them, or even what there instance names are.
Instead of having your Views know about one another, have a third party (which, again, you can choose to use the main Document Class for or not) that transfers requests for state changes (in the form of events) from one to another.
I've got the following problem, my boss wants me to make our app far more responsive without any waiting time between switching views. It used to a "standard" application based on a ViewNavigator but with just one View that was destroyed and re-created with different content based on the user's selection of tabs he created himself. Views were switched with the default SlideViewTransition. I'm down to half a second now with a slightly more lightweight approach as described below, however that half second is still too much.
The app is a tabbed application where the user can create and edit new views himself, so create/edit/delete tabs and their corresponding tabs.
My current implementation is based on a ButtonBar and a Group that is used to display the "views". The group's content is created based on the selected tab. The content is based on XML data that stores all the required information to build the "view". Naturally, removing and creating the component's takes a little while (the half second I talked about), so I'm after another solution.
What I thought about is using the ViewNavigator and create all stored views upon application start.
Very much like this:
for each (var _view:XML in _allViewsConfig.children()) {
var compView:View = new View();
compView.percentHeight = 100;
compView.percentWidth = 100;
compView.name = _view.label;
for each (var _groupElement:XML in _view.vgroup) {
var group:VGroup = new VGroup;
group.percentWidth = 100;
group.percentHeight = 100;
for each (var _windowElement:XML in _groupElement.window) {
var window:WindowContainer = new WindowContainer;
for each (var _componentElement:XML in _windowElement.component) {
var component:UIComponent = _componentManager.create(_componentElement.#type, _componentElement);
window.addElement(component);
}
group.addElement(window);
}
compView.addElement(group);
}
views.addItem(compView);
}
views is an ArrayList that is used to store the created views.
The only problem I've got right now is that I can't use the Views stored in this ArrayList in the corresponding ViewNavigator.
I tried it the usual way, i.e. navigation.pushView(_viewCreator.views.getItemAt(0) as Class);
This, however doesn't work, no error or anything, the ViewNavigatorjust doesn't do anything, so I guess that a View class can't be created like this.
So how can I make this work?
Also, do you guys think that this is a proper solution to the problem, especially considering the whole dynamic nature of the application (being based on tabs)?
Naturally, slide transitions will be completely disabled as they are quite slow with our complex components.
Any help, comments or thoughts would be greatly appreciated!
EDIT:
On second thought, simply using Groups instead of ViewNavigator and View should make this a little more lightweight and solve the issue of views not being pushed.
In fact ViewNavigator pushView() is a mechanism which create an instance of a given Class (method parameter).
For all navigation history purpose, ViewNavigator uses NavigationStack objects to store relevant values (that you can customize too).
I don't have a straightforward answer for you, but I think you'll have to implement your own custom ViewNavigator mechanism (extending ViewNavigator to leverage existing useful methods and override others).
My head is spinning from two days of trying to find an answer to this seemingly simple question.
I'm developing a Flex/AIR application built entirely in ActionScript -- there's no MXML beyond what was originally auto-created.
I need to dynamically generate some kind of editable text-field with high control over formatting. The TLF text fields all seem great, except that I can't get any of them to render on the screen. Due to the nature of the application, they have to be inside a MovieClip, but since I've read that everything must be a descendant of UIComponent, I use UIMovieClip, which is AddChild'ed to the stage.
I'm about to go crazy here, the whole application is in jeopardy over this. I CAN NOT use MXML, and all the 10,000 examples on the internet are MXML. I need to generate these dynamically. I need to generate upwards of 50 fields under one movieclip based on database data. There's no way to hardcode that with MXML. Please don't suggest to change this. The GUI is very specific about this, and it's the right GUI.
In two days of searching, I can't find a single example in ActionScript, only MXML. I've tried everything that smelled like an example.
Is there some obvious general pointer I'm missing? I'll be happy to post code, but it doesn't make sense because I've been through so many examples.
Does anyone have the simplest possible code for creating any kind of TLF text editing field in ActionScript only (zero MXML), which is then added to a MovieClip or UIMovieClip, which is added to the stage of a desktop AIR application?
I will greatly cherish any help here.
Best,
Per
This should get you started:
//create your TextFlow component
var textFlow:TextFlow = new TextFlow();
var p:ParagraphElement = new ParagraphElement();
var span:SpanElement = new SpanElement();
span.text = "hello world";
p.addChild(span);
textFlow.addChild(p);
//create a Sprite that will contain the text
var textBlock:Sprite = new Sprite();
//create a controller for compositing
var controller:ContainerController = new ContainerController(textBlock);
//set the size of the composition
controller.setCompositionSize(100, 200);
//make the controller control the TextFlow object
textFlow.flowComposer.addController(controller);
//update the composition
textFlow.flowComposer.updateAllControllers();
//add to the stage
addChild(textBlock);
About the size: it is important you use setCompositionSize() instead of the Sprite's width and height properties.
Using addController() you could spread the text over several Sprites. Each Sprite would have its own ContainerController, but all would share the same FlowComposer which would calculate the composition.
warning : using TLF like this can be pretty complicated. Above code is the bare minimum to get things running. I do not know your requirements, but you'll probably hit a few other roadblocks along the way. You have to ask yourself this question: are you really willing to drop all the built-in features of TextArea? It might cost you months of development to get things right, depending on the requirements. You still may want to reconsider your architecture...