Coder Social home page Coder Social logo

rikulo / ui Goto Github PK

View Code? Open in Web Editor NEW
208.0 21.0 49.0 6.35 MB

Rikulo UI is a cross-platform framework for creating amazing Web and mobile applications in Dart and HTML 5.

Home Page: https://quire.io

License: Other

Dart 91.83% CSS 2.12% Shell 1.01% Awk 0.20% HTML 4.83%

ui's Introduction

#Rikulo UI

Rikulo UI is a cross-platform framework for creating amazing Web and native mobile applications in Dart and HTML 5. Our aim is to bring structure to your user interface with a strong layout system, recursive component composition, and neat libraries.

You can access your application directly with a modern Web browser without any plug-in. You can also build it as a native mobile application accessing the device's resources transparently.

Rikulo is distributed under an Apache 2.0 License.

Build Status

##Installation

Add this to your pubspec.yaml (or create it):

dependencies:
  rikulo_ui:

Then run the Pub Package Manager (comes with the Dart SDK):

pub install

For more information, please refer to Rikulo: Getting Started and Pub: Getting Started.

##Usage

Creating UI in Rikulo is straightforward.

import 'package:rikulo_ui/view.dart';

void main() {
  new TextView("Hello World!") //create UI
    .addToDocument(); //make it available to the browser
}

For more information, please refer to the Hello World sample application.

##Notes to Contributors

###Create Addons

Rikulo is easy to extend. The simplest way to enhance Rikulo is to create a new repository and add your own great widgets and libraries to it.

###Fork Rikulo

If you'd like to contribute back to the core, you can fork this repository and send us a pull request, when it is ready.

Please be aware that one of Rikulo's design goals is to keep the sphere of API as neat and consistency as possible. Strong enhancement always demands greater consensus.

If you are new to Git or GitHub, please read this guide first.

##Development Notes

###Compile LESS to CSS

Rikulo CSS rules are placed in view.less. They are written in LESS. If you modify view.less, you have to invoke tool/l2c to generate view.css (under Linux or Cygwin bash).

ui's People

Contributors

henrichen avatar luisvt avatar tomyeh 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  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  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  avatar

ui's Issues

ConcurrentModificationError when removing root view in ActivateEvent handler

Test case: see test/TestPopup1.dart

Cause:
Broadcaster.dart:
bool send(ViewEvent event, {String type}) {
...
//broadcast to all root views
for (final v in rootViews)
if (v.sendEvent(event, type: type))
dispatched = true;
...
}

As ActivateEvent will be broadcasted, any removal/addition of root view within the event handler will cause ConcurrentModificationError in the new List implementation of M3. The old dart implementation doesn't seem to check concurrent modification.

Replace addChild method for Children setter

It would be shorter to have a children setter instead the addChild Method, for examplo:

void main() {
  new View()
    ..addChild(new TextView("Hello World!")
    ..on.click.listen((event) {
      (event.target as TextView).text = "Welcome to Rikulo.";
      event.target.requestLayout();
    }), new TextView("Hello World!"))
    ..addChild(new View()
      ..layout.type = "linear" //arrange the layout of child views linearly
      ..addChild(new TextView("Name")) //a label
      ..addChild(new TextBox()))
    ..addToDocument(); 

}

would be shorter to have

new View()
    ..children = [
      new TextView("Hello World!")
        ..on.click.listen((event) {
          (event.target as TextView).text = "Welcome to Rikulo.";
          event.target.requestLayout();
      }),
      new View()
        ..layout.type = "linear" //arrange the layout of child views linearly
        ..children = [
          new TextView("Name"), //a label
          new TextBox()
      ]
   ]
   ..addToDocument(); 

I think that it could be solved adding this code to the View class:

set children(List<View> views) {
    views.forEach((view) => this.addChild(view));
  }

Links to source and blog post for examples give 404s

The examples on this page work fine, but when you click "Source code" or "Blog post" on any of them, they can't be found.

I found Rikulo yesterday, after the Dart M1 / pub.dartlang.org release, and it looks very good. Though dead links don't give the best first impressions.

Switch in hidden View does not correctly show "false" state when show

  1. Switch with "false" state and in a hidden View
  2. Show the View and request layout
  3. Switch does not correctly show the "false" state

Issue5.dart

#import('../../client/app/app.dart');
#import('../../client/view/view.dart');
#import('../../client/model/model.dart');
#import('../../client/event/event.dart');
#import('../../client/util/util.dart');

class Issue5 extends Activity {

