GithubHelp home page GithubHelp logo

enigma-dev / radialgm Goto Github PK

View Code? Open in Web Editor NEW
44.0 20.0 20.0 3.95 MB

A native IDE for ENIGMA written in C++ using the Qt Framework.

License: GNU General Public License v3.0

C++ 94.91% QMake 1.75% CMake 2.77% Shell 0.03% C 0.55%

radialgm's People

Contributors

9morello avatar dazappa avatar fundies avatar hitcoder9768 avatar joshdreamland avatar kartikshrivastava avatar polygoned avatar removerusky avatar robertbcolton avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

radialgm's Issues

3/28/2018 Tasks

  • Read more about the arena allocation and see if we can just swap when restoring the buffer in the proto model: https://developers.google.com/protocol-buffers/docs/reference/arenas
  • Investigate the QHash destruction for subWindows and resourceModels on the main window
  • Add a "heartbeats" option to the CLI server mode that is turned on by default "GRPC_ARG_KEEPALIVE_TIMEOUT_MS"
  • Make fundies sprite forms
  • Make qscintilla conditional, when off it builds with QPlainTextEdit (so i can debug easier): b459ba8
  • Investigate ways to change the default layout spacing.
  • Review #17

Code Editor Preferences

We need a tab in the preferences dialog to configure syntax highlighting and all that. Also fundies does not like word wrapping so for now I sent #161 to just disable it by default until the preferences are added.

Termination Signal On Close

Just repro'd this while testing to close out another issue.

  1. Open a game.
  2. Open a resource (like room)
  3. Change a setting (like caption or checkbox)
  4. Close main window
  5. Hit cancel
21:11:22: Debugging starts
terminate called after throwing an instance of 'std::bad_array_new_length'
  what():  std::bad_array_new_length
21:11:43: Debugging has finished

Shared Preview Selection Model

Following up on #179, right now the path preview does not use an actual QItemSelectionModel and does not support multiple point selection. It would be possible for the preview to share the same selection model as the points table list. If it did use the model a lot of the selection logic in the path editor could be simplified.
https://doc.qt.io/qt-5/qtwidgets-itemviews-chart-example.html
It would be useful for editing to select several points and move them together. This behavior would also be desired in the room editor where we can consider doing the same thing. Finally, we could also correctly use the current style to paint selection and focus according to the platform conventions, like QGraphicsView/QGraphicsScene does with selected items.

Crash opening debug build

==23262==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000629f2 at pc 0x7f5fe6ef5ab4 bp 0x7fff5c414790 sp 0x7fff5c413f38
READ of size 404 at 0x6140000629f2 thread T0
    #0 0x7f5fe6ef5ab3 in __interceptor_memcpy /build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:790
    #1 0x7f5fe437b68c in QString::QString(QChar const*, int) (/usr/lib/libQt5Core.so.5+0x14a68c)
    #2 0x7f5fe438405a in QStringRef::toString() const (/usr/lib/libQt5Core.so.5+0x15305a)
    #3 0x556d2634dee1 in ResourceReader::process(buffers::Resource const&) /home/greg/RadialGM/Plugins/ServerPlugin.cpp:96
    #4 0x556d2635d477 in AsyncReadWorker<buffers::Resource>::operator()(grpc::Status const&) /home/greg/RadialGM/Plugins/ServerPlugin.cpp:28
    #5 0x556d2633aad4 in CompilerClient::UpdateLoop(void*, bool) /home/greg/RadialGM/Plugins/ServerPlugin.cpp:236
    #6 0x556d2618192d in CompilerClient::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/greg/build/RadialGM-Debug_autogen/SW3NWFZ6YS/moc_ServerPlugin.cpp:230
    #7 0x7f5fe4503ad9 in QObject::event(QEvent*) (/usr/lib/libQt5Core.so.5+0x2d2ad9)
    #8 0x7f5fe512d351 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/libQt5Widgets.so.5+0x15b351)
    #9 0x7f5fe5136828 in QApplication::notify(QObject*, QEvent*) (/usr/lib/libQt5Widgets.so.5+0x164828)
    #10 0x7f5fe44d64f1 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/libQt5Core.so.5+0x2a54f1)
    #11 0x7f5fe44d8d55 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/usr/lib/libQt5Core.so.5+0x2a7d55)
    #12 0x7f5fe452f243  (/usr/lib/libQt5Core.so.5+0x2fe243)
    #13 0x7f5fe34fd6bd in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6b6bd)
    #14 0x7f5fe34ff530  (/usr/lib/libglib-2.0.so.0+0x6d530)
    #15 0x7f5fe34ff570 in g_main_context_iteration (/usr/lib/libglib-2.0.so.0+0x6d570)
    #16 0x7f5fe452e88f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/libQt5Core.so.5+0x2fd88f)
    #17 0x7f5fe44d505b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/libQt5Core.so.5+0x2a405b)
    #18 0x7f5fe44dd065 in QCoreApplication::exec() (/usr/lib/libQt5Core.so.5+0x2ac065)
    #19 0x556d2619db53 in main /home/greg/RadialGM/main.cpp:42
    #20 0x7f5fe3ce5022 in __libc_start_main (/usr/lib/libc.so.6+0x27022)
    #21 0x556d261780ed in _start (/home/greg/rgm/RadialGM-Debug+0x19e0ed)