  void onCreate_() {
    TextView btn = new TextView("show");
    mainView.addChild(btn);
    View myView = new View();
    mainView.addChild(myView);

    btn.on.click.add((event) {
        myView.hidden = false;
        myView.requestLayout();
    });

    myView.hidden = true;
    myView.layout.text = "type: linear; orient: vertical";

    myView.addChild(createSwitch(true));
    myView.addChild(createSwitch(false));
    myView.addChild(createSwitch(true, "Yes", "No"));
    myView.addChild(createSwitch(false, "True", "False"));
    myView.addChild(createSwitch(true, small: true));
    myView.addChild(createSwitch(false, small: true));

  }
  Switch createSwitch(bool value, [String onLabel, String offLabel, bool small=false]) {
    Switch view = new Switch(value, onLabel, offLabel);
    if (small)
      view.classes.add("v-small");
    view.on.change.add((event){
      log("Switch${view.uuid}: ${view.value}");
    });
    return view;
  }
}

void main() {
  new Issue5().run();
}

EasingMotion breaks encapsulation

creating multiple easingmotions with different durations seem to conflict with one another, either the longer time will cause the shorter to repeat, or worse, the _animator object gets an out of bounds error when trying to remove a task

[layout]liner layout + flex TextView + TextView with "profile.width"

Expect right text to be positioned at "right" but was positioned at "left top". Note that if we remove this line:

  ...
  right.profile.width="50px";
  ...

then things work as expected.

B0002.dart

#import('../../client/app/app.dart');
#import('../../client/view/view.dart');
#import('../../client/model/model.dart');
#import('../../client/event/event.dart');

class B0002 extends Activity {
  void onCreate_() {
    mainView.layout.type = "linear";
    mainView.layout.orient = "vertical";

    //hlayout
    View hlayout = new View();
    hlayout.layout.type = "linear";
    hlayout.layout.orient = "horizontal";
    hlayout.profile.width = "100%";
    hlayout.profile.height = "content";
    mainView.addChild(hlayout);

    //left text
    TextView left = new TextView("LEFT TEXT");
    left.profile.width = "flex";
    left.style.lineHeight = "30px";
    hlayout.addChild(left);

    //right text
    TextView right = new TextView("RIGHT TEXT");
    right.profile.width="50px";  //<----------- if remove this line, then things work well
    hlayout.addChild(right);
  }
}

main() {
  new B0002().run();
}

B0002.html

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="../../resources/css/view.css" />
  </head>
  <body>
    <script type="application/dart" src="B0002.dart"></script>
    <script src="../../resources/js/dart.js"></script>
  </body>
</html>

Update for rikulo_commons 2.0.x

Needs an update to allow it to work with rikulo_commons 2.0.x. At the moment it fails as some of the libraries have been removed e.g. html.dart.

Alternative is to set rikulo_commons to <2.0.0 in pubspec.

[layout] liner layout + flex TextView + anchored right TextView

Right TextView expected to be place at "center, right" corner but was at "top, left".

B0000.dart

#import('../../client/app/app.dart');
#import('../../client/view/view.dart');
#import('../../client/model/model.dart');
#import('../../client/event/event.dart');

class B0000 extends Activity {
  void onCreate_() {
    mainView.layout.type = "linear";
    mainView.layout.orient = "vertical";

    //hlayout
    View hlayout = new View();
    hlayout.layout.type = "linear";
    hlayout.layout.orient = "horizontal";
    hlayout.profile.width = "100%";
    hlayout.profile.height = "content";
    mainView.addChild(hlayout);

    //left text
    TextView left = new TextView("LEFT TEXT");
    left.profile.width = "flex";
    left.style.lineHeight = "30px";
    hlayout.addChild(left);

    //right text
    TextView right = new TextView("RIGHT TEXT");
    right.profile.anchor = "parent";
    right.profile.location = "center, right";
    hlayout.addChild(right);
  }
}

main() {
  new B0000().run();
}

B0000.html

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="../../resources/css/view.css" />
  </head>
  <body>
    <script type="application/dart" src="B0000.dart"></script>
    <script src="../../resources/js/dart.js"></script>
  </body>
</html>

event.target may not be Element in _ViewImpl: _domEvtDisp(String)

In _ViewImpl.dart:

_DOMEventDispatcher _domEvtDisp(String type) {
  return (View target) {
    return (Event event) {
      var tv = event.target; //the real target based on the event
      if (tv != null)
        tv = ViewUtil.getView(tv);
      target.sendEvent(new DOMEvent(event, type, tv != null ? tv: target));
    };
  };
}

event.target may not be an Element (for example, text node) and will cause cast exceptions.

ConcurrentModificationError in RunOnceViewManager._flushAll()

The method starts with code:

for (final View view in _views) {
if (_ignoreDetached && !view.inDocument) {
_views.remove(view); //ignore detached
continue;
}
...

So, when the if is triggered, a child is removed from _views and thus the for-each throws the error.

I will try to submit a pull request if I have time. I suggest just making a copy of the set before iterating (possible optimization: if _ignoreDetached==false and _ignoreSubviews==false no copy is needed).

Image disapper after hide and show

  1. Image in a View.
  2. Hide the View
  3. Show the View
  4. Should see the image but cannot.

Issue6.dart

#import('../../client/app/app.dart');
#import('../../client/view/view.dart');
#import('../../client/model/model.dart');
#import('../../client/event/event.dart');
#import('../../client/util/util.dart');

class Issue6 extends Activity {

  void onCreate_() {
    TextView btn = new TextView("show");
    btn.profile.anchor = "parent";
    btn.profile.location = "top center";

    TextView btn2 = new TextView("hide");
    btn2.profile.anchor = "parent";
    btn2.profile.location = "top right";

    mainView.addChild(btn);
    mainView.addChild(btn2);

    View myView = new View();
    mainView.addChild(myView);
    myView.layout.text = "type: linear; orient: vertical";
    myView.addChild(new Image("res/search.png"));

    btn2.on.click.add((event) {
      log("click hide");
      myView.hidden = true;
      myView.requestLayout();
    });

    btn.on.click.add((event) {
      log("click show");
        myView.hidden = false;
        myView.requestLayout();
    });
  }
}

void main() {
  new Issue6().run();
}

Compilation of view when adding a background image causes a problem

In my snake example I add a background image using the following code:

View div = new View();
div.style.backgroundImage = "url('./res/snake_bg.png')";
div.profile.width = "flex";
div.profile.height = "flex";

However, when compiled the background image isn't outputted correctly (at least on Firefox). I did a small test using pure Dart and it worked well, here is the test code that I compiled:

test.dart

#import('dart:html');

void main() {
    document.query("#blah").attributes["style"] = "background-image: url('./res/snake_bg.png')";
}

index.html

<!DOCTYPE html>
<html>
    <!-- Demo of animating canvas -->
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="./resources/css/view.css" />
  </head>
  <body>
    <script type="application/dart" src="test.dart"></script>
    <script src="./resources/js/dart.js"></script>
    <div id="blah">
        Blah
    </div>
  </body>
</html>

Feature: Drag and Drop

Dragger is not enough for handling drag-and-drop. Though it is possible to handle it at DOM level, it is better to have a more elegant and transparent approach for doing it.

[view]View.hidden not work properly

call _left.hidden=true; _right.hidden=false; then requestLayout, expect _right to show(which was original hidden) but it does not.

B0003.dart

#import('../../client/app/app.dart');
#import('../../client/view/view.dart');
#import('../../client/model/model.dart');
#import('../../client/event/event.dart');

class B0003 extends Activity {
  View _left, _right;
  void onCreate_() {
    mainView.layout.type = "linear";
    mainView.layout.orient = "vertical";

    //hlayout
    View hlayout = new View();
    hlayout.layout.type = "linear";
    hlayout.layout.orient = "horizontal";
    hlayout.profile.width = "100%";
    hlayout.profile.height = "content";
    mainView.addChild(hlayout);

    //left text
    TextView left = new TextView("LEFT TEXT");
    hlayout.addChild(left);
    _left = left;

    //right text
    TextView right = new TextView("RIGHT TEXT");
    right.hidden = true;
    hlayout.addChild(right);
    _right = right;

    _left.on.click.add((event) {_left.hidden = true; _right.hidden = false; mainView.requestLayout();});
    _right.on.click.add((event) {_left.hidden = false; _right.hidden = true; mainView.requestLayout();});
  }
}

main() {
  new B0003().run();
}

B0003.html

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="../../resources/css/view.css" />
  </head>
  <body>
    <script type="application/dart" src="B0003.dart"></script>
    <script src="../../resources/js/dart.js"></script>
  </body>
</html>

requestLayout(immediate: true) shalln't ignore immediate if there is a pending model rendering request

Currently, requestLayout(immediate: true) will wait if there is a pending model rendering (i.e., modelRenderer is not empty). It is not correct since the caller of requestLayout will assume everything is ready (otherwise, it is hard to write the code).

Example,

class Issue11 extends Activity {

  void onCreate_() {
    mainView.layout.text = "type: linear; orient: vertical";

    //prepare data
    final DefaultListModel<String> model
      = new DefaultListModel(["apple", "orange", "lemon", "juice"]);
    model.addToSelection("orange");
    model.addToDisables("juice");

    final rg = new RadioGroup();
    mainView.addChild(rg);

    final btn = new Button("test");
    btn.on.click.add((event) {
      rg.model = model;
      mainView.requestLayout(immediate: true);
      mainView.addChild(
        new TextView(rg.node.query('input') != null ?
          "Success!":
          "Wrong! requestLayout+immediate shall force model to render immediately"));
      mainView.requestLayout();
    });
    mainView.addChild(btn);
  }
}

Each subclass of View shall override className

Currently, it depends on this.runtimeType.toString(). However, it is meaningless if it is converted to JS with the minify flag.

Thus, each subclass shall override it and return its class name.

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.