0x6140000629f2 is located 0 bytes to the right of 434-byte region [0x614000062840,0x6140000629f2)
allocated by thread T0 here:
    #0 0x7f5fe6f69b3a in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:144
    #1 0x7f5fe43060d2 in QArrayData::allocate(unsigned long, unsigned long, unsigned long, QFlags<QArrayData::AllocationOption>) (/usr/lib/libQt5Core.so.5+0xd50d2)

SUMMARY: AddressSanitizer: heap-buffer-overflow /build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:790 in __interceptor_memcpy
Shadow bytes around the buggy address:
  0x0c28800044e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c28800044f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa
  0x0c2880004500: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c2880004510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2880004520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c2880004530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[02]fa
  0x0c2880004540: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c2880004550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2880004560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2880004570: 00 00 00 00 00 00 00 00 00 00 00 00 00 06 fa fa
  0x0c2880004580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==23262==ABORTING```

Feature Ideas

  • Shortcut to open a resource when highlighting it in the code editor
  • Should be able to right click and open resources in external editor directly from the tree, bypassing the internal editor
  • Anywhere there's a resource picker, such as dnd window or object parent, you should also be able to open the resource window just by clicking it
  • Should have modular way for a resource to provide a tooltip to preview its contents when hovering over its node in the tree, i.e. hover over script would show tooltip with first few lines of code
  • Import/export dialog with tree merge
  • Game setting for starting room

Default Values

This is really odd and occurs on master. For some reason the x and y scale are invalid when loading a GMX, but the x and y value of instances is correct. I can reproduce it loading TKG's Key to Success GMX project. I looked high and low and can't seem to find the source of the bug, the Room proto seems correct and has the correct GMX alias of the field name.

Asset Edit Widget

Need to post this before it gets duplicated in too many places since I just copied it from event args dialog to room editor. We need one of those widgets that let's you pick an asset, aka AssetEdit, for parameters and stuff. I want to do a little better and more compact on this than GM did. Ideally I would like you to be able to not only select an asset, but also add one like the add on the object editor in GM8 for the sprite. I would also like it to be easy to open the selected asset for editing from this widget, like the "Edit" button for the sprite on the object editor. The selection and icon preview should be on the left either in a line edit with autocomplete or a combobox or something. The icon preview should show the asset type's icon if the asset type does not have a preview like sprites. The icon preview should have an image tooltip with a transparency background. Finally, on the right should be a split button with Add/Edit/Delete in its menu or something. It also needs to support drag and drop between other asset edits and the main tree like LGM does.

Room Editor Features

As a small project

Complete the RadialGM room editor, bringing it to feature parity with LateralGM (our old Java IDE) and Game Maker.

This includes the following features:

  • Dragging and dropping instances and tiles
  • Selecting regions of instances and tiles to drag
  • Visually editing properties of instances, such as scale and rotation

These items can easily be completed within the 175-hour GSoC timetable. Remaining hours, up to the full 350, can be invested in other items below.

Mentors: Josh, Greg
Difficulty: Easy
Expected size: 175h (can scale to 350h)
Skills required: C++ fundamentals, UI Experience
Skills preferred: Experience with Qt, experience with custom UI programming

Features to scale to a large project

Custom instance properties

Allow setting arbitrary properties (variables) on instances.
Properties can have various types:

  • Coordinates (pair of x/y variables)
  • Regions (two pairs of x/y variables)
  • Corresponding instance (instance ID variable)
  • Path (array of coordinate pairs)

Instance and Tile Groups

Allow users to create groups, similar to in tools like InkScape and Microsoft Office. These groups can be manipulated as a unit using click and drag, or double-clicked to be entered.

Instance and Tile Regions

Think of regions as an optimized group.

The EGM spec supports defining regions of evenly-distributed instances, but the room editor simply unpacks these into an ordinary, dissociative collection of instances upon load. Saving reconstructs groups using connected components.

Add support for defining regions of instances in the room editor instead of placing each instance one-by-one.

Currently, all EGM-generated regions are rectangular, but the IDE should be able to define polygonal regions, as well.

Dynamic groups

A cool feature to add to instance or tile groups is placement semantics. That is, allow the room editor to dynamically fill tile groups based on preset patterns and roles of tiles in a tileset. Examples:

  • Fill a region with a grid of instances (the default behavior for a region).
  • Fill a region with an isometric grid of instances.
  • Randomly fill a region with a certain number or density of instances.
  • Fill a region with a grid of tiles, choosing particular tiles for corners,
    edges, slopes, inner corners, and filling.
    • Allow setting probabilities when multiple options are available for a
      given tile.

For randomized regions, the seed should be a parameter so that users can preview what the result will look like and choose a favorite seed.

Dynamic regions should be ungroupable so that the randomized output can be edited manually.

The EGM spec will need to be extended to support storing the dynamic format. The library that generates the filled ares must go in the ENIGMA Shared folder so that both the engine and IDE can use it.

Overworld support

Create a new resource to allow placing rooms inside a larger room, called an overworld. See the Overworld project proposal for more information.

Data Changed Parent Propagation

Ran into this in #173 working on the room layers, I can't get the repeated model of layers to synchronize with selected layer edits in the property view. There's quite a few issues with the system.

  1. We are passing the child's row & column count as the parent indexes when forwarding the data changed.
    emit m->DataChanged(m->index(0, 0), m->index(rowCount() - 1, columnCount() - 1));
  2. We are saying that the ENTIRE parent model, all rows and all columns, were changed instead of just the submodel's row.
    emit m->DataChanged(m->index(0, 0), m->index(rowCount() - 1, columnCount() - 1));
  3. The parent model getter is giving a proto model of the parent message, not the actual repeated model parent.
    // For *a* instance it would be a pointer to a room's instances field's model

Data Query is Slow

Discovered this while benchmarking the room clip with Rusky. Basically, accessing proto data through the models we provide is pretty damn slow, even in release mode. While this may be ok for some editors and reflection based views, it's particularly problematic for performance-critical views like the room editor.

One area I tested was caching of the descriptor and reflector used in the proto model. This cut field access for the x property of 100,000 instances from 13,000~ microseconds down to about 6,000~ microseconds.

const Descriptor *desc = _protobuf->GetDescriptor();

I have not yet been able to determine from the documentation whether it would be ok for us to do this all the time.
https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message#Reflection

There are also other potential avenues for optimizing all of this, including avoidance of QVariant for data access. One way to do so would be to simply grab and use the protobuf directly in the room painting, rather than access the data through the model.

Narrow 'Create Resource' list based on folder

Hi,
Create Resource menu in RGM shows whole list of resources ignoring the folder type user has clicked on:

image

Taking reference of LGM, it shows only desired Create Resource button instead of a nested list:
image

Avant Garde Editor Layouts

Just a compilation of some various editor ideas I have. Even if we don't go with some of these, a few can still be made into preferences, especially right orientation layout from LGM. One of the reasons why I want to test them now is because of an old idea I had. I was always of the opinion that the background/sprite editor previewers could have easily doubled as the actual built in image editor. If we think of a nice way to lay out the controls, the paint tool palette would just be an embedded dialog.

GameMaker Save Name Right Orientation
GameMaker Layout Save Name Layout Right Orientation Layout
Stacked Embedded Popup
Stacked Layout Embedded Layout Popup Layout
Toolbox Inspector Vertical
Toolbox Layout Inspector Layout Vertical Layout

High DPI Problems

There's going to be a load of these but this is the first bothering me on my 4k display. The tree view has inconsistent icon sizes. The disabled pixmap on empty groups is being rendered bigger than the icons used on all the other tree items. Part of the problem (though I don't understand why it is a problem) is just that we use the disabled pixmap from the group icon.

return icon.pixmap(icon.availableSizes().first(), QIcon::Disabled);

This may not actually be our fault because I have tested using a QIcon vs a QPixmap in a tree model, and I found that icons are always rendered smaller than pixmaps even if they both are loaded from the exact same file. For that reason I am considering reporting this bug upstream to Qt. One workaround for this issue I found is to just construct and return an icon from the disabled pixmap, or alternatively we could change all the icons to pixmaps and use only pixmaps.

QIcon(":/resources/group.png" ) QPixmap(":/resources/group.png" )

Help Crash/Compile Fail Regression

Me and Banshee discussed this over Discord as we both found it independently. It started occurring after I merged #36 and needs resolved. If you go to the master commit just before that it doesn't occur.

There are two ways that the issue manifests. The first is by simply expanding the "Help" group in the project tree, which immediately results in a crash.

20:25:28: Starting C:\Users\Owner\Desktop\Projects\build-RadialGM-Desktop_Qt_MinGW_w64_64bit_MSYS2-Debug\debug\RadialGM...
[libprotobuf FATAL C:/msys64/mingw64/include/google/protobuf/repeated_field.h:1506] CHECK failed: (index) < (current_size_): 
QBackingStore::endPaint() called with active painter on backingstore paint device
terminate called after throwing an instance of 'google::protobuf::FatalException'
  what():  CHECK failed: (index) < (current_size_): 
[libprotobuf FATAL C:/msys64/mingw64/include/google/protobuf/repeated_field.h:1506] CHECK failed: (index) < (current_size_): 
20:25:43: C:/Users/Owner/Desktop/Projects/build-RadialGM-Desktop_Qt_MinGW_w64_64bit_MSYS2-Debug/debug/RadialGM exited with code 3

The second way is by compiling a GMX project which results in the following compile error.

g++ -std=c++11 -I/mingw64/lib/libffi-3.2.1/include -I../Additional/i686-w64-mingw32/include -Wall -s -O3 -fno-rtti -fno-exceptions -DENIGMA_PLATFORM_WINDOWS -DGLEW_STATIC -DCOLLISION_NONE -IPlatforms/Win32/Info -IGraphics_Systems/OpenGL1/Info -IAudio_Systems/None/Info -ICollision_Systems/None/Info -IWidget_Systems/None/Info -INetworking_Systems/None/Info -IUniversal_System/Info -I. -IC:/Users/Owner/AppData/Local/ENIGMA/ -I../../shared/lodepng -I../../shared  -MMD -MP -c -o C:/Users/Owner/AppData/Local/ENIGMA/.eobjs/Windows/Windows/Mingw_GCC_G++/Run/SHELLmain.o SHELLmain.cpp
In file included from SHELLmain.cpp:93:
C:/Users/Owner/AppData/Local/ENIGMA/Preprocessor_Environment_Editable/IDE_EDIT_resourcenames.h: In function 'std::__cxx11::string enigma_user::sprite_get_name(int)':
C:/Users/Owner/AppData/Local/ENIGMA/Preprocessor_Environment_Editable/IDE_EDIT_resourcenames.h:59:5: error: duplicate case value
     case 0: return "help"; break;
     ^~~~
C:/Users/Owner/AppData/Local/ENIGMA/Preprocessor_Environment_Editable/IDE_EDIT_resourcenames.h:58:5: note: previously used here
     case 0: return "sprite0"; break;
     ^~~~
rm -f C:/Users/Owner/AppData/Local/ENIGMA/.eobjs/Windows/Windows/Mingw_GCC_G++/Run/Universal_System/loading.o
make[1]: Leaving directory '/c/Users/Owner/Desktop/Projects/RadialGM/Submodules/enigma-dev/ENIGMAsystem/SHELL'
make: *** [Makefile:20: Game] Error 2

Row Removal Selection Bug

The RepeatedModel::RowRemovalOperation does a full model reset, even for a single row remove.

emit _model.beginResetModel();

The result is that the next item/row is not automatically selected by Qt and no selection changed signal is fired.

CMake error due to gRPC

The following error appears when running cmake command:

~/Desktop/RadialGM/build$ cmake ..
CMake Error at CMakeLists.txt:248 (find_package):
Found package configuration file:

  /usr/local/lib/cmake/grpc/gRPCConfig.cmake

but it set gRPC_FOUND to FALSE so package "gRPC" is considered to be NOT
FOUND.  Reason given by package:

The following imported targets are referenced, but are missing:
protobuf::libprotobuf protobuf::libprotoc

Model Index Validity Checking

I want to talk about #61 which was just merged. What daz did there does in deed fix the crash when creating a new sprite by checking if the model index is valid in the sprite model. However, it did not fix where our code was actually invalid, which is in the sprite editor.

ui->subImageList->setIconSize(spriteModel->GetIconSize());

What I think we need to consider here is if we should be checking if the model indexes are valid in our data models at runtime. This is what is done in official Qt examples. However, I am concerned it will allow us to get away with writing buggy/incorrect code and have it going unnoticed. What I think should be considered is that we move these model index validity checks to the debug build and change them to assertions.

TreeModel needs refactor

The tree model should refactored to inherit from the other models (particularly RepeadedMessageModel)

Delete object crash

If you delete obj_game in the attached file rgm crashes. However if you have all the rooms open in the editors and delete it it will not crash.
tetris.zip

Robert may have broken this but I'm not sure when this broke or if it always had issues.

Protocol Model

It's important that we get this worked out sooner rather than later, and I'd prefer the work to be done starting at the head of the grpc branch.

How things work now

Every editor is constructed with a proto model and a single mapper that can only read and write from the resource associated with that editor:

T *EditorFactory(ProtoModel *model, QWidget *parent) {

This allows editor construction to be generic and a map of the model for each resource (with its tree node as the key) to be held weakly by the main window.

The problem with the current approach

The main window currently has a crash from the destruction of the QHash happening before the QObject::destroyed signal is received by the mdi subwindows:

subWindow->connect(subWindow, &QObject::destroyed, [=]() {

Some people feel this is a mistake with the Qt documentation which explains as though the ::destroyed signal is processed before the destructor, when it's actually the opposite. So the QHash is gone when we get the signal and we can't remove it from the map then.

Not only is this a lot of pointer madness, it doesn't even allow a potential Room editor to access Object or Sprite data. Clearly we can just overload the constructor to the room editor, but then there would go our generic editor construction.

What we should do instead

Let's combine all of the individual proto models into a table-like model and hold a unique_ptr to one instance of it in the main window. Not only is this a lot less nonsensical, and safer, it allows editors to refer to other resources without having to overload their constructors.

Specifically, the editor factory should be changed to:

T *EditorFactory(ProtoModel *model, QModelIndex &modelIndex, QWidget *parent) { 

All editor constructors should be changed to:

BaseEditor::BaseEditor(ProtoModel* model, QModelIndex &modelIndex, QWidget* parent)
: QWidget(parent), model(model), modelIndex(modelIndex), mapper(new ImmediateDataWidgetMapper(this)) {

The ProtoModel class should have a few public helper methods with the following prototypes:

QModelIndex indexOfName(QString resourceName);
QModelIndex indexOfId(buffers::resources::TreeNode::TypeCase type, int id);

Editors have only the requirement that they should be allowed to construct additional ImmediateMapper instances if they so choose to use one for editing resources of another kind. They should still have a default one automatically for the resource of the kind they were created for. They should also be able to use the helper methods on the global protocol model passed to them in their constructor in order to find resources of another kind using the string reference from their proto.

Asset Background Problems

I need to document a couple of issues that came up during implementation of the spatial hash for the room editor. They pertain mainly to the clipping of the painting for asset scroll area.

  1. We are painting the room grid outside of the actual room, which LGM does not do, but I am totally fine with this. I think it's a good idea.
  2. AssetScrollAreaBackground is not using its paint event at all, which tells it the current region being exposed that needs to be repainted. It's much more efficient for us to only paint what needs to be painted.
  3. AssetView is not informed of the paint event by AssetScrollAreaBackground and thus has to completely guess which part of it is exposed for painting. This makes it difficult for the room view to know which window to query in the spatial hash.

Automatic resource naming seems inconsistent

Hi,
I've noticed that whenever we create a new resource under same resource type folder, the index in the name does not increment automatically. It would be convinient to increment the index if user relies on automatic naming.
For example: These three sprite resources are created with the same name:
image

Room Property Editor Has Gaps

This is because the underlying proto field numbers are not contiguous. We are simply using the existing proto model to generate the property editor rows. There are several ways to address this problem.

  • Flatten the existing proto model and or only the edit role. This could be problematic as we made the RepeatedMessageModel use column 0, a field number that can't exist in protobuf, to return the underlying proto model pointer.
  • Provide a proxy model on top of the proto model which flattens the rows.
  • Create a custom property editor view which knows how to skip non-existing rows in the proto model.

Tiles & Instances Outside Room Bug

Currently, there is what should be considered a bug in the room editor. The bounds of the asset scroll area background are fixed around the size of the room, instead of the bounding box of instances and tiles within the room. This makes it difficult, if not impossible, to edit instances and tiles outside of the room.

GameMaker added this starting with version 8.1, but LGM always had it. What's interesting is that GM8.1 removed scrollbars from the room editor completely by offering middle mouse pan, while LGM still managed to keep them. I don't have a preference either way if we keep the scrollbars, but I do think we need to compute a bounding box around the instances and tiles of the room to fix the scrollbars to allow you to go outside the room, or else add middle mouse pan like GM8.1. It would also be ok to do both.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